diff options
Diffstat (limited to 'arch/x86/kernel/reboot.c')
-rw-r--r-- | arch/x86/kernel/reboot.c | 82 |
1 files changed, 41 insertions, 41 deletions
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 25b48edb847c..52190a938b4a 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -1,3 +1,5 @@ | |||
1 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
2 | |||
1 | #include <linux/module.h> | 3 | #include <linux/module.h> |
2 | #include <linux/reboot.h> | 4 | #include <linux/reboot.h> |
3 | #include <linux/init.h> | 5 | #include <linux/init.h> |
@@ -20,14 +22,12 @@ | |||
20 | #include <asm/virtext.h> | 22 | #include <asm/virtext.h> |
21 | #include <asm/cpu.h> | 23 | #include <asm/cpu.h> |
22 | #include <asm/nmi.h> | 24 | #include <asm/nmi.h> |
25 | #include <asm/smp.h> | ||
23 | 26 | ||
24 | #ifdef CONFIG_X86_32 | 27 | #include <linux/ctype.h> |
25 | # include <linux/ctype.h> | 28 | #include <linux/mc146818rtc.h> |
26 | # include <linux/mc146818rtc.h> | 29 | #include <asm/realmode.h> |
27 | # include <asm/realmode.h> | 30 | #include <asm/x86_init.h> |
28 | #else | ||
29 | # include <asm/x86_init.h> | ||
30 | #endif | ||
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Power off function, if any | 33 | * Power off function, if any |
@@ -49,7 +49,7 @@ int reboot_force; | |||
49 | */ | 49 | */ |
50 | static int reboot_default = 1; | 50 | static int reboot_default = 1; |
51 | 51 | ||
52 | #if defined(CONFIG_X86_32) && defined(CONFIG_SMP) | 52 | #ifdef CONFIG_SMP |
53 | static int reboot_cpu = -1; | 53 | static int reboot_cpu = -1; |
54 | #endif | 54 | #endif |
55 | 55 | ||
@@ -67,8 +67,8 @@ bool port_cf9_safe = false; | |||
67 | * reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci] | 67 | * reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci] |
68 | * warm Don't set the cold reboot flag | 68 | * warm Don't set the cold reboot flag |
69 | * cold Set the cold reboot flag | 69 | * cold Set the cold reboot flag |
70 | * bios Reboot by jumping through the BIOS (only for X86_32) | 70 | * bios Reboot by jumping through the BIOS |
71 | * smp Reboot by executing reset on BSP or other CPU (only for X86_32) | 71 | * smp Reboot by executing reset on BSP or other CPU |
72 | * triple Force a triple fault (init) | 72 | * triple Force a triple fault (init) |
73 | * kbd Use the keyboard controller. cold reset (default) | 73 | * kbd Use the keyboard controller. cold reset (default) |
74 | * acpi Use the RESET_REG in the FADT | 74 | * acpi Use the RESET_REG in the FADT |
@@ -95,7 +95,6 @@ static int __init reboot_setup(char *str) | |||
95 | reboot_mode = 0; | 95 | reboot_mode = 0; |
96 | break; | 96 | break; |
97 | 97 | ||
98 | #ifdef CONFIG_X86_32 | ||
99 | #ifdef CONFIG_SMP | 98 | #ifdef CONFIG_SMP |
100 | case 's': | 99 | case 's': |
101 | if (isdigit(*(str+1))) { | 100 | if (isdigit(*(str+1))) { |
@@ -112,7 +111,6 @@ static int __init reboot_setup(char *str) | |||
112 | #endif /* CONFIG_SMP */ | 111 | #endif /* CONFIG_SMP */ |
113 | 112 | ||
114 | case 'b': | 113 | case 'b': |
115 | #endif | ||
116 | case 'a': | 114 | case 'a': |
117 | case 'k': | 115 | case 'k': |
118 | case 't': | 116 | case 't': |
@@ -138,7 +136,6 @@ static int __init reboot_setup(char *str) | |||
138 | __setup("reboot=", reboot_setup); | 136 | __setup("reboot=", reboot_setup); |
139 | 137 | ||
140 | 138 | ||
141 | #ifdef CONFIG_X86_32 | ||
142 | /* | 139 | /* |
143 | * Reboot options and system auto-detection code provided by | 140 | * Reboot options and system auto-detection code provided by |
144 | * Dell Inc. so their systems "just work". :-) | 141 | * Dell Inc. so their systems "just work". :-) |
@@ -152,16 +149,14 @@ static int __init set_bios_reboot(const struct dmi_system_id *d) | |||
152 | { | 149 | { |
153 | if (reboot_type != BOOT_BIOS) { | 150 | if (reboot_type != BOOT_BIOS) { |
154 | reboot_type = BOOT_BIOS; | 151 | reboot_type = BOOT_BIOS; |
155 | printk(KERN_INFO "%s series board detected. Selecting BIOS-method for reboots.\n", d->ident); | 152 | pr_info("%s series board detected. Selecting %s-method for reboots.\n", |
153 | "BIOS", d->ident); | ||
156 | } | 154 | } |
157 | return 0; | 155 | return 0; |
158 | } | 156 | } |
159 | 157 | ||
160 | void machine_real_restart(unsigned int type) | 158 | void __noreturn machine_real_restart(unsigned int type) |
161 | { | 159 | { |
162 | void (*restart_lowmem)(unsigned int) = (void (*)(unsigned int)) | ||
163 | real_mode_header->machine_real_restart_asm; | ||
164 | |||
165 | local_irq_disable(); | 160 | local_irq_disable(); |
166 | 161 | ||
167 | /* | 162 | /* |
@@ -181,25 +176,28 @@ void machine_real_restart(unsigned int type) | |||
181 | /* | 176 | /* |
182 | * Switch back to the initial page table. | 177 | * Switch back to the initial page table. |
183 | */ | 178 | */ |
179 | #ifdef CONFIG_X86_32 | ||
184 | load_cr3(initial_page_table); | 180 | load_cr3(initial_page_table); |
185 | 181 | #else | |
186 | /* | 182 | write_cr3(real_mode_header->trampoline_pgd); |
187 | * Write 0x1234 to absolute memory location 0x472. The BIOS reads | 183 | #endif |
188 | * this on booting to tell it to "Bypass memory test (also warm | ||
189 | * boot)". This seems like a fairly standard thing that gets set by | ||
190 | * REBOOT.COM programs, and the previous reset routine did this | ||
191 | * too. */ | ||
192 | *((unsigned short *)0x472) = reboot_mode; | ||
193 | 184 | ||
194 | /* Jump to the identity-mapped low memory code */ | 185 | /* Jump to the identity-mapped low memory code */ |
195 | restart_lowmem(type); | 186 | #ifdef CONFIG_X86_32 |
187 | asm volatile("jmpl *%0" : : | ||
188 | "rm" (real_mode_header->machine_real_restart_asm), | ||
189 | "a" (type)); | ||
190 | #else | ||
191 | asm volatile("ljmpl *%0" : : | ||
192 | "m" (real_mode_header->machine_real_restart_asm), | ||
193 | "D" (type)); | ||
194 | #endif | ||
195 | unreachable(); | ||
196 | } | 196 | } |
197 | #ifdef CONFIG_APM_MODULE | 197 | #ifdef CONFIG_APM_MODULE |
198 | EXPORT_SYMBOL(machine_real_restart); | 198 | EXPORT_SYMBOL(machine_real_restart); |
199 | #endif | 199 | #endif |
200 | 200 | ||
201 | #endif /* CONFIG_X86_32 */ | ||
202 | |||
203 | /* | 201 | /* |
204 | * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot | 202 | * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot |
205 | */ | 203 | */ |
@@ -207,8 +205,8 @@ static int __init set_pci_reboot(const struct dmi_system_id *d) | |||
207 | { | 205 | { |
208 | if (reboot_type != BOOT_CF9) { | 206 | if (reboot_type != BOOT_CF9) { |
209 | reboot_type = BOOT_CF9; | 207 | reboot_type = BOOT_CF9; |
210 | printk(KERN_INFO "%s series board detected. " | 208 | pr_info("%s series board detected. Selecting %s-method for reboots.\n", |
211 | "Selecting PCI-method for reboots.\n", d->ident); | 209 | "PCI", d->ident); |
212 | } | 210 | } |
213 | return 0; | 211 | return 0; |
214 | } | 212 | } |
@@ -217,17 +215,16 @@ static int __init set_kbd_reboot(const struct dmi_system_id *d) | |||
217 | { | 215 | { |
218 | if (reboot_type != BOOT_KBD) { | 216 | if (reboot_type != BOOT_KBD) { |
219 | reboot_type = BOOT_KBD; | 217 | reboot_type = BOOT_KBD; |
220 | printk(KERN_INFO "%s series board detected. Selecting KBD-method for reboot.\n", d->ident); | 218 | pr_info("%s series board detected. Selecting %s-method for reboot.\n", |
219 | "KBD", d->ident); | ||
221 | } | 220 | } |
222 | return 0; | 221 | return 0; |
223 | } | 222 | } |
224 | 223 | ||
225 | /* | 224 | /* |
226 | * This is a single dmi_table handling all reboot quirks. Note that | 225 | * This is a single dmi_table handling all reboot quirks. |
227 | * REBOOT_BIOS is only available for 32bit | ||
228 | */ | 226 | */ |
229 | static struct dmi_system_id __initdata reboot_dmi_table[] = { | 227 | static struct dmi_system_id __initdata reboot_dmi_table[] = { |
230 | #ifdef CONFIG_X86_32 | ||
231 | { /* Handle problems with rebooting on Dell E520's */ | 228 | { /* Handle problems with rebooting on Dell E520's */ |
232 | .callback = set_bios_reboot, | 229 | .callback = set_bios_reboot, |
233 | .ident = "Dell E520", | 230 | .ident = "Dell E520", |
@@ -377,7 +374,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
377 | DMI_MATCH(DMI_BOARD_NAME, "P4S800"), | 374 | DMI_MATCH(DMI_BOARD_NAME, "P4S800"), |
378 | }, | 375 | }, |
379 | }, | 376 | }, |
380 | #endif /* CONFIG_X86_32 */ | ||
381 | 377 | ||
382 | { /* Handle reboot issue on Acer Aspire one */ | 378 | { /* Handle reboot issue on Acer Aspire one */ |
383 | .callback = set_kbd_reboot, | 379 | .callback = set_kbd_reboot, |
@@ -451,6 +447,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
451 | DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"), | 447 | DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"), |
452 | }, | 448 | }, |
453 | }, | 449 | }, |
450 | { /* Handle problems with rebooting on the Precision M6600. */ | ||
451 | .callback = set_pci_reboot, | ||
452 | .ident = "Dell OptiPlex 990", | ||
453 | .matches = { | ||
454 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
455 | DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"), | ||
456 | }, | ||
457 | }, | ||
454 | { } | 458 | { } |
455 | }; | 459 | }; |
456 | 460 | ||
@@ -576,13 +580,11 @@ static void native_machine_emergency_restart(void) | |||
576 | reboot_type = BOOT_KBD; | 580 | reboot_type = BOOT_KBD; |
577 | break; | 581 | break; |
578 | 582 | ||
579 | #ifdef CONFIG_X86_32 | ||
580 | case BOOT_BIOS: | 583 | case BOOT_BIOS: |
581 | machine_real_restart(MRR_BIOS); | 584 | machine_real_restart(MRR_BIOS); |
582 | 585 | ||
583 | reboot_type = BOOT_KBD; | 586 | reboot_type = BOOT_KBD; |
584 | break; | 587 | break; |
585 | #endif | ||
586 | 588 | ||
587 | case BOOT_ACPI: | 589 | case BOOT_ACPI: |
588 | acpi_reboot(); | 590 | acpi_reboot(); |
@@ -624,12 +626,10 @@ void native_machine_shutdown(void) | |||
624 | /* The boot cpu is always logical cpu 0 */ | 626 | /* The boot cpu is always logical cpu 0 */ |
625 | int reboot_cpu_id = 0; | 627 | int reboot_cpu_id = 0; |
626 | 628 | ||
627 | #ifdef CONFIG_X86_32 | ||
628 | /* See if there has been given a command line override */ | 629 | /* See if there has been given a command line override */ |
629 | if ((reboot_cpu != -1) && (reboot_cpu < nr_cpu_ids) && | 630 | if ((reboot_cpu != -1) && (reboot_cpu < nr_cpu_ids) && |
630 | cpu_online(reboot_cpu)) | 631 | cpu_online(reboot_cpu)) |
631 | reboot_cpu_id = reboot_cpu; | 632 | reboot_cpu_id = reboot_cpu; |
632 | #endif | ||
633 | 633 | ||
634 | /* Make certain the cpu I'm about to reboot on is online */ | 634 | /* Make certain the cpu I'm about to reboot on is online */ |
635 | if (!cpu_online(reboot_cpu_id)) | 635 | if (!cpu_online(reboot_cpu_id)) |
@@ -670,7 +670,7 @@ static void __machine_emergency_restart(int emergency) | |||
670 | 670 | ||
671 | static void native_machine_restart(char *__unused) | 671 | static void native_machine_restart(char *__unused) |
672 | { | 672 | { |
673 | printk("machine restart\n"); | 673 | pr_notice("machine restart\n"); |
674 | 674 | ||
675 | if (!reboot_force) | 675 | if (!reboot_force) |
676 | machine_shutdown(); | 676 | machine_shutdown(); |