On Mon, 3 Sep 2012, Jan Kiszka wrote: > > - Qemu output (without this patch): > > elcr=0c00 cmdRead ummask mask sti irq15 unmask DONE > > > > But on real hardware, the master seems to treat IRQ2 as level triggered,
That is not universally true, however in reality it does not matter, more on that below. > > and doesn't deliver an interrupt to the CPU until the slave unmasks IRQ14. > > I've tried this on several machines, including a non-PCI 486 that > > does not seem to have ELCR registers. > > > > - Typical output (pentium/pentium pro/dual AMD Athlon/etc; slight > > variations in some elcr bits depending on machine, but bit 0x04 > > is always clear): > > elcr=0c20 cmdRead unmask mask sti unmask irq14 DONE > > > > - 486 without elcr (just an ISA bus): > > elcr=e0e0 cmdRead unmask mask sti unmask irq14 DONE > > > > - One failure: It doesn't boot properly (no output) with a USB floppy > > drive on my Intel Core I7. Guess: The test program just barely > > fits in a sector, with no room for any tables (partition/etc) > > that BIOS might check for if it isn't an original, native floppy > > drive. > > > > ----------------------- > > > > I've found a few descriptions of programming the i8259. > > I was mostly following the official "8259A PROGRAMMABLE INTERRUPT > CONTROLLER (8259A 8259A-2)" by Intel. But it also doesn't mention any > trigger mode changes for the cascading input lines. The datasheet is vague on the subject and there is apparently a common misconception on how the 8259A trigger modes work. PIC core modifications, especially the ELCR (originally added for EISA support), seen in chipsets obfuscate the matter further. So first of all, the *output* of the 8259A is always edge triggered, regardless of whether it's the master or one of the slaves (only one slave is used in the PC/AT architecture, but up to eight are supported; the PC/XT had none). If once an interrupt has been served any interrupts remain in the pending state, then the 8259A deasserts its output briefly before reasserting it. Secondly, for inputs the original 8259A only allowed a global (i.e. for all at once) edge/level selection via ICW1. That somehow had to be compatible with the master/slave mode. However as of the 8259A "edge-triggered" in Intel's nomenclature meant: "asserted with a low-to-high transition at the time an interrupt is registered and then kept high until the interrupt is served via one of the EOI mechanisms (there are a few, including AEOI) or goes away unhandled." This is important for the output because the x86 architecture's definition for the INT input is level-triggered. The edge-triggered mode was also the only one supported for inputs with the original 8080-compatible 8259; note that for inputs a high-to-low transition cancels the interrupt as in the level-triggered mode. The "level-triggered" mode was then added with the usual meaning -- essentially copying the interrupt input onto the output, ORing with the other inputs. So thus defined "edge-triggered" mode is in fact compatible with both edge-triggered and level-triggered inputs -- the former work by means of observing the low-to-high transition and the latter also work by only seeing the interrupt go away briefly -- but that does not really matter for level-triggered interrupts as the 8259A still knows an IRQ is pending and if a race causes an INTA cycle to arrive at the time the PIC's output is low it will still correctly serve the vector (I think in practice it does not really happen as the vector is served with the second INTA cycle only and by then the interrupt output must have recovered). There were some interesting errata in some early embedded 8259A cores in EISA chipses where the brief deassertion of the output did not happen. That worked just fine when wired directly to an x86 processor (because as noted above the INT input is level-triggered), however when connected to an i82489DX discrete APIC, that interprets the edge-triggered mode in the traditional way and implies that mode for inputs cascaded to 8259A, the problem had to be worked around in hardware, by adding extra logic to regenerate the missing high-to-low-to-high transition. Some of the information presented here was only noted by Intel in APIC documentation; I may track down and quote references, but these documents have never been available online anyway. Did that help? Maciej