mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-25 22:14:37 +00:00
interrupts: Update MainInterruptHandler
This commit is contained in:
parent
ab6529f6e6
commit
6dc734bb0b
@ -280,60 +280,11 @@ namespace Interrupts
|
|||||||
warn("IRQ%d not found.", InterruptNumber);
|
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();
|
CPUData *CoreData = GetCurrentCPU();
|
||||||
int Core = CoreData->ID;
|
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 */
|
/* TODO: This should be done when the os is idle */
|
||||||
if (SortEvents++ > SORT_ITR)
|
if (SortEvents++ > SORT_ITR)
|
||||||
{
|
{
|
||||||
@ -362,17 +313,63 @@ namespace Interrupts
|
|||||||
{
|
{
|
||||||
APIC::APIC *this_apic = (APIC::APIC *)apic[Core];
|
APIC::APIC *this_apic = (APIC::APIC *)apic[Core];
|
||||||
this_apic->EOI();
|
this_apic->EOI();
|
||||||
// TODO: Handle PIC too
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fixme("APIC not found for core %d", Core);
|
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();
|
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)
|
Handler::Handler(int InterruptNumber, bool Critical)
|
||||||
{
|
{
|
||||||
foreach (auto ev in RegisteredEvents)
|
foreach (auto ev in RegisteredEvents)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user