/* * 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(); }
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); }