mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
Pass CPU state as a pointer
Previously CPU statue was passed on the stack, but the compiler is allowed to clobber values passed to it on the stack in the SysV x86 ABI. So now leave the state on the stack but pass a pointer to it into the ISR functions.
This commit is contained in:
@@ -18,8 +18,8 @@ static const uint16_t PIC2 = 0xa0;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
void _halt();
|
void _halt();
|
||||||
|
|
||||||
uintptr_t isr_handler(uintptr_t, cpu_state);
|
uintptr_t isr_handler(uintptr_t, cpu_state*);
|
||||||
uintptr_t irq_handler(uintptr_t, cpu_state);
|
uintptr_t irq_handler(uintptr_t, cpu_state*);
|
||||||
uintptr_t syscall_handler(uintptr_t, cpu_state);
|
uintptr_t syscall_handler(uintptr_t, cpu_state);
|
||||||
|
|
||||||
#define ISR(i, name) extern void name ();
|
#define ISR(i, name) extern void name ();
|
||||||
@@ -105,23 +105,23 @@ interrupts_init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t
|
uintptr_t
|
||||||
isr_handler(uintptr_t return_rsp, cpu_state regs)
|
isr_handler(uintptr_t return_rsp, cpu_state *regs)
|
||||||
{
|
{
|
||||||
console *cons = console::get();
|
console *cons = console::get();
|
||||||
|
|
||||||
switch (static_cast<isr>(regs.interrupt & 0xff)) {
|
switch (static_cast<isr>(regs->interrupt & 0xff)) {
|
||||||
|
|
||||||
case isr::isrGPFault: {
|
case isr::isrGPFault: {
|
||||||
cons->set_color(9);
|
cons->set_color(9);
|
||||||
cons->puts("\nGeneral Protection Fault:\n");
|
cons->puts("\nGeneral Protection Fault:\n");
|
||||||
cons->set_color();
|
cons->set_color();
|
||||||
|
|
||||||
cons->printf(" errorcode: %lx", regs.errorcode);
|
cons->printf(" errorcode: %lx", regs->errorcode);
|
||||||
if (regs.errorcode & 0x01) cons->puts(" external");
|
if (regs->errorcode & 0x01) cons->puts(" external");
|
||||||
|
|
||||||
int index = (regs.errorcode & 0xffff) >> 4;
|
int index = (regs->errorcode & 0xffff) >> 4;
|
||||||
if (index) {
|
if (index) {
|
||||||
switch ((regs.errorcode & 0x07) >> 1) {
|
switch ((regs->errorcode & 0x07) >> 1) {
|
||||||
case 0:
|
case 0:
|
||||||
cons->printf(" GDT[%x]\n", index);
|
cons->printf(" GDT[%x]\n", index);
|
||||||
gdt_dump();
|
gdt_dump();
|
||||||
@@ -140,10 +140,10 @@ isr_handler(uintptr_t return_rsp, cpu_state regs)
|
|||||||
} else {
|
} else {
|
||||||
cons->putc('\n');
|
cons->putc('\n');
|
||||||
}
|
}
|
||||||
print_regs(regs);
|
print_regs(*regs);
|
||||||
/*
|
/*
|
||||||
print_stacktrace(2);
|
print_stacktrace(2);
|
||||||
print_stack(regs);
|
print_stack(*regs);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -156,19 +156,19 @@ isr_handler(uintptr_t return_rsp, cpu_state regs)
|
|||||||
cons->set_color();
|
cons->set_color();
|
||||||
|
|
||||||
cons->puts(" flags:");
|
cons->puts(" flags:");
|
||||||
if (regs.errorcode & 0x01) cons->puts(" present");
|
if (regs->errorcode & 0x01) cons->puts(" present");
|
||||||
if (regs.errorcode & 0x02) cons->puts(" write");
|
if (regs->errorcode & 0x02) cons->puts(" write");
|
||||||
if (regs.errorcode & 0x04) cons->puts(" user");
|
if (regs->errorcode & 0x04) cons->puts(" user");
|
||||||
if (regs.errorcode & 0x08) cons->puts(" reserved");
|
if (regs->errorcode & 0x08) cons->puts(" reserved");
|
||||||
if (regs.errorcode & 0x10) cons->puts(" ip");
|
if (regs->errorcode & 0x10) cons->puts(" ip");
|
||||||
cons->puts("\n");
|
cons->puts("\n");
|
||||||
|
|
||||||
uint64_t cr2 = 0;
|
uint64_t cr2 = 0;
|
||||||
__asm__ __volatile__ ("mov %%cr2, %0" : "=r"(cr2));
|
__asm__ __volatile__ ("mov %%cr2, %0" : "=r"(cr2));
|
||||||
print_reg("cr2", cr2);
|
print_reg("cr2", cr2);
|
||||||
|
|
||||||
print_reg("rsp", regs.user_rsp);
|
print_reg("rsp", regs->user_rsp);
|
||||||
print_reg("rip", regs.rip);
|
print_reg("rip", regs->rip);
|
||||||
|
|
||||||
cons->puts("\n");
|
cons->puts("\n");
|
||||||
print_stacktrace(2);
|
print_stacktrace(2);
|
||||||
@@ -192,14 +192,14 @@ isr_handler(uintptr_t return_rsp, cpu_state regs)
|
|||||||
|
|
||||||
case isr::isrAssert: {
|
case isr::isrAssert: {
|
||||||
cons->set_color();
|
cons->set_color();
|
||||||
print_regs(regs);
|
print_regs(*regs);
|
||||||
print_stacktrace(2);
|
print_stacktrace(2);
|
||||||
}
|
}
|
||||||
_halt();
|
_halt();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case isr::isrSyscall: {
|
case isr::isrSyscall: {
|
||||||
return_rsp = syscall_dispatch(return_rsp, regs);
|
return_rsp = syscall_dispatch(return_rsp, *regs);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ isr_handler(uintptr_t return_rsp, cpu_state regs)
|
|||||||
case isr::isrIgnore5:
|
case isr::isrIgnore5:
|
||||||
case isr::isrIgnore6:
|
case isr::isrIgnore6:
|
||||||
case isr::isrIgnore7:
|
case isr::isrIgnore7:
|
||||||
//cons->printf("\nIGNORED: %02x\n", regs.interrupt);
|
//cons->printf("\nIGNORED: %02x\n", regs->interrupt);
|
||||||
outb(PIC1, 0x20);
|
outb(PIC1, 0x20);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -227,7 +227,7 @@ isr_handler(uintptr_t return_rsp, cpu_state regs)
|
|||||||
case isr::isrIgnoreD:
|
case isr::isrIgnoreD:
|
||||||
case isr::isrIgnoreE:
|
case isr::isrIgnoreE:
|
||||||
case isr::isrIgnoreF:
|
case isr::isrIgnoreF:
|
||||||
//cons->printf("\nIGNORED: %02x\n", regs.interrupt);
|
//cons->printf("\nIGNORED: %02x\n", regs->interrupt);
|
||||||
outb(PIC1, 0x20);
|
outb(PIC1, 0x20);
|
||||||
outb(PIC2, 0x20);
|
outb(PIC2, 0x20);
|
||||||
break;
|
break;
|
||||||
@@ -235,13 +235,13 @@ isr_handler(uintptr_t return_rsp, cpu_state regs)
|
|||||||
default:
|
default:
|
||||||
cons->set_color(9);
|
cons->set_color(9);
|
||||||
cons->printf("\nReceived %02x interrupt:\n",
|
cons->printf("\nReceived %02x interrupt:\n",
|
||||||
(static_cast<isr>(regs.interrupt)));
|
(static_cast<isr>(regs->interrupt)));
|
||||||
|
|
||||||
cons->set_color();
|
cons->set_color();
|
||||||
cons->printf(" ISR: %02lx ERR: %lx\n\n",
|
cons->printf(" ISR: %02lx ERR: %lx\n\n",
|
||||||
regs.interrupt, regs.errorcode);
|
regs->interrupt, regs->errorcode);
|
||||||
|
|
||||||
print_regs(regs);
|
print_regs(*regs);
|
||||||
//print_stacktrace(2);
|
//print_stacktrace(2);
|
||||||
_halt();
|
_halt();
|
||||||
}
|
}
|
||||||
@@ -251,16 +251,16 @@ isr_handler(uintptr_t return_rsp, cpu_state regs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t
|
uintptr_t
|
||||||
irq_handler(uintptr_t return_rsp, cpu_state regs)
|
irq_handler(uintptr_t return_rsp, cpu_state *regs)
|
||||||
{
|
{
|
||||||
console *cons = console::get();
|
console *cons = console::get();
|
||||||
uint8_t irq = get_irq(regs.interrupt);
|
uint8_t irq = get_irq(regs->interrupt);
|
||||||
if (! device_manager::get().dispatch_irq(irq)) {
|
if (! device_manager::get().dispatch_irq(irq)) {
|
||||||
cons->set_color(11);
|
cons->set_color(11);
|
||||||
cons->printf("\nReceived unknown IRQ: %d (vec %d)\n",
|
cons->printf("\nReceived unknown IRQ: %d (vec %d)\n",
|
||||||
irq, regs.interrupt);
|
irq, regs->interrupt);
|
||||||
cons->set_color();
|
cons->set_color();
|
||||||
print_regs(regs);
|
print_regs(*regs);
|
||||||
_halt();
|
_halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ isr_handler_prelude:
|
|||||||
push_all_and_segments
|
push_all_and_segments
|
||||||
|
|
||||||
mov rdi, rsp
|
mov rdi, rsp
|
||||||
|
mov rsi, rsp
|
||||||
call isr_handler
|
call isr_handler
|
||||||
mov rsp, rax
|
mov rsp, rax
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ irq_handler_prelude:
|
|||||||
push_all_and_segments
|
push_all_and_segments
|
||||||
|
|
||||||
mov rdi, rsp
|
mov rdi, rsp
|
||||||
|
mov rsi, rsp
|
||||||
call irq_handler
|
call irq_handler
|
||||||
mov rsp, rax
|
mov rsp, rax
|
||||||
|
|
||||||
@@ -56,8 +58,8 @@ irq_handler_prelude:
|
|||||||
jmp irq_handler_prelude
|
jmp irq_handler_prelude
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
%define EISR(i, name) EMIT_EISR name, i
|
%define EISR(i, name) EMIT_EISR name, i ; ISR with error code
|
||||||
%define UISR(i, name) EMIT_ISR name, i
|
%define UISR(i, name) EMIT_ISR name, i ; ISR callable from user space
|
||||||
%define ISR(i, name) EMIT_ISR name, i
|
%define ISR(i, name) EMIT_ISR name, i
|
||||||
%define IRQ(i, q, name) EMIT_IRQ name, i
|
%define IRQ(i, q, name) EMIT_IRQ name, i
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class lapic;
|
|||||||
struct page_table;
|
struct page_table;
|
||||||
struct cpu_state;
|
struct cpu_state;
|
||||||
|
|
||||||
extern "C" uintptr_t isr_handler(uintptr_t, cpu_state);
|
extern "C" uintptr_t isr_handler(uintptr_t, cpu_state*);
|
||||||
|
|
||||||
|
|
||||||
/// The task scheduler
|
/// The task scheduler
|
||||||
@@ -59,8 +59,8 @@ public:
|
|||||||
static scheduler & get() { return s_instance; }
|
static scheduler & get() { return s_instance; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend uintptr_t syscall_dispatch(uintptr_t, const cpu_state &);
|
friend uintptr_t syscall_dispatch(uintptr_t, cpu_state &);
|
||||||
friend uintptr_t isr_handler(uintptr_t, cpu_state);
|
friend uintptr_t isr_handler(uintptr_t, cpu_state*);
|
||||||
|
|
||||||
/// Handle a timer tick
|
/// Handle a timer tick
|
||||||
/// \arg rsp0 The stack pointer of the current interrupt handler
|
/// \arg rsp0 The stack pointer of the current interrupt handler
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ syscall_enable()
|
|||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t
|
uintptr_t
|
||||||
syscall_dispatch(uintptr_t return_rsp, const cpu_state ®s)
|
syscall_dispatch(uintptr_t return_rsp, cpu_state ®s)
|
||||||
{
|
{
|
||||||
console *cons = console::get();
|
console *cons = console::get();
|
||||||
syscall call = static_cast<syscall>(regs.rax);
|
syscall call = static_cast<syscall>(regs.rax);
|
||||||
@@ -65,7 +65,7 @@ syscall_dispatch(uintptr_t return_rsp, const cpu_state ®s)
|
|||||||
auto *p = s.current();
|
auto *p = s.current();
|
||||||
p->wait_on_signal(-1ull);
|
p->wait_on_signal(-1ull);
|
||||||
cons->printf("\nReceived PAUSE syscall\n");
|
cons->printf("\nReceived PAUSE syscall\n");
|
||||||
return_rsp = s.tick(return_rsp);
|
return_rsp = s.schedule(return_rsp);
|
||||||
cons->set_color();
|
cons->set_color();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -78,7 +78,7 @@ syscall_dispatch(uintptr_t return_rsp, const cpu_state ®s)
|
|||||||
auto *p = s.current();
|
auto *p = s.current();
|
||||||
p->wait_on_time(regs.rbx);
|
p->wait_on_time(regs.rbx);
|
||||||
cons->printf("\nReceived SLEEP syscall\n");
|
cons->printf("\nReceived SLEEP syscall\n");
|
||||||
return_rsp = s.tick(return_rsp);
|
return_rsp = s.schedule(return_rsp);
|
||||||
cons->set_color();
|
cons->set_color();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -16,5 +16,5 @@ enum class syscall : uint64_t
|
|||||||
};
|
};
|
||||||
|
|
||||||
void syscall_enable();
|
void syscall_enable();
|
||||||
uintptr_t syscall_dispatch(uintptr_t, const cpu_state &);
|
uintptr_t syscall_dispatch(uintptr_t, cpu_state &);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user