Commit e5684ec4 authored by H. Peter Anvin's avatar H. Peter Anvin

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: default avatarH. Peter Anvin <hpa@linux.intel.com>
Link: http://lkml.kernel.org/r/1336501366-28617-15-git-send-email-jarkko.sakkinen@intel.com
parent 968ff9ee
#ifndef ARCH_X86_REALMODE_RM_REALMODE_H
#define ARCH_X86_REALMODE_RM_REALMODE_H
#ifdef __ASSEMBLY__
/*
* 16-bit ljmpw to the real_mode_seg
*
* This must be open-coded since gas will choke on using a
* relocatable symbol for the segment portion.
*/
#define LJMPW_RM(to) .byte 0xea ; .word (to), real_mode_seg
#endif /* __ASSEMBLY__ */
#endif /* ARCH_X86_REALMODE_RM_REALMODE_H */
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/page_types.h> #include <asm/page_types.h>
#include "realmode.h"
/* /*
* The following code and data reboots the machine by switching to real * The following code and data reboots the machine by switching to real
...@@ -82,10 +83,7 @@ machine_real_restart_asm16: ...@@ -82,10 +83,7 @@ machine_real_restart_asm16:
2: 2:
andb $0x10, %dl andb $0x10, %dl
movl %edx, %cr0 movl %edx, %cr0
.byte 0xea /* ljmpw */ LJMPW_RM(3f)
.word 3f /* Offset */
.word real_mode_seg /* Segment */
3: 3:
testb $0, %al testb $0, %al
jz bios jz bios
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/page_types.h> #include <asm/page_types.h>
#include "realmode.h"
.text .text
.code16 .code16
...@@ -38,9 +39,7 @@ ...@@ -38,9 +39,7 @@
trampoline_data: trampoline_data:
wbinvd # Needed for NUMA-Q should be harmless for others wbinvd # Needed for NUMA-Q should be harmless for others
.byte 0xea # ljmpw LJMPW_RM(1f)
.word 1f # Offset
.word real_mode_seg # Segment
1: 1:
mov %cs, %ax # Code and data in the same place mov %cs, %ax # Code and data in the same place
mov %ax, %ds mov %ax, %ds
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <asm/msr.h> #include <asm/msr.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/processor-flags.h> #include <asm/processor-flags.h>
#include "realmode.h"
.text .text
.balign PAGE_SIZE .balign PAGE_SIZE
...@@ -40,9 +41,7 @@ ENTRY(trampoline_data) ...@@ -40,9 +41,7 @@ ENTRY(trampoline_data)
cli # We should be safe anyway cli # We should be safe anyway
wbinvd wbinvd
.byte 0xea # ljmpw LJMPW_RM(1f)
.word 1f # Offset
.word real_mode_seg # Segment
1: 1:
mov %cs, %ax # Code and data in the same place mov %cs, %ax # Code and data in the same place
mov %ax, %ds mov %ax, %ds
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <asm/page_types.h> #include <asm/page_types.h>
#include <asm/pgtable_types.h> #include <asm/pgtable_types.h>
#include <asm/processor-flags.h> #include <asm/processor-flags.h>
#include "../realmode.h"
#include "wakeup.h" #include "wakeup.h"
.code16 .code16
...@@ -36,9 +37,7 @@ wakeup_start: ...@@ -36,9 +37,7 @@ wakeup_start:
cli cli
cld cld
.byte 0xea /* ljmpw */ LJMPW_RM(3f)
.word 3f
.word real_mode_seg
3: 3:
/* Apparently some dimwit BIOS programmers don't know how to /* Apparently some dimwit BIOS programmers don't know how to
program a PM to RM transition, and we might end up here with program a PM to RM transition, and we might end up here with
...@@ -59,9 +58,7 @@ wakeup_start: ...@@ -59,9 +58,7 @@ wakeup_start:
andb $~X86_CR0_PE, %al andb $~X86_CR0_PE, %al
movl %eax, %cr0 movl %eax, %cr0
.byte 0xea /* ljmpw */ LJMPW_RM(3f)
.word 3f
.word real_mode_seg
3: 3:
/* Set up segments */ /* Set up segments */
movw %cs, %ax movw %cs, %ax
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment