#include <kernel/kernel.h> #include <kernel/thread.h> #include <kernel/sys.h> #include <kernel/vmm.h> #include <kernel/obj.h> #include <kernel/fs.h> #include <kernel/port.h> #include <errno.h> volatile int syscall_level; extern tss_t tss; thread_t* sysCreateThread(addr_t entry, dword param, unsigned priority) { thread_t* thr; context_t* ctx; dword* dw; thr = thrCreate(current->process->level, current->process, (const void*) entry, priority); if (thr == NULL) return NULL; ctx = thrContext(thr); dw = (dword*) ctx->esp; dw[1] = 0; dw[2] = param; ctx->esp += sizeof(dword); thrSuspend(thr, false); thrSchedule(); return thr; } void syscall(context_t* ctx) { //dword code = ctx->regs.eax; switch (ctx->regs.eax) { case 0: ctx->regs.eax = (dword) thrCreate86(current->process, (const byte*) ctx->regs.ebx, ctx->regs.ecx, sysV86Fault, ctx->regs.edx); break; case 1: ctx->regs.eax = keShutdown(ctx->regs.ebx); break; case 2: thrSchedule(); break; case 4: wprintf(L"[enter] ctx = %x esp = %x tss.esp0 = %x syscall_level = %d\n", ctx, current->kernel_esp, tss.esp0, syscall_level); if (syscall_level < 3) { syscall_level++; asm("mov $4, %eax ; int $0x30"); syscall_level--; } wprintf(L" [exit] ctx = %x esp = %x tss.esp0 = %x syscall_level = %d\n", ctx, current->kernel_esp, tss.esp0, syscall_level); break; case 3: procTerminate(current->process); break; case 8: ctx->regs.eax = (dword) sysOpen((const wchar_t*) ctx->regs.ebx); break; case 9: sysMount((const wchar_t*) ctx->regs.ebx, (void*) ctx->regs.ecx); break; case 10: ctx->regs.eax = sysInvoke((void*) ctx->regs.ebx, ctx->regs.ecx, (dword*) ctx->regs.edx, ctx->regs.esi); break; case 0x0100: thrSleep(current, ctx->regs.ebx); ctx->regs.eax = 1; break; case 0x0101: thrWaitHandle(current, (void**) ctx->regs.ebx, ctx->regs.ecx, ctx->regs.edx); ctx->regs.eax = 1; break; case 0x102: ctx->regs.eax = uptime; break; case 0x103: thrCall(current, (void*) ctx->regs.ebx, (void*) ctx->regs.ecx, ctx->regs.edx); ctx->regs.eax = 0; break; /*case 0x104: current->tls = ctx->regs.ebx; ctx->regs.eax = 1; break; case 0x105: ctx->regs.eax = current->tls; break;*/ case 0x106: thrDelete(current); thrSchedule(); break; case 0x107: ctx->regs.eax = (dword) sysCreateThread(ctx->regs.ebx, ctx->regs.ecx, ctx->regs.edx); break; case 0x200: ctx->regs.eax = (dword) procLoad(3, (const wchar_t*) ctx->regs.ebx, (const wchar_t*) ctx->regs.ecx, ctx->regs.edx, (file_t*) ctx->regs.esi, (file_t*) ctx->regs.edi); thrSchedule(); break; case 0x201: ctx->regs.eax = (dword) current->process; break; case 0x300: ctx->regs.eax = (dword) vmmAlloc(current->process, ctx->regs.ebx, ctx->regs.ecx, ctx->regs.edx); break; case 0x400: ctx->regs.eax = (dword) objMarshal(current->process, (void*) ctx->regs.ebx); break; case 0x401: ctx->regs.eax = (dword) objUnmarshal(current->process, (marshal_t) ctx->regs.ebx); break; case 0x402: objNotifyDelete(current->process, (marshal_t) ctx->regs.ebx); break; case 0x500: ctx->regs.eax = (dword) devOpen((const wchar_t*) ctx->regs.ebx, (const wchar_t*) ctx->regs.ecx); break; case 0x501: ctx->regs.eax = devClose((device_t*) ctx->regs.ebx); break; case 0x502: errno = devUserRequest((device_t*) ctx->regs.ebx, (request_t*) ctx->regs.ecx, (size_t) ctx->regs.edx); ctx->regs.eax = errno == 0; break; case 0x503: //devSwapUserBuffers((request_t*) ctx->regs.ebx); //ctx->regs.eax = 1; errno = devUserFinishRequest((request_t*) ctx->regs.ebx, (bool) ctx->regs.ecx); ctx->regs.eax = errno == 0; break; case 0x600: ctx->regs.eax = (dword) hndAlloc((size_t) ctx->regs.ebx, current->process); break; case 0x601: hndFree((void*) ctx->regs.ebx); ctx->regs.eax = 1; break; case 0x602: if (ctx->regs.ebx == NULL) ctx->regs.eax = NULL; else ctx->regs.eax = (dword) hndHandle(ctx->regs.ebx)->process; break; case 0x700: ctx->regs.eax = (dword) fsOpen((const wchar_t*) ctx->regs.ebx); break; case 0x701: ctx->regs.eax = fsClose((file_t*) ctx->regs.ebx); break; case 0x702: if (ctx->regs.ebx == NULL) { request_t *req; req = (request_t*) ctx->regs.ecx; /* need to zero this in case devUserFinishRequest() is called */ req->kernel_request = NULL; errno = EINVALID; ctx->regs.eax = 0; } else { errno = devUserRequest(((file_t*) ctx->regs.ebx)->fsd, (request_t*) ctx->regs.ecx, (size_t) ctx->regs.edx); ctx->regs.eax = errno == 0; } break; case 0x703: fsSeek((file_t*) ctx->regs.ebx, (qword) ctx->regs.ecx | (qword) ctx->regs.edx << 32); break; case 0x704: if (ctx->regs.ebx == NULL) { errno = EINVALID; ctx->regs.eax = 0; } else { qword pos = ((file_t*) ctx->regs.ebx)->pos; ctx->regs.eax = pos & 0xffffffff; ctx->regs.edx = (pos >> 32) & 0xffffffff; } break; case 0x705: { qword length = fsGetLength((file_t*) ctx->regs.ebx); ctx->regs.eax = length & 0xffffffff; ctx->regs.edx = (length >> 32) & 0xffffffff; } break; case 0x800: ctx->regs.eax = (dword) portCreate(current->process, (const wchar_t*) ctx->regs.ebx); break; case 0x801: ctx->regs.eax = portListen((port_t*) ctx->regs.ebx); break; case 0x802: ctx->regs.eax = portConnect((port_t*) ctx->regs.ebx, (const wchar_t*) ctx->regs.ecx); thrSchedule(); break; case 0x803: ctx->regs.eax = (dword) portAccept((port_t*) ctx->regs.ebx); thrSchedule(); break; case 0x804: portDelete((port_t*) ctx->regs.ebx); ctx->regs.eax = true; break; default: wprintf(L"%d: invalid syscall\n", ctx->regs.eax); } }