Split apic and ioapic code
This commit is contained in:
parent
ba85d9337d
commit
87d8c9c713
@ -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
82
src/kernel/cpu/ioapic.c
Normal 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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user