IRQ registration helper functions
This commit is contained in:
parent
6d09e71d9a
commit
a1c44dca93
@ -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",
|
||||
|
@ -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
52
sys/amd64/irq.c
Normal 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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -89,6 +89,7 @@ void Machine_Init()
|
||||
PAlloc_AddRegion(16*1024*1024, 16*1024*1024);
|
||||
PMap_Init();
|
||||
|
||||
IRQ_Init();
|
||||
LAPIC_Init();
|
||||
IOAPIC_Init();
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <kconfig.h>
|
||||
#include <kassert.h>
|
||||
#include <irq.h>
|
||||
|
||||
#include "amd64.h"
|
||||
#include "lapic.h"
|
||||
@ -89,8 +90,8 @@ trap_entry(TrapFrame *tf)
|
||||
// Halt on kernel errors
|
||||
if (tf->vector <= T_CPU_LAST && tf->cs == SEL_KCS)
|
||||
{
|
||||
kprintf("Kernel Fault!\n");
|
||||
Trap_Dump(tf);
|
||||
|
||||
while (1)
|
||||
hlt();
|
||||
}
|
||||
@ -112,14 +113,31 @@ trap_entry(TrapFrame *tf)
|
||||
if (tf->vector >= T_IRQ_BASE && tf->vector <= T_IRQ_MAX)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -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
20
sys/include/irq.h
Normal 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__ */
|
||||
|
Loading…
Reference in New Issue
Block a user