try multiple reset methods
. fixes reboot-hang under vbox . makes experience nicer under vmware . taken from netbsd reset code
This commit is contained in:
parent
a953da6e10
commit
ca47635d0a
5 changed files with 71 additions and 3 deletions
|
@ -364,3 +364,13 @@ PUBLIC short cpu_load(void)
|
|||
*last_idle = *current_idle;
|
||||
return load;
|
||||
}
|
||||
|
||||
PUBLIC void busy_delay_ms(int ms)
|
||||
{
|
||||
u64_t cycles = ms_2_cpu_time(ms), tsc0, tsc, tsc1;
|
||||
read_tsc_64(&tsc0);
|
||||
tsc1 = tsc0 + cycles;
|
||||
do { read_tsc_64(&tsc); } while(tsc < tsc1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,62 @@ PUBLIC __dead void arch_monitor(void)
|
|||
monitor();
|
||||
}
|
||||
|
||||
#define KBCMDP 4 /* kbd controller port (O) */
|
||||
#define KBC_PULSE0 0xfe /* pulse output bit 0 */
|
||||
#define IO_KBD 0x060 /* 8042 Keyboard */
|
||||
|
||||
void
|
||||
reset(void)
|
||||
{
|
||||
uint8_t b;
|
||||
/*
|
||||
* The keyboard controller has 4 random output pins, one of which is
|
||||
* connected to the RESET pin on the CPU in many PCs. We tell the
|
||||
* keyboard controller to pulse this line a couple of times.
|
||||
*/
|
||||
outb(IO_KBD + KBCMDP, KBC_PULSE0);
|
||||
busy_delay_ms(100);
|
||||
outb(IO_KBD + KBCMDP, KBC_PULSE0);
|
||||
busy_delay_ms(100);
|
||||
|
||||
/*
|
||||
* Attempt to force a reset via the Reset Control register at
|
||||
* I/O port 0xcf9. Bit 2 forces a system reset when it
|
||||
* transitions from 0 to 1. Bit 1 selects the type of reset
|
||||
* to attempt: 0 selects a "soft" reset, and 1 selects a
|
||||
* "hard" reset. We try a "hard" reset. The first write sets
|
||||
* bit 1 to select a "hard" reset and clears bit 2. The
|
||||
* second write forces a 0 -> 1 transition in bit 2 to trigger
|
||||
* a reset.
|
||||
*/
|
||||
outb(0xcf9, 0x2);
|
||||
outb(0xcf9, 0x6);
|
||||
busy_delay_ms(500); /* wait 0.5 sec to see if that did it */
|
||||
|
||||
/*
|
||||
* Attempt to force a reset via the Fast A20 and Init register
|
||||
* at I/O port 0x92. Bit 1 serves as an alternate A20 gate.
|
||||
* Bit 0 asserts INIT# when set to 1. We are careful to only
|
||||
* preserve bit 1 while setting bit 0. We also must clear bit
|
||||
* 0 before setting it if it isn't already clear.
|
||||
*/
|
||||
b = inb(0x92);
|
||||
if (b != 0xff) {
|
||||
if ((b & 0x1) != 0)
|
||||
outb(0x92, b & 0xfe);
|
||||
outb(0x92, b | 0x1);
|
||||
busy_delay_ms(500); /* wait 0.5 sec to see if that did it */
|
||||
}
|
||||
|
||||
/* Triple fault */
|
||||
x86_triplefault();
|
||||
|
||||
/* Give up on resetting */
|
||||
while(1) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
PRIVATE __dead void arch_bios_poweroff(void)
|
||||
{
|
||||
u32_t cr0;
|
||||
|
|
|
@ -75,6 +75,7 @@ _PROTOTYPE( void exception, (struct exception_frame * frame));
|
|||
/* klib386.s */
|
||||
_PROTOTYPE( __dead void monitor, (void) );
|
||||
_PROTOTYPE( __dead void reset, (void) );
|
||||
_PROTOTYPE( __dead void x86_triplefault, (void) );
|
||||
_PROTOTYPE( void int86, (void) );
|
||||
_PROTOTYPE( reg_t read_cr0, (void) );
|
||||
_PROTOTYPE( reg_t read_cr2, (void) );
|
||||
|
|
|
@ -499,13 +499,13 @@ ENTRY(mem_rdw)
|
|||
|
||||
|
||||
/*===========================================================================*/
|
||||
/* reset */
|
||||
/* x86_triplefault */
|
||||
/*===========================================================================*/
|
||||
/*
|
||||
* PUBLIC void reset();
|
||||
* PUBLIC void x86_triplefault();
|
||||
* Reset the system by loading IDT with offset 0 and interrupting.
|
||||
*/
|
||||
ENTRY(reset)
|
||||
ENTRY(x86_triplefault)
|
||||
lidt idt_zero
|
||||
int $3 /* anything goes, the 386 will not like it */
|
||||
.data
|
||||
|
|
|
@ -230,6 +230,7 @@ _PROTOTYPE(void disable_fpu_exception, (void));
|
|||
_PROTOTYPE(void release_fpu, (struct proc * p));
|
||||
_PROTOTYPE(void arch_pause,(void));
|
||||
_PROTOTYPE(short cpu_load, (void));
|
||||
_PROTOTYPE(void busy_delay_ms, (int ms));
|
||||
|
||||
/* utility.c */
|
||||
_PROTOTYPE( void cpu_print_freq, (unsigned cpu));
|
||||
|
|
Loading…
Reference in a new issue