In response:
1) PIC seems to be masked correctly. I have remapped PIC to 0x20->0x2F, and the IOAPIC to 0x30->0x4F so i can be sure which one fired. After the PIC is disabled and IOAPIC enabled, I only get IOAPIC interrupts.
2) Spurious Vector and enable flag are set on each AP.
3) Task Priority is set on each AP.
4) DFR and LFR are set (although I am using physical destination anyway).
5) ...
6) STI is called after setup on each AP
5) Setup the IOAPIC for AP delivery is a bit tricker - it 'seems' to be setup although I have not recieved a single IOAPIC-generated IRQ on an AP. It delivers fine to the BSP - PIT Timer & keyboard IRQs are delivered without problem. I believe that if I want the interrupts delivered to APICID=1 (an AP) rather than APICID=0 (my BSP) that I just need to change the destination in the IOREDTBL - which I have done... No interrupts are delivered
I tried what gerryg400 mentioned (getting Local APIC timer working) - Have run into a new snag. I programmed the LAPIC timer in periodic mode and recieved 1 interrupt from each AP, then nothing

The processors have returned from the interrupt handlers - the 'heartbeat' is still working - but no further interrupts (The BSP is the same).
I tried moving the IOAPIC interrupts back to the BSP with the Local APIC timers enabled - same problem. I recieved one keyboard interrupt from the IOAPIC, then one LAPIC timer interrupt and then no more - it also blocks delivery of further IOAPIC interrupts.
It appears I am not handling the EOI for the LAPIC correctly. At present, I just do:
volatile u32 *apic_eoi = (u32 *)0xFEE000B0;
*apic_eoi = 0;
Am I missing something?
PS: I don't have paging enabled
