示例#1
0
/*
 * This overrides the _exit() function in libc.
 * If the serial console (or remote GDB) is being used, it waits
 * until all the data has cleared out of the FIFOs; if the VGA
 * display is being used (normal console), then it waits for a keypress.
 * When it is done, it calls pc_reset() to reboot the computer.
 */
static void
our_exit(int rc)
{
	extern oskit_addr_t return_address;

#if 0
	printf("_exit(%d) called; %s...\r\n",
	       rc, return_address ? "returning to netboot" : "rebooting");
#endif

	if (enable_gdb) {
		/* Detach from the remote GDB. */
		gdb_serial_exit(rc);

#ifdef HAVE_DEBUG_REGS
		/* Turn off the debug registers. */
		set_dr7(get_dr7() & ~(DR7_G0 | DR7_G1 | DR7_G2 | DR7_G3));
#endif

	}

	/* flush and wait for `_exit called` message */
	oskit_stream_release(console);
	if (!serial_console) {
		/* This is so that the user has a chance to SEE the output */
		//~ printf("Press a key to reboot");
		//~ printf("hit dat shit yo.");
		//~ getchar();
	}

	if (return_address) {
		/*
		 * The cleanup needs to be done here instead of in the
		 * returned-to code because the return address may not
		 * be accessible with our current paging and segment
		 * state.
		 * The order is important here: paging must be disabled
		 * after we reload the gdt.
		 */
		cli();
		clts();
		phys_mem_va = 0;
		linear_base_va = 0;
		base_gdt_init();
		/* Reload all since we changed linear_base_va. */
		base_cpu_load();
		paging_disable();
		((void (*)(void))return_address)();
	}
	else
		pc_reset();
}
示例#2
0
void db_dr (
	int		num,
	vm_offset_t	linear_addr,
	int		type,
	int		len,
	int		persistence)
{
	int s = splhigh();
	unsigned long dr7;

	if (!kernel_dr) {
	    if (!linear_addr) {
		splx(s);
		return;
	    }
	    kernel_dr = TRUE;
	    /* Clear user debugging registers */
	    set_dr7(0);
	    set_dr0(0);
	    set_dr1(0);
	    set_dr2(0);
	    set_dr3(0);
	}

	ids.dr[num] = linear_addr;
	switch (num) {
	    case 0: set_dr0(linear_addr); break;
	    case 1: set_dr1(linear_addr); break;
	    case 2: set_dr2(linear_addr); break;
	    case 3: set_dr3(linear_addr); break;
	}

	/* Replace type/len/persistence for DRnum in dr7 */
	dr7 = get_dr7 ();
	dr7 &= ~(0xfUL << (4*num+16)) & ~(0x3UL << (2*num));
	dr7 |= (((len << 2) | type) << (4*num+16)) | (persistence << (2*num));
	set_dr7 (dr7);

	if (kernel_dr) {
	    if (!ids.dr[0] && !ids.dr[1] && !ids.dr[2] && !ids.dr[3]) {
		/* Not used any more, switch back to user debugging registers */
		set_dr7 (0);
		kernel_dr = FALSE;
		zero_dr = TRUE;
		db_load_context(current_thread()->pcb);
	    }
	}
	splx(s);
}