Пример #1
1
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;
}
Пример #2
0
/* 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) {
	}
}