Newer
Older
AMI-Aptio-BIOS-Reversed / Legacy8259 / Legacy8259.md
@Ajax Dong Ajax Dong 2 days ago 6 KB Init

Legacy8259

Function Table

Address Name Description
IoRead8
IoWrite8
PicReadImr
PicInitialize
PicGetState
PicSetState
PicSetMode
PicGetVector
PicEnableIrq
PicDisableIrq
PicEndOfInterrupt
PicGetPcatCompatibilityFlag
DebugAssert
ReadUnaligned64
CompareGuid
ModuleEntryPoint
Legacy8259DriverEntry
Raise TPL to prevent interrupts during PIC programming.
OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
If slave vector base changed, re-initialize slave PIC.
if (SlaveBase != mSlaveVectorBase) {
Save current slave IMR for restoration after ICW sequence.
SavedImr = IoRead8 (LEGACY_8259_SLAVE_PIC_DATA);
IoWrite8 (LEGACY_8259_SLAVE_PIC_CMD, LEGACY_8259_ICW1_INIT_SEQ);
IoWrite8 (LEGACY_8259_SLAVE_PIC_DATA, mSlaveVectorBase);
IoWrite8 (LEGACY_8259_SLAVE_PIC_DATA, LEGACY_8259_ICW3_SLAVE_CASCADE);
IoWrite8 (LEGACY_8259_SLAVE_PIC_DATA, LEGACY_8259_ICW4_8086);
Restore saved slave IMR
IoWrite8 (LEGACY_8259_SLAVE_PIC_DATA, SavedImr);
If master vector base changed, re-initialize master PIC.
if (MasterBase != mMasterVectorBase) {
Save current master IMR for restoration after ICW sequence.
SavedImr = IoRead8 (LEGACY_8259_MASTER_PIC_DATA);
IoWrite8 (LEGACY_8259_MASTER_PIC_CMD, LEGACY_8259_ICW1_INIT_SEQ);
IoWrite8 (LEGACY_8259_MASTER_PIC_DATA, mMasterVectorBase);
IoWrite8 (LEGACY_8259_MASTER_PIC_DATA, LEGACY_8259_ICW3_MASTER_CASCADE);
IoWrite8 (LEGACY_8259_MASTER_PIC_DATA, LEGACY_8259_ICW4_8086);
Restore saved master IMR
IoWrite8 (LEGACY_8259_MASTER_PIC_DATA, SavedImr);
Send non-specific EOI to both PICs to clear any pending ISR bits.
IoWrite8 (LEGACY_8259_SLAVE_PIC_CMD, LEGACY_8259_OCW2_NON_SPECIFIC_EOI);
Restore TPL.
Return cached register values from shadow variables.
Virtual wire mode: write the provided IMR values directly.
ImrToWrite = State->MasterImr;
Legacy mode: write the shadow IMR and caller's ELCR.
ImrToWrite = mMasterImr;
Write IMR to hardware ports.
IoWrite8 (LEGACY_8259_MASTER_PIC_DATA, (UINT8)(ImrToWrite & 0xFF));
Write ELCR values from the state SlaveImr field.
IoWrite8 (LEGACY_8259_ELCR1, (UINT8)(State->SlaveImr & 0xFF));
Update ELCR shadows.
mElcrCombined = (UINT16)(State->SlaveImr & 0xFFFF);
Save current hardware state before switching.
SavedImr **= (UINT16)(IoRead8 (LEGACY_8259_MASTER_PIC_DATA) **
Legacy mode: route all IRQs through PIC.
Ensure timer (IRQ0) is unmasked.
mMasterImr = SavedImr & (UINT16)~(1U << 0);
Write IMR to hardware.
IoWrite8 (LEGACY_8259_MASTER_PIC_DATA, (UINT8)(mMasterImr & 0xFF));
Write ELCR to hardware (preserving SavedElcr).
IoWrite8 (LEGACY_8259_ELCR1, (UINT8)(SavedElcr & 0xFF));
Virtual wire mode: only IRQ0 via PIC, rest via I/O APIC.
Preserve IRQ0 unmasked (clear bit 0).
Write ELCR to hardware.
mElcrCombined = SavedElcr;
Slave PIC IRQs: subtract cascade offset.
IRQ8 -> mSlaveVectorBase (0x70 = 112)
Master PIC IRQs: direct offset from master base.
IRQ0 -> mMasterVectorBase (0x58 = 88)
mMasterImr &= (UINT16)~(1U << Irq);
mMasterImr ** = (UINT16)(1U << Irq);**
Write to hardware.
IoWrite8 (LEGACY_8259_MASTER_PIC_DATA, (UINT8)(NewImr & 0xFF));
Update slave ELCR shadow.
mElcr2 = (UINT16)((NewElcr >> 8) & 0xFF);
Mask in IMR (set bit).
Clear ELCR bit (force edge-triggered).
mElcr2 = (UINT16)((mElcrCombined >> 8) & 0xFF);
Slave IRQ requires EOI to slave PIC first (cascade on IRQ2).
if (Irq >= 8) {
Always send EOI to master PIC.
IoWrite8 (LEGACY_8259_MASTER_PIC_CMD, LEGACY_8259_OCW2_NON_SPECIFIC_EOI);
Open the PCAT compatibility protocol on the given handle.
Status = gBS->HandleProtocol (
Read byte at offset 0x3C (60) of the protocol interface data.
This is the PCAT_COMPAT flag in the MADT (or equivalent table).
Raise to TPL_HIGH_LEVEL, then restore to check current TPL.
If OldTpl > TPL_NOTIFY, we are in an interrupt context and
LocateProtocol cannot be safely called.
Call the debug protocol's DebugAssert function at offset +8.
Validate and cache UEFI service table pointers.
if (ImageHandle == NULL) {
Initialize HOB list for DXE library.
GetHobList ();
return Legacy8259DriverEntry ();
Step 1: Set IMR shadow to default programming value (0x0EB8).
0x0EB8 bit assignments:
Bit 0 = 0 (IRQ0 - Timer: unmasked)
Bit 1 = 0 (IRQ1 - Keyboard: unmasked)
Bit 2 = 0 (IRQ2 - Slave cascade: unmasked)
Bit 3 = 1 (IRQ3 - COM2: masked)
Bit 4 = 1 (IRQ4 - COM1: masked)
Bit 5 = 0 (IRQ5 - LPT2 or free: unmasked)
Bit 6 = 1 (IRQ6 - Floppy: masked)
Bit 7 = 1 (IRQ7 - LPT1: masked)
Bit 8 = 1 (IRQ8 - RTC: masked on slave)
mCachedMasterImr = 0x0EB8;
Step 2: Clear any stale ISR bits by sending EOI to both PICs
for all possible IRQs (0-15).
for (Index = 0; Index <= 15; Index++) {
Slave IRQ: EOI to slave PIC first.
Send EOI to master PIC.
Step 3: Initialize protocol dispatch table.
Step 4: Program PICs with ICW1-ICW4.
Master vector base: 0x58 (IRQ0 -> INT 88).
Slave vector base: 0x70 (IRQ8 -> INT 112).
PicInitialize (
Step 5: Write initial IMR and ELCR values to hardware.
IoWrite8 (LEGACY_8259_MASTER_PIC_DATA, (UINT8)(mCachedMasterImr & 0xFF));
Step 6: Install the EFI_LEGACY_8259_PROTOCOL.
return gBS->InstallProtocolInterface (

Generated by HR650X BIOS Decompilation Project