Interrupts: Remove ensure_handler and use a more reliable way of detecting if we are in a handler
This commit is contained in:
parent
6c036dfe99
commit
46f459337c
@ -7,6 +7,5 @@ namespace Interrupts
|
||||
void disable();
|
||||
|
||||
bool is_in_handler();
|
||||
void ensure_handler();
|
||||
void return_from_handler(Context* context);
|
||||
}
|
@ -11,3 +11,5 @@ struct StackTracer
|
||||
private:
|
||||
uintptr_t m_base_pointer;
|
||||
};
|
||||
|
||||
bool stack_trace_contains(uintptr_t address);
|
@ -17,8 +17,6 @@ extern "C" void common_handler(Context* context)
|
||||
ASSERT(Interrupts::is_in_handler());
|
||||
if (context->number >= 0x20 && context->number < 0x30)
|
||||
{
|
||||
Interrupts::ensure_handler(); // restore the "in-interrupt flag" if an interrupt happened in the middle of this
|
||||
// one
|
||||
IRQ::interrupt_handler(context);
|
||||
return;
|
||||
}
|
||||
@ -35,7 +33,6 @@ extern "C" void common_handler(Context* context)
|
||||
|
||||
StackTracer tracer(context->rbp);
|
||||
tracer.trace_with_ip(context->rip);
|
||||
Interrupts::ensure_handler();
|
||||
Scheduler::task_misbehave(context);
|
||||
}
|
||||
}
|
||||
@ -53,27 +50,14 @@ extern "C" void common_handler(Context* context)
|
||||
StackTracer tracer(context->rbp);
|
||||
tracer.trace_with_ip(context->rip);
|
||||
|
||||
Interrupts::ensure_handler();
|
||||
Scheduler::task_misbehave(context);
|
||||
}
|
||||
}
|
||||
if (context->number == 8) { int_panic(context, "Double fault, halting"); }
|
||||
if (context->number == 48)
|
||||
{
|
||||
Interrupts::ensure_handler();
|
||||
Scheduler::task_yield(context);
|
||||
}
|
||||
if (context->number == 49)
|
||||
{
|
||||
Interrupts::ensure_handler();
|
||||
Scheduler::task_exit(context);
|
||||
}
|
||||
if (context->number == 48) { Scheduler::task_yield(context); }
|
||||
if (context->number == 49) { Scheduler::task_exit(context); }
|
||||
if (context->number == 50) { Serial::print((const char*)context->rdi); }
|
||||
if (context->number == 51)
|
||||
{
|
||||
Interrupts::ensure_handler();
|
||||
Scheduler::task_sleep(context);
|
||||
}
|
||||
if (context->number == 51) { Scheduler::task_sleep(context); }
|
||||
if (context->number == 256) { kwarnln("Unused interrupt"); }
|
||||
return;
|
||||
}
|
@ -37,11 +37,6 @@ unused:
|
||||
|
||||
extern common_handler
|
||||
|
||||
section .bss
|
||||
global __is_in_interrupt_handler
|
||||
__is_in_interrupt_handler:
|
||||
resb 1
|
||||
|
||||
section .text
|
||||
global asm_common
|
||||
asm_common:
|
||||
@ -68,8 +63,6 @@ asm_common:
|
||||
mov r8, cr2
|
||||
push r8
|
||||
|
||||
mov BYTE [__is_in_interrupt_handler], 1
|
||||
|
||||
mov rdi, rsp
|
||||
|
||||
call common_handler
|
||||
@ -83,8 +76,6 @@ _asm_interrupt_exit:
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
|
||||
mov BYTE [__is_in_interrupt_handler], 0
|
||||
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "interrupts/Interrupts.h"
|
||||
#include "trace/StackTracer.h"
|
||||
|
||||
void Interrupts::disable()
|
||||
{
|
||||
@ -10,15 +11,11 @@ void Interrupts::enable()
|
||||
asm volatile("sti");
|
||||
}
|
||||
|
||||
extern char __is_in_interrupt_handler;
|
||||
extern int _asm_interrupt_exit;
|
||||
|
||||
bool Interrupts::is_in_handler()
|
||||
{
|
||||
return __is_in_interrupt_handler;
|
||||
}
|
||||
|
||||
void Interrupts::ensure_handler()
|
||||
{
|
||||
__is_in_interrupt_handler = true;
|
||||
return stack_trace_contains((uintptr_t)&_asm_interrupt_exit);
|
||||
}
|
||||
|
||||
void Interrupts::return_from_handler(Context* context)
|
||||
|
@ -36,3 +36,16 @@ void StackTracer::trace_with_ip(uintptr_t ip)
|
||||
printf("%lx: %s\n", ip, symbol_name);
|
||||
trace();
|
||||
}
|
||||
|
||||
bool stack_trace_contains(uintptr_t address)
|
||||
{
|
||||
uintptr_t base_pointer;
|
||||
asm volatile("mov %%rbp, %0" : "=r"(base_pointer));
|
||||
stackframe* frame = (stackframe*)base_pointer;
|
||||
while (frame && (uint64_t)frame > 0xfffffffff8000000)
|
||||
{
|
||||
if (frame->instruction == address) return true;
|
||||
frame = frame->next;
|
||||
}
|
||||
return false;
|
||||
}
|
Loading…
Reference in New Issue
Block a user