summaryrefslogtreecommitdiff
path: root/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/smp.c')
-rw-r--r--kernel/smp.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/kernel/smp.c b/kernel/smp.c
index b2ce6b0..0c8d2dd 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -43,8 +43,30 @@ volatile uint8_t proc;
uint32_t cpu_counter[SMP_MAX_PROC];
uint32_t local_apic_addr;
+uint32_t io_apic_addr;
+
uint32_t countdown;
+void writeIOAPIC(uint32_t offset, uint32_t value)
+{
+ uint32_t *reg=io_apic_addr;
+ reg[0]=(offset & 0xff);
+ reg[4]= value;
+}
+
+uint32_t readIOAPIC(uint32_t offset)
+{
+ uint32_t *reg=io_apic_addr;
+ reg[0]=(offset & 0xff);
+ return reg[4];
+}
+
+void irqIOAPIC(uint32_t irq, uint32_t low, uint32_t high)
+{
+ writeIOAPIC(0x10+irq*2,low);
+ writeIOAPIC(0x11+irq*2,high);
+}
+
void writeAPIC(uint32_t offset, uint32_t value)
{
uint32_t *reg;
@@ -180,6 +202,8 @@ void smp_start_aps(smp_processors *pros)
{
// TODO: check if local APIC is present via CPUID (P6 (i686) and above)
local_apic_addr=pros->local_apic_address;
+ io_apic_addr=pros->io_apic_address;
+
klog("bsp local apic id: 0x%08X",apicID());
apicEnable(); // bsp apic seems to be enabled anyway.
@@ -192,6 +216,15 @@ void smp_start_aps(smp_processors *pros)
writeAPIC(APIC_LVT_TMR, 200 | TMR_PERIODIC); // on interrupt 200
writeAPIC(APIC_TMRINITCNT, countdown);
+ // setup IO APIC
+ // PIT irq 00 -> 02 flags 0 -> 0x90
+ // kb irq 01 -> 01 flags ? -> 0x91
+ // mouse irq 12 -> 12 flags ? -> 0x92
+
+ irqIOAPIC(2,0x90,0x0);
+ irqIOAPIC(1,0x91,0x0);
+ irqIOAPIC(12,0x92,0x0);
+
for(int i=0;i<pros->processors;i++)
{
if(pros->boot==i)continue;