]> git.buserror.net Git - polintos/scott/priv.git/commitdiff
Regs struct, int98/99
authorScott Wood <scott@buserror.net>
Wed, 18 Apr 2007 01:30:32 +0000 (20:30 -0500)
committerScott Wood <scott@buserror.net>
Wed, 18 Apr 2007 01:30:32 +0000 (20:30 -0500)
kernel/arch/x86/descriptors.cc
kernel/arch/x86/entry.S
kernel/arch/x86/misc.cc
kernel/include/arch-x86/regs.h [new file with mode: 0644]
kernel/include/kern/orb.h
kernel/orb/invoke.cc

index 8619e1c01d7cf027958b2f2b172a6bce3a2ab705..e281895386764fec8f8481a58c5d455bfca38421 100644 (file)
@@ -152,7 +152,8 @@ static void set_int_gate(int num, void *addrptr, bool ints_off = false,
 }
 
 extern int x86_diverr, x86_debug, x86_breakpoint;
-extern int x86_gpf, x86_page_fault, x86_invalid_insn, x86_int99_entry;
+extern int x86_gpf, x86_page_fault, x86_invalid_insn;
+extern int x86_int98_entry, x86_int99_entry;
 extern void *x86_irqs[256];
 
 namespace Arch {
@@ -170,7 +171,8 @@ namespace Priv {
                set_int_gate(6, &x86_invalid_insn);
                set_int_gate(13, &x86_gpf);
                set_int_gate(14, &x86_page_fault, true);
-               set_int_gate(0x99, &x86_int99_entry);
+               set_int_gate(0x98, &x86_int98_entry, false, true);
+               set_int_gate(0x99, &x86_int99_entry, false, true);
                
                for (int i = 0x20; i < 0x30; i++)
                        set_int_gate(i, x86_irqs[i], true);
index f8cf68420facff66239e57ee1b6a7d1109683134..3483893d93f4c9c642d7244bc493eff25cff6cf2 100644 (file)
@@ -139,10 +139,25 @@ no_pentium_str:
 
 no_multiboot_str:
        .string "Unrecognized bootloader; a multiboot-compliant loader is required."
+
+       .macro  enterkernel, reg
+       pushl   %es
+       pushl   %ds
+       movl    $8, \reg
+       cld
+       movl    \reg, %ds
+       movl    \reg, %es
+       .endm
+       
+       .macro  exitkernel
+       popl    %ds
+       popl    %es
+       .endm
        
        .macro  pushvolatilesnoeax
        pushl   %ecx
        pushl   %edx
+       enterkernel %ecx
        .endm
        
        .macro  pushvolatiles
@@ -151,6 +166,7 @@ no_multiboot_str:
        .endm
 
        .macro  popvolatiles
+       exitkernel
        popl    %edx
        popl    %ecx
        popl    %eax
@@ -164,11 +180,11 @@ no_multiboot_str:
        .macro  pushall
        pushl   %esi
        pushl   %ebp
-       pushl   %esp
        pushl   %ebx
        pushl   %edx
        pushl   %ecx
        pushl   %eax
+       enterkernel %esi
        .endm
        
        .macro  pushallnoerr
@@ -177,11 +193,11 @@ no_multiboot_str:
        .endm
 
        .macro  popall
+       exitkernel
        popl    %eax
        popl    %ecx
        popl    %edx
        popl    %ebx
-       addl    $4, %esp
        popl    %ebp
        popl    %esi
        popl    %edi
@@ -261,17 +277,44 @@ x86_page_fault:
        popall
        iret
 
+       .global x86_int98_entry
+x86_int98_entry:
+       pushl   $0
+       pushl   %eax
+       enterkernel %ecx
+
+       pushl   %esp
+       call    x86_invoke_method
+       addl    $4, %esp
+
+       exitkernel
+       popl    %eax
+       xorl    %ecx, %ecx
+       popl    %edx
+       xorl    %ebx, %ebx
+       xorl    %ebp, %ebp
+       xorl    %esi, %esi
+       xorl    %edi, %edi
+       iret
+
        .global x86_int99_entry
 x86_int99_entry:
-       pushl   %edx
-       pushl   4(%esp)
-       pushl   %edx
        pushl   %ecx
        pushl   %eax
-       call    invoke_method
-       addl    $16, %esp
-       xorl    %ecx, %ecx
-       popl    %edx
+       enterkernel %edx
+
+       pushl   %esp
+       call    x86_return_from_method
+       addl    $4, %esp
+
+       exitkernel
+       popl    %eax
+       popl    %ecx
+       xorl    %edx, %edx
+       xorl    %ebx, %ebx
+       xorl    %ebp, %ebp
+       xorl    %esi, %esi
+       xorl    %edi, %edi
        iret
 
        .global x86_irq
@@ -342,16 +385,47 @@ x86_new_thread:
 
        .section ".roshared","x"
        
-       // The syscall pointer must be the first thing in roshared
-       // (at vaddr 0x7fff0000), so that user code can make method
-       // invocations to find out where other stuff is.
+       // The vsyscall table must be the first thing in roshared (at
+       // vaddr 0x7fff0000).
+
+#define PTR(x) (x - x86_syscall_ptr + 0x7fff0000)
        
        .global x86_syscall_ptr
 x86_syscall_ptr:
-       .long   x86_shared_int99 - x86_syscall_ptr + 0x7fff0000
-       
-       .global x86_shared_int99
+       .long   PTR(x86_shared_int98)
+
+       .global x86_sysret_ptr
+x86_sysret_ptr:
+       .long   PTR(x86_shared_int99)
+
+x86_shared_int98:
+       // FIXME: This must be unpreemptible by traps
+       pushl   %gs
+       pushl   %fs
+       pushl   %ebp
+       pushl   %edi
+       pushl   %esi
+       pushl   %ebx
+       int     $0x98
+       popl    %ebx
+       popl    %esi
+       popl    %edi
+       popl    %ebp
+       popl    %fs
+       popl    %gs
+       ret
+
 x86_shared_int99:
        int     $0x99
-       // FIXME: search for exception handler
        ret
+
+       .section ".rwshared",""
+
+       // Userspace must set this to an appropriate entry point
+       // prior to registering objects with the kernel.  It should
+       // not be modified while an object is registered (the kernel
+       // won't mind, but there's no mechanism to wait until no more
+       // upcalls to the old entry point are in progress).
+       .global x86_upcall_entry
+x86_upcall_entry:
+       .long   0
index 48bf24cffc7b8a558d4b854400b50039e7e21b1f..a1b6e18b2dc2fb5d2171a05ac8fb9eac1da7bc6f 100644 (file)
 #include <kern/thread.h>
 #include <kern/mem.h>
 #include <kern/process.h>
+#include <kern/orb.h>
 
 #include <arch/addrs.h>
 #include <arch/multiboot.h>
+#include <arch/regs.h>
 
 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);
+}
diff --git a/kernel/include/arch-x86/regs.h b/kernel/include/arch-x86/regs.h
new file mode 100644 (file)
index 0000000..90c2177
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _ARCH_REGS_H
+#define _ARCH_REGS_H
+
+namespace Arch {
+namespace Priv {
+       struct Regs {
+               u32 ds, es;
+       
+               union {
+                       struct {
+                               u32 eax, ecx, edx, ebx, ebp, esi, edi;
+                       };
+                       
+                       u32 gpr[8];
+               };
+               
+               u32 eip, cs, eflags, user_esp, user_ss;
+       };
+}};
+
+#endif
index f90d0512f3ee0c9355edd5a402d0611c5dd08196..404e9c0dbad8ab78daa30300f8f0930559d08254 100644 (file)
@@ -101,6 +101,9 @@ namespace ORB {
                ObjectHdr *get_local_hdr(Object *obj);
                Object *newobj(Mem::ProcAddrSpace *aspace, uintptr_t entry);
        };
+       
+       void invoke_method(System::RunTime::ParamInfoBlock *pib, uintptr_t &stack);
+       uintptr_t return_from_method(uintptr_t &exptr, size_t &exlen);
 }
 
 #endif
index 102ea95ba40704e26c850c8a968cb02adedcf7f1..ffcd8372318c4e8f581fc490602c73b750c4993b 100644 (file)
@@ -77,20 +77,28 @@ namespace ORB {
                
                return obj;
        }
-}
 
-extern "C" void invoke_method(ParamInfoBlock *user_pib, ulong ret_pc)
-{
-       ParamInfoBlock pib = Arch::copyin(user_pib);
-       CallFrame *frame = new_frame(curthread);
-       
-//     frame->object = objid;
-       frame->caller_user_pib = user_pib;
-       frame->ret_pc = ret_pc;
-       
-       printf("invoke_method: frame %p pib %p ret %lx\n",
-              frame, frame->caller_user_pib,
-              frame->ret_pc);
-       
+       void invoke_method(ParamInfoBlock *user_pib, uintptr_t &stack)
+       {
+               ParamInfoBlock pib = Arch::copyin(user_pib);
+               CallFrame *frame = new_frame(curthread);
+               
+//             if (pib->objlist_len == 0)
+                       
+               
+//             frame->object = objid;
+               frame->caller_user_pib = user_pib;
+//             frame->ret_pc = ret_pc;
+               
+               printf("invoke_method: frame %p pib %p ret %lx\n",
+                      frame, frame->caller_user_pib,
+                      frame->ret_pc);
+               
+               
+       }
        
+       uintptr_t return_from_method(uintptr_t &exptr, size_t &exlen)
+       {
+               return 0;
+       }
 }