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();
|
void disable();
|
||||||
|
|
||||||
bool is_in_handler();
|
bool is_in_handler();
|
||||||
void ensure_handler();
|
|
||||||
void return_from_handler(Context* context);
|
void return_from_handler(Context* context);
|
||||||
}
|
}
|
@ -11,3 +11,5 @@ struct StackTracer
|
|||||||
private:
|
private:
|
||||||
uintptr_t m_base_pointer;
|
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());
|
ASSERT(Interrupts::is_in_handler());
|
||||||
if (context->number >= 0x20 && context->number < 0x30)
|
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);
|
IRQ::interrupt_handler(context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -35,7 +33,6 @@ extern "C" void common_handler(Context* context)
|
|||||||
|
|
||||||
StackTracer tracer(context->rbp);
|
StackTracer tracer(context->rbp);
|
||||||
tracer.trace_with_ip(context->rip);
|
tracer.trace_with_ip(context->rip);
|
||||||
Interrupts::ensure_handler();
|
|
||||||
Scheduler::task_misbehave(context);
|
Scheduler::task_misbehave(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,27 +50,14 @@ extern "C" void common_handler(Context* context)
|
|||||||
StackTracer tracer(context->rbp);
|
StackTracer tracer(context->rbp);
|
||||||
tracer.trace_with_ip(context->rip);
|
tracer.trace_with_ip(context->rip);
|
||||||
|
|
||||||
Interrupts::ensure_handler();
|
|
||||||
Scheduler::task_misbehave(context);
|
Scheduler::task_misbehave(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (context->number == 8) { int_panic(context, "Double fault, halting"); }
|
if (context->number == 8) { int_panic(context, "Double fault, halting"); }
|
||||||
if (context->number == 48)
|
if (context->number == 48) { Scheduler::task_yield(context); }
|
||||||
{
|
if (context->number == 49) { Scheduler::task_exit(context); }
|
||||||
Interrupts::ensure_handler();
|
|
||||||
Scheduler::task_yield(context);
|
|
||||||
}
|
|
||||||
if (context->number == 49)
|
|
||||||
{
|
|
||||||
Interrupts::ensure_handler();
|
|
||||||
Scheduler::task_exit(context);
|
|
||||||
}
|
|
||||||
if (context->number == 50) { Serial::print((const char*)context->rdi); }
|
if (context->number == 50) { Serial::print((const char*)context->rdi); }
|
||||||
if (context->number == 51)
|
if (context->number == 51) { Scheduler::task_sleep(context); }
|
||||||
{
|
|
||||||
Interrupts::ensure_handler();
|
|
||||||
Scheduler::task_sleep(context);
|
|
||||||
}
|
|
||||||
if (context->number == 256) { kwarnln("Unused interrupt"); }
|
if (context->number == 256) { kwarnln("Unused interrupt"); }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
@ -37,11 +37,6 @@ unused:
|
|||||||
|
|
||||||
extern common_handler
|
extern common_handler
|
||||||
|
|
||||||
section .bss
|
|
||||||
global __is_in_interrupt_handler
|
|
||||||
__is_in_interrupt_handler:
|
|
||||||
resb 1
|
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
global asm_common
|
global asm_common
|
||||||
asm_common:
|
asm_common:
|
||||||
@ -68,8 +63,6 @@ asm_common:
|
|||||||
mov r8, cr2
|
mov r8, cr2
|
||||||
push r8
|
push r8
|
||||||
|
|
||||||
mov BYTE [__is_in_interrupt_handler], 1
|
|
||||||
|
|
||||||
mov rdi, rsp
|
mov rdi, rsp
|
||||||
|
|
||||||
call common_handler
|
call common_handler
|
||||||
@ -83,8 +76,6 @@ _asm_interrupt_exit:
|
|||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
||||||
mov BYTE [__is_in_interrupt_handler], 0
|
|
||||||
|
|
||||||
pop r15
|
pop r15
|
||||||
pop r14
|
pop r14
|
||||||
pop r13
|
pop r13
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "interrupts/Interrupts.h"
|
#include "interrupts/Interrupts.h"
|
||||||
|
#include "trace/StackTracer.h"
|
||||||
|
|
||||||
void Interrupts::disable()
|
void Interrupts::disable()
|
||||||
{
|
{
|
||||||
@ -10,15 +11,11 @@ void Interrupts::enable()
|
|||||||
asm volatile("sti");
|
asm volatile("sti");
|
||||||
}
|
}
|
||||||
|
|
||||||
extern char __is_in_interrupt_handler;
|
extern int _asm_interrupt_exit;
|
||||||
|
|
||||||
bool Interrupts::is_in_handler()
|
bool Interrupts::is_in_handler()
|
||||||
{
|
{
|
||||||
return __is_in_interrupt_handler;
|
return stack_trace_contains((uintptr_t)&_asm_interrupt_exit);
|
||||||
}
|
|
||||||
|
|
||||||
void Interrupts::ensure_handler()
|
|
||||||
{
|
|
||||||
__is_in_interrupt_handler = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interrupts::return_from_handler(Context* context)
|
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);
|
printf("%lx: %s\n", ip, symbol_name);
|
||||||
trace();
|
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