aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2012-05-08 14:22:37 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2012-05-08 14:48:03 -0400
commite5684ec438a094bec0f7d5c52652c0901b48b613 (patch)
tree8cc3cf787a582977ff08ed578907d6df7dbc7e6e /arch/x86
parent968ff9ee56f1e3ed4ff4a6d10185865dc77d8f7e (diff)
x86, realmode: Replace open-coded ljmpw with a macro
We cannot code an ljmpw to the real-mode segment directly, because gas refuses to assemble an ljmp with a symbolic segment. Instead of open-coding it everywhere, define a macro and use it for this case. This is specifically an ljmpw from a 16-bit segment. This is okay, as one should never enter real mode from a 32-bit segment: if one do, the CPU ends up in a bizarre (and useless) mode sometimes called "unreal mode" where segments behave like real mode but the default address and operand sizes is 32 bits. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> Link: http://lkml.kernel.org/r/1336501366-28617-15-git-send-email-jarkko.sakkinen@intel.com
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/realmode/rm/realmode.h16
-rw-r--r--arch/x86/realmode/rm/reboot_32.S6
-rw-r--r--arch/x86/realmode/rm/trampoline_32.S5
-rw-r--r--arch/x86/realmode/rm/trampoline_64.S5
-rw-r--r--arch/x86/realmode/rm/wakeup/wakeup_asm.S9
5 files changed, 25 insertions, 16 deletions
diff --git a/arch/x86/realmode/rm/realmode.h b/arch/x86/realmode/rm/realmode.h
new file mode 100644
index 00000000000..15ab6335f84
--- /dev/null
+++ b/arch/x86/realmode/rm/realmode.h
@@ -0,0 +1,16 @@
1#ifndef ARCH_X86_REALMODE_RM_REALMODE_H
2#define ARCH_X86_REALMODE_RM_REALMODE_H
3
4#ifdef __ASSEMBLY__
5
6/*
7 * 16-bit ljmpw to the real_mode_seg
8 *
9 * This must be open-coded since gas will choke on using a
10 * relocatable symbol for the segment portion.
11 */
12#define LJMPW_RM(to) .byte 0xea ; .word (to), real_mode_seg
13
14#endif /* __ASSEMBLY__ */
15
16#endif /* ARCH_X86_REALMODE_RM_REALMODE_H */
diff --git a/arch/x86/realmode/rm/reboot_32.S b/arch/x86/realmode/rm/reboot_32.S
index 83803c222b4..e90f8c4bbae 100644
--- a/arch/x86/realmode/rm/reboot_32.S
+++ b/arch/x86/realmode/rm/reboot_32.S
@@ -2,6 +2,7 @@
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 "realmode.h"
5 6
6/* 7/*
7 * The following code and data reboots the machine by switching to real 8 * The following code and data reboots the machine by switching to real
@@ -82,10 +83,7 @@ machine_real_restart_asm16:
822: 832:
83 andb $0x10, %dl 84 andb $0x10, %dl
84 movl %edx, %cr0 85 movl %edx, %cr0
85 .byte 0xea /* ljmpw */ 86 LJMPW_RM(3f)
86 .word 3f /* Offset */
87 .word real_mode_seg /* Segment */
88
893: 873:
90 testb $0, %al 88 testb $0, %al
91 jz bios 89 jz bios
diff --git a/arch/x86/realmode/rm/trampoline_32.S b/arch/x86/realmode/rm/trampoline_32.S
index 1315ef48dbf..279f82ef7a9 100644
--- a/arch/x86/realmode/rm/trampoline_32.S
+++ b/arch/x86/realmode/rm/trampoline_32.S
@@ -29,6 +29,7 @@
29#include <linux/init.h> 29#include <linux/init.h>
30#include <asm/segment.h> 30#include <asm/segment.h>
31#include <asm/page_types.h> 31#include <asm/page_types.h>
32#include "realmode.h"
32 33
33 .text 34 .text
34 .code16 35 .code16
@@ -38,9 +39,7 @@
38trampoline_data: 39trampoline_data:
39 wbinvd # Needed for NUMA-Q should be harmless for others 40 wbinvd # Needed for NUMA-Q should be harmless for others
40 41
41 .byte 0xea # ljmpw 42 LJMPW_RM(1f)
42 .word 1f # Offset
43 .word real_mode_seg # Segment
441: 431:
45 mov %cs, %ax # Code and data in the same place 44 mov %cs, %ax # Code and data in the same place
46 mov %ax, %ds 45 mov %ax, %ds
diff --git a/arch/x86/realmode/rm/trampoline_64.S b/arch/x86/realmode/rm/trampoline_64.S
index 77b72b45d70..7459c52f0c2 100644
--- a/arch/x86/realmode/rm/trampoline_64.S
+++ b/arch/x86/realmode/rm/trampoline_64.S
@@ -31,6 +31,7 @@
31#include <asm/msr.h> 31#include <asm/msr.h>
32#include <asm/segment.h> 32#include <asm/segment.h>
33#include <asm/processor-flags.h> 33#include <asm/processor-flags.h>
34#include "realmode.h"
34 35
35 .text 36 .text
36 .balign PAGE_SIZE 37 .balign PAGE_SIZE
@@ -40,9 +41,7 @@ ENTRY(trampoline_data)
40 cli # We should be safe anyway 41 cli # We should be safe anyway
41 wbinvd 42 wbinvd
42 43
43 .byte 0xea # ljmpw 44 LJMPW_RM(1f)
44 .word 1f # Offset
45 .word real_mode_seg # Segment
461: 451:
47 mov %cs, %ax # Code and data in the same place 46 mov %cs, %ax # Code and data in the same place
48 mov %ax, %ds 47 mov %ax, %ds
diff --git a/arch/x86/realmode/rm/wakeup/wakeup_asm.S b/arch/x86/realmode/rm/wakeup/wakeup_asm.S
index 4c5c5f2bfbe..8064e1c3591 100644
--- a/arch/x86/realmode/rm/wakeup/wakeup_asm.S
+++ b/arch/x86/realmode/rm/wakeup/wakeup_asm.S
@@ -6,6 +6,7 @@
6#include <asm/page_types.h> 6#include <asm/page_types.h>
7#include <asm/pgtable_types.h> 7#include <asm/pgtable_types.h>
8#include <asm/processor-flags.h> 8#include <asm/processor-flags.h>
9#include "../realmode.h"
9#include "wakeup.h" 10#include "wakeup.h"
10 11
11 .code16 12 .code16
@@ -36,9 +37,7 @@ wakeup_start:
36 cli 37 cli
37 cld 38 cld
38 39
39 .byte 0xea /* ljmpw */ 40 LJMPW_RM(3f)
40 .word 3f
41 .word real_mode_seg
423: 413:
43 /* Apparently some dimwit BIOS programmers don't know how to 42 /* Apparently some dimwit BIOS programmers don't know how to
44 program a PM to RM transition, and we might end up here with 43 program a PM to RM transition, and we might end up here with
@@ -59,9 +58,7 @@ wakeup_start:
59 58
60 andb $~X86_CR0_PE, %al 59 andb $~X86_CR0_PE, %al
61 movl %eax, %cr0 60 movl %eax, %cr0
62 .byte 0xea /* ljmpw */ 61 LJMPW_RM(3f)
63 .word 3f
64 .word real_mode_seg
653: 623:
66 /* Set up segments */ 63 /* Set up segments */
67 movw %cs, %ax 64 movw %cs, %ax