Revision 22a9fe38

b/hw/hpet.c
159 159
    }
160 160
}
161 161

  
162
static void update_irq(struct HPETTimer *timer)
162
static void update_irq(struct HPETTimer *timer, int set)
163 163
{
164
    uint64_t mask;
165
    HPETState *s;
164 166
    int route;
165 167

  
166 168
    if (timer->tn <= 1 && hpet_in_legacy_mode(timer->state)) {
......
172 174
    } else {
173 175
        route = timer_int_route(timer);
174 176
    }
175
    if (!timer_enabled(timer) || !hpet_enabled(timer->state)) {
176
        return;
177
    s = timer->state;
178
    mask = 1 << timer->tn;
179
    if (!set || !timer_enabled(timer) || !hpet_enabled(timer->state)) {
180
        s->isr &= ~mask;
181
        qemu_irq_lower(s->irqs[route]);
182
    } else if (timer->config & HPET_TN_TYPE_LEVEL) {
183
        s->isr |= mask;
184
        qemu_irq_raise(s->irqs[route]);
185
    } else {
186
        s->isr &= ~mask;
187
        qemu_irq_pulse(s->irqs[route]);
177 188
    }
178
    qemu_irq_pulse(timer->state->irqs[route]);
179 189
}
180 190

  
181 191
static void hpet_pre_save(void *opaque)
......
261 271
            t->wrap_flag = 0;
262 272
        }
263 273
    }
264
    update_irq(t);
274
    update_irq(t, 1);
265 275
}
266 276

  
267 277
static void hpet_set_timer(HPETTimer *t)
......
291 301
static void hpet_del_timer(HPETTimer *t)
292 302
{
293 303
    qemu_del_timer(t->qemu_timer);
304
    update_irq(t, 0);
294 305
}
295 306

  
296 307
#ifdef HPET_DEBUG
......
423 434
                timer->cmp = (uint32_t)timer->cmp;
424 435
                timer->period = (uint32_t)timer->period;
425 436
            }
426
            if (new_val & HPET_TN_TYPE_LEVEL) {
427
                printf("qemu: level-triggered hpet not supported\n");
428
                exit (-1);
429
            }
430 437
            if (activating_bit(old_val, new_val, HPET_TN_ENABLE)) {
431 438
                hpet_set_timer(timer);
432 439
            } else if (deactivating_bit(old_val, new_val, HPET_TN_ENABLE)) {
......
522 529
            DPRINTF("qemu: invalid HPET_CFG+4 write \n");
523 530
            break;
524 531
        case HPET_STATUS:
525
            /* FIXME: need to handle level-triggered interrupts */
532
            val = new_val & s->isr;
533
            for (i = 0; i < HPET_NUM_TIMERS; i++) {
534
                if (val & (1 << i)) {
535
                    update_irq(&s->timer[i], 0);
536
                }
537
            }
526 538
            break;
527 539
        case HPET_COUNTER:
528 540
            if (hpet_enabled(s)) {

Also available in: Unified diff