aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/reboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/reboot.c')
-rw-r--r--arch/x86/kernel/reboot.c204
1 files changed, 97 insertions, 107 deletions
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index e3af342fe83a..9242436e9937 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -6,6 +6,7 @@
6#include <linux/dmi.h> 6#include <linux/dmi.h>
7#include <linux/sched.h> 7#include <linux/sched.h>
8#include <linux/tboot.h> 8#include <linux/tboot.h>
9#include <linux/delay.h>
9#include <acpi/reboot.h> 10#include <acpi/reboot.h>
10#include <asm/io.h> 11#include <asm/io.h>
11#include <asm/apic.h> 12#include <asm/apic.h>
@@ -18,6 +19,7 @@
18#include <asm/pci_x86.h> 19#include <asm/pci_x86.h>
19#include <asm/virtext.h> 20#include <asm/virtext.h>
20#include <asm/cpu.h> 21#include <asm/cpu.h>
22#include <asm/nmi.h>
21 23
22#ifdef CONFIG_X86_32 24#ifdef CONFIG_X86_32
23# include <linux/ctype.h> 25# include <linux/ctype.h>
@@ -34,7 +36,7 @@ EXPORT_SYMBOL(pm_power_off);
34 36
35static const struct desc_ptr no_idt = {}; 37static const struct desc_ptr no_idt = {};
36static int reboot_mode; 38static int reboot_mode;
37enum reboot_type reboot_type = BOOT_KBD; 39enum reboot_type reboot_type = BOOT_ACPI;
38int reboot_force; 40int reboot_force;
39 41
40#if defined(CONFIG_X86_32) && defined(CONFIG_SMP) 42#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
@@ -84,7 +86,7 @@ static int __init reboot_setup(char *str)
84 } 86 }
85 /* we will leave sorting out the final value 87 /* we will leave sorting out the final value
86 when we are ready to reboot, since we might not 88 when we are ready to reboot, since we might not
87 have set up boot_cpu_id or smp_num_cpu */ 89 have detected BSP APIC ID or smp_num_cpu */
88 break; 90 break;
89#endif /* CONFIG_SMP */ 91#endif /* CONFIG_SMP */
90 92
@@ -284,6 +286,22 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
284 DMI_MATCH(DMI_BOARD_NAME, "P4S800"), 286 DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
285 }, 287 },
286 }, 288 },
289 { /* Handle problems with rebooting on VersaLogic Menlow boards */
290 .callback = set_bios_reboot,
291 .ident = "VersaLogic Menlow based board",
292 .matches = {
293 DMI_MATCH(DMI_BOARD_VENDOR, "VersaLogic Corporation"),
294 DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"),
295 },
296 },
297 { /* Handle reboot issue on Acer Aspire one */
298 .callback = set_bios_reboot,
299 .ident = "Acer Aspire One A110",
300 .matches = {
301 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
302 DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
303 },
304 },
287 { } 305 { }
288}; 306};
289 307
@@ -294,68 +312,16 @@ static int __init reboot_init(void)
294} 312}
295core_initcall(reboot_init); 313core_initcall(reboot_init);
296 314
297/* The following code and data reboots the machine by switching to real 315extern const unsigned char machine_real_restart_asm[];
298 mode and jumping to the BIOS reset entry point, as if the CPU has 316extern const u64 machine_real_restart_gdt[3];
299 really been reset. The previous version asked the keyboard
300 controller to pulse the CPU reset line, which is more thorough, but
301 doesn't work with at least one type of 486 motherboard. It is easy
302 to stop this code working; hence the copious comments. */
303static const unsigned long long
304real_mode_gdt_entries [3] =
305{
306 0x0000000000000000ULL, /* Null descriptor */
307 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
308 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
309};
310 317
311static const struct desc_ptr 318void machine_real_restart(unsigned int type)
312real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
313real_mode_idt = { 0x3ff, 0 };
314
315/* This is 16-bit protected mode code to disable paging and the cache,
316 switch to real mode and jump to the BIOS reset code.
317
318 The instruction that switches to real mode by writing to CR0 must be
319 followed immediately by a far jump instruction, which set CS to a
320 valid value for real mode, and flushes the prefetch queue to avoid
321 running instructions that have already been decoded in protected
322 mode.
323
324 Clears all the flags except ET, especially PG (paging), PE
325 (protected-mode enable) and TS (task switch for coprocessor state
326 save). Flushes the TLB after paging has been disabled. Sets CD and
327 NW, to disable the cache on a 486, and invalidates the cache. This
328 is more like the state of a 486 after reset. I don't know if
329 something else should be done for other chips.
330
331 More could be done here to set up the registers as if a CPU reset had
332 occurred; hopefully real BIOSs don't assume much. */
333static const unsigned char real_mode_switch [] =
334{ 319{
335 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */ 320 void *restart_va;
336 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */ 321 unsigned long restart_pa;
337 0x66, 0x0d, 0x00, 0x00, 0x00, 0x60, /* orl $0x60000000,%eax */ 322 void (*restart_lowmem)(unsigned int);
338 0x66, 0x0f, 0x22, 0xc0, /* movl %eax,%cr0 */ 323 u64 *lowmem_gdt;
339 0x66, 0x0f, 0x22, 0xd8, /* movl %eax,%cr3 */
340 0x66, 0x0f, 0x20, 0xc3, /* movl %cr0,%ebx */
341 0x66, 0x81, 0xe3, 0x00, 0x00, 0x00, 0x60, /* andl $0x60000000,%ebx */
342 0x74, 0x02, /* jz f */
343 0x0f, 0x09, /* wbinvd */
344 0x24, 0x10, /* f: andb $0x10,al */
345 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
346};
347static const unsigned char jump_to_bios [] =
348{
349 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
350};
351 324
352/*
353 * Switch to real mode and then execute the code
354 * specified by the code and length parameters.
355 * We assume that length will aways be less that 100!
356 */
357void machine_real_restart(const unsigned char *code, int length)
358{
359 local_irq_disable(); 325 local_irq_disable();
360 326
361 /* Write zero to CMOS register number 0x0f, which the BIOS POST 327 /* Write zero to CMOS register number 0x0f, which the BIOS POST
@@ -371,16 +337,10 @@ void machine_real_restart(const unsigned char *code, int length)
371 CMOS_WRITE(0x00, 0x8f); 337 CMOS_WRITE(0x00, 0x8f);
372 spin_unlock(&rtc_lock); 338 spin_unlock(&rtc_lock);
373 339
374 /* Remap the kernel at virtual address zero, as well as offset zero
375 from the kernel segment. This assumes the kernel segment starts at
376 virtual address PAGE_OFFSET. */
377 memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
378 sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
379
380 /* 340 /*
381 * Use `swapper_pg_dir' as our page directory. 341 * Switch back to the initial page table.
382 */ 342 */
383 load_cr3(swapper_pg_dir); 343 load_cr3(initial_page_table);
384 344
385 /* Write 0x1234 to absolute memory location 0x472. The BIOS reads 345 /* Write 0x1234 to absolute memory location 0x472. The BIOS reads
386 this on booting to tell it to "Bypass memory test (also warm 346 this on booting to tell it to "Bypass memory test (also warm
@@ -389,41 +349,23 @@ void machine_real_restart(const unsigned char *code, int length)
389 too. */ 349 too. */
390 *((unsigned short *)0x472) = reboot_mode; 350 *((unsigned short *)0x472) = reboot_mode;
391 351
392 /* For the switch to real mode, copy some code to low memory. It has 352 /* Patch the GDT in the low memory trampoline */
393 to be in the first 64k because it is running in 16-bit mode, and it 353 lowmem_gdt = TRAMPOLINE_SYM(machine_real_restart_gdt);
394 has to have the same physical and virtual address, because it turns 354
395 off paging. Copy it near the end of the first page, out of the way 355 restart_va = TRAMPOLINE_SYM(machine_real_restart_asm);
396 of BIOS variables. */ 356 restart_pa = virt_to_phys(restart_va);
397 memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100), 357 restart_lowmem = (void (*)(unsigned int))restart_pa;
398 real_mode_switch, sizeof (real_mode_switch)); 358
399 memcpy((void *)(0x1000 - 100), code, length); 359 /* GDT[0]: GDT self-pointer */
400 360 lowmem_gdt[0] =
401 /* Set up the IDT for real mode. */ 361 (u64)(sizeof(machine_real_restart_gdt) - 1) +
402 load_idt(&real_mode_idt); 362 ((u64)virt_to_phys(lowmem_gdt) << 16);
403 363 /* GDT[1]: 64K real mode code segment */
404 /* Set up a GDT from which we can load segment descriptors for real 364 lowmem_gdt[1] =
405 mode. The GDT is not used in real mode; it is just needed here to 365 GDT_ENTRY(0x009b, restart_pa, 0xffff);
406 prepare the descriptors. */ 366
407 load_gdt(&real_mode_gdt); 367 /* Jump to the identity-mapped low memory code */
408 368 restart_lowmem(type);
409 /* Load the data segment registers, and thus the descriptors ready for
410 real mode. The base address of each segment is 0x100, 16 times the
411 selector value being loaded here. This is so that the segment
412 registers don't have to be reloaded after switching to real mode:
413 the values are consistent for real mode operation already. */
414 __asm__ __volatile__ ("movl $0x0010,%%eax\n"
415 "\tmovl %%eax,%%ds\n"
416 "\tmovl %%eax,%%es\n"
417 "\tmovl %%eax,%%fs\n"
418 "\tmovl %%eax,%%gs\n"
419 "\tmovl %%eax,%%ss" : : : "eax");
420
421 /* Jump to the 16-bit code that we copied earlier. It disables paging
422 and the cache, switches to real mode, and jumps to the BIOS reset
423 entry point. */
424 __asm__ __volatile__ ("ljmp $0x0008,%0"
425 :
426 : "i" ((void *)(0x1000 - sizeof (real_mode_switch) - 100)));
427} 369}
428#ifdef CONFIG_APM_MODULE 370#ifdef CONFIG_APM_MODULE
429EXPORT_SYMBOL(machine_real_restart); 371EXPORT_SYMBOL(machine_real_restart);
@@ -477,6 +419,30 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
477 DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"), 419 DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"),
478 }, 420 },
479 }, 421 },
422 { /* Handle problems with rebooting on the Latitude E6320. */
423 .callback = set_pci_reboot,
424 .ident = "Dell Latitude E6320",
425 .matches = {
426 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
427 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6320"),
428 },
429 },
430 { /* Handle problems with rebooting on the Latitude E5420. */
431 .callback = set_pci_reboot,
432 .ident = "Dell Latitude E5420",
433 .matches = {
434 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
435 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5420"),
436 },
437 },
438 { /* Handle problems with rebooting on the Latitude E6420. */
439 .callback = set_pci_reboot,
440 .ident = "Dell Latitude E6420",
441 .matches = {
442 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
443 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6420"),
444 },
445 },
480 { } 446 { }
481}; 447};
482 448
@@ -544,9 +510,24 @@ void __attribute__((weak)) mach_reboot_fixups(void)
544{ 510{
545} 511}
546 512
513/*
514 * Windows compatible x86 hardware expects the following on reboot:
515 *
516 * 1) If the FADT has the ACPI reboot register flag set, try it
517 * 2) If still alive, write to the keyboard controller
518 * 3) If still alive, write to the ACPI reboot register again
519 * 4) If still alive, write to the keyboard controller again
520 *
521 * If the machine is still alive at this stage, it gives up. We default to
522 * following the same pattern, except that if we're still alive after (4) we'll
523 * try to force a triple fault and then cycle between hitting the keyboard
524 * controller and doing that
525 */
547static void native_machine_emergency_restart(void) 526static void native_machine_emergency_restart(void)
548{ 527{
549 int i; 528 int i;
529 int attempt = 0;
530 int orig_reboot_type = reboot_type;
550 531
551 if (reboot_emergency) 532 if (reboot_emergency)
552 emergency_vmx_disable_all(); 533 emergency_vmx_disable_all();
@@ -568,6 +549,13 @@ static void native_machine_emergency_restart(void)
568 outb(0xfe, 0x64); /* pulse reset low */ 549 outb(0xfe, 0x64); /* pulse reset low */
569 udelay(50); 550 udelay(50);
570 } 551 }
552 if (attempt == 0 && orig_reboot_type == BOOT_ACPI) {
553 attempt = 1;
554 reboot_type = BOOT_ACPI;
555 } else {
556 reboot_type = BOOT_TRIPLE;
557 }
558 break;
571 559
572 case BOOT_TRIPLE: 560 case BOOT_TRIPLE:
573 load_idt(&no_idt); 561 load_idt(&no_idt);
@@ -578,7 +566,7 @@ static void native_machine_emergency_restart(void)
578 566
579#ifdef CONFIG_X86_32 567#ifdef CONFIG_X86_32
580 case BOOT_BIOS: 568 case BOOT_BIOS:
581 machine_real_restart(jump_to_bios, sizeof(jump_to_bios)); 569 machine_real_restart(MRR_BIOS);
582 570
583 reboot_type = BOOT_KBD; 571 reboot_type = BOOT_KBD;
584 break; 572 break;
@@ -641,7 +629,7 @@ void native_machine_shutdown(void)
641 /* O.K Now that I'm on the appropriate processor, 629 /* O.K Now that I'm on the appropriate processor,
642 * stop all of the others. 630 * stop all of the others.
643 */ 631 */
644 smp_send_stop(); 632 stop_other_cpus();
645#endif 633#endif
646 634
647 lapic_shutdown(); 635 lapic_shutdown();
@@ -753,7 +741,7 @@ static int crash_nmi_callback(struct notifier_block *self,
753{ 741{
754 int cpu; 742 int cpu;
755 743
756 if (val != DIE_NMI_IPI) 744 if (val != DIE_NMI)
757 return NOTIFY_OK; 745 return NOTIFY_OK;
758 746
759 cpu = raw_smp_processor_id(); 747 cpu = raw_smp_processor_id();
@@ -784,6 +772,8 @@ static void smp_send_nmi_allbutself(void)
784 772
785static struct notifier_block crash_nmi_nb = { 773static struct notifier_block crash_nmi_nb = {
786 .notifier_call = crash_nmi_callback, 774 .notifier_call = crash_nmi_callback,
775 /* we want to be the first one called */
776 .priority = NMI_LOCAL_HIGH_PRIOR+1,
787}; 777};
788 778
789/* Halt all other CPUs, calling the specified function on each of them 779/* Halt all other CPUs, calling the specified function on each of them