mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:17:45 +00:00
Add IRQHandler class that can be subclasses to handle an IRQ.
Also move Keyboard to a class implementation using this pattern.
This commit is contained in:
parent
8f941561b4
commit
a9ca75c98b
8 changed files with 152 additions and 100 deletions
|
@ -5,6 +5,8 @@
|
|||
#include "Assertions.h"
|
||||
#include "Task.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "IRQHandler.h"
|
||||
#include "PIC.h"
|
||||
|
||||
struct DescriptorTablePointer {
|
||||
WORD size;
|
||||
|
@ -16,6 +18,8 @@ static DescriptorTablePointer s_gdtr;
|
|||
static Descriptor* s_idt;
|
||||
static Descriptor* s_gdt;
|
||||
|
||||
static IRQHandler** s_irqHandler;
|
||||
|
||||
static WORD s_gdtLength;
|
||||
|
||||
WORD allocateGDTEntry()
|
||||
|
@ -27,6 +31,26 @@ WORD allocateGDTEntry()
|
|||
return newGDTEntry;
|
||||
}
|
||||
|
||||
extern "C" void handleIRQ();
|
||||
extern "C" void commonIRQEntry();
|
||||
|
||||
asm(
|
||||
".globl commonIRQEntry\n"
|
||||
"commonIRQEntry: \n"
|
||||
" pusha\n"
|
||||
" pushw %ds\n"
|
||||
" pushw %es\n"
|
||||
" pushw %ss\n"
|
||||
" pushw %ss\n"
|
||||
" popw %ds\n"
|
||||
" popw %es\n"
|
||||
" call handleIRQ\n"
|
||||
" popw %es\n"
|
||||
" popw %ds\n"
|
||||
" popa\n"
|
||||
" iret\n"
|
||||
);
|
||||
|
||||
extern volatile dword exception_state_dump;
|
||||
extern volatile word exception_code;
|
||||
asm(
|
||||
|
@ -290,6 +314,20 @@ static void unimp_trap()
|
|||
HANG;
|
||||
}
|
||||
|
||||
void registerIRQHandler(byte irq, IRQHandler& handler)
|
||||
{
|
||||
ASSERT(!s_irqHandler[irq]);
|
||||
s_irqHandler[irq] = &handler;
|
||||
kprintf("irq handler for %u: %p\n", irq, &handler);
|
||||
registerInterruptHandler(IRQ_VECTOR_BASE + irq, commonIRQEntry);
|
||||
}
|
||||
|
||||
void unregisterIRQHandler(byte irq, IRQHandler& handler)
|
||||
{
|
||||
ASSERT(s_irqHandler[irq] == &handler);
|
||||
s_irqHandler[irq] = nullptr;
|
||||
}
|
||||
|
||||
void registerInterruptHandler(BYTE index, void (*f)())
|
||||
{
|
||||
s_idt[index].low = 0x00080000 | LSW((f));
|
||||
|
@ -351,6 +389,11 @@ void idt_init()
|
|||
|
||||
registerInterruptHandler(0x57, irq7_handler);
|
||||
|
||||
s_irqHandler = new IRQHandler*[16];
|
||||
for (byte i = 0; i < 16; ++i) {
|
||||
s_irqHandler[i] = nullptr;
|
||||
}
|
||||
|
||||
flushIDT();
|
||||
}
|
||||
|
||||
|
@ -358,3 +401,25 @@ void loadTaskRegister(WORD selector)
|
|||
{
|
||||
asm("ltr %0"::"r"(selector));
|
||||
}
|
||||
|
||||
void handleIRQ()
|
||||
{
|
||||
WORD isr = PIC::getISR();
|
||||
if (!isr) {
|
||||
kprintf("Spurious IRQ\n");
|
||||
return;
|
||||
}
|
||||
|
||||
byte irq;
|
||||
for (byte i = 0; i < 16; ++i) {
|
||||
if (isr & (1 << i)) {
|
||||
irq = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (s_irqHandler[irq])
|
||||
s_irqHandler[irq]->handleIRQ();
|
||||
PIC::eoi(irq);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue