Documentation
This commit is contained in:
@@ -9,12 +9,7 @@
|
||||
|
||||
#define APIC_REG(r) (((uint32_t *)P2V(APIC_BASE + (r)))[0])
|
||||
|
||||
union ioapic_redirection {
|
||||
uint64_t val;
|
||||
struct {
|
||||
uint32_t l;
|
||||
uint32_t h;
|
||||
}__attribute__((packed));
|
||||
union iored {
|
||||
struct {
|
||||
uint8_t vector;
|
||||
uint8_t flags;
|
||||
@@ -22,6 +17,11 @@ union ioapic_redirection {
|
||||
uint32_t reserved;
|
||||
uint8_t target;
|
||||
}__attribute__((packed));
|
||||
struct {
|
||||
uint32_t l;
|
||||
uint32_t h;
|
||||
}__attribute__((packed));
|
||||
uint64_t val;
|
||||
};
|
||||
|
||||
static uint32_t ioapic_read(int reg) {
|
||||
@@ -38,42 +38,43 @@ static void ioapic_write(int reg, uint32_t value) {
|
||||
}
|
||||
|
||||
static uint64_t ioapic_read_redirection(int irq) {
|
||||
union ioapic_redirection retval;
|
||||
union iored retval;
|
||||
retval.l = ioapic_read(0x10 + 2*irq);
|
||||
retval.h = ioapic_read(0x11 + 2*irq);
|
||||
return retval.val;
|
||||
}
|
||||
static void ioapic_write_redirection(int irq, uint64_t val) {
|
||||
union ioapic_redirection value;
|
||||
union iored value;
|
||||
value.val = val;
|
||||
ioapic_write(0x10 + 2*irq, value.l);
|
||||
ioapic_write(0x11 + 2*irq, value.h);
|
||||
}
|
||||
|
||||
void ioapic_init() {
|
||||
// Map ioapic offset into kernel memory
|
||||
vmm_set_page(kernel_P4, (uintptr_t)P2V(ioapic.addr), ioapic.addr, PAGE_PRESENT | PAGE_WRITE | PAGE_GLOBAL);
|
||||
|
||||
union ioapic_redirection red;
|
||||
union iored iored;
|
||||
for(int i = 0; i < 24; i++) {
|
||||
red.val = ioapic_read_redirection(i);
|
||||
red.vector = IRQ_BASE+i;
|
||||
red.flags = 0x0;
|
||||
if(i == 1) // Mask the timer interrupt
|
||||
red.mask &= ~0x1;
|
||||
else // but unmask all others for testing
|
||||
red.mask |= 0x1;
|
||||
red.target = 0x0;
|
||||
ioapic_write_redirection(i, red.val);
|
||||
iored.val = ioapic_read_redirection(i);
|
||||
iored.vector = IRQ_BASE+i;
|
||||
iored.flags = 0x0;
|
||||
iored.mask |= 1;
|
||||
iored.target = 0x0;
|
||||
ioapic_write_redirection(i, iored.val);
|
||||
}
|
||||
|
||||
// TEMPORARY
|
||||
// Unmask PS/2 keyboard interrupt
|
||||
iored.val = ioapic_read_redirection(irq_redirects[1]);
|
||||
iored.mask &= ~0x1;
|
||||
ioapic_write_redirection(irq_redirects[1], iored.val);
|
||||
}
|
||||
|
||||
void apic_init() {
|
||||
// Enable local APIC
|
||||
write_msr(MSR_APIC_BASE, read_msr(MSR_APIC_BASE) | APIC_MSR_ENABLE);
|
||||
|
||||
// Map apic offset into kernel memory
|
||||
vmm_set_page(kernel_P4, (uintptr_t)P2V(APIC_BASE), APIC_BASE, PAGE_PRESENT | PAGE_WRITE | PAGE_GLOBAL);
|
||||
|
||||
APIC_REG(0xF0) = APIC_REG(0xF0) | (1<<8);
|
||||
APIC_REG(0xB0) = 0;
|
||||
// Allow LAPIC to receive interrupts
|
||||
APIC_REG(0xF0) = APIC_REG(0xF0) | 0x100 | 0xFF;
|
||||
}
|
||||
@@ -10,18 +10,7 @@ uint8_t irq_redirects[MAX_IRQS] = \
|
||||
|
||||
#define PIC1_ADDR 0x20
|
||||
#define PIC2_ADDR 0xA0
|
||||
#define PIC_INITIALIZE 0x10
|
||||
#define PIC_SINGLE 0x02
|
||||
static void pic_disable() {
|
||||
// Absolute minimum work to initialize and disable legacy PIC.
|
||||
// Both the primary and secondary PIC will think they are alone
|
||||
// in a MCS-80 arch computer but that doesn't matter since all
|
||||
// interrupts will be masked anyway :)
|
||||
// Ref: Intel 8259A Datasheet
|
||||
outb(PIC1_ADDR, PIC_INITIALIZE | PIC_SINGLE);
|
||||
outb(PIC2_ADDR, PIC_INITIALIZE | PIC_SINGLE);
|
||||
outb(PIC1_ADDR | 1, 0);
|
||||
outb(PIC2_ADDR | 1, 0);
|
||||
// Mask all interrupts
|
||||
outb(PIC1_ADDR | 1, 0xFF);
|
||||
outb(PIC2_ADDR | 1, 0xFF);
|
||||
|
||||
Reference in New Issue
Block a user