2 * linux/arch/i386/kernel/reboot.c
5 #include <linux/config.h>
7 #include <linux/module.h>
8 #include <linux/delay.h>
9 #include <linux/init.h>
10 #include <linux/interrupt.h>
11 #include <linux/mc146818rtc.h>
12 #include <linux/efi.h>
13 #include <linux/dmi.h>
14 #include <asm/uaccess.h>
16 #include "mach_reboot.h"
17 #include <linux/reboot_fixups.h>
20 * Power off function, if any
22 void (*pm_power_off)(void);
23 EXPORT_SYMBOL(pm_power_off);
25 static int reboot_mode;
26 static int reboot_thru_bios;
30 static int reboot_cpu = -1;
31 /* shamelessly grabbed from lib/vsprintf.c for readability */
32 #define is_digit(c) ((c) >= '0' && (c) <= '9')
34 static int __init reboot_setup(char *str)
38 case 'w': /* "warm" reboot (no memory testing etc) */
41 case 'c': /* "cold" reboot (with memory testing etc) */
44 case 'b': /* "bios" reboot by jumping through the BIOS */
47 case 'h': /* "hard" reboot by toggling RESET and/or crashing the CPU */
51 case 's': /* "smp" reboot by executing reset on BSP or other CPU*/
53 if (is_digit(*(str+1))) {
54 reboot_cpu = (int) (*(str+1) - '0');
55 if (is_digit(*(str+2)))
56 reboot_cpu = reboot_cpu*10 + (int)(*(str+2) - '0');
58 /* we will leave sorting out the final value
59 when we are ready to reboot, since we might not
60 have set up boot_cpu_id or smp_num_cpu */
64 if((str = strchr(str,',')) != NULL)
72 __setup("reboot=", reboot_setup);
75 * Reboot options and system auto-detection code provided by
76 * Dell Inc. so their systems "just work". :-)
80 * Some machines require the "reboot=b" commandline option, this quirk makes that automatic.
82 static int __init set_bios_reboot(struct dmi_system_id *d)
84 if (!reboot_thru_bios) {
86 printk(KERN_INFO "%s series board detected. Selecting BIOS-method for reboots.\n", d->ident);
92 * Some machines require the "reboot=s" commandline option, this quirk makes that automatic.
94 static int __init set_smp_reboot(struct dmi_system_id *d)
99 printk(KERN_INFO "%s series board detected. Selecting SMP-method for reboots.\n", d->ident);
106 * Some machines require the "reboot=b,s" commandline option, this quirk makes that automatic.
108 static int __init set_smp_bios_reboot(struct dmi_system_id *d)
115 static struct dmi_system_id __initdata reboot_dmi_table[] = {
116 { /* Handle problems with rebooting on Dell 1300's */
117 .callback = set_smp_bios_reboot,
118 .ident = "Dell PowerEdge 1300",
120 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
121 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"),
124 { /* Handle problems with rebooting on Dell 300's */
125 .callback = set_bios_reboot,
126 .ident = "Dell PowerEdge 300",
128 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
129 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"),
132 { /* Handle problems with rebooting on Dell 2400's */
133 .callback = set_bios_reboot,
134 .ident = "Dell PowerEdge 2400",
136 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
137 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"),
143 static int __init reboot_init(void)
145 dmi_check_system(reboot_dmi_table);
149 core_initcall(reboot_init);
151 /* The following code and data reboots the machine by switching to real
152 mode and jumping to the BIOS reset entry point, as if the CPU has
153 really been reset. The previous version asked the keyboard
154 controller to pulse the CPU reset line, which is more thorough, but
155 doesn't work with at least one type of 486 motherboard. It is easy
156 to stop this code working; hence the copious comments. */
158 static unsigned long long
159 real_mode_gdt_entries [3] =
161 0x0000000000000000ULL, /* Null descriptor */
162 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
163 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
168 unsigned short size __attribute__ ((packed));
169 unsigned long long * base __attribute__ ((packed));
171 real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
172 real_mode_idt = { 0x3ff, NULL },
173 no_idt = { 0, NULL };
176 /* This is 16-bit protected mode code to disable paging and the cache,
177 switch to real mode and jump to the BIOS reset code.
179 The instruction that switches to real mode by writing to CR0 must be
180 followed immediately by a far jump instruction, which set CS to a
181 valid value for real mode, and flushes the prefetch queue to avoid
182 running instructions that have already been decoded in protected
185 Clears all the flags except ET, especially PG (paging), PE
186 (protected-mode enable) and TS (task switch for coprocessor state
187 save). Flushes the TLB after paging has been disabled. Sets CD and
188 NW, to disable the cache on a 486, and invalidates the cache. This
189 is more like the state of a 486 after reset. I don't know if
190 something else should be done for other chips.
192 More could be done here to set up the registers as if a CPU reset had
193 occurred; hopefully real BIOSs don't assume much. */
195 static unsigned char real_mode_switch [] =
197 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
198 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
199 0x66, 0x0d, 0x00, 0x00, 0x00, 0x60, /* orl $0x60000000,%eax */
200 0x66, 0x0f, 0x22, 0xc0, /* movl %eax,%cr0 */
201 0x66, 0x0f, 0x22, 0xd8, /* movl %eax,%cr3 */
202 0x66, 0x0f, 0x20, 0xc3, /* movl %cr0,%ebx */
203 0x66, 0x81, 0xe3, 0x00, 0x00, 0x00, 0x60, /* andl $0x60000000,%ebx */
204 0x74, 0x02, /* jz f */
205 0x0f, 0x09, /* wbinvd */
206 0x24, 0x10, /* f: andb $0x10,al */
207 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
209 static unsigned char jump_to_bios [] =
211 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
215 * Switch to real mode and then execute the code
216 * specified by the code and length parameters.
217 * We assume that length will aways be less that 100!
219 void machine_real_restart(unsigned char *code, int length)
225 /* Write zero to CMOS register number 0x0f, which the BIOS POST
226 routine will recognize as telling it to do a proper reboot. (Well
227 that's what this book in front of me says -- it may only apply to
228 the Phoenix BIOS though, it's not clear). At the same time,
229 disable NMIs by setting the top bit in the CMOS address register,
230 as we're about to do peculiar things to the CPU. I'm not sure if
231 `outb_p' is needed instead of just `outb'. Use it to be on the
232 safe side. (Yes, CMOS_WRITE does outb_p's. - Paul G.)
235 spin_lock_irqsave(&rtc_lock, flags);
236 CMOS_WRITE(0x00, 0x8f);
237 spin_unlock_irqrestore(&rtc_lock, flags);
239 /* Remap the kernel at virtual address zero, as well as offset zero
240 from the kernel segment. This assumes the kernel segment starts at
241 virtual address PAGE_OFFSET. */
243 memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
244 sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
247 * Use `swapper_pg_dir' as our page directory.
249 load_cr3(swapper_pg_dir);
251 /* Write 0x1234 to absolute memory location 0x472. The BIOS reads
252 this on booting to tell it to "Bypass memory test (also warm
253 boot)". This seems like a fairly standard thing that gets set by
254 REBOOT.COM programs, and the previous reset routine did this
257 *((unsigned short *)0x472) = reboot_mode;
259 /* For the switch to real mode, copy some code to low memory. It has
260 to be in the first 64k because it is running in 16-bit mode, and it
261 has to have the same physical and virtual address, because it turns
262 off paging. Copy it near the end of the first page, out of the way
263 of BIOS variables. */
265 memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
266 real_mode_switch, sizeof (real_mode_switch));
267 memcpy ((void *) (0x1000 - 100), code, length);
269 /* Set up the IDT for real mode. */
271 __asm__ __volatile__ ("lidt %0" : : "m" (real_mode_idt));
273 /* Set up a GDT from which we can load segment descriptors for real
274 mode. The GDT is not used in real mode; it is just needed here to
275 prepare the descriptors. */
277 __asm__ __volatile__ ("lgdt %0" : : "m" (real_mode_gdt));
279 /* Load the data segment registers, and thus the descriptors ready for
280 real mode. The base address of each segment is 0x100, 16 times the
281 selector value being loaded here. This is so that the segment
282 registers don't have to be reloaded after switching to real mode:
283 the values are consistent for real mode operation already. */
285 __asm__ __volatile__ ("movl $0x0010,%%eax\n"
286 "\tmovl %%eax,%%ds\n"
287 "\tmovl %%eax,%%es\n"
288 "\tmovl %%eax,%%fs\n"
289 "\tmovl %%eax,%%gs\n"
290 "\tmovl %%eax,%%ss" : : : "eax");
292 /* Jump to the 16-bit code that we copied earlier. It disables paging
293 and the cache, switches to real mode, and jumps to the BIOS reset
296 __asm__ __volatile__ ("ljmp $0x0008,%0"
298 : "i" ((void *) (0x1000 - sizeof (real_mode_switch) - 100)));
300 #ifdef CONFIG_APM_MODULE
301 EXPORT_SYMBOL(machine_real_restart);
304 void machine_restart(char * __unused)
309 cpuid = GET_APIC_ID(apic_read(APIC_ID));
313 /* check to see if reboot_cpu is valid
314 if its not, default to the BSP */
315 if ((reboot_cpu == -1) ||
316 (reboot_cpu > (NR_CPUS -1)) ||
317 !physid_isset(cpuid, phys_cpu_present_map))
318 reboot_cpu = boot_cpu_physical_apicid;
320 reboot_smp = 0; /* use this as a flag to only go through this once*/
321 /* re-run this function on the other CPUs
322 it will fall though this section since we have
323 cleared reboot_smp, and do the reboot if it is the
324 correct CPU, otherwise it halts. */
325 if (reboot_cpu != cpuid)
326 smp_call_function((void *)machine_restart , NULL, 1, 0);
329 /* if reboot_cpu is still -1, then we want a tradional reboot,
330 and if we are not running on the reboot_cpu,, halt */
331 if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) {
333 __asm__ __volatile__ ("hlt");
336 * Stop all CPUs and turn off local APICs and the IO-APIC, so
337 * other OSs see a clean IRQ state.
340 #endif /* CONFIG_SMP */
344 #ifdef CONFIG_X86_IO_APIC
348 if (!reboot_thru_bios) {
350 efi.reset_system(EFI_RESET_COLD, EFI_SUCCESS, 0, NULL);
351 __asm__ __volatile__("lidt %0": :"m" (no_idt));
352 __asm__ __volatile__("int3");
354 /* rebooting needs to touch the page at absolute addr 0 */
355 *((unsigned short *)__va(0x472)) = reboot_mode;
357 mach_reboot_fixups(); /* for board specific fixups */
359 /* That didn't work - force a triple fault.. */
360 __asm__ __volatile__("lidt %0": :"m" (no_idt));
361 __asm__ __volatile__("int3");
365 efi.reset_system(EFI_RESET_WARM, EFI_SUCCESS, 0, NULL);
367 machine_real_restart(jump_to_bios, sizeof(jump_to_bios));
370 EXPORT_SYMBOL(machine_restart);
372 void machine_halt(void)
376 EXPORT_SYMBOL(machine_halt);
378 void machine_power_off(void)
383 efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
388 EXPORT_SYMBOL(machine_power_off);