Split apic and ioapic code

This commit is contained in:
Thomas Lovén 2022-01-20 15:29:58 +01:00
parent ba85d9337d
commit 87d8c9c713
3 changed files with 94 additions and 85 deletions

View File

@ -3,93 +3,8 @@
#include <debug.h>
#include <ports.h>
#define APIC_BASE 0xFEE00000
#define APIC_MSR_ENABLE (1<<11)
#define APIC_EOI 0xB0
#define APIC_SPURIOUS 0xF0
#define APIC_REG(r) (((uint32_t *)P2V(APIC_BASE + (r)))[0])
#define IOREDTBL(irq) (0x10 + (irq)*2)
union iored {
struct {
uint8_t vector;
uint8_t flags;
uint8_t mask;
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) {
uint32_t volatile *ioregsel = P2V(ioapic.addr);
uint32_t volatile *iowin = P2V(ioapic.addr + 0x10);
*ioregsel = reg;
return *iowin;
}
static void ioapic_write(int reg, uint32_t value) {
uint32_t volatile *ioregsel = P2V(ioapic.addr);
uint32_t volatile *iowin = P2V(ioapic.addr + 0x10);
*ioregsel = reg;
*iowin = value;
}
static uint64_t ioapic_read_redirection(int irq) {
union iored retval;
retval.l = ioapic_read(IOREDTBL(irq));
retval.h = ioapic_read(IOREDTBL(irq)+1);
return retval.val;
}
static void ioapic_write_redirection(int irq, uint64_t val) {
union iored value;
value.val = val;
ioapic_write(IOREDTBL(irq), value.l);
ioapic_write(IOREDTBL(irq) + 1, value.h);
}
void irq_ack() {
APIC_REG(APIC_EOI) = 0;
}
void irq_mask(int irq) {
union iored iored;
iored.val = ioapic_read_redirection(irq_redirects[irq]);
iored.mask |= 0x1;
ioapic_write_redirection(irq_redirects[irq], iored.val);
}
void irq_unmask(int irq) {
union iored iored;
iored.val = ioapic_read_redirection(irq_redirects[irq]);
iored.mask &= ~0x1;
ioapic_write_redirection(irq_redirects[irq], iored.val);
}
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 iored iored;
for(int i = 0; i < 24; i++) {
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);
}
}
void apic_init() {
// Map apic offset into kernel memory
vmm_set_page(kernel_P4,

82
src/kernel/cpu/ioapic.c Normal file
View File

@ -0,0 +1,82 @@
#include <cpu.h>
#include <memory.h>
#include <stdint.h>
#define IOREDTBL(irq) (0x10 + (irq)*2)
union iored {
struct {
uint8_t vector;
uint8_t flags;
uint8_t mask;
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) {
uint32_t volatile *ioregsel = P2V(ioapic.addr);
uint32_t volatile *iowin = P2V(ioapic.addr + 0x10);
*ioregsel = reg;
return *iowin;
}
static void ioapic_write(int reg, uint32_t value) {
uint32_t volatile *ioregsel = P2V(ioapic.addr);
uint32_t volatile *iowin = P2V(ioapic.addr + 0x10);
*ioregsel = reg;
*iowin = value;
}
static uint64_t ioapic_read_redirection(int irq) {
union iored retval;
retval.l = ioapic_read(IOREDTBL(irq));
retval.h = ioapic_read(IOREDTBL(irq)+1);
return retval.val;
}
static void ioapic_write_redirection(int irq, uint64_t val) {
union iored value;
value.val = val;
ioapic_write(IOREDTBL(irq), value.l);
ioapic_write(IOREDTBL(irq) + 1, value.h);
}
void irq_ack() {
APIC_REG(APIC_EOI) = 0;
}
void irq_mask(int irq) {
union iored iored;
iored.val = ioapic_read_redirection(irq_redirects[irq]);
iored.mask |= 0x1;
ioapic_write_redirection(irq_redirects[irq], iored.val);
}
void irq_unmask(int irq) {
union iored iored;
iored.val = ioapic_read_redirection(irq_redirects[irq]);
iored.mask &= ~0x1;
ioapic_write_redirection(irq_redirects[irq], iored.val);
}
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 iored iored;
for(int i = 0; i < 24; i++) {
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);
}
}

View File

@ -1,5 +1,6 @@
#pragma once
#include <stdint.h>
#include <memory.h>
#define MSR_APIC_BASE 0x0000001B
@ -12,6 +13,14 @@
#define IRQ_PS2_KBD 0x1
#define IRQ_SPURIOUS 0xFF
#define APIC_BASE 0xFEE00000
#define APIC_REG(r) (((uint32_t *)P2V(APIC_BASE + (r)))[0])
#define APIC_EOI 0xB0
#define APIC_SPURIOUS 0xF0
#define APIC_LVT(r) (0x320 + 0x10*(r))
#define LVT_TIMER 0
typedef struct {
uint64_t rax;
uint64_t rbx;
@ -75,6 +84,9 @@ int_handler_t bind_interrupt(uint32_t num, int_handler_t fn);
void acpi_parse(void *_rsdp);
// cpu/apic.c
void apic_init();
// cpu/ioapic.c
void irq_ack();
void irq_mask(int irq);
void irq_unmask(int irq);