2 #include "kernel/kernel.h"
6 #include <machine/cmos.h>
7 #include <machine/bios.h>
8 #include <machine/cpu.h>
9 #include <minix/cpufeature.h>
10 #include <sys/reboot.h>
14 #include <minix/u64.h>
16 #include "arch_proto.h"
18 #include "direct_utils.h"
24 #define KBCMDP 4 /* kbd controller port (O) */
25 #define KBC_PULSE0 0xfe /* pulse output bit 0 */
26 #define IO_KBD 0x060 /* 8042 Keyboard */
35 * The keyboard controller has 4 random output pins, one of which is
36 * connected to the RESET pin on the CPU in many PCs. We tell the
37 * keyboard controller to pulse this line a couple of times.
39 outb(IO_KBD
+ KBCMDP
, KBC_PULSE0
);
41 outb(IO_KBD
+ KBCMDP
, KBC_PULSE0
);
45 * Attempt to force a reset via the Reset Control register at
46 * I/O port 0xcf9. Bit 2 forces a system reset when it
47 * transitions from 0 to 1. Bit 1 selects the type of reset
48 * to attempt: 0 selects a "soft" reset, and 1 selects a
49 * "hard" reset. We try a "hard" reset. The first write sets
50 * bit 1 to select a "hard" reset and clears bit 2. The
51 * second write forces a 0 -> 1 transition in bit 2 to trigger
56 busy_delay_ms(500); /* wait 0.5 sec to see if that did it */
59 * Attempt to force a reset via the Fast A20 and Init register
60 * at I/O port 0x92. Bit 1 serves as an alternate A20 gate.
61 * Bit 0 asserts INIT# when set to 1. We are careful to only
62 * preserve bit 1 while setting bit 0. We also must clear bit
63 * 0 before setting it if it isn't already clear.
70 busy_delay_ms(500); /* wait 0.5 sec to see if that did it */
76 /* Give up on resetting */
92 const char *shutdown_str
;
97 /* Bochs/QEMU poweroff */
98 shutdown_str
= "Shutdown";
99 while (*shutdown_str
) outb(0x8900, *(shutdown_str
++));
101 /* VMware magic power off; likely to halt CPU */
102 poweroff_vmware_clihlt();
104 /* fallback option: hang */
108 __dead
void arch_shutdown(int how
)
110 unsigned char unused_ch
;
111 /* Mask all interrupts, including the clock. */
112 outb( INT_CTLMASK
, ~0);
115 while(direct_read_char(&unused_ch
))
118 if(kinfo
.minix_panicing
) {
119 /* Printing is done synchronously over serial. */
120 if (kinfo
.do_serial_debug
)
123 /* Print accumulated diagnostics buffer and reset. */
125 direct_print("Minix panic. System diagnostics buffer:\n\n");
126 direct_print(kmess
.kmess_buf
);
127 direct_print("\nSystem has panicked, press any key to reboot");
128 while (!direct_read_char(&unused_ch
))
133 if((how
& RB_POWERDOWN
) == RB_POWERDOWN
) {
134 /* Power off if possible, hang otherwise */
141 for (; ; ) halt_cpu();
145 /* Reset the system by forcing a processor shutdown.
146 * First stop the BIOS memory test by setting a soft
154 void ser_putc(char c
)
164 for (i
= 0; i
<100000; i
++)
166 if (inb( lsr
) & LSR_THRE
)