diff --git a/src/ec.cc b/src/ec.cc index 2fa08fe..0a091ef 100644 --- a/src/ec.cc +++ b/src/ec.cc @@ -94,7 +94,12 @@ void Ec::root_invoke() printf ("iret to user ...\n"); - // TODO prepare stack and iret to user + mword stack[] = { code, SEL_USER_CODE, 0x200, 2 * PAGE_SIZE, SEL_USER_DATA }; + + asm volatile ( + "mov %0, %%esp ;" + "iret ;" + : : "r" (&stack) : "memory"); UNREACHED; } @@ -106,7 +111,23 @@ void Ec::handle_tss() void Ec::syscall_handler (uint8 number) { - printf ("syscall %d\n", number); + Sys_regs * r = current->sys_regs(); + + switch (number) { + + case 0: // nop + printf ("syscall %d - nop\n", number); + break; + + case 1: // add + printf ("syscall %d - add : %lu + %lu\n", number, r->esi, r->edi); + r->esi += r->edi; + break; + + default: + printf ("syscall %d - unknown\n", number); + break; + }; ret_user_sysexit(); diff --git a/src/usercode.cc b/src/usercode.cc index a3acf93..6a27426 100644 --- a/src/usercode.cc +++ b/src/usercode.cc @@ -1,12 +1,48 @@ #include "compiler.h" +USER +unsigned syscall1 (unsigned w0) +{ + asm volatile ( + " mov %%esp, %%ecx ;" + " mov $1f, %%edx ;" + " and $0xfff, %%edx ;" + " add $0x2000, %%edx ;" + " sysenter ;" + "1: ;" + : "+a" (w0) : : "ecx", "edx"); + return w0; +} + +USER +unsigned syscall3 (unsigned w0, unsigned w1, unsigned w2) +{ + asm volatile ( + " mov %%esp, %%ecx ;" + " mov $1f, %%edx ;" + " and $0xfff, %%edx ;" + " add $0x2000, %%edx ;" + " sysenter ;" + "1: ;" + : "+a" (w0) : "S" (w1), "D" (w2) : "ecx", "edx"); + return w0; +} + +unsigned sys_nop() +{ + return syscall1 (0); +} + +unsigned sys_add (unsigned a, unsigned b) +{ + return syscall3 (1,a,b); +} + EXTERN_C REGPARM(1) NORETURN USER void usercode (unsigned) { - // TODO - // - 1st : ud2 or force page fault here - // - 2nd : reenter the kernel via sysenter - // - 3rd : so some simple system calls, like adding two numbers + sys_nop(); + sys_add(2,3); while (1) ; }