diff options
author | H. Peter Anvin <hpa@zytor.com> | 2012-06-17 00:47:37 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2012-06-17 13:51:01 -0400 |
commit | 650513979a437c32d7a0a84f0ed952a55bbb5583 (patch) | |
tree | b831bcbfdfce6abb31573e67669272f368626b5b /arch/x86/realmode | |
parent | cfaf025112d3856637ff34a767ef785ef5cf2ca9 (diff) |
x86-64, reboot: Allow reboot=bios and reboot-cpu override on x86-64
With the revamped realmode trampoline code, it is trivial to extend
support for reboot=bios to x86-64. Furthermore, while we are at it,
remove the restriction that only we can only override the reboot CPU
on 32 bits.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Link: http://lkml.kernel.org/n/tip-jopx7y6g6dbcx4tpal8q0jlr@git.kernel.org
Diffstat (limited to 'arch/x86/realmode')
-rw-r--r-- | arch/x86/realmode/rm/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/realmode/rm/header.S | 4 | ||||
-rw-r--r-- | arch/x86/realmode/rm/reboot.S (renamed from arch/x86/realmode/rm/reboot_32.S) | 26 |
3 files changed, 27 insertions, 5 deletions
diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile index 5b84a2d30888..b2d534cab25f 100644 --- a/arch/x86/realmode/rm/Makefile +++ b/arch/x86/realmode/rm/Makefile | |||
@@ -22,7 +22,7 @@ wakeup-objs += video-bios.o | |||
22 | realmode-y += header.o | 22 | realmode-y += header.o |
23 | realmode-y += trampoline_$(BITS).o | 23 | realmode-y += trampoline_$(BITS).o |
24 | realmode-y += stack.o | 24 | realmode-y += stack.o |
25 | realmode-$(CONFIG_X86_32) += reboot_32.o | 25 | realmode-y += reboot.o |
26 | realmode-$(CONFIG_ACPI_SLEEP) += $(wakeup-objs) | 26 | realmode-$(CONFIG_ACPI_SLEEP) += $(wakeup-objs) |
27 | 27 | ||
28 | targets += $(realmode-y) | 28 | targets += $(realmode-y) |
diff --git a/arch/x86/realmode/rm/header.S b/arch/x86/realmode/rm/header.S index fadf48378ada..a28221d94e69 100644 --- a/arch/x86/realmode/rm/header.S +++ b/arch/x86/realmode/rm/header.S | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | #include <linux/linkage.h> | 7 | #include <linux/linkage.h> |
8 | #include <asm/page_types.h> | 8 | #include <asm/page_types.h> |
9 | #include <asm/segment.h> | ||
9 | 10 | ||
10 | #include "realmode.h" | 11 | #include "realmode.h" |
11 | 12 | ||
@@ -28,8 +29,9 @@ GLOBAL(real_mode_header) | |||
28 | .long pa_wakeup_header | 29 | .long pa_wakeup_header |
29 | #endif | 30 | #endif |
30 | /* APM/BIOS reboot */ | 31 | /* APM/BIOS reboot */ |
31 | #ifdef CONFIG_X86_32 | ||
32 | .long pa_machine_real_restart_asm | 32 | .long pa_machine_real_restart_asm |
33 | #ifdef CONFIG_X86_64 | ||
34 | .long __KERNEL32_CS | ||
33 | #endif | 35 | #endif |
34 | END(real_mode_header) | 36 | END(real_mode_header) |
35 | 37 | ||
diff --git a/arch/x86/realmode/rm/reboot_32.S b/arch/x86/realmode/rm/reboot.S index 114044876b3d..6bf8feac5557 100644 --- a/arch/x86/realmode/rm/reboot_32.S +++ b/arch/x86/realmode/rm/reboot.S | |||
@@ -2,6 +2,8 @@ | |||
2 | #include <linux/init.h> | 2 | #include <linux/init.h> |
3 | #include <asm/segment.h> | 3 | #include <asm/segment.h> |
4 | #include <asm/page_types.h> | 4 | #include <asm/page_types.h> |
5 | #include <asm/processor-flags.h> | ||
6 | #include <asm/msr-index.h> | ||
5 | #include "realmode.h" | 7 | #include "realmode.h" |
6 | 8 | ||
7 | /* | 9 | /* |
@@ -12,13 +14,31 @@ | |||
12 | * doesn't work with at least one type of 486 motherboard. It is easy | 14 | * doesn't work with at least one type of 486 motherboard. It is easy |
13 | * to stop this code working; hence the copious comments. | 15 | * to stop this code working; hence the copious comments. |
14 | * | 16 | * |
15 | * This code is called with the restart type (0 = BIOS, 1 = APM) in %eax. | 17 | * This code is called with the restart type (0 = BIOS, 1 = APM) in |
18 | * the primary argument register (%eax for 32 bit, %edi for 64 bit). | ||
16 | */ | 19 | */ |
17 | .section ".text32", "ax" | 20 | .section ".text32", "ax" |
18 | .code32 | 21 | .code32 |
19 | |||
20 | .balign 16 | ||
21 | ENTRY(machine_real_restart_asm) | 22 | ENTRY(machine_real_restart_asm) |
23 | |||
24 | #ifdef CONFIG_X86_64 | ||
25 | |||
26 | /* Disable paging to drop us out of long mode */ | ||
27 | movl %cr0, %eax | ||
28 | andl $~X86_CR0_PG, %eax | ||
29 | movl %eax, %cr0 | ||
30 | jmp 1f /* "A branch" may be needed here, assume near is OK */ | ||
31 | |||
32 | 1: | ||
33 | xorl %eax, %eax | ||
34 | xorl %edx, %edx | ||
35 | movl $MSR_EFER, %ecx | ||
36 | wrmsr | ||
37 | |||
38 | movl %edi, %eax | ||
39 | |||
40 | #endif /* CONFIG_X86_64 */ | ||
41 | |||
22 | /* Set up the IDT for real mode. */ | 42 | /* Set up the IDT for real mode. */ |
23 | lidtl pa_machine_real_restart_idt | 43 | lidtl pa_machine_real_restart_idt |
24 | 44 | ||