interrupts: Update MainInterruptHandler

This commit is contained in:
EnderIce2 2024-10-30 03:07:47 +02:00
parent ab6529f6e6
commit 6dc734bb0b
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD

View File

@ -280,60 +280,11 @@ namespace Interrupts
warn("IRQ%d not found.", InterruptNumber);
}
extern "C" nsa void MainInterruptHandler(void *Data)
nsa inline void ReturnFromInterrupt(CPU::TrapFrame *)
{
CPU::TrapFrame *Frame = (CPU::TrapFrame *)Data;
// debug("IRQ%ld", Frame->InterruptNumber - 32);
/* If this is false, we have a big problem. */
if (unlikely(Frame->InterruptNumber >= CPU::x86::IRQ223 ||
Frame->InterruptNumber <= CPU::x86::ISR0))
{
error("Interrupt number %d is out of range.",
Frame->InterruptNumber);
assert(!"Interrupt number is out of range.");
}
/* Halt core interrupt */
if (unlikely(Frame->InterruptNumber == CPU::x86::IRQ31))
CPU::Stop();
bool InterruptHandled = false;
int iEvNum = -1;
foreach (auto &ev in RegisteredEvents)
{
iEvNum = ev.IRQ;
#if defined(a86)
iEvNum += CPU::x86::IRQ0;
#endif
if (iEvNum != s_cst(int, Frame->InterruptNumber))
continue;
if (ev.IsHandler)
{
Handler *hnd = (Handler *)ev.Data;
hnd->OnInterruptReceived(Frame);
}
else
{
if (ev.Context != nullptr)
ev.Callback((CPU::TrapFrame *)ev.Context);
else
ev.Callback(Frame);
}
ev.Priority++;
InterruptHandled = true;
}
CPUData *CoreData = GetCurrentCPU();
int Core = CoreData->ID;
if (unlikely(!InterruptHandled))
{
error("IRQ%d is unhandled on CPU %d.",
Frame->InterruptNumber - 32, Core);
}
/* TODO: This should be done when the os is idle */
if (SortEvents++ > SORT_ITR)
{
@ -362,17 +313,63 @@ namespace Interrupts
{
APIC::APIC *this_apic = (APIC::APIC *)apic[Core];
this_apic->EOI();
// TODO: Handle PIC too
return;
}
else
fixme("APIC not found for core %d", Core);
// TODO: PIC
// TODO: Handle PIC too
assert(!"Interrupt EOI not handled.");
assert(!"EOI not handled.");
CPU::Stop();
}
extern "C" nsa void MainInterruptHandler(void *Data)
{
CPU::TrapFrame *Frame = (CPU::TrapFrame *)Data;
// debug("IRQ%ld", Frame->InterruptNumber - 32);
/* Halt core interrupt */
if (unlikely(Frame->InterruptNumber == CPU::x86::IRQ31))
CPU::Stop();
assert(Frame->InterruptNumber <= CPU::x86::IRQ223);
auto it = RegisteredEvents.begin();
while (it != RegisteredEvents.end())
{
int iEvNum = it->IRQ;
#if defined(a86)
iEvNum += CPU::x86::IRQ0;
#endif
if (iEvNum == s_cst(int, Frame->InterruptNumber))
break;
++it;
}
if (it == RegisteredEvents.end())
{
warn("IRQ%d is not registered.", Frame->InterruptNumber - 32);
ReturnFromInterrupt(Frame);
return;
}
it->Priority++;
if (it->IsHandler)
{
Handler *hnd = (Handler *)it->Data;
hnd->OnInterruptReceived(Frame);
}
else
{
if (it->Context != nullptr)
it->Callback((CPU::TrapFrame *)it->Context);
else
it->Callback(Frame);
}
ReturnFromInterrupt(Frame);
}
Handler::Handler(int InterruptNumber, bool Critical)
{
foreach (auto ev in RegisteredEvents)