struct cpu_state* syscall(struct cpu_state* cpu) { save_cpu_state(cpu); cpu = get_current_task()->cpuState; switch (cpu->eax) { case 1: /* exit */ return terminate_current(cpu); case 3: /* exec */ { cpu->eax = vfs_exec((char*) cpu->ebx, (char**) cpu->ecx); } break; case 4: /* getargs */ { cpu->eax = (uint32_t) get_current_task()->args; } break; case 5: /* yield */ { cpu = schedule(cpu); } break; case 10: /* fopen */ { char* name = strclone((char*) cpu->ebx); uint32_t fmode = (uint32_t) cpu->ecx; struct res_handle* handle = vfs_open(name, fmode); if(handle) { register_handle(handle); cpu->eax = (uint32_t) handle; } else { cpu->eax = 0; } free(name); } break; case 11: /* fclose */ { struct res_handle* handle = (void*) cpu->ebx; if(!unregister_handle(handle)) { vfs_close(handle); cpu->eax = 0; } else { cpu->eax = (uint32_t) -1; } } break; case 12: /* fwrite */ { struct res_handle* handle = (void*) cpu->ebx; if(handle != 0) { cpu->eax = vfs_write(handle, (char*) cpu->ecx, cpu->edx, 1); } else { cpu->eax = RW_ERR_VFS; } } break; case 13: /* fread */ { struct res_handle* handle = (void*) cpu->ebx; if(handle != 0) { cpu->eax = vfs_read(handle, (char*) cpu->ecx, cpu->edx, 1); } else { cpu->eax = RW_ERR_VFS; } } break; case 14: /* fmkfifo */ { char* name = strclone((char*) cpu->ebx); vfs_create_kfile(name, ramfs_fifo_driver_struct(), &(uint32_t){4096}); //default to 4k Buffer-size struct res_handle* handle = vfs_open(name, FM_READ | FM_WRITE); if(handle) { register_handle(handle); cpu->eax = (uint32_t) handle; } else { cpu->eax = 0; } free(name); } break; case 20: /* getpmhandle */ { struct res_handle* handle = 0; switch(cpu->ebx) { case PMID_STDOUT: handle = get_current_task()->stdout; break; case PMID_STDIN: handle = get_current_task()->stdin; break; case PMID_STDERR: handle = get_current_task()->stderr; break; default: handle = get_current_task()->stdout; break; } cpu->eax = (uint32_t) handle; } break; case 21: /* fopenpmhandle */ { char* path = strclone((char*)cpu->ecx); struct res_handle* open; uint32_t fm = FM_WRITE; if(cpu->ebx == PMID_STDIN) { fm = FM_READ; } open = vfs_open(path, fm); free(path); if(!open) { cpu->eax = (uint32_t) -1; break; } struct res_handle* oldhandle = 0; switch(cpu->ebx) { case PMID_STDOUT: oldhandle = get_current_task()->stdout; get_current_task()->stdout = open; break; case PMID_STDIN: oldhandle = get_current_task()->stdin; get_current_task()->stdin = open; break; case PMID_STDERR: oldhandle = get_current_task()->stderr; get_current_task()->stderr = open; break; default: oldhandle = get_current_task()->stdout; get_current_task()->stdout = open; break; } if(oldhandle != 0) { vfs_close(oldhandle); } cpu->eax = 0; } break; case 201: /* kputc */ cpu->eax = kprintf("%c", cpu->ebx); break; case 202: /* kputs */ cpu->eax = kprintf("%s", cpu->ebx); break; case 203: /* vmm_alloc_ucont */ cpu->eax = (uint32_t) vmm_alloc_ucont(cpu->ebx); break; case 204: /* vmm_free */ cpu->eax = 0; if (cpu->ebx >= PROGRAM_BOTTOM) { //Only in PROGRAM AREA ;) vmm_free((void*) cpu->ebx); } break; case 205: /* pmm_print_stats */ pmm_print_stats(); break; default: kprintf("Invalid Syscall %d...", cpu->eax); break; } return cpu; }
/* Function: starter_main * Description: Called by start() in starter.S. Jumps to xmon_loader - xmon loader. * This function never returns back. * Input: Registers pushed right to left: * eip0 - return address on stack, * pushal - eax, ecx, edx, ebx, esp, ebp, esi, edi * pushfl - flags */ void starter_main(uint32_t eflags, uint32_t edi, uint32_t esi, uint32_t ebp, uint32_t esp, uint32_t ebx, uint32_t edx, uint32_t ecx, uint32_t eax, uint32_t eip0) { uint32_t eip1; xmon_desc_t *td; mon_guest_cpu_startup_state_t *s; eip1 = (uint32_t)RETURN_ADDRESS(); td = (xmon_desc_t *)((eip1 & 0xffffff00) - 0x400); mon_memset((void *)GUEST1_BASE(td), 0, XMON_LOADER_BASE(td) - GUEST1_BASE(td) ); s = (mon_guest_cpu_startup_state_t *)GUEST1_BASE(td); s->gp.reg[IA32_REG_RIP] = eip0; s->gp.reg[IA32_REG_RFLAGS] = eflags; s->gp.reg[IA32_REG_RAX] = eax; s->gp.reg[IA32_REG_RCX] = ecx; s->gp.reg[IA32_REG_RDX] = edx; s->gp.reg[IA32_REG_RBX] = ebx; s->gp.reg[IA32_REG_RSP] = esp + 4; s->gp.reg[IA32_REG_RBP] = ebp; s->gp.reg[IA32_REG_RSI] = esi; s->gp.reg[IA32_REG_RDI] = edi; save_cpu_state(s); if (check_vmx_support() != 0) { goto error; } run_xmon_loader(td); error: /* clean memory */ mon_memset((void *)((uint32_t)td + td->xmon_loader_start * 512), 0, XMON_LOADER_HEAP_BASE(td) + XMON_LOADER_HEAP_SIZE - (td->xmon_loader_start) * 512); while (1) { } }