예제 #1
0
파일: exception.c 프로젝트: cod5/kielder
void PrintException (struct ContextState *es, char *str, int panic)
{
	int privilege;
	
	privilege = es->return_cs & 0x03;
		
	if (privilege != 0)
	{
		KPRINTF("return_ss     = %#010x   return_esp = %#010x", es->return_ss, es->return_esp);
	}

	KPRINTF("return_eflags = %#010x          cr2 = %#010x", es->return_eflags, GetCR2());
	KPRINTF("return_cs     = %#010x   return_eip = %#010x", es->return_cs, es->return_eip);
	KPRINTF("error_code    = %#010x    exception = %#010x", es->error_code, es->exception);
	
	KPRINTF("EAX = %#010x   ECX = %#010x", es->eax, es->ecx);
	KPRINTF("EDX = %#010x   EBX = %#010x", es->edx, es->ebx);
	KPRINTF("EBP = %#010x   ", es->ebp);
	KPRINTF("ESI = %#010x   EDI = %#010x", es->esi, es->edi);
	
	KPRINTF ("EXCEPTION = %d #%s name = %s",  es->exception, exception_string[es->exception % 32],
				current_process->exe_name);
	
	KPRINTF ("pid = %d, Name = %s", current_process->pid, current_process->exe_name);
	
	if (panic == TRUE)
		KPANIC (str);
}
예제 #2
0
void kloader_cmain(struct mem_map_entry mem_map[], uint32_t mem_entry_count)
{
    screen_init();
    screen_cursor_hide();
    terminal_init();

    KINFO("Welcome to Nox (Bootloader mode)");

    mem_mgr_init(mem_map, mem_entry_count);

    ata_init();
    fs_init();

    struct fat_part_info* part_info = fs_get_system_part();
    struct fat_dir_entry kernel;
    if(!fat_get_dir_entry(part_info, "KERNEL  ELF", &kernel)) {
        KPANIC("Failed to locate KERNEL.ELF");
        while(1);
    }

    intptr_t kernel_entry_point;

    if(!elf_load_trusted("KERNEL  ELF", &kernel_entry_point)) {
        KWARN("Failed to load elf!");
    } 

    kernel_entry cmain = (kernel_entry)(kernel_entry_point);

    cmain(mem_map, mem_entry_count);


    KINFO("Bootloader done");

    while(1);
}
예제 #3
0
파일: v86.c 프로젝트: cod5/kielder
int32 V86Start (struct ContextState *state)
{
	struct Msg *msg;
	uint32 signals;
	
	
	if ((v86_msgport = CreateMsgPort()) != NULL)
	{
		KSignal (v86_init_pid, SIG_INIT);
	}
	else
	{
		KPANIC ("V86 error");
	}

	
	
	while (1)
	{
		signals = KWait (1 << v86_msgport->signal);
		
		if (signals & (1 << v86_msgport->signal))
			if ((msg = GetMsg (v86_msgport)) != NULL)
				break;
	}
	
	
	handler_v86msg = (struct V86Msg *) msg;
	
	state->eax = handler_v86msg->state->eax;
	state->ebx = handler_v86msg->state->ebx;
	state->ecx = handler_v86msg->state->ecx;
	state->edx = handler_v86msg->state->edx;
	state->esi = handler_v86msg->state->esi;
	state->edi = handler_v86msg->state->edi;
	state->ebp = handler_v86msg->state->ebp;
	
	state->gs = PL3_DATA_SEGMENT;
	state->fs = PL3_DATA_SEGMENT;
	state->es = PL3_DATA_SEGMENT;
	state->ds = PL3_DATA_SEGMENT;

	state->v86_gs = handler_v86msg->state->gs;
	state->v86_fs = handler_v86msg->state->fs;
	state->v86_es = handler_v86msg->state->es;
	state->v86_ds = handler_v86msg->state->ds;
	
	*(uint8 *)(0x00010000) = OPCODE_INT;
	*(uint8 *)(0x00010001) = handler_v86msg->vector;
	*(uint8 *)(0x00010002) = OPCODE_IRET;
		
	state->return_eip    = 0x0000;
	state->return_cs     = 0x1000;
	state->return_eflags = EFLG_IF | EFLG_VM;
	state->return_esp    = 0xfff0;
	state->return_ss     = 0x2000;

	return 0;
}
예제 #4
0
파일: condvar.c 프로젝트: cod5/kielder
void CondWait (struct Cond *cond, struct Mutex *mutex)
{
	struct Process *proc;
	
	if (current_process == NULL)
		return;
	
	DisableInterrupts();
	
	/* Release Mutex */
	
	if (mutex->locked == TRUE)   
	{
		proc = LIST_HEAD (&mutex->blocked_list);
		
		if (proc != NULL)
		{
			LIST_REM_HEAD (&mutex->blocked_list, blocked_entry);
			proc->state = PROC_STATE_READY;
			SchedReady (proc);
		}
		else
		{
			mutex->locked = FALSE;
		}
	}
	else
	{
		KPANIC ("CondWait() on a free mutex");
	}
	
	
	/* Block current process on Condvar */
	
	LIST_ADD_TAIL (&cond->blocked_list, current_process, blocked_entry);
	current_process->state = PROC_STATE_COND_BLOCKED;
	SchedUnready (current_process);
	Reschedule();
	
	
	/* Now acquire mutex */
	
	if (mutex->locked == TRUE)
	{
		LIST_ADD_TAIL (&mutex->blocked_list, current_process, blocked_entry);
		current_process->state = PROC_STATE_MUTEX_BLOCKED;
		SchedUnready (current_process);
		Reschedule();
	}
	else
	{
		mutex->locked = TRUE;
	}
	
	
	
	EnableInterrupts();
}
예제 #5
0
파일: condvar.c 프로젝트: cod5/kielder
int CondTimedWait (volatile struct Cond *cond, struct Mutex *mutex, struct TimeVal *tv)
{
	struct Process *proc;
	struct Timer timer;
	
	if (current_process == NULL)
		return 0;
	
	DisableInterrupts();
	
	if (mutex->locked == TRUE)   
	{
		/* Release Mutex */

		proc = LIST_HEAD (&mutex->blocked_list);
		
		if (proc != NULL)
		{
			LIST_REM_HEAD (&mutex->blocked_list, blocked_entry);
			proc->state = PROC_STATE_READY;
			SchedReady (proc);
		}
		else
		{
			mutex->locked = FALSE;
		}
	}
	else
	{
		KPANIC ("CondTimedWait() on a free mutex");
	}
	
	
	/* Block current process on Condvar */

	LIST_ADD_TAIL (&cond->blocked_list, current_process, blocked_entry);
		
	SetTimer (&timer, TIMER_TYPE_RELATIVE, tv, &CondTimedWaitCallout, &cond);
	current_process->state = PROC_STATE_COND_BLOCKED;
	SchedUnready (current_process);
	Reschedule();

	CancelTimer (&timer);

	/* Now acquire mutex */
	
	if (mutex->locked == TRUE)
	{
		LIST_ADD_TAIL (&mutex->blocked_list, current_process, blocked_entry);
		current_process->state = PROC_STATE_MUTEX_BLOCKED;
		SchedUnready (current_process);
		Reschedule();
	}
	else
	{
		mutex->locked = TRUE;
	}
	
	
	EnableInterrupts();
	
	if (cond == NULL)
		return -1;
	else
		return 0;
}
예제 #6
0
파일: args.c 프로젝트: cod5/kielder
int CreateArgEnv (struct ArgInfo *ai, char **argv, char **env)
{
	void *buf;
	char **kargv, **kenv;
	char **targv, **tenv;
	
	
	KPRINTF ("CreateArgEnv()");
	
	if ((buf = (void *)KMap (ARG_MAX, VM_PROT_READWRITE)) != (void *)MAP_FAILED)
	{
		ai->buf = buf;
		ai->nbytes_free = ARG_MAX;
		ai->current_pos = buf;
		ai->argc = 0;
		ai->envc = 0;
		
		kargv = NULL;
		kenv = NULL;	
		
		if (argv != NULL)
			if ((kargv = ReadPointerArray (argv, ai)) == NULL)
				goto ErrorExit;
		
		if (env != NULL)
			if ((kenv = ReadPointerArray (env, ai)) == NULL)
				goto ErrorExit;
	
		targv = kargv;
		tenv = kenv;
		
		if (targv != NULL)
		{
			while (*targv != NULL)
			{
				if ((*targv = ReadArgString (*targv, ai)) == NULL)
					goto ErrorExit;
				targv++;
				
				ai->argc ++;
			}
		}
		
		if (tenv != NULL)
		{
			while (*tenv != NULL)
			{
				if ((*tenv = ReadArgString (*tenv, ai)) == NULL)
					goto ErrorExit;
				tenv++;

				ai->envc ++;
			}
		}	
		
		ai->argv = kargv;
		ai->env  = kenv;
		
		return 0;
		
		ErrorExit:
		KUnmap ((vm_addr)buf);
	}
	
	
	KPANIC ("CreateArgEnv FAILED");
	
	return -1;
}
예제 #7
0
파일: root_handler.c 프로젝트: cod5/kielder
void root_beginio (void *ioreq)
{
	struct FSReq *fsreq = ioreq;
	struct RootFilp *filp;
	struct Mount *mount;
	int len;
	
	KPRINTF ("root_beginio()");
	
	fsreq->flags |= IOF_QUICK;
	
	switch (fsreq->cmd)
	{
		case FS_CMD_OPEN:
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;
		
		case FS_CMD_PIPE:
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;

		case FS_CMD_CLOSE:
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;


		case FS_CMD_DUP:		/* Might want to dup() the handle? */
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;

		case FS_CMD_READ:
			fsreq->error = ENOSYS;
			fsreq->nbytes_transferred = -1;
			fsreq->rc = -1;
			break;

		case FS_CMD_WRITE:
			fsreq->error = ENOSYS;
			fsreq->nbytes_transferred = -1;
			fsreq->rc = -1;
			break;

		case FS_CMD_LSEEK:
			fsreq->error = ENOSYS;
			fsreq->position = -1;
			break;

		case FS_CMD_UNLINK:
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;

		case FS_CMD_RENAME:
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;

		case FS_CMD_FTRUNCATE:
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;

		case FS_CMD_FSTAT:
			fsreq->stat->st_mode = S_IFDIR  | (S_IRUSR | S_IRGRP | S_IROTH);
			fsreq->stat->st_nlink = 1; /* ??? 0 ??? */
			fsreq->stat->st_uid = 1;
			fsreq->stat->st_gid = 1;
			fsreq->stat->st_rdev = 5;	
			fsreq->stat->st_size = 0;
			fsreq->stat->st_atime = 0;
			fsreq->stat->st_mtime = 0;
			fsreq->stat->st_ctime = 0;
			fsreq->stat->st_blocks = 0;
			fsreq->error = 0;
			fsreq->rc = 0;
			break;

		case FS_CMD_STAT:
			fsreq->stat->st_mode = S_IFDIR  | (S_IRUSR | S_IRGRP | S_IROTH);
			fsreq->stat->st_nlink = 1; /* ??? 0 ??? */
			fsreq->stat->st_uid = 1;
			fsreq->stat->st_gid = 1;
			fsreq->stat->st_rdev = 5;	
			fsreq->stat->st_size = 0;
			fsreq->stat->st_atime = 0;
			fsreq->stat->st_mtime = 0;
			fsreq->stat->st_ctime = 0;
			fsreq->stat->st_blocks = 0;
			fsreq->error = 0;
			fsreq->rc = 0;
			break;

		case FS_CMD_FSTATFS:
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;

		case FS_CMD_FSYNC:
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;

		case FS_CMD_SYNC:
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;

		case FS_CMD_MKDIR:
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;
			
		case FS_CMD_RMDIR:
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;
		
			
		case FS_CMD_OPENDIR:
		{
			if ((filp = KMalloc (sizeof (struct RootFilp))) != NULL)
			{
				filp->device = &root_handler;
				filp->seek_mount = LIST_HEAD (&mount_list);
				
				LIST_ADD_TAIL (&root_filp_list, filp, filp_entry);
								
				fsreq->filp = filp;
				fsreq->device = &root_handler;  
				fsreq->error = 0;
				fsreq->rc = 0;
			}
			else
			{
				fsreq->error = ENOSYS;
				fsreq->rc = -1;
			}
			break;
		}
			
		case FS_CMD_CLOSEDIR:
		{
			filp = fsreq->filp;
			
			LIST_REM_ENTRY (&root_filp_list, filp, filp_entry);
			KFree (filp);
			fsreq->error = 0;
			fsreq->rc = 0;
			break;
		}
			
		case FS_CMD_READDIR:
			filp = fsreq->filp;
			
			mount = filp->seek_mount;
						
			if (mount != NULL)
			{
				len = StrLen (mount->name);	
			
				if (len + 1 <= NAME_MAX)
				{
					CopyOut (fsreq->as, &fsreq->dirent->d_name, mount->name, len + 1);
		
					filp->seek_mount = LIST_NEXT (mount, mount_list_entry);

					fsreq->error = 0;
					fsreq->rc = 0;
				}
				else
				{
					fsreq->dirent = NULL;
					fsreq->error = ENAMETOOLONG;
					fsreq->rc = -1;
				}
			}
			else
			{
				fsreq->dirent = NULL;
				fsreq->error = 0;
				fsreq->rc = -1;
			}
			break;
			
		
		case FS_CMD_REWINDDIR:
			filp = fsreq->filp;
			filp->seek_mount = LIST_HEAD (&mount_list);
			
			fsreq->error = 0;
			fsreq->rc = 0;
			break;
			
		case FS_CMD_ISATTY:
			fsreq->error = 0;
			fsreq->rc = 0;
			break;

		case FS_CMD_TCGETATTR:
			fsreq->error = ENOTTY;
			fsreq->rc = -1;
			break;

		case FS_CMD_TCSETATTR:
			fsreq->error = ENOTTY;
			fsreq->rc = -1;
			break;

		case FS_CMD_IOCTL:
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;
	
		default:
		{
			KPANIC ("ROOT Unknown command");
			fsreq->error = ENOSYS;
			fsreq->rc = -1;
			break;
		}
	}
}
예제 #8
0
파일: wrapper.c 프로젝트: cod5/kielder
int cd_opendevice (int unit, void *ioreq, uint32 flags)
{
	struct FSReq *fsreq = ioreq;
	struct CDSB *cdsb;
	struct MountEnviron *me;
	struct BlkReq blkreq;
	
	
	KPRINTF ("cd_opendevice ()");
	
	
	if ((cdsb = KMalloc (sizeof (struct CDSB))) != NULL)
	{
		me = fsreq->me;
		
		
		if (OpenDevice (me->device_name, me->device_unit, &blkreq, me->device_flags) == 0)
		{	
			/* FIXME:  Shouldn't need it (also in fat handler) */
			MemSet (cdsb, 0, sizeof (struct CDSB)); /* Need it as cdsb->validated isn't initialized */
			
			cdsb->device = blkreq.device;
			cdsb->unitp = blkreq.unitp;
			cdsb->me = fsreq->me;
			cdsb->reference_cnt = 0;
							
			LIST_INIT (&cdsb->node_list);
			LIST_INIT (&cdsb->active_filp_list);
			LIST_INIT (&cdsb->invalid_filp_list);
			
			cdsb->root_node.flags = ISO_DIRECTORY;
			cdsb->root_node.cdsb = cdsb;
			cdsb->root_node.reference_cnt = 0;
			
			if ((cdsb->buf = CreateBuf (cdsb->device, cdsb->unitp,
							me->buffer_cnt, me->block_size,
							me->partition_start, me->partition_end,
							me->writethru_critical, me->writeback_delay,
							me->max_transfer)) != NULL)
			{
				if (KSpawn (CDTask, cdsb, 10, "cd.handler") != -1)
				{		
					KWait (SIGF_INIT);
					
					RWWriteLock (&mountlist_rwlock);
					cd_device.reference_cnt ++;
					
					cdsb->device_mount = MakeMount (cdsb->me, &cd_device, cdsb);
					AddMount (cdsb->device_mount);
					
					RWUnlock (&mountlist_rwlock);

					fsreq->unitp = cdsb;
					fsreq->error = 0;
					fsreq->rc = 0;
					return 0;
				}
			}
		
			CloseDevice (&blkreq);
		}
		
		KFree (cdsb);
	}
	
	fsreq->error = IOERR_OPENFAIL;
	fsreq->rc = -1;
	
	KPANIC ("CD OpenDevice FAIL");
	return -1;
}
예제 #9
0
파일: exception.c 프로젝트: cod5/kielder
void DispatchException (struct ContextState *es)
{
	int privilege_level;
	int pf_direction;
	vm_addr pf_addr;
	
		
	if (isr_depth > 0)
		PrintException (es, "Exception in interrupt Handler", TRUE);


	if (es->return_eflags & EFLG_VM)
	{
		KPANIC ("V86 Exception");
	
		switch (es->exception)
		{
			case EXCEPTION_GP:
				EnableInterrupts();
				V86GPHandler (es);
				DisableInterrupts();
				break;
			
			default:
				PrintException (es, "#GP in V86", TRUE); 
			
		}
	}
	else if ((privilege_level = es->return_cs & 0x03) == 0)
	{	
		switch (es->exception)
		{
			case EXCEPTION_PF:
				pf_addr = GetCR2();
				
				if ((es->error_code & PF_ERRORCODE_DIRECTION) == 0)
					pf_direction = PF_DIR_READ;
				else
					pf_direction = PF_DIR_WRITE;
				
				EnableInterrupts();
					
				if (PageFault (pf_addr, pf_direction, privilege_level) != 0)
				{
					if (current_process->archproc.resume_eip != 0 &&
						current_process->archproc.resume_esp != 0)
					{
						es->return_eip = current_process->archproc.resume_eip;
						es->return_esp = current_process->archproc.resume_esp;
						current_process->archproc.resume_eip = 0;
						current_process->archproc.resume_esp = 0;
					}
					else
					{
						PrintException (es, "#PF in Kernel", TRUE);
					}
				}
				
				DisableInterrupts();
				
				break;
				
			default:
				PrintException (es, "Exception in Kernel", TRUE);
				
		}
	}
	else
	{
		switch (es->exception)
		{
			case EXCEPTION_DE:	/* Divide Error */
				current_process->usignal.sig_pending |= SIGFFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_signo = SIGFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGFPE-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_DB:  /* Debug */
				current_process->usignal.sig_pending |= SIGFTRAP;
				current_process->usignal.siginfo_data[SIGTRAP-1].si_signo = SIGTRAP;
				current_process->usignal.siginfo_data[SIGTRAP-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGTRAP-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_NMI: /* Non-Maskable Interupt */
				break;
			case EXCEPTION_BP:  /* Breakpoint */
				current_process->usignal.sig_pending |= SIGFTRAP;
				current_process->usignal.siginfo_data[SIGTRAP-1].si_signo = SIGTRAP;
				current_process->usignal.siginfo_data[SIGTRAP-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGTRAP-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_OF:  /* Overflow */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_BR:  /* Boundary-Range Exceeded */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_UD:  /* Undefined-Opcode */
				current_process->usignal.sig_pending |= SIGFILL;
				current_process->usignal.siginfo_data[SIGILL-1].si_signo = SIGILL;
				current_process->usignal.siginfo_data[SIGILL-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGILL-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_NM:  /* Device-Not Available */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_DF:  /* Double-Fault */
				KPANIC ("DF");				
				break;
			case EXCEPTION_CSO: /* Reserved : Coprocessor Segment Overrun */
				current_process->usignal.sig_pending |= SIGFFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_signo = SIGFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGFPE-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_TS:  /* Invalid TSS */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_NP:  /* Segment / Not Present */
				current_process->usignal.sig_pending |= SIGFBUS;
				current_process->usignal.siginfo_data[SIGBUS-1].si_signo = SIGBUS;
				current_process->usignal.siginfo_data[SIGBUS-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGBUS-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_SS:  /* Stack Segment */
				current_process->usignal.sig_pending |= SIGFBUS;
				current_process->usignal.siginfo_data[SIGBUS-1].si_signo = SIGBUS;
				current_process->usignal.siginfo_data[SIGBUS-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGBUS-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_GP:  /* General Protection */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_PF:
				pf_addr = GetCR2();
			
				if ((es->error_code & PF_ERRORCODE_DIRECTION) == 0)
					pf_direction = PF_DIR_READ;
				else
					pf_direction = PF_DIR_WRITE;
				
				EnableInterrupts();
					
				if (PageFault (pf_addr, pf_direction, privilege_level) != 0)
				{
					current_process->usignal.sig_pending |= SIGFSEGV;
					current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
					current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
					current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
					
					PrintException (es, "Page Fault in PL3", FALSE);
				}
			
				DisableInterrupts();
			
				break;
			case EXCEPTION_RESV: /* Reserved */
				break;
			case EXCEPTION_MF:  /* Math Fault */
				current_process->usignal.sig_pending |= SIGFFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_signo = SIGFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGFPE-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_AC:  /* Alignment Check */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_MC:  /* Machine Check */
				break;
			case EXCEPTION_XF:  /* Extended Math Fault */
				current_process->usignal.sig_pending |= SIGFFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_signo = SIGFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGFPE-1].si_value.sival_int = 0;
				break;
			default:            /* Unknown Exception */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
		}
	}
}
예제 #10
0
파일: v86.c 프로젝트: cod5/kielder
int V86HandleOpcode (struct ContextState *state)
{
	bool is_operand32 = FALSE;
	bool is_address32 = FALSE;
	uint32 *sp32;
	uint16 *sp16;
	uint32 eflags;
	uint8 *ip;
		
	uint32 new_ip;
	uint32 new_cs;
	uint8 *vector;

	
	
	
	while (1)
	{
		ip = V86GetAddress (state->return_eip, state->return_cs);
		
		switch (*ip)
		{
			case PREFIX_O32:
				is_operand32 = TRUE;
				state->return_eip = (state->return_eip + 1) & 0x0000ffff;
				continue;
				
			case PREFIX_A32:
				is_address32 = TRUE;
				ip++;
				state->return_eip = (state->return_eip + 1) & 0x0000ffff;
				continue;
			
				
			case OPCODE_PUSHF:
				if (is_operand32 == TRUE)
				{
					state->return_esp = ((state->return_esp & 0x0000ffff) - 4) & 0x0000ffff;
					sp32 = V86GetAddress (state->return_esp, state->return_ss);
					eflags = state->return_eflags & V86_EFLAG_MASK;

					*sp32 = (v86_if == TRUE)
							? eflags | EFLAG_IF
							: eflags & ~EFLAG_IF;
				}
				else
				{
					state->return_esp = ((state->return_esp & 0x0000ffff) - 2) & 0x0000ffff; 
					sp16 = V86GetAddress (state->return_esp, state->return_ss);
					eflags = state->return_eflags & V86_EFLAG_MASK;

					*sp16 = (uint16) (v86_if == TRUE)
							? eflags | EFLAG_IF
							: eflags & ~EFLAG_IF;					
					
				}
			
				state->return_eip = (state->return_eip + 1) & 0x0000ffff;
				return 0;
				
			case OPCODE_POPF:
				if (is_operand32 == TRUE)
				{
					sp32 = V86GetAddress (state->return_esp, state->return_ss);
					eflags = *sp32;
					state->return_eflags = (eflags & V86_EFLAG_MASK) | EFLAG_IF | EFLAG_VM;
					v86_if = (eflags & EFLAG_IF) ? TRUE : FALSE;
					state->return_esp = ((state->return_esp & 0x0000ffff) + 4) & 0x0000ffff;
				}
				else
				{
					sp16 = V86GetAddress (state->return_esp, state->return_ss);
					eflags = *sp16;
					state->return_eflags = (eflags & V86_EFLAG_MASK) | EFLAG_IF | EFLAG_VM;
					v86_if = (eflags & EFLAG_IF) ? TRUE : FALSE;
					state->return_esp = ((state->return_esp & 0x0000ffff) + 2) & 0x0000ffff;
				}

				state->return_eip = (state->return_eip + 1) & 0x0000ffff;
				return 0;

			
			case OPCODE_INT:
			{
				state->return_eip = (state->return_eip + 1) & 0x0000ffff;
				vector = V86GetAddress (state->return_eip, state->return_cs);
				V86GetInterruptVector (*vector, &new_ip, &new_cs);
				state->return_eip = (state->return_eip + 1) & 0x0000ffff;
				
				state->return_esp = ((state->return_esp & 0x0000ffff) - 2) & 0x0000ffff;
				sp16 = V86GetAddress (state->return_esp, state->return_ss);
				*sp16 = (uint16) state->return_eip;
				
				state->return_esp = ((state->return_esp & 0x0000ffff) - 2) & 0x0000ffff;
				sp16 = V86GetAddress (state->return_esp, state->return_ss);
				*sp16 = (uint16) state->return_cs;
				
				state->return_esp = ((state->return_esp & 0x0000ffff) - 2) & 0x0000ffff;
				sp16 = V86GetAddress (state->return_esp, state->return_ss);
				
				eflags = (v86_if == TRUE)
						? (state->return_eflags & V86_EFLAG_MASK) | EFLAG_IF
						: (state->return_eflags & V86_EFLAG_MASK) & ~EFLAG_IF;
				
				*sp16 = (uint16) eflags;
				
				state->return_eflags = (state->return_eflags & ~(EFLAG_IF | EFLAG_TF | EFLAG_AC)) | EFLAG_VM;
				v86_if = FALSE;
				
				state->return_eip = new_ip & 0x0000ffff;
				state->return_cs = new_cs & 0x0000ffff;
				
				return 0;
			}
			
			case OPCODE_IRET:
				if (state->return_eip == 0x0002 && state->return_cs == 0x1000)
				{
					return 1;
				}
				else
				{
					sp16 = V86GetAddress (state->return_esp, state->return_ss);
					eflags = *sp16;
					
					eflags = (eflags & 0x257fd5) | (state->return_eflags & 0x1a0000);
					
					state->return_eflags = eflags | EFLAG_IF | EFLAG_VM;
					v86_if = (eflags & EFLAG_IF) ? TRUE : FALSE;
							
					state->return_esp = ((state->return_esp & 0x0000ffff) + 2) & 0x0000ffff;
					
					sp16 = V86GetAddress (state->return_esp, state->return_ss);
					state->return_cs = *sp16;
					state->return_esp = ((state->return_esp & 0x0000ffff) + 2) & 0x0000ffff;
					
					sp16 = V86GetAddress (state->return_esp, state->return_ss);
					state->return_eip = *sp16;
					state->return_esp = ((state->return_esp & 0x0000ffff) + 2) & 0x0000ffff;

					return 0;
				}
							
				
			case OPCODE_CLI:
				v86_if = FALSE;
				state->return_eip = (state->return_eip + 1) & 0x0000ffff;
				return 0;
							
			case OPCODE_STI:
				v86_if = TRUE;
				state->return_eip = (state->return_eip + 1) & 0x0000ffff;
				return 0;
					
		
			case OPCODE_OUTB:
				OutByte (state->edx, state->eax);
				state->return_eip = (state->return_eip + 1) & 0x0000ffff;
				return 0;
			
			case OPCODE_INB:
				state->eax = InByte (state->edx);
				state->return_eip = (state->return_eip + 1) & 0x0000ffff;
				return 0;
			
			case OPCODE_OUTWL:
				if(is_operand32 == FALSE)
					OutWord (state->edx, state->eax);
				else
					OutLong (state->edx, state->eax);
				
				state->return_eip = (state->return_eip + 1) & 0x0000ffff;
				return 0;
			
			case OPCODE_INWL:
				if(is_operand32 == FALSE)
					state->eax = InWord (state->edx);
				else
					state->eax = InLong (state->edx);

				state->return_eip = (state->return_eip + 1) & 0x0000ffff;
				return 0;

			case OPCODE_OUTB_AL_NN:
				OutByte (*(ip+1), state->eax);
				state->return_eip = (state->return_eip + 2) & 0x0000ffff;
				return 0;

			case OPCODE_INB_NN_AL:
				state->eax = InByte (*(ip+1));
				state->return_eip = (state->return_eip + 2) & 0x0000ffff;
				return 0;
			
			case OPCODE_OUTWL_EAX_NN:
				if (is_operand32 == FALSE)
					OutWord (*(ip+1), state->eax);
				else
					OutLong (*(ip+1), state->eax);

				state->return_eip = (state->return_eip + 2) & 0x0000ffff;
				return 0;
			
			case OPCODE_INWL_NN_EAX:
				if(is_operand32 == FALSE)
					state->eax = InWord (*(ip+1));
				else
					state->eax = InLong (*(ip+1));
				
				state->return_eip = (state->return_eip + 2) & 0x0000ffff;
				return 0;
			
			
			case OPCODE_HLT:
			{
				KPANIC ("Halt in V86");
			}
			
			default:
			{
				KPRINTF ("opcode = %#010x", *ip);
				KPANIC ("#GP Unknown V86 opcode");
			}
		}
	}
}