mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-26 11:28:28 +00:00
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
This commit is contained in:
parent
968ff9ee56
commit
e5684ec438
16
arch/x86/realmode/rm/realmode.h
Normal file
16
arch/x86/realmode/rm/realmode.h
Normal file
@ -0,0 +1,16 @@
|
||||
#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 @@
|
||||
#include <linux/init.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/page_types.h>
|
||||
#include "realmode.h"
|
||||
|
||||
/*
|
||||
* The following code and data reboots the machine by switching to real
|
||||
@ -82,10 +83,7 @@ machine_real_restart_asm16:
|
||||
2:
|
||||
andb $0x10, %dl
|
||||
movl %edx, %cr0
|
||||
.byte 0xea /* ljmpw */
|
||||
.word 3f /* Offset */
|
||||
.word real_mode_seg /* Segment */
|
||||
|
||||
LJMPW_RM(3f)
|
||||
3:
|
||||
testb $0, %al
|
||||
jz bios
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/page_types.h>
|
||||
#include "realmode.h"
|
||||
|
||||
.text
|
||||
.code16
|
||||
@ -38,9 +39,7 @@
|
||||
trampoline_data:
|
||||
wbinvd # Needed for NUMA-Q should be harmless for others
|
||||
|
||||
.byte 0xea # ljmpw
|
||||
.word 1f # Offset
|
||||
.word real_mode_seg # Segment
|
||||
LJMPW_RM(1f)
|
||||
1:
|
||||
mov %cs, %ax # Code and data in the same place
|
||||
mov %ax, %ds
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <asm/msr.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/processor-flags.h>
|
||||
#include "realmode.h"
|
||||
|
||||
.text
|
||||
.balign PAGE_SIZE
|
||||
@ -40,9 +41,7 @@ ENTRY(trampoline_data)
|
||||
cli # We should be safe anyway
|
||||
wbinvd
|
||||
|
||||
.byte 0xea # ljmpw
|
||||
.word 1f # Offset
|
||||
.word real_mode_seg # Segment
|
||||
LJMPW_RM(1f)
|
||||
1:
|
||||
mov %cs, %ax # Code and data in the same place
|
||||
mov %ax, %ds
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <asm/page_types.h>
|
||||
#include <asm/pgtable_types.h>
|
||||
#include <asm/processor-flags.h>
|
||||
#include "../realmode.h"
|
||||
#include "wakeup.h"
|
||||
|
||||
.code16
|
||||
@ -36,9 +37,7 @@ wakeup_start:
|
||||
cli
|
||||
cld
|
||||
|
||||
.byte 0xea /* ljmpw */
|
||||
.word 3f
|
||||
.word real_mode_seg
|
||||
LJMPW_RM(3f)
|
||||
3:
|
||||
/* Apparently some dimwit BIOS programmers don't know how to
|
||||
program a PM to RM transition, and we might end up here with
|
||||
@ -59,9 +58,7 @@ wakeup_start:
|
||||
|
||||
andb $~X86_CR0_PE, %al
|
||||
movl %eax, %cr0
|
||||
.byte 0xea /* ljmpw */
|
||||
.word 3f
|
||||
.word real_mode_seg
|
||||
LJMPW_RM(3f)
|
||||
3:
|
||||
/* Set up segments */
|
||||
movw %cs, %ax
|
||||
|
Loading…
Reference in New Issue
Block a user