IRQ registration helper functions
This commit is contained in:
parent
6d09e71d9a
commit
a1c44dca93
@ -18,6 +18,7 @@ src_amd64 = [
|
|||||||
"amd64/pmap.c",
|
"amd64/pmap.c",
|
||||||
"amd64/lapic.c",
|
"amd64/lapic.c",
|
||||||
"amd64/ioapic.c",
|
"amd64/ioapic.c",
|
||||||
|
"amd64/irq.c",
|
||||||
"dev/x86/debugcons.c",
|
"dev/x86/debugcons.c",
|
||||||
"dev/x86/vgacons.c",
|
"dev/x86/vgacons.c",
|
||||||
"dev/x86/ide.c",
|
"dev/x86/ide.c",
|
||||||
|
@ -51,7 +51,7 @@ IOAPIC_Init()
|
|||||||
uint32_t id = (IOAPIC_Read(IOAPICID) >> 24) & 0x0F;
|
uint32_t id = (IOAPIC_Read(IOAPICID) >> 24) & 0x0F;
|
||||||
uint32_t maxInts = (IOAPIC_Read(IOAPICVER) >> 16) & 0xFF;
|
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++)
|
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);
|
base = rdmsr(IA32_APIC_BASE_MSR);
|
||||||
wrmsr(IA32_APIC_BASE_MSR, base | IA32_APIC_BASE_MSR_ENABLE);
|
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
|
// Enable interrupts
|
||||||
LAPIC_Write(LAPIC_SIV, LAPIC_SIV_ENABLE | T_IRQ_SPURIOUS);
|
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);
|
PAlloc_AddRegion(16*1024*1024, 16*1024*1024);
|
||||||
PMap_Init();
|
PMap_Init();
|
||||||
|
|
||||||
|
IRQ_Init();
|
||||||
LAPIC_Init();
|
LAPIC_Init();
|
||||||
IOAPIC_Init();
|
IOAPIC_Init();
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <kconfig.h>
|
#include <kconfig.h>
|
||||||
#include <kassert.h>
|
#include <kassert.h>
|
||||||
|
#include <irq.h>
|
||||||
|
|
||||||
#include "amd64.h"
|
#include "amd64.h"
|
||||||
#include "lapic.h"
|
#include "lapic.h"
|
||||||
@ -89,10 +90,10 @@ trap_entry(TrapFrame *tf)
|
|||||||
// Halt on kernel errors
|
// Halt on kernel errors
|
||||||
if (tf->vector <= T_CPU_LAST && tf->cs == SEL_KCS)
|
if (tf->vector <= T_CPU_LAST && tf->cs == SEL_KCS)
|
||||||
{
|
{
|
||||||
Trap_Dump(tf);
|
kprintf("Kernel Fault!\n");
|
||||||
|
Trap_Dump(tf);
|
||||||
while (1)
|
while (1)
|
||||||
hlt();
|
hlt();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (tf->vector)
|
switch (tf->vector)
|
||||||
@ -111,15 +112,32 @@ trap_entry(TrapFrame *tf)
|
|||||||
|
|
||||||
if (tf->vector >= T_IRQ_BASE && tf->vector <= T_IRQ_MAX)
|
if (tf->vector >= T_IRQ_BASE && tf->vector <= T_IRQ_MAX)
|
||||||
{
|
{
|
||||||
kprintf("IRQ: %d\n", tf->vector);
|
kprintf("IRQ: %d\n", tf->vector);
|
||||||
|
IRQ_Handler(tf->vector - T_IRQ_BASE);
|
||||||
LAPIC_SendEOI();
|
LAPIC_SendEOI();
|
||||||
|
|
||||||
return;
|
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_TIMER (T_IRQ_BASE + 0)
|
||||||
#define T_IRQ_KBD (T_IRQ_BASE + 1)
|
#define T_IRQ_KBD (T_IRQ_BASE + 1)
|
||||||
#define T_IRQ_COM1 (T_IRQ_BASE + 4)
|
#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_SPURIOUS (T_IRQ_BASE + 24)
|
||||||
#define T_IRQ_ERROR (T_IRQ_BASE + 25)
|
#define T_IRQ_ERROR (T_IRQ_BASE + 25)
|
||||||
#define T_IRQ_THERMAL (T_IRQ_BASE + 26)
|
#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