Revision 27bb0b2d

b/hw/hpet.c
37 37
#define DPRINTF(...)
38 38
#endif
39 39

  
40
struct HPETState;
41
typedef struct HPETTimer {  /* timers */
42
    uint8_t tn;             /*timer number*/
43
    QEMUTimer *qemu_timer;
44
    struct HPETState *state;
45
    /* Memory-mapped, software visible timer registers */
46
    uint64_t config;        /* configuration/cap */
47
    uint64_t cmp;           /* comparator */
48
    uint64_t fsb;           /* FSB route, not supported now */
49
    /* Hidden register state */
50
    uint64_t period;        /* Last value written to comparator */
51
    uint8_t wrap_flag;      /* timer pop will indicate wrap for one-shot 32-bit
52
                             * mode. Next pop will be actual timer expiration.
53
                             */
54
} HPETTimer;
55

  
56
typedef struct HPETState {
57
    uint64_t hpet_offset;
58
    qemu_irq *irqs;
59
    HPETTimer timer[HPET_NUM_TIMERS];
60

  
61
    /* Memory-mapped, software visible registers */
62
    uint64_t capability;        /* capabilities */
63
    uint64_t config;            /* configuration */
64
    uint64_t isr;               /* interrupt status reg */
65
    uint64_t hpet_counter;      /* main counter */
66
} HPETState;
67

  
40 68
static HPETState *hpet_statep;
41 69

  
42 70
uint32_t hpet_in_legacy_mode(void)
43 71
{
44
    if (hpet_statep)
45
        return hpet_statep->config & HPET_CFG_LEGACY;
46
    else
72
    if (!hpet_statep) {
47 73
        return 0;
74
    }
75
    return hpet_statep->config & HPET_CFG_LEGACY;
48 76
}
49 77

  
50 78
static uint32_t timer_int_route(struct HPETTimer *timer)
51 79
{
52
    uint32_t route;
53
    route = (timer->config & HPET_TN_INT_ROUTE_MASK) >> HPET_TN_INT_ROUTE_SHIFT;
54
    return route;
80
    return (timer->config & HPET_TN_INT_ROUTE_MASK) >> HPET_TN_INT_ROUTE_SHIFT;
55 81
}
56 82

  
57 83
static uint32_t hpet_enabled(void)
......
108 134

  
109 135
static uint64_t hpet_get_ticks(void)
110 136
{
111
    uint64_t ticks;
112
    ticks = ns_to_ticks(qemu_get_clock(vm_clock) + hpet_statep->hpet_offset);
113
    return ticks;
137
    return ns_to_ticks(qemu_get_clock(vm_clock) + hpet_statep->hpet_offset);
114 138
}
115 139

  
116 140
/*
......
121 145

  
122 146
    if (t->config & HPET_TN_32BIT) {
123 147
        uint32_t diff, cmp;
148

  
124 149
        cmp = (uint32_t)t->cmp;
125 150
        diff = cmp - (uint32_t)current;
126 151
        diff = (int32_t)diff > 0 ? diff : (uint32_t)0;
127 152
        return (uint64_t)diff;
128 153
    } else {
129 154
        uint64_t diff, cmp;
155

  
130 156
        cmp = t->cmp;
131 157
        diff = cmp - current;
132 158
        diff = (int64_t)diff > 0 ? diff : (uint64_t)0;
......
136 162

  
137 163
static void update_irq(struct HPETTimer *timer)
138 164
{
139
    qemu_irq irq;
140 165
    int route;
141 166

  
142 167
    if (timer->tn <= 1 && hpet_in_legacy_mode()) {
......
144 169
         * timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC,
145 170
         * timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC.
146 171
         */
147
        if (timer->tn == 0) {
148
            irq=timer->state->irqs[0];
149
        } else
150
            irq=timer->state->irqs[8];
172
        route = (timer->tn == 0) ? 0 : 8;
151 173
    } else {
152
        route=timer_int_route(timer);
153
        irq=timer->state->irqs[route];
174
        route = timer_int_route(timer);
154 175
    }
155
    if (timer_enabled(timer) && hpet_enabled()) {
156
        qemu_irq_pulse(irq);
176
    if (!timer_enabled(timer) || !hpet_enabled()) {
177
        return;
157 178
    }
179
    qemu_irq_pulse(timer->state->irqs[route]);
158 180
}
159 181

  
160 182
static void hpet_pre_save(void *opaque)
161 183
{
162 184
    HPETState *s = opaque;
185

  
163 186
    /* save current counter value */
164 187
    s->hpet_counter = hpet_get_ticks();
165 188
}
......
212 235
 */
213 236
static void hpet_timer(void *opaque)
214 237
{
215
    HPETTimer *t = (HPETTimer*)opaque;
238
    HPETTimer *t = opaque;
216 239
    uint64_t diff;
217 240

  
218 241
    uint64_t period = t->period;
......
220 243

  
221 244
    if (timer_is_periodic(t) && period != 0) {
222 245
        if (t->config & HPET_TN_32BIT) {
223
            while (hpet_time_after(cur_tick, t->cmp))
246
            while (hpet_time_after(cur_tick, t->cmp)) {
224 247
                t->cmp = (uint32_t)(t->cmp + t->period);
225
        } else
226
            while (hpet_time_after64(cur_tick, t->cmp))
248
            }
249
        } else {
250
            while (hpet_time_after64(cur_tick, t->cmp)) {
227 251
                t->cmp += period;
228

  
252
            }
253
        }
229 254
        diff = hpet_calculate_diff(t, cur_tick);
230
        qemu_mod_timer(t->qemu_timer, qemu_get_clock(vm_clock)
231
                       + (int64_t)ticks_to_ns(diff));
255
        qemu_mod_timer(t->qemu_timer,
256
                       qemu_get_clock(vm_clock) + (int64_t)ticks_to_ns(diff));
232 257
    } else if (t->config & HPET_TN_32BIT && !timer_is_periodic(t)) {
233 258
        if (t->wrap_flag) {
234 259
            diff = hpet_calculate_diff(t, cur_tick);
235
            qemu_mod_timer(t->qemu_timer, qemu_get_clock(vm_clock)
236
                           + (int64_t)ticks_to_ns(diff));
260
            qemu_mod_timer(t->qemu_timer, qemu_get_clock(vm_clock) +
261
                           (int64_t)ticks_to_ns(diff));
237 262
            t->wrap_flag = 0;
238 263
        }
239 264
    }
......
260 285
            t->wrap_flag = 1;
261 286
        }
262 287
    }
263
    qemu_mod_timer(t->qemu_timer, qemu_get_clock(vm_clock)
264
                   + (int64_t)ticks_to_ns(diff));
288
    qemu_mod_timer(t->qemu_timer,
289
                   qemu_get_clock(vm_clock) + (int64_t)ticks_to_ns(diff));
265 290
}
266 291

  
267 292
static void hpet_del_timer(HPETTimer *t)
......
285 310

  
286 311
static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr)
287 312
{
288
    HPETState *s = (HPETState *)opaque;
313
    HPETState *s = opaque;
289 314
    uint64_t cur_tick, index;
290 315

  
291 316
    DPRINTF("qemu: Enter hpet_ram_readl at %" PRIx64 "\n", addr);
......
293 318
    /*address range of all TN regs*/
294 319
    if (index >= 0x100 && index <= 0x3ff) {
295 320
        uint8_t timer_id = (addr - 0x100) / 0x20;
321
        HPETTimer *timer = &s->timer[timer_id];
322

  
296 323
        if (timer_id > HPET_NUM_TIMERS - 1) {
297 324
            DPRINTF("qemu: timer id out of range\n");
298 325
            return 0;
299 326
        }
300
        HPETTimer *timer = &s->timer[timer_id];
301 327

  
302 328
        switch ((addr - 0x100) % 0x20) {
303
            case HPET_TN_CFG:
304
                return timer->config;
305
            case HPET_TN_CFG + 4: // Interrupt capabilities
306
                return timer->config >> 32;
307
            case HPET_TN_CMP: // comparator register
308
                return timer->cmp;
309
            case HPET_TN_CMP + 4:
310
                return timer->cmp >> 32;
311
            case HPET_TN_ROUTE:
312
                return timer->fsb >> 32;
313
            default:
314
                DPRINTF("qemu: invalid hpet_ram_readl\n");
315
                break;
329
        case HPET_TN_CFG:
330
            return timer->config;
331
        case HPET_TN_CFG + 4: // Interrupt capabilities
332
            return timer->config >> 32;
333
        case HPET_TN_CMP: // comparator register
334
            return timer->cmp;
335
        case HPET_TN_CMP + 4:
336
            return timer->cmp >> 32;
337
        case HPET_TN_ROUTE:
338
            return timer->fsb >> 32;
339
        default:
340
            DPRINTF("qemu: invalid hpet_ram_readl\n");
341
            break;
316 342
        }
317 343
    } else {
318 344
        switch (index) {
319
            case HPET_ID:
320
                return s->capability;
321
            case HPET_PERIOD:
322
                return s->capability >> 32;
323
            case HPET_CFG:
324
                return s->config;
325
            case HPET_CFG + 4:
326
                DPRINTF("qemu: invalid HPET_CFG + 4 hpet_ram_readl \n");
327
                return 0;
328
            case HPET_COUNTER:
329
                if (hpet_enabled())
330
                    cur_tick = hpet_get_ticks();
331
                else
332
                    cur_tick = s->hpet_counter;
333
                DPRINTF("qemu: reading counter  = %" PRIx64 "\n", cur_tick);
334
                return cur_tick;
335
            case HPET_COUNTER + 4:
336
                if (hpet_enabled())
337
                    cur_tick = hpet_get_ticks();
338
                else
339
                    cur_tick = s->hpet_counter;
340
                DPRINTF("qemu: reading counter + 4  = %" PRIx64 "\n", cur_tick);
341
                return cur_tick >> 32;
342
            case HPET_STATUS:
343
                return s->isr;
344
            default:
345
                DPRINTF("qemu: invalid hpet_ram_readl\n");
346
                break;
345
        case HPET_ID:
346
            return s->capability;
347
        case HPET_PERIOD:
348
            return s->capability >> 32;
349
        case HPET_CFG:
350
            return s->config;
351
        case HPET_CFG + 4:
352
            DPRINTF("qemu: invalid HPET_CFG + 4 hpet_ram_readl \n");
353
            return 0;
354
        case HPET_COUNTER:
355
            if (hpet_enabled()) {
356
                cur_tick = hpet_get_ticks();
357
            } else {
358
                cur_tick = s->hpet_counter;
359
            }
360
            DPRINTF("qemu: reading counter  = %" PRIx64 "\n", cur_tick);
361
            return cur_tick;
362
        case HPET_COUNTER + 4:
363
            if (hpet_enabled()) {
364
                cur_tick = hpet_get_ticks();
365
            } else {
366
                cur_tick = s->hpet_counter;
367
            }
368
            DPRINTF("qemu: reading counter + 4  = %" PRIx64 "\n", cur_tick);
369
            return cur_tick >> 32;
370
        case HPET_STATUS:
371
            return s->isr;
372
        default:
373
            DPRINTF("qemu: invalid hpet_ram_readl\n");
374
            break;
347 375
        }
348 376
    }
349 377
    return 0;
......
369 397
                            uint32_t value)
370 398
{
371 399
    int i;
372
    HPETState *s = (HPETState *)opaque;
400
    HPETState *s = opaque;
373 401
    uint64_t old_val, new_val, val, index;
374 402

  
375 403
    DPRINTF("qemu: Enter hpet_ram_writel at %" PRIx64 " = %#x\n", addr, value);
......
380 408
    /*address range of all TN regs*/
381 409
    if (index >= 0x100 && index <= 0x3ff) {
382 410
        uint8_t timer_id = (addr - 0x100) / 0x20;
383
        DPRINTF("qemu: hpet_ram_writel timer_id = %#x \n", timer_id);
384 411
        HPETTimer *timer = &s->timer[timer_id];
385 412

  
413
        DPRINTF("qemu: hpet_ram_writel timer_id = %#x \n", timer_id);
386 414
        if (timer_id > HPET_NUM_TIMERS - 1) {
387 415
            DPRINTF("qemu: timer id out of range\n");
388 416
            return;
389 417
        }
390 418
        switch ((addr - 0x100) % 0x20) {
391
            case HPET_TN_CFG:
392
                DPRINTF("qemu: hpet_ram_writel HPET_TN_CFG\n");
393
                val = hpet_fixup_reg(new_val, old_val, HPET_TN_CFG_WRITE_MASK);
394
                timer->config = (timer->config & 0xffffffff00000000ULL) | val;
395
                if (new_val & HPET_TN_32BIT) {
396
                    timer->cmp = (uint32_t)timer->cmp;
397
                    timer->period = (uint32_t)timer->period;
398
                }
399
                if (new_val & HPET_TIMER_TYPE_LEVEL) {
400
                    printf("qemu: level-triggered hpet not supported\n");
401
                    exit (-1);
402
                }
403

  
404
                break;
405
            case HPET_TN_CFG + 4: // Interrupt capabilities
406
                DPRINTF("qemu: invalid HPET_TN_CFG+4 write\n");
407
                break;
408
            case HPET_TN_CMP: // comparator register
409
                DPRINTF("qemu: hpet_ram_writel HPET_TN_CMP \n");
410
                if (timer->config & HPET_TN_32BIT)
411
                    new_val = (uint32_t)new_val;
412
                if (!timer_is_periodic(timer) ||
413
                           (timer->config & HPET_TN_SETVAL))
414
                    timer->cmp = (timer->cmp & 0xffffffff00000000ULL)
415
                                  | new_val;
416
                if (timer_is_periodic(timer)) {
417
                    /*
418
                     * FIXME: Clamp period to reasonable min value?
419
                     * Clamp period to reasonable max value
420
                     */
421
                    new_val &= (timer->config & HPET_TN_32BIT ? ~0u : ~0ull) >> 1;
422
                    timer->period = (timer->period & 0xffffffff00000000ULL)
423
                                     | new_val;
419
        case HPET_TN_CFG:
420
            DPRINTF("qemu: hpet_ram_writel HPET_TN_CFG\n");
421
            val = hpet_fixup_reg(new_val, old_val, HPET_TN_CFG_WRITE_MASK);
422
            timer->config = (timer->config & 0xffffffff00000000ULL) | val;
423
            if (new_val & HPET_TN_32BIT) {
424
                timer->cmp = (uint32_t)timer->cmp;
425
                timer->period = (uint32_t)timer->period;
426
            }
427
            if (new_val & HPET_TN_TYPE_LEVEL) {
428
                printf("qemu: level-triggered hpet not supported\n");
429
                exit (-1);
430
            }
431
            break;
432
        case HPET_TN_CFG + 4: // Interrupt capabilities
433
            DPRINTF("qemu: invalid HPET_TN_CFG+4 write\n");
434
            break;
435
        case HPET_TN_CMP: // comparator register
436
            DPRINTF("qemu: hpet_ram_writel HPET_TN_CMP \n");
437
            if (timer->config & HPET_TN_32BIT) {
438
                new_val = (uint32_t)new_val;
439
            }
440
            if (!timer_is_periodic(timer)
441
                || (timer->config & HPET_TN_SETVAL)) {
442
                timer->cmp = (timer->cmp & 0xffffffff00000000ULL) | new_val;
443
            }
444
            if (timer_is_periodic(timer)) {
445
                /*
446
                 * FIXME: Clamp period to reasonable min value?
447
                 * Clamp period to reasonable max value
448
                 */
449
                new_val &= (timer->config & HPET_TN_32BIT ? ~0u : ~0ull) >> 1;
450
                timer->period =
451
                    (timer->period & 0xffffffff00000000ULL) | new_val;
452
            }
453
            timer->config &= ~HPET_TN_SETVAL;
454
            if (hpet_enabled()) {
455
                hpet_set_timer(timer);
456
            }
457
            break;
458
        case HPET_TN_CMP + 4: // comparator register high order
459
            DPRINTF("qemu: hpet_ram_writel HPET_TN_CMP + 4\n");
460
            if (!timer_is_periodic(timer)
461
                || (timer->config & HPET_TN_SETVAL)) {
462
                timer->cmp = (timer->cmp & 0xffffffffULL) | new_val << 32;
463
            } else {
464
                /*
465
                 * FIXME: Clamp period to reasonable min value?
466
                 * Clamp period to reasonable max value
467
                 */
468
                new_val &= (timer->config & HPET_TN_32BIT ? ~0u : ~0ull) >> 1;
469
                timer->period =
470
                    (timer->period & 0xffffffffULL) | new_val << 32;
424 471
                }
425 472
                timer->config &= ~HPET_TN_SETVAL;
426
                if (hpet_enabled())
473
                if (hpet_enabled()) {
427 474
                    hpet_set_timer(timer);
428
                break;
429
            case HPET_TN_CMP + 4: // comparator register high order
430
                DPRINTF("qemu: hpet_ram_writel HPET_TN_CMP + 4\n");
431
                if (!timer_is_periodic(timer) ||
432
                           (timer->config & HPET_TN_SETVAL))
433
                    timer->cmp = (timer->cmp & 0xffffffffULL)
434
                                  | new_val << 32;
435
                else {
436
                    /*
437
                     * FIXME: Clamp period to reasonable min value?
438
                     * Clamp period to reasonable max value
439
                     */
440
                    new_val &= (timer->config
441
                                & HPET_TN_32BIT ? ~0u : ~0ull) >> 1;
442
                    timer->period = (timer->period & 0xffffffffULL)
443
                                     | new_val << 32;
444 475
                }
445
                timer->config &= ~HPET_TN_SETVAL;
446
                if (hpet_enabled())
447
                    hpet_set_timer(timer);
448
                break;
449
            case HPET_TN_ROUTE + 4:
450
                DPRINTF("qemu: hpet_ram_writel HPET_TN_ROUTE + 4\n");
451
                break;
452
            default:
453
                DPRINTF("qemu: invalid hpet_ram_writel\n");
454 476
                break;
477
        case HPET_TN_ROUTE + 4:
478
            DPRINTF("qemu: hpet_ram_writel HPET_TN_ROUTE + 4\n");
479
            break;
480
        default:
481
            DPRINTF("qemu: invalid hpet_ram_writel\n");
482
            break;
455 483
        }
456 484
        return;
457 485
    } else {
458 486
        switch (index) {
459
            case HPET_ID:
460
                return;
461
            case HPET_CFG:
462
                val = hpet_fixup_reg(new_val, old_val, HPET_CFG_WRITE_MASK);
463
                s->config = (s->config & 0xffffffff00000000ULL) | val;
464
                if (activating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
465
                    /* Enable main counter and interrupt generation. */
466
                    s->hpet_offset = ticks_to_ns(s->hpet_counter)
467
                                     - qemu_get_clock(vm_clock);
468
                    for (i = 0; i < HPET_NUM_TIMERS; i++)
469
                        if ((&s->timer[i])->cmp != ~0ULL)
470
                            hpet_set_timer(&s->timer[i]);
471
                }
472
                else if (deactivating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
473
                    /* Halt main counter and disable interrupt generation. */
474
                    s->hpet_counter = hpet_get_ticks();
475
                    for (i = 0; i < HPET_NUM_TIMERS; i++)
476
                        hpet_del_timer(&s->timer[i]);
487
        case HPET_ID:
488
            return;
489
        case HPET_CFG:
490
            val = hpet_fixup_reg(new_val, old_val, HPET_CFG_WRITE_MASK);
491
            s->config = (s->config & 0xffffffff00000000ULL) | val;
492
            if (activating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
493
                /* Enable main counter and interrupt generation. */
494
                s->hpet_offset =
495
                    ticks_to_ns(s->hpet_counter) - qemu_get_clock(vm_clock);
496
                for (i = 0; i < HPET_NUM_TIMERS; i++) {
497
                    if ((&s->timer[i])->cmp != ~0ULL) {
498
                        hpet_set_timer(&s->timer[i]);
499
                    }
477 500
                }
478
                /* i8254 and RTC are disabled when HPET is in legacy mode */
479
                if (activating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
480
                    hpet_pit_disable();
481
                } else if (deactivating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
482
                    hpet_pit_enable();
501
            } else if (deactivating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
502
                /* Halt main counter and disable interrupt generation. */
503
                s->hpet_counter = hpet_get_ticks();
504
                for (i = 0; i < HPET_NUM_TIMERS; i++) {
505
                    hpet_del_timer(&s->timer[i]);
483 506
                }
484
                break;
485
            case HPET_CFG + 4:
486
                DPRINTF("qemu: invalid HPET_CFG+4 write \n");
487
                break;
488
            case HPET_STATUS:
489
                /* FIXME: need to handle level-triggered interrupts */
490
                break;
491
            case HPET_COUNTER:
492
               if (hpet_enabled())
493
                   printf("qemu: Writing counter while HPET enabled!\n");
494
               s->hpet_counter = (s->hpet_counter & 0xffffffff00000000ULL)
495
                                  | value;
496
               DPRINTF("qemu: HPET counter written. ctr = %#x -> %" PRIx64 "\n",
497
                        value, s->hpet_counter);
498
               break;
499
            case HPET_COUNTER + 4:
500
               if (hpet_enabled())
501
                   printf("qemu: Writing counter while HPET enabled!\n");
502
               s->hpet_counter = (s->hpet_counter & 0xffffffffULL)
503
                                  | (((uint64_t)value) << 32);
504
               DPRINTF("qemu: HPET counter + 4 written. ctr = %#x -> %" PRIx64 "\n",
505
                        value, s->hpet_counter);
506
               break;
507
            default:
508
               DPRINTF("qemu: invalid hpet_ram_writel\n");
509
               break;
507
            }
508
            /* i8254 and RTC are disabled when HPET is in legacy mode */
509
            if (activating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
510
                hpet_pit_disable();
511
            } else if (deactivating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
512
                hpet_pit_enable();
513
            }
514
            break;
515
        case HPET_CFG + 4:
516
            DPRINTF("qemu: invalid HPET_CFG+4 write \n");
517
            break;
518
        case HPET_STATUS:
519
            /* FIXME: need to handle level-triggered interrupts */
520
            break;
521
        case HPET_COUNTER:
522
            if (hpet_enabled()) {
523
                printf("qemu: Writing counter while HPET enabled!\n");
524
            }
525
            s->hpet_counter =
526
                (s->hpet_counter & 0xffffffff00000000ULL) | value;
527
            DPRINTF("qemu: HPET counter written. ctr = %#x -> %" PRIx64 "\n",
528
                    value, s->hpet_counter);
529
            break;
530
        case HPET_COUNTER + 4:
531
            if (hpet_enabled()) {
532
                printf("qemu: Writing counter while HPET enabled!\n");
533
            }
534
            s->hpet_counter =
535
                (s->hpet_counter & 0xffffffffULL) | (((uint64_t)value) << 32);
536
            DPRINTF("qemu: HPET counter + 4 written. ctr = %#x -> %" PRIx64 "\n",
537
                    value, s->hpet_counter);
538
            break;
539
        default:
540
            DPRINTF("qemu: invalid hpet_ram_writel\n");
541
            break;
510 542
        }
511 543
    }
512 544
}
......
533 565
    hpet_ram_writel,
534 566
};
535 567

  
536
static void hpet_reset(void *opaque) {
568
static void hpet_reset(void *opaque)
569
{
537 570
    HPETState *s = opaque;
538 571
    int i;
539 572
    static int count = 0;
540 573

  
541
    for (i=0; i<HPET_NUM_TIMERS; i++) {
574
    for (i = 0; i < HPET_NUM_TIMERS; i++) {
542 575
        HPETTimer *timer = &s->timer[i];
576

  
543 577
        hpet_del_timer(timer);
544 578
        timer->tn = i;
545 579
        timer->cmp = ~0ULL;
......
557 591
    s->capability = 0x8086a201ULL;
558 592
    s->capability |= ((HPET_CLK_PERIOD) << 32);
559 593
    s->config = 0ULL;
560
    if (count > 0)
594
    if (count > 0) {
561 595
        /* we don't enable pit when hpet_reset is first called (by hpet_init)
562 596
         * because hpet is taking over for pit here. On subsequent invocations,
563 597
         * hpet_reset is called due to system reset. At this point control must
564 598
         * be returned to pit until SW reenables hpet.
565 599
         */
566 600
        hpet_pit_enable();
601
    }
567 602
    count = 1;
568 603
}
569 604

  
570 605

  
571
void hpet_init(qemu_irq *irq) {
606
void hpet_init(qemu_irq *irq)
607
{
572 608
    int i, iomemtype;
609
    HPETTimer *timer;
573 610
    HPETState *s;
574 611

  
575 612
    DPRINTF ("hpet_init\n");
......
577 614
    s = qemu_mallocz(sizeof(HPETState));
578 615
    hpet_statep = s;
579 616
    s->irqs = irq;
580
    for (i=0; i<HPET_NUM_TIMERS; i++) {
581
        HPETTimer *timer = &s->timer[i];
617
    for (i = 0; i < HPET_NUM_TIMERS; i++) {
618
        timer = &s->timer[i];
582 619
        timer->qemu_timer = qemu_new_timer(vm_clock, hpet_timer, timer);
583 620
    }
584 621
    vmstate_register(-1, &vmstate_hpet, s);
b/hw/hpet_emul.h
18 18

  
19 19
#define FS_PER_NS 1000000
20 20
#define HPET_NUM_TIMERS 3
21
#define HPET_TIMER_TYPE_LEVEL 0x002
22 21

  
23 22
#define HPET_CFG_ENABLE 0x001
24 23
#define HPET_CFG_LEGACY 0x002
......
33 32
#define HPET_TN_ROUTE   0x010
34 33
#define HPET_CFG_WRITE_MASK  0x3
35 34

  
36

  
35
#define HPET_TN_TYPE_LEVEL       0x002
37 36
#define HPET_TN_ENABLE           0x004
38 37
#define HPET_TN_PERIODIC         0x008
39 38
#define HPET_TN_PERIODIC_CAP     0x010
......
46 45
#define HPET_TN_INT_ROUTE_CAP_SHIFT 32
47 46
#define HPET_TN_CFG_BITS_READONLY_OR_RESERVED 0xffff80b1U
48 47

  
49
struct HPETState;
50
typedef struct HPETTimer {  /* timers */
51
    uint8_t tn;             /*timer number*/
52
    QEMUTimer *qemu_timer;
53
    struct HPETState *state;
54
    /* Memory-mapped, software visible timer registers */
55
    uint64_t config;        /* configuration/cap */
56
    uint64_t cmp;           /* comparator */
57
    uint64_t fsb;           /* FSB route, not supported now */
58
    /* Hidden register state */
59
    uint64_t period;        /* Last value written to comparator */
60
    uint8_t wrap_flag;      /* timer pop will indicate wrap for one-shot 32-bit
61
                             * mode. Next pop will be actual timer expiration.
62
                             */
63
} HPETTimer;
64

  
65
typedef struct HPETState {
66
    uint64_t hpet_offset;
67
    qemu_irq *irqs;
68
    HPETTimer timer[HPET_NUM_TIMERS];
69

  
70
    /* Memory-mapped, software visible registers */
71
    uint64_t capability;        /* capabilities */
72
    uint64_t config;            /* configuration */
73
    uint64_t isr;               /* interrupt status reg */
74
    uint64_t hpet_counter;      /* main counter */
75
} HPETState;
76

  
77 48
#if defined TARGET_I386
78 49
extern uint32_t hpet_in_legacy_mode(void);
79 50
extern void hpet_init(qemu_irq *irq);

Also available in: Unified diff