make vfs & filesystems use failable copying
[minix3.git] / kernel / arch / i386 / arch_reset.c
blob855bd36f23713767646208f3a6fa06aed7ea6443
2 #include "kernel/kernel.h"
4 #include <ctype.h>
5 #include <string.h>
6 #include <machine/cmos.h>
7 #include <machine/bios.h>
8 #include <machine/cpu.h>
9 #include <minix/portio.h>
10 #include <minix/cpufeature.h>
11 #include <sys/reboot.h>
12 #include <assert.h>
13 #include <signal.h>
14 #include <machine/vm.h>
16 #include <minix/u64.h>
18 #include "archconst.h"
19 #include "arch_proto.h"
20 #include "serial.h"
21 #include "oxpcie.h"
22 #include "direct_utils.h"
23 #include <machine/multiboot.h>
25 #ifdef USE_ACPI
26 #include "acpi.h"
27 #endif
29 #define KBCMDP 4 /* kbd controller port (O) */
30 #define KBC_PULSE0 0xfe /* pulse output bit 0 */
31 #define IO_KBD 0x060 /* 8042 Keyboard */
33 int cpu_has_tsc;
35 void
36 reset(void)
38 uint8_t b;
40 * The keyboard controller has 4 random output pins, one of which is
41 * connected to the RESET pin on the CPU in many PCs. We tell the
42 * keyboard controller to pulse this line a couple of times.
44 outb(IO_KBD + KBCMDP, KBC_PULSE0);
45 busy_delay_ms(100);
46 outb(IO_KBD + KBCMDP, KBC_PULSE0);
47 busy_delay_ms(100);
50 * Attempt to force a reset via the Reset Control register at
51 * I/O port 0xcf9. Bit 2 forces a system reset when it
52 * transitions from 0 to 1. Bit 1 selects the type of reset
53 * to attempt: 0 selects a "soft" reset, and 1 selects a
54 * "hard" reset. We try a "hard" reset. The first write sets
55 * bit 1 to select a "hard" reset and clears bit 2. The
56 * second write forces a 0 -> 1 transition in bit 2 to trigger
57 * a reset.
59 outb(0xcf9, 0x2);
60 outb(0xcf9, 0x6);
61 busy_delay_ms(500); /* wait 0.5 sec to see if that did it */
64 * Attempt to force a reset via the Fast A20 and Init register
65 * at I/O port 0x92. Bit 1 serves as an alternate A20 gate.
66 * Bit 0 asserts INIT# when set to 1. We are careful to only
67 * preserve bit 1 while setting bit 0. We also must clear bit
68 * 0 before setting it if it isn't already clear.
70 b = inb(0x92);
71 if (b != 0xff) {
72 if ((b & 0x1) != 0)
73 outb(0x92, b & 0xfe);
74 outb(0x92, b | 0x1);
75 busy_delay_ms(500); /* wait 0.5 sec to see if that did it */
78 /* Triple fault */
79 x86_triplefault();
81 /* Give up on resetting */
82 while(1) {
87 static __dead void
88 halt(void)
90 for ( ; ; )
91 halt_cpu();
94 static __dead void
95 poweroff(void)
97 const char *shutdown_str;
99 #ifdef USE_ACPI
100 acpi_poweroff();
101 #endif
102 /* Bochs/QEMU poweroff */
103 shutdown_str = "Shutdown";
104 while (*shutdown_str) outb(0x8900, *(shutdown_str++));
106 /* VMware magic power off; likely to halt CPU */
107 poweroff_vmware_clihlt();
109 /* fallback option: hang */
110 halt();
113 __dead void arch_shutdown(int how)
115 unsigned char unused_ch;
116 /* Mask all interrupts, including the clock. */
117 outb( INT_CTLMASK, ~0);
119 /* Empty buffer */
120 while(direct_read_char(&unused_ch))
123 if(kinfo.minix_panicing) {
124 /* Printing is done synchronously over serial. */
125 if (kinfo.do_serial_debug)
126 reset();
128 /* Print accumulated diagnostics buffer and reset. */
129 direct_cls();
130 direct_print("Minix panic. System diagnostics buffer:\n\n");
131 direct_print(kmess.kmess_buf);
132 direct_print("\nSystem has panicked, press any key to reboot");
133 while (!direct_read_char(&unused_ch))
135 reset();
138 if((how & RB_POWERDOWN) == RB_POWERDOWN) {
139 /* Power off if possible, hang otherwise */
140 poweroff();
141 NOT_REACHABLE;
144 if(how & RB_HALT) {
145 /* Hang */
146 for (; ; ) halt_cpu();
147 NOT_REACHABLE;
150 /* Reset the system by forcing a processor shutdown.
151 * First stop the BIOS memory test by setting a soft
152 * reset flag.
154 reset();
155 NOT_REACHABLE;
158 #ifdef DEBUG_SERIAL
159 void ser_putc(char c)
161 int i;
162 int lsr, thr;
164 #if CONFIG_OXPCIE
165 oxpcie_putc(c);
166 #else
167 lsr= COM1_LSR;
168 thr= COM1_THR;
169 for (i= 0; i<100000; i++)
171 if (inb( lsr) & LSR_THRE)
172 break;
174 outb( thr, c);
175 #endif
178 #endif