Documentation

This commit is contained in:
2022-01-17 20:43:21 +01:00
parent 5f8ed13a95
commit 6c98be764b
3 changed files with 190 additions and 34 deletions

View File

@@ -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;
}

View File

@@ -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);