IRQ registration helper functions

This commit is contained in:
Ali Mashtizadeh 2014-07-10 14:01:15 -07:00
parent 6d09e71d9a
commit a1c44dca93
8 changed files with 104 additions and 11 deletions

View File

@ -18,6 +18,7 @@ src_amd64 = [
"amd64/pmap.c",
"amd64/lapic.c",
"amd64/ioapic.c",
"amd64/irq.c",
"dev/x86/debugcons.c",
"dev/x86/vgacons.c",
"dev/x86/ide.c",

View File

@ -51,7 +51,7 @@ IOAPIC_Init()
uint32_t id = (IOAPIC_Read(IOAPICID) >> 24) & 0x0F;
uint32_t maxInts = (IOAPIC_Read(IOAPICVER) >> 16) & 0xFF;
kprintf("IOAPIC ID:%d Max Interrupts: %d\n", id, maxInts);
kprintf("IOAPIC: ID:%d Max Interrupts: %d\n", id, maxInts);
for (i = 0; i <= IOREDTBL_LEN; i++)
{

52
sys/amd64/irq.c Normal file
View File

@ -0,0 +1,52 @@
#include <stdint.h>
#include <kassert.h>
#include "trap.h"
#include "ioapic.h"
#include <irq.h>
LIST_HEAD(IRQHandlerList, IRQHandler);
struct IRQHandlerList handlers[T_IRQ_LEN];
void
IRQ_Init()
{
int i;
for (i = 0; i < T_IRQ_LEN; i++)
{
LIST_INIT(&handlers[i]);
}
}
void
IRQ_Handler(int irq)
{
struct IRQHandler *h;
LIST_FOREACH(h, &handlers[irq], link)
{
h->cb(h->arg);
}
}
void
IRQ_Register(int irq, struct IRQHandler *h)
{
ASSERT(irq < T_IRQ_LEN);
LIST_INSERT_HEAD(&handlers[irq], h, link);
IOAPIC_Enable(irq);
}
void
IRQ_Unregister(int irq, struct IRQHandler *h)
{
LIST_REMOVE(h, link);
if (LIST_EMPTY(&handlers[irq]))
IOAPIC_Disable(irq);
}

View File

@ -99,7 +99,7 @@ LAPIC_Init()
base = rdmsr(IA32_APIC_BASE_MSR);
wrmsr(IA32_APIC_BASE_MSR, base | IA32_APIC_BASE_MSR_ENABLE);
kprintf("CPU %d LAPIC found at 0x%016llx\n", LAPIC_CPU(), base);
kprintf("LAPIC: CPU %d found at 0x%016llx\n", LAPIC_CPU(), base);
// Enable interrupts
LAPIC_Write(LAPIC_SIV, LAPIC_SIV_ENABLE | T_IRQ_SPURIOUS);

View File

@ -89,6 +89,7 @@ void Machine_Init()
PAlloc_AddRegion(16*1024*1024, 16*1024*1024);
PMap_Init();
IRQ_Init();
LAPIC_Init();
IOAPIC_Init();

View File

@ -3,6 +3,7 @@
#include <kconfig.h>
#include <kassert.h>
#include <irq.h>
#include "amd64.h"
#include "lapic.h"
@ -89,10 +90,10 @@ trap_entry(TrapFrame *tf)
// Halt on kernel errors
if (tf->vector <= T_CPU_LAST && tf->cs == SEL_KCS)
{
Trap_Dump(tf);
while (1)
hlt();
kprintf("Kernel Fault!\n");
Trap_Dump(tf);
while (1)
hlt();
}
switch (tf->vector)
@ -111,15 +112,32 @@ trap_entry(TrapFrame *tf)
if (tf->vector >= T_IRQ_BASE && tf->vector <= T_IRQ_MAX)
{
kprintf("IRQ: %d\n", tf->vector);
LAPIC_SendEOI();
kprintf("IRQ: %d\n", tf->vector);
IRQ_Handler(tf->vector - T_IRQ_BASE);
LAPIC_SendEOI();
return;
}
Trap_Dump(tf);
// LAPIC Special Vectors
if (tf->vector == T_IRQ_SPURIOUS)
return;
if (tf->vector == T_IRQ_ERROR)
{
kprintf("LAPIC Error!\n");
while (1)
hlt();
}
if (tf->vector == T_IRQ_THERMAL)
{
kprintf("Thermal Error!\n");
while (1)
hlt();
}
while (1) { }
kprintf("Unhandled Interrupt!\n");
Trap_Dump(tf);
while (1)
hlt();
}

View File

@ -31,6 +31,7 @@
#define T_IRQ_TIMER (T_IRQ_BASE + 0)
#define T_IRQ_KBD (T_IRQ_BASE + 1)
#define T_IRQ_COM1 (T_IRQ_BASE + 4)
#define T_IRQ_MOUSE (T_IRQ_BASE + 12)
#define T_IRQ_SPURIOUS (T_IRQ_BASE + 24)
#define T_IRQ_ERROR (T_IRQ_BASE + 25)
#define T_IRQ_THERMAL (T_IRQ_BASE + 26)

20
sys/include/irq.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef __IRQ_H__
#define __IRQ_H__
#include <queue.h>
typedef struct IRQHandler {
int irq;
void (*cb)(void*);
void *arg;
LIST_ENTRY(IRQHandler) link;
} IRQHandler;
void IRQ_Init();
void IRQ_Handler(int irq);
void IRQ_Register(int irq, struct IRQHandler *h);
void IRQ_Unregister(int irq, struct IRQHandler *h);
#endif /* __IRQ_H__ */