diff options
Diffstat (limited to 'arch/x86/realmode/rm/trampoline_32.S')
-rw-r--r-- | arch/x86/realmode/rm/trampoline_32.S | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/arch/x86/realmode/rm/trampoline_32.S b/arch/x86/realmode/rm/trampoline_32.S new file mode 100644 index 000000000000..c1b2791183e7 --- /dev/null +++ b/arch/x86/realmode/rm/trampoline_32.S | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Trampoline.S Derived from Setup.S by Linus Torvalds | ||
4 | * | ||
5 | * 4 Jan 1997 Michael Chastain: changed to gnu as. | ||
6 | * | ||
7 | * This is only used for booting secondary CPUs in SMP machine | ||
8 | * | ||
9 | * Entry: CS:IP point to the start of our code, we are | ||
10 | * in real mode with no stack, but the rest of the | ||
11 | * trampoline page to make our stack and everything else | ||
12 | * is a mystery. | ||
13 | * | ||
14 | * We jump into arch/x86/kernel/head_32.S. | ||
15 | * | ||
16 | * On entry to trampoline_start, the processor is in real mode | ||
17 | * with 16-bit addressing and 16-bit data. CS has some value | ||
18 | * and IP is zero. Thus, we load CS to the physical segment | ||
19 | * of the real mode code before doing anything further. | ||
20 | */ | ||
21 | |||
22 | #include <linux/linkage.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <asm/segment.h> | ||
25 | #include <asm/page_types.h> | ||
26 | #include "realmode.h" | ||
27 | |||
28 | .text | ||
29 | .code16 | ||
30 | |||
31 | .balign PAGE_SIZE | ||
32 | ENTRY(trampoline_start) | ||
33 | wbinvd # Needed for NUMA-Q should be harmless for others | ||
34 | |||
35 | LJMPW_RM(1f) | ||
36 | 1: | ||
37 | mov %cs, %ax # Code and data in the same place | ||
38 | mov %ax, %ds | ||
39 | |||
40 | cli # We should be safe anyway | ||
41 | |||
42 | movl tr_start, %eax # where we need to go | ||
43 | |||
44 | movl $0xA5A5A5A5, trampoline_status | ||
45 | # write marker for master knows we're running | ||
46 | |||
47 | /* | ||
48 | * GDT tables in non default location kernel can be beyond 16MB and | ||
49 | * lgdt will not be able to load the address as in real mode default | ||
50 | * operand size is 16bit. Use lgdtl instead to force operand size | ||
51 | * to 32 bit. | ||
52 | */ | ||
53 | lidtl tr_idt # load idt with 0, 0 | ||
54 | lgdtl tr_gdt # load gdt with whatever is appropriate | ||
55 | |||
56 | movw $1, %dx # protected mode (PE) bit | ||
57 | lmsw %dx # into protected mode | ||
58 | |||
59 | ljmpl $__BOOT_CS, $pa_startup_32 | ||
60 | |||
61 | .section ".text32","ax" | ||
62 | .code32 | ||
63 | ENTRY(startup_32) # note: also used from wakeup_asm.S | ||
64 | jmp *%eax | ||
65 | |||
66 | .bss | ||
67 | .balign 8 | ||
68 | GLOBAL(trampoline_header) | ||
69 | tr_start: .space 4 | ||
70 | tr_gdt_pad: .space 2 | ||
71 | tr_gdt: .space 6 | ||
72 | END(trampoline_header) | ||
73 | |||
74 | #include "trampoline_common.S" | ||