Ejemplo n.º 1
0
/*
 * Trap handler. All we (currently) care about is page faults. Everything
 * else is passed through.
 */
int
svm_page_fault_handler(struct trap_state *ts)
{
	if (ts->trapno == T_PAGE_FAULT) {
		int	rcode, enabled;

		enabled = osenv_intr_save_disable();
		     
		ts->cr2 = get_cr2();
		rcode   = svm_fault(ts->cr2, ts->err);

		if (enabled)
			osenv_intr_enable();

		if (rcode != SVM_FAULT_OKAY)
			rcode = oskit_sendsig(rcode == SVM_FAULT_PAGEFLT
					      ? SIGSEGV : SIGBUS, ts);
		
		return rcode;
	}

	/*
	 * Not a page fault. Pass it through to the application as
	 * a signal. If signal handling is not enabled, a trap dump
	 * will be generated.
	 */
	return sendsig_trap_handler(ts);
}
Ejemplo n.º 2
0
/*
 * Non-blocking socket accept.
 */
int
oskitunix_threaded_accept(int fd, struct sockaddr* addr, size_t* len)
{
	int		newfd;
	int		enabled;

	enabled = osenv_intr_save_disable();
	for (;;) {
		newfd = NATIVEOS(accept)(fd, addr, len);
		if (newfd >= 0)
			break;

		if (!((NATIVEOS(errno) == EAGAIN)
		      || (NATIVEOS(errno) == EINTR))) {
			errno = NATIVEOS(errno);
			break;
		}

		if (oskitunix_threaded_fd_wait(fd, IOTYPE_READ)) {
			errno = EINTR;
			newfd = -1;
			break;
		}
	}

	if (enabled)
		osenv_intr_enable();
	return newfd;
}
Ejemplo n.º 3
0
/*
 * Added to improve console output performance.
 */
int
console_putbytes(const char *str, int len)
{
	int	rc = 0;
	int	enabled;

	enabled = osenv_intr_save_disable();

	while (len) {
		rc = NATIVEOS(write)(1, str, len);

		if (rc < 0) {
			if (errno == EAGAIN)
				continue;
			break;
		}

		len -= rc;
		str += rc;
	}

	if (enabled)
		osenv_intr_enable();

	if (rc < 0)
		return EOF;
	else
		return 0;
}
Ejemplo n.º 4
0
/*
 * Non-blocking read from an fd.
 */
int
oskitunix_threaded_read(int fd, void* buf, size_t len)
{
	int		count;
	int		enabled;

	enabled = osenv_intr_save_disable();

	for (;;) {
		count = NATIVEOS(read)(fd, buf, len);
		if (count >= 0)
			break;

		/* a "real" error */
		if (!((NATIVEOS(errno) == EAGAIN)
		      || (NATIVEOS(errno) == EINTR))) {
			errno = NATIVEOS(errno);
			break;
		}

		/* an interruption */
		if (oskitunix_threaded_fd_wait(fd, IOTYPE_READ)) {
			errno = EINTR;
			count = -1;
			break;
		}
	}

	if (enabled)
		osenv_intr_enable();
	return count;
}
Ejemplo n.º 5
0
/*
 * Non-blocking socket recvfrom
 */
int
oskitunix_threaded_recvfrom(int fd, void* buf, size_t len, int flags,
	struct sockaddr* from, int* fromlen)
{
	int		count;
	int		enabled;

	enabled = osenv_intr_save_disable();
	for (;;) {
		count = NATIVEOS(recvfrom)(fd, buf, len, flags, from, fromlen);
		if (count >= 0)
			break;

		if (!((NATIVEOS(errno) == EAGAIN)
		      || (NATIVEOS(errno) == EINTR)))
		{
			errno = NATIVEOS(errno);
			break;
		}

		if (oskitunix_threaded_fd_wait(fd, IOTYPE_READ)) {
			errno = EINTR;
			count = -1;
			break;
		}
	}

	if (enabled)
		osenv_intr_enable();
	return count;
}
Ejemplo n.º 6
0
int
osenv_timer_pit_read()
{
	int enb;
	int value;

	enb = osenv_intr_save_disable();
	value = pit_read(0);
	if (enb)
		osenv_intr_enable();
	return value;
}
Ejemplo n.º 7
0
void
linux_restore_flags(unsigned flags)
{
	/*
	 * XXX: Linux drivers only count on the interrupt enable bit
	 * being properly restored.
	 */
	if (flags & IF_FLAG)
		osenv_intr_enable();
	else
		osenv_intr_disable();
}
Ejemplo n.º 8
0
/*
 * Init the VM code. 
 */
void
oskit_uvm_redzone_init(void)
{
	oskit_addr_t	addr;

	/*
	 * We use a task gate to catch page faults, since a stack overflow
	 * will try and dump more stuff on the stack. This is the easiest
	 * way to deal with it.
	 */
	if ((addr = (oskit_addr_t)
	            lmm_alloc_aligned(&malloc_lmm, STACKSIZE, 0, 12, 0)) == 0)
		panic(__FUNCTION__": Could not allocate stack\n");

	task_tss.ss0   = KERNEL_DS;
	task_tss.esp0  = addr + STACKSIZE - sizeof(double);
	task_tss.esp   = task_tss.esp0;
	task_tss.ss    = KERNEL_DS;
	task_tss.ds    = KERNEL_DS;
	task_tss.es    = KERNEL_DS;
	task_tss.fs    = KERNEL_DS;
	task_tss.gs    = KERNEL_DS;
	task_tss.cs    = KERNEL_CS;
	task_tss.io_bit_map_offset = sizeof(task_tss);
	task_tss.eip    = (int) double_fault_handler;

	/* Make sure the task is started with interrupts disabled */
	osenv_intr_disable();
	task_tss.eflags = (int) get_eflags();
	osenv_intr_enable();
	
	/* Both TSSs has to know about the page tables */
	task_tss.cr3    = get_cr3();
	base_tss.cr3	= get_cr3();

	/* Initialize the base TSS descriptor.  */
	fill_descriptor(&base_gdt[KERNEL_TRAP_TSS / 8],
			kvtolin(&task_tss), sizeof(task_tss) - 1,
			ACC_PL_K|ACC_TSS|ACC_P, 0);

	/*
	 * NOTE: The task switch will include an extra word on the stack,
	 * pushed by the CPU. The handler will need to be in assembly code
	 * if we care about that value. As it is, the handler routine
	 * stack is going to be slightly messed up, but since the handler
	 * calls panic, it is not a problem right now. 
	 */
	fill_gate(&base_idt[T_DOUBLE_FAULT],
		  0, KERNEL_TRAP_TSS, ACC_TASK_GATE|ACC_P|ACC_PL_K, 0);

	base_idt_load();
	base_gdt_load();
}
Ejemplo n.º 9
0
static OSKIT_COMDECL
sched_set_share(pfq_sched_t *_sched, pfq_sched_t *_child, float share)
{
	struct pfq_impl *parent = (void *)_sched;
	struct pfq_impl *child = (void *)_child;

	if (parent == NULL || parent->p_count == 0 ||
	    child == NULL || child->p_count == 0)
		return OSKIT_E_INVALIDARG;

	osenv_intr_disable();

	child->p_byte_charge = (float)PFQ_TOTAL_SHARE / share;

	osenv_intr_enable();
	return 0;
}
Ejemplo n.º 10
0
static OSKIT_COMDECL
sched_remove_child(pfq_sched_t *_sched, pfq_sched_t *_child)
{
	struct pfq_impl *parent = (void *)_sched;
	struct pfq_impl *child = (void *)_child;

	if (parent == NULL || parent->p_count == 0 ||
	    child == NULL || child->p_count == 0)
		return OSKIT_E_INVALIDARG;

	osenv_intr_disable();

	/* It might or might not be in the virtual queue. */
	oskit_pqueue_remove(parent->p_virtq, (oskit_iunknown_t *)_child);

	child->p_parent = NULL;
	pfq_sched_release(_child);

	osenv_intr_enable();
	return 0;
}
Ejemplo n.º 11
0
int
osenv_sleep(osenv_sleeprec_t *sr) 
{
	volatile osenv_sleeprec_t *vsr = sr;
	int was_enabled = osenv_intr_enabled();
	printf("inside osenv_sleep\n");
	osenv_assert(sr);

	/* We won't get anywhere if interrupts aren't enabled! */
	osenv_intr_enable();

	/* Busy-wait until osenv_wakeup() clears the flag in the sleeprec */
	while (vsr->data[1])
		/* NOTHING */;

	/* Restore the original interrupt enable state */
	if (!was_enabled)
		osenv_intr_disable();

	return (int) vsr->data[0];
}
Ejemplo n.º 12
0
/*
 * Write system	time back to RTC
 */
void
resettodr()
{
	oskit_timespec_t t = { 0, 0 };
	oskit_time_t 	tm;

	osenv_intr_disable();
	tm = time.tv_sec;
	osenv_intr_enable();

	/* convert from GMT to localtime */
#if 0
	tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
#else
	/* hack for Salt Lake City */
	t.tv_sec -= 7 * 60 *60;
#endif

	t.tv_sec = tm;
	osenv_rtc_set(&t);
}
Ejemplo n.º 13
0
/*
 * Non-blocking write to an fd.
 */
int
oskitunix_threaded_write(int fd, const void* buf, size_t len)
{
	int		count = 1;
	const void*	ptr;
	int		enabled;

	ptr = buf;
	enabled = osenv_intr_save_disable();

	while (len > 0 && count > 0) {
		count = NATIVEOS(write)(fd, ptr, len);
		if (count >= 0) {
			ptr += count;
			len -= count;
			count = ptr - buf;
			continue;
		}

		/* a regular error */
		if (!((NATIVEOS(errno) == EAGAIN)
		      || (NATIVEOS(errno) == EINTR))) {
			errno = NATIVEOS(errno);
			break;
		}

		/* an interruption */
		if (oskitunix_threaded_fd_wait(fd, IOTYPE_WRITE)) {
			errno = EINTR;
			count = -1;
			break;
		}
		count = 1;
	}
	if (enabled)
		osenv_intr_enable();
	return count;
}
Ejemplo n.º 14
0
/* ARGSUSED */
int
inittodr(time_t base)
{
	oskit_timespec_t	t;

	osenv_intr_disable();

	/* read real time clock */
	osenv_rtc_get(&t);

	/* t.tv_sec now contains the number of seconds, since Jan 1 1970,
	   in the local	time zone */
#if 0
	/* original BSD code to convert to GMT */
	t.tv_sec += tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
#else
	/* hack for Salt Lake City */
	t.tv_sec += 7 * 60 *60;
#endif
	time.tv_sec = t.tv_sec;
	osenv_intr_enable();
	return 0;
}
Ejemplo n.º 15
0
/*
 * Non-blocking socket connect.
 */
int
oskitunix_threaded_connect(int fd, struct sockaddr* addr, size_t len)
{
	int		rc;
	int		enabled;

	enabled = osenv_intr_save_disable();

	for (;;) {
		rc = NATIVEOS(connect)(fd, addr, len);
		if (rc == 0)
			break;

		/* A "real" error */
		if (!((NATIVEOS(errno) == EINPROGRESS)
		      || (NATIVEOS(errno) == EALREADY)
		      || (NATIVEOS(errno) == EINTR))) {
			errno = NATIVEOS(errno);
			break;
		}

		/* an interruption */
		if (oskitunix_threaded_fd_wait(fd, IOTYPE_WRITE)) {
			errno = EINTR;
			rc    = -1;
			break;
		}
	}
	/* annul EISCONN error */
	if ((rc < 0)
	    && (NATIVEOS(errno) == EISCONN)) 
		rc = 0;

	if (enabled)
		osenv_intr_enable();
	return rc;
}
Ejemplo n.º 16
0
/*
 * This is what you're looking for.
 * It does the ARRIVE(i, Packet) algorithm from the paper.
 */
static OSKIT_COMDECL
netio_push(oskit_netio_t *_, oskit_bufio_t *b, oskit_size_t size)
{
	struct netio_impl *n = (void *)_;
	struct pfq_impl *p = n->n_leaf;
	oskit_error_t err;

	assert(n && n->n_count);

	osenv_intr_disable();

	pfq_stats.arrived++;

	/* Append to end of physical queue. */
	err = oskit_queue_enqueue(p->p_packq, b, 0);
	if (err == OSKIT_E_FAIL)
		pfq_stats.qfull++;

	/* Done if p_logicalq is non-empty. */
	if (p->p_logicalq)
		goto done;

	/* Otherwise, this packet becomes the head of the p_logicalq queue. */
	p->p_logicalq = b;
	oskit_bufio_addref(b);

	/* Update start and finish times. */
	_pfq_update_start_finish(p, 0);

	/* Restart our parent if they're not watching T.V. */
	if (! p->p_parent->p_busy)
		_pfq_restart_node(p->p_parent);

 done:
	osenv_intr_enable();
	return 0;
}
Ejemplo n.º 17
0
/*
 * Non-blocking socket sendto
 */
int
oskitunix_threaded_sendto(int fd, const void* buf, size_t len, int flags,
			  struct sockaddr* to, int tolen)
{
	int		total = 0, count;
	int		enabled;

	enabled = osenv_intr_save_disable();
	while (len > 0) {
		count = NATIVEOS(sendto)(fd, buf, len, flags, to, tolen);
		if (count >= 0) {
			buf   += count;
			len   -= count;
			total += count;
			continue;
		}

		if (!((NATIVEOS(errno) == EAGAIN)
		      || (NATIVEOS(errno) == EINTR))) 
		{
			errno = NATIVEOS(errno);
			break;
		}

		if (oskitunix_threaded_fd_wait(fd, IOTYPE_WRITE)) {
			errno = EINTR;
			total = -1;
			break;
		}
		count = 1;
	}

	if (enabled)
		osenv_intr_enable();
	return total;
}
Ejemplo n.º 18
0
void
linux_sti()
{
	osenv_intr_enable();
}