Split apic and ioapic code
This commit is contained in:
parent
ba85d9337d
commit
87d8c9c713
@ -3,93 +3,8 @@
|
|||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <ports.h>
|
#include <ports.h>
|
||||||
|
|
||||||
#define APIC_BASE 0xFEE00000
|
|
||||||
|
|
||||||
#define APIC_MSR_ENABLE (1<<11)
|
#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() {
|
void apic_init() {
|
||||||
// Map apic offset into kernel memory
|
// Map apic offset into kernel memory
|
||||||
vmm_set_page(kernel_P4,
|
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
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <memory.h>
|
||||||
|
|
||||||
#define MSR_APIC_BASE 0x0000001B
|
#define MSR_APIC_BASE 0x0000001B
|
||||||
|
|
||||||
@ -12,6 +13,14 @@
|
|||||||
#define IRQ_PS2_KBD 0x1
|
#define IRQ_PS2_KBD 0x1
|
||||||
#define IRQ_SPURIOUS 0xFF
|
#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 {
|
typedef struct {
|
||||||
uint64_t rax;
|
uint64_t rax;
|
||||||
uint64_t rbx;
|
uint64_t rbx;
|
||||||
@ -75,6 +84,9 @@ int_handler_t bind_interrupt(uint32_t num, int_handler_t fn);
|
|||||||
void acpi_parse(void *_rsdp);
|
void acpi_parse(void *_rsdp);
|
||||||
|
|
||||||
// cpu/apic.c
|
// cpu/apic.c
|
||||||
|
void apic_init();
|
||||||
|
|
||||||
|
// cpu/ioapic.c
|
||||||
void irq_ack();
|
void irq_ack();
|
||||||
void irq_mask(int irq);
|
void irq_mask(int irq);
|
||||||
void irq_unmask(int irq);
|
void irq_unmask(int irq);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user