Loading hw/i8259.c +34 −20 Original line number Diff line number Diff line Loading @@ -84,11 +84,14 @@ static PicState *slave_pic; static int get_priority(PicState *s, int mask) { int priority; if (mask == 0) if (mask == 0) { return 8; } priority = 0; while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0) while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0) { priority++; } return priority; } Loading @@ -99,14 +102,16 @@ static int pic_get_irq(PicState *s) mask = s->irr & ~s->imr; priority = get_priority(s, mask); if (priority == 8) if (priority == 8) { return -1; } /* compute current priority. If special fully nested mode on the master, the IRQ coming from the slave is not taken into account for the priority computation. */ mask = s->isr; if (s->special_mask) if (s->special_mask) { mask &= ~s->imr; } if (s->special_fully_nested_mode && s->master) { mask &= ~(1 << 2); } Loading Loading @@ -188,14 +193,16 @@ static void pic_set_irq(void *opaque, int irq, int level) static void pic_intack(PicState *s, int irq) { if (s->auto_eoi) { if (s->rotate_on_auto_eoi) if (s->rotate_on_auto_eoi) { s->priority_add = (irq + 1) & 7; } } else { s->isr |= (1 << irq); } /* We don't clear a level sensitive interrupt here */ if (!(s->elcr & (1 << irq))) if (!(s->elcr & (1 << irq))) { s->irr &= ~(1 << irq); } pic_update_irq(s); } Loading Loading @@ -283,15 +290,19 @@ static void pic_ioport_write(void *opaque, target_phys_addr_t addr64, s->init_state = 1; s->init4 = val & 1; s->single_mode = val & 2; if (val & 0x08) if (val & 0x08) { hw_error("level sensitive irq not supported"); } } else if (val & 0x08) { if (val & 0x04) if (val & 0x04) { s->poll = 1; if (val & 0x02) } if (val & 0x02) { s->read_reg_select = val & 1; if (val & 0x40) } if (val & 0x40) { s->special_mask = (val >> 5) & 1; } } else { cmd = val >> 5; switch (cmd) { Loading @@ -305,8 +316,9 @@ static void pic_ioport_write(void *opaque, target_phys_addr_t addr64, if (priority != 8) { irq = (priority + s->priority_add) & 7; s->isr &= ~(1 << irq); if (cmd == 5) if (cmd == 5) { s->priority_add = (irq + 1) & 7; } pic_update_irq(s); } break; Loading Loading @@ -374,10 +386,11 @@ static uint64_t pic_ioport_read(void *opaque, target_phys_addr_t addr, s->poll = 0; } else { if (addr == 0) { if (s->read_reg_select) if (s->read_reg_select) { ret = s->isr; else } else { ret = s->irr; } } else { ret = s->imr; } Loading Loading @@ -474,9 +487,9 @@ void pic_info(Monitor *mon) int i; PicState *s; if (!isa_pic) if (!isa_pic) { return; } for (i = 0; i < 2; i++) { s = i == 0 ? isa_pic : slave_pic; monitor_printf(mon, "pic%d: irr=%02x imr=%02x isr=%02x hprio=%d " Loading @@ -498,9 +511,10 @@ void irq_info(Monitor *mon) monitor_printf(mon, "IRQ statistics:\n"); for (i = 0; i < 16; i++) { count = irq_count[i]; if (count > 0) if (count > 0) { monitor_printf(mon, "%2d: %" PRId64 "\n", i, count); } } #endif } Loading Loading
hw/i8259.c +34 −20 Original line number Diff line number Diff line Loading @@ -84,11 +84,14 @@ static PicState *slave_pic; static int get_priority(PicState *s, int mask) { int priority; if (mask == 0) if (mask == 0) { return 8; } priority = 0; while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0) while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0) { priority++; } return priority; } Loading @@ -99,14 +102,16 @@ static int pic_get_irq(PicState *s) mask = s->irr & ~s->imr; priority = get_priority(s, mask); if (priority == 8) if (priority == 8) { return -1; } /* compute current priority. If special fully nested mode on the master, the IRQ coming from the slave is not taken into account for the priority computation. */ mask = s->isr; if (s->special_mask) if (s->special_mask) { mask &= ~s->imr; } if (s->special_fully_nested_mode && s->master) { mask &= ~(1 << 2); } Loading Loading @@ -188,14 +193,16 @@ static void pic_set_irq(void *opaque, int irq, int level) static void pic_intack(PicState *s, int irq) { if (s->auto_eoi) { if (s->rotate_on_auto_eoi) if (s->rotate_on_auto_eoi) { s->priority_add = (irq + 1) & 7; } } else { s->isr |= (1 << irq); } /* We don't clear a level sensitive interrupt here */ if (!(s->elcr & (1 << irq))) if (!(s->elcr & (1 << irq))) { s->irr &= ~(1 << irq); } pic_update_irq(s); } Loading Loading @@ -283,15 +290,19 @@ static void pic_ioport_write(void *opaque, target_phys_addr_t addr64, s->init_state = 1; s->init4 = val & 1; s->single_mode = val & 2; if (val & 0x08) if (val & 0x08) { hw_error("level sensitive irq not supported"); } } else if (val & 0x08) { if (val & 0x04) if (val & 0x04) { s->poll = 1; if (val & 0x02) } if (val & 0x02) { s->read_reg_select = val & 1; if (val & 0x40) } if (val & 0x40) { s->special_mask = (val >> 5) & 1; } } else { cmd = val >> 5; switch (cmd) { Loading @@ -305,8 +316,9 @@ static void pic_ioport_write(void *opaque, target_phys_addr_t addr64, if (priority != 8) { irq = (priority + s->priority_add) & 7; s->isr &= ~(1 << irq); if (cmd == 5) if (cmd == 5) { s->priority_add = (irq + 1) & 7; } pic_update_irq(s); } break; Loading Loading @@ -374,10 +386,11 @@ static uint64_t pic_ioport_read(void *opaque, target_phys_addr_t addr, s->poll = 0; } else { if (addr == 0) { if (s->read_reg_select) if (s->read_reg_select) { ret = s->isr; else } else { ret = s->irr; } } else { ret = s->imr; } Loading Loading @@ -474,9 +487,9 @@ void pic_info(Monitor *mon) int i; PicState *s; if (!isa_pic) if (!isa_pic) { return; } for (i = 0; i < 2; i++) { s = i == 0 ? isa_pic : slave_pic; monitor_printf(mon, "pic%d: irr=%02x imr=%02x isr=%02x hprio=%d " Loading @@ -498,9 +511,10 @@ void irq_info(Monitor *mon) monitor_printf(mon, "IRQ statistics:\n"); for (i = 0; i < 16; i++) { count = irq_count[i]; if (count > 0) if (count > 0) { monitor_printf(mon, "%2d: %" PRId64 "\n", i, count); } } #endif } Loading