The following occurs under Bochs 2.4.1 compiled from source running inside a xubuntu environment. The system being booted on top of box is a custom operating system under development.
Current PCI device interrupts (tested via the NE2K PCI NIC) are being routed to two entries in the IOAPIC. For a given PCI IRQ X, they are routed to:
1) IOAPIC Entry X
2) IOAPIC Entry 16 + PIRQ
The set_irq_level() code inside of pci2isa.cc first calls DEV_ioapic_set_irq_level(pirq + 16, level), then potentially calls DEV_pic_raise_irq(irq). However, the first few lines of code inside of raise_irq() inside pic.cc also contain a call to DEV_ioapic_set_irq_level(irq_no, 1).
void bx_pic_c::raise_irq(unsigned irq_no)
{
// forward this function call to the ioapic too
if (DEV_ioapic_present() && (irq_no != 2)) {
DEV_ioapic_set_irq_level(irq_no, 1);
}
Bit8u mask = (1 << (irq_no & 7));
if ((irq_no <= 7) && !(BX_PIC_THIS s.master_pic.IRQ_in & mask)) {
BX_DEBUG(("IRQ line %d now high", (unsigned) irq_no));
BX_PIC_THIS s.master_pic.IRQ_in |= mask;
.....
void bx_piix3_c::pci_set_irq(Bit8u devfunc, unsigned line, bx_bool level)
{
Bit8u pirq = ((devfunc >> 3) + line - 2) & 0x03;
// forward this function call to the ioapic too
if (DEV_ioapic_present()) {
DEV_ioapic_set_irq_level(pirq + 16, level);
}
Bit8u irq = BX_P2I_THIS s.pci_conf[0x60 + pirq];
if ((irq < 16) && (((1 << irq) & 0xdef8) > 0)) {
if (level == 1) {
if (!BX_P2I_THIS s.irq_level[irq]) {
DEV_pic_raise_irq(irq);
.....
As you can see the code segment that routes interrupts to the IOAPIC appears to be repeated.
It also appears that the IOAPIC trigger type for both of these entries is set to edge, although I would expect them to be level sensitive.
-Paul
paul.j.pearce@gmail.com