mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
Pause syscall and int 0xee interrupt syscalls
The syscall/sysret instructions don't swap stacks. This was bad but passable until syscalls caused the scheduler to run, and scheduling a task that paused due to interrupt. Adding a new (hopefully temporary) syscall interrupt `int 0xee` to allow me to test syscalls without stack issues before I tackle the syscall/sysret issue. Also implemented a basic `pause` syscall that causes the calling process to become unready. Because nothing can wake a process yet, it never returns.
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "kutil/memory.h"
|
||||
#include "console.h"
|
||||
#include "cpu.h"
|
||||
#include "debug.h"
|
||||
#include "device_manager.h"
|
||||
#include "gdt.h"
|
||||
#include "interrupts.h"
|
||||
@@ -19,9 +21,11 @@ extern "C" {
|
||||
|
||||
#define ISR(i, name) extern void name ();
|
||||
#define EISR(i, name) extern void name ();
|
||||
#define UISR(i, name) extern void name ();
|
||||
#define IRQ(i, q, name) extern void name ();
|
||||
#include "interrupt_isrs.inc"
|
||||
#undef IRQ
|
||||
#undef UISR
|
||||
#undef EISR
|
||||
#undef ISR
|
||||
}
|
||||
@@ -39,9 +43,11 @@ get_irq(unsigned vector)
|
||||
switch (vector) {
|
||||
#define ISR(i, name)
|
||||
#define EISR(i, name)
|
||||
#define UISR(i, name)
|
||||
#define IRQ(i, q, name) case i : return q;
|
||||
#include "interrupt_isrs.inc"
|
||||
#undef IRQ
|
||||
#undef UISR
|
||||
#undef EISR
|
||||
#undef ISR
|
||||
|
||||
@@ -52,7 +58,6 @@ get_irq(unsigned vector)
|
||||
static void
|
||||
disable_legacy_pic()
|
||||
{
|
||||
|
||||
static const uint16_t PIC1 = 0x20;
|
||||
static const uint16_t PIC2 = 0xa0;
|
||||
|
||||
@@ -85,9 +90,11 @@ interrupts_init()
|
||||
{
|
||||
#define ISR(i, name) idt_set_entry(i, reinterpret_cast<uint64_t>(& name), 0x08, 0x8e);
|
||||
#define EISR(i, name) idt_set_entry(i, reinterpret_cast<uint64_t>(& name), 0x08, 0x8e);
|
||||
#define UISR(i, name) idt_set_entry(i, reinterpret_cast<uint64_t>(& name), 0x08, 0xee);
|
||||
#define IRQ(i, q, name) idt_set_entry(i, reinterpret_cast<uint64_t>(& name), 0x08, 0x8e);
|
||||
#include "interrupt_isrs.inc"
|
||||
#undef IRQ
|
||||
#undef UISR
|
||||
#undef EISR
|
||||
#undef ISR
|
||||
|
||||
@@ -97,71 +104,6 @@ interrupts_init()
|
||||
log::info(logs::boot, "Interrupts enabled.");
|
||||
}
|
||||
|
||||
#define print_reg(name, value) cons->printf(" %s: %016lx\n", name, (value));
|
||||
|
||||
extern "C" uint64_t get_frame(int frame);
|
||||
|
||||
void
|
||||
print_stacktrace(int skip = 0)
|
||||
{
|
||||
console *cons = console::get();
|
||||
int frame = 0;
|
||||
uint64_t bp = get_frame(skip);
|
||||
while (bp) {
|
||||
cons->printf(" frame %2d: %lx\n", frame, bp);
|
||||
bp = get_frame(++frame + skip);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
print_regs(const cpu_state ®s)
|
||||
{
|
||||
console *cons = console::get();
|
||||
|
||||
print_reg("rax", regs.rax);
|
||||
print_reg("rbx", regs.rbx);
|
||||
print_reg("rcx", regs.rcx);
|
||||
print_reg("rdx", regs.rdx);
|
||||
print_reg("rdi", regs.rdi);
|
||||
print_reg("rsi", regs.rsi);
|
||||
|
||||
cons->puts("\n");
|
||||
print_reg(" r8", regs.r8);
|
||||
print_reg(" r9", regs.r9);
|
||||
print_reg("r10", regs.r10);
|
||||
print_reg("r11", regs.r11);
|
||||
print_reg("r12", regs.r12);
|
||||
print_reg("r13", regs.r13);
|
||||
print_reg("r14", regs.r14);
|
||||
print_reg("r15", regs.r15);
|
||||
|
||||
cons->puts("\n");
|
||||
print_reg("rbp", regs.rbp);
|
||||
print_reg("rsp", regs.user_rsp);
|
||||
print_reg("sp0", tss_get_stack(0));
|
||||
|
||||
cons->puts("\n");
|
||||
print_reg(" ds", regs.ds);
|
||||
print_reg(" cs", regs.cs);
|
||||
print_reg(" ss", regs.ss);
|
||||
|
||||
cons->puts("\n");
|
||||
print_reg("rip", regs.rip);
|
||||
}
|
||||
|
||||
void
|
||||
print_stack(const cpu_state ®s)
|
||||
{
|
||||
console *cons = console::get();
|
||||
|
||||
cons->puts("\nStack:\n");
|
||||
uint64_t sp = regs.user_rsp;
|
||||
while (sp <= regs.rbp) {
|
||||
cons->printf("%016x: %016x\n", sp, *reinterpret_cast<uint64_t *>(sp));
|
||||
sp += sizeof(uint64_t);
|
||||
}
|
||||
}
|
||||
|
||||
addr_t
|
||||
isr_handler(addr_t return_rsp, cpu_state regs)
|
||||
{
|
||||
@@ -197,33 +139,35 @@ isr_handler(addr_t return_rsp, cpu_state regs)
|
||||
cons->puts("\nGeneral Protection Fault:\n");
|
||||
cons->set_color();
|
||||
|
||||
cons->puts(" flags:");
|
||||
cons->printf(" errorcode: %lx", regs.errorcode);
|
||||
if (regs.errorcode & 0x01) cons->puts(" external");
|
||||
|
||||
int index = (regs.errorcode & 0xf8) >> 3;
|
||||
int index = (regs.errorcode & 0xffff) >> 4;
|
||||
if (index) {
|
||||
switch (regs.errorcode & 0x06) {
|
||||
switch ((regs.errorcode & 0x07) >> 1) {
|
||||
case 0:
|
||||
cons->printf(" GDT[%d]\n", index);
|
||||
cons->printf(" GDT[%x]\n", index);
|
||||
gdt_dump();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case 3:
|
||||
cons->printf(" IDT[%d]\n", index);
|
||||
cons->printf(" IDT[%x]\n", index);
|
||||
idt_dump();
|
||||
break;
|
||||
|
||||
default:
|
||||
cons->printf(" LDT[%d]??\n", index);
|
||||
cons->printf(" LDT[%x]??\n", index);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
cons->putc('\n');
|
||||
}
|
||||
print_regs(regs);
|
||||
/*
|
||||
print_stacktrace(2);
|
||||
print_stack(regs);
|
||||
*/
|
||||
|
||||
}
|
||||
_halt();
|
||||
@@ -263,17 +207,22 @@ isr_handler(addr_t return_rsp, cpu_state regs)
|
||||
_halt();
|
||||
break;
|
||||
|
||||
case isr::isrSyscall: {
|
||||
return_rsp = syscall_dispatch(return_rsp, regs);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
cons->set_color(9);
|
||||
cons->puts("\nReceived ISR interrupt:\n");
|
||||
cons->set_color();
|
||||
cons->printf("\nReceived %02x interrupt:\n",
|
||||
(static_cast<isr>(regs.interrupt)));
|
||||
|
||||
cons->printf(" ISR: %02lx\n", regs.interrupt);
|
||||
cons->printf(" ERR: %lx\n", regs.errorcode);
|
||||
cons->puts("\n");
|
||||
cons->set_color();
|
||||
cons->printf(" ISR: %02lx ERR: %lx\n\n",
|
||||
regs.interrupt, regs.errorcode);
|
||||
|
||||
print_regs(regs);
|
||||
print_stacktrace(2);
|
||||
//print_stacktrace(2);
|
||||
_halt();
|
||||
}
|
||||
*reinterpret_cast<uint32_t *>(0xffffff80fee000b0) = 0;
|
||||
@@ -302,34 +251,5 @@ irq_handler(addr_t return_rsp, cpu_state regs)
|
||||
addr_t
|
||||
syscall_handler(addr_t return_rsp, cpu_state regs)
|
||||
{
|
||||
console *cons = console::get();
|
||||
syscall call = static_cast<syscall>(regs.rax);
|
||||
|
||||
switch (call) {
|
||||
case syscall::noop:
|
||||
break;
|
||||
|
||||
case syscall::debug:
|
||||
cons->set_color(11);
|
||||
cons->printf("\nReceived DEBUG syscall\n");
|
||||
cons->set_color();
|
||||
print_regs(regs);
|
||||
break;
|
||||
|
||||
case syscall::message:
|
||||
cons->set_color(11);
|
||||
cons->printf("\nReceived MESSAGE syscall\n");
|
||||
cons->set_color();
|
||||
break;
|
||||
|
||||
default:
|
||||
cons->set_color(9);
|
||||
cons->printf("\nReceived unknown syscall: %02x\n", call);
|
||||
cons->set_color();
|
||||
print_regs(regs);
|
||||
_halt();
|
||||
break;
|
||||
}
|
||||
|
||||
return return_rsp;
|
||||
return syscall_dispatch(return_rsp, regs);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user