Based on:
With a uniprocessor configuration, the only lapic setup needed to get the keyboard working seems to be setting the software enable.8.4.7.1. LOCAL APIC STATE AFTER POWER-UP OR RESET
Following a power-up or RESET of the processor, the state of local APIC and its registers are
as follows:
• The following registers are reset to all 0s: the IRR, ISR, TMR, ICR, LDR, and TPR
registers; the timer initial count and timer current count registers; and the divide configuration
register.
• The DFR register is reset to all 1s.
• The LVT register entries are reset to all 0s except for the mask bits, which are set to 1s.
• The local APIC ID register is set to a unique APIC ID. (Pentium and P6 family processors
only) The Arb ID register is set to the value in the APIC ID register.
• The spurious-interrupt vector register is initialized to 0000 00FFH. The setting of bit 8 to 0
software disables the local APIC
Code: Select all
APIC_SPURIOUS = 0xF0
APIC_SW_ENABLE = 100h
mov rsi, [LocalAPICAddress]
or dword[rsi+APIC_SPURIOUS], APIC_SW_ENABLE
The minimum change I needed to get the keyboard responsive again after disabling the pic, was to make the redirection entries in the IOAPIC:
Code: Select all
set_irqs:
push r8
mov edi, [IOAPICAddress]
mov rax, 0
mov rdx, 0x20
@@:
call ioapic_set_irq
inc rdx
inc rax
cmp rax, 24
jne @b
pop r8
ret
ioapic_set_irq:
lea ebx, [0x10 + rax*2]
call ioapic_read
and ecx, 0xFFFEF0FF ; unmask the IRQ (16), set physical delivery mode (11), set fixed delivery mode (8,9,10)
mov cl, dl ; set delivery vector
call ioapic_write
lea ebx, [0x10 + rax*2 + 1]
call ioapic_read
and ecx, 0x00FFFFFF ; APICID is 0 for uniprocessor
call ioapic_write
ret
; -----------------------------------------------------------------------------
; IN : RDI = ioapic address, EBX = index register
; OUT: ECX = return value
ioapic_read:
mov [rdi], ebx
mov ecx, [rdi + 0x10]
ret
; -----------------------------------------------------------------------------
; IN : RDI = ioapic address, EBX = index register, ECX = value
; OUT: -
ioapic_write:
mov [rdi], ebx
mov [rdi + 0x10], ecx
ret