X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?p=polintos%2Fscott%2Fpriv.git;a=blobdiff_plain;f=kernel%2Farch%2Fx86%2Fmisc.cc;h=a1b6e18b2dc2fb5d2171a05ac8fb9eac1da7bc6f;hp=48bf24cffc7b8a558d4b854400b50039e7e21b1f;hb=0601614ebbcc48b961a2f0613281e6e629af29b1;hpb=292f369387f0b1018b3cfc59ad555698d75d6d46 diff --git a/kernel/arch/x86/misc.cc b/kernel/arch/x86/misc.cc index 48bf24c..a1b6e18 100644 --- a/kernel/arch/x86/misc.cc +++ b/kernel/arch/x86/misc.cc @@ -20,9 +20,11 @@ #include #include #include +#include #include #include +#include extern u32 x86_init_ptbl_l2[1024]; @@ -35,22 +37,18 @@ namespace Arch { namespace Priv { void set_idt(); - void show_regs(u32 *stack) { + void show_regs(Regs *regs) + { printf("eax: 0x%08x ecx: 0x%08x edx: 0x%08x ebx: 0x%08x\n" "esp: 0x%08x ebp: 0x%08x esi: 0x%08x edi: 0x%08x\n" - "eflags: 0x%08x\n", - stack[0], - stack[1], - stack[2], - stack[3], - stack[9] & 3 ? stack[11] : (u32)stack + 11 * 4, - stack[5], - stack[6], - stack[7], - stack[10]); + "eflags: 0x%08x ds: %04x es: %04x ss: %04x\n", + regs->eax, regs->ecx, regs->edx, regs->ebx, + regs->cs & 3 ? regs->user_esp : (u32)regs + (u32)sizeof(regs), + regs->ebp, regs->esi, regs->edi, regs->eflags, + regs->ds, regs->es, regs->cs & 3 ? regs->user_ss : regs->ds); printf("Stack trace: "); - u32 *frame = (u32 *)stack[5]; + u32 *frame = (u32 *)regs->ebp; for (int i = 2; i < 32; i++) { u32 stackptr = frame[1]; @@ -119,36 +117,37 @@ namespace Arch { } using Arch::Priv::show_regs; +using Arch::Priv::Regs; -extern "C" void x86_do_diverr(u32 *stack) +extern "C" void x86_do_diverr(Regs *regs) { - printf("Division error at 0x%04x:0x%08x\n", stack[9], stack[8]); - show_regs(stack); + printf("Division error at 0x%04x:0x%08x\n", regs->cs, regs->eip); + show_regs(regs); for(;;); } -extern "C" void x86_do_debug(u32 *stack) +extern "C" void x86_do_debug(Regs *regs) { - printf("Debug exception at 0x%04x:0x%08x\n", stack[9], stack[8]); - show_regs(stack); + printf("Debug exception at 0x%04x:0x%08x\n", regs->cs, regs->eip); + show_regs(regs); for(;;); } -extern "C" void x86_do_breakpoint(u32 *stack) +extern "C" void x86_do_breakpoint(Regs *regs) { - printf("Breakpoint at 0x%04x:0x%08x\n", stack[9], stack[8]); - show_regs(stack); + printf("Breakpoint at 0x%04x:0x%08x\n", regs->cs, regs->eip); + show_regs(regs); for(;;); } -extern "C" void x86_do_invalid_insn(u32 *stack) +extern "C" void x86_do_invalid_insn(Regs *regs) { - printf("Invalid instruction at 0x%04x:0x%08x\n", stack[9], stack[8]); - show_regs(stack); + printf("Invalid instruction at 0x%04x:0x%08x\n", regs->cs, regs->eip); + show_regs(regs); for(;;); } -extern "C" void x86_do_page_fault(u32 *stack, u32 fault_addr, u32 error_code) +extern "C" void x86_do_page_fault(Regs *regs, u32 fault_addr, u32 error_code) { Mem::AddrSpace *as; @@ -167,7 +166,7 @@ extern "C" void x86_do_page_fault(u32 *stack, u32 fault_addr, u32 error_code) // accomplish much other than decreasing the odds that the fault message // gets out. - if (!(stack[10] & 0x200)) + if (!(regs->eflags & 0x200)) goto bad_fault; // Don't allow fault-ins using a borrowed addr-space. @@ -190,14 +189,14 @@ bad_fault: in_fault++; printf("Page fault at 0x%04x:0x%08x for 0x%08x, error code: 0x%04x\n", - stack[9], stack[8], fault_addr, error_code); + regs->cs, regs->eip, fault_addr, error_code); - show_regs(stack); + show_regs(regs); for(;;); } -extern "C" void x86_do_gpf(u32 *stack, u32 error_code) +extern "C" void x86_do_gpf(Regs *regs, u32 error_code) { if (in_fault) for(;;); @@ -205,9 +204,9 @@ extern "C" void x86_do_gpf(u32 *stack, u32 error_code) in_fault++; printf("General protection fault at 0x%04x:0x%08x, error code: 0x%04x\n", - stack[9], stack[8], error_code); + regs->cs, regs->eip, error_code); - show_regs(stack); + show_regs(regs); for(;;); } @@ -216,3 +215,32 @@ extern "C" void x86_do_irq(int irq) { IRQ::i8259.handle_irq(irq - 0x20); } + +namespace Arch { +namespace Priv { + struct OrbRegs { + union { + System::RunTime::ParamInfoBlock *pib; + ulong exptr; + }; + + union { + ulong caller; + ulong exlen; + }; + + ulong eip, cs, eflags, user_esp, user_ss; + }; +}} + +extern "C" void x86_invoke_method(Arch::Priv::OrbRegs *regs) +{ + assert(regs->cs & 3); + ORB::invoke_method(regs->pib, regs->user_esp); +} + +extern "C" void x86_return_from_method(Arch::Priv::OrbRegs *regs) +{ + assert(regs->cs & 3); + regs->user_esp = ORB::return_from_method(regs->exptr, regs->exlen); +}