don't double patch!
[debian/elilo] / x86_64 / rmswitch.S
1 #
2 # Switch from protected mode to real mode and jump to setup.S
3 # image located at %cx:0.
4 #
5 # This module must be placed into physical memory at 0:7C00h.
6 # EFI has some real mode thunking code at 2000:0h.
7 #
8 # Processor and non-maskable interrupts should be disabled
9 # before control is passed to this module.
10 #
11
12 .global _start
13
14 .code32
15 .text
16 _start:
17         #
18         # Load identity mapped GDT & real mode IDT.
19         # Add 7C00h to the addresses since this is linked to start
20         # at 0h and it is being placed at 7C00h.
21         #
22
23         lgdt    %cs:gdt_48 + 0x7C00
24         lidt    %cs:idt_48 + 0x7C00
25
26         #
27         # Turn off PG bit in CR0 and set CR3 to zero.
28         #
29
30         movl    %cr0, %eax
31         andl    $0x7FFFFFFF, %eax
32         movl    %eax, %cr0
33
34         xorl    %eax, %eax
35         movl    %eax, %cr3
36
37         #
38         # Reload CS.
39         # Now we add 7B00h because we need to force the segment
40         # address and selector to be the same.
41         #
42
43         .byte   0xEA
44         .long   pm_reload + 0x7B00
45         .word   0x10
46
47 pm_reload:
48
49 .code16
50
51         #
52         # Reload DS, ES, FS, GS & SS.
53         #
54
55         movw    $0x18, %ax
56         movw    %ax, %ds
57         movw    %ax, %es
58         movw    %ax, %fs
59         movw    %ax, %gs
60         movw    %ax, %ss
61
62         #
63         # Switch to real mode.  Clear PE bit in CR0.
64         #
65
66         movl    %cr0, %eax
67         andl    $0xFFFFFFFE, %eax
68         movl    %eax, %cr0
69
70         #
71         # Reload CS.
72         #
73
74         .byte   0xEA
75         .word   rm_reload + 0x7C00
76         .word   0
77
78 rm_reload:
79
80         #
81         # Reload SS & SP.
82         #
83
84         xorw    %ax, %ax
85         movw    %ax, %ss
86         movw    $0x7BFE, %sp
87
88         #
89         # Start running setup.S
90         #
91
92         .byte   0xEA
93         .word   0
94         .word   0x9020
95
96         #
97         # GDT & IDT stuff for switching into real mode.
98         #
99
100 gdt:    .word   0, 0, 0, 0              # unused (00h)
101         .word   0, 0, 0, 0              # dummy (08h)
102         .word   0xFFFF, 0x100           # code (10h)
103         .word   0x9A00, 0
104         .word   0xFFFF, 0x180           # data (18h)
105         .word   0x9200, 0
106
107 gdt_48: .word   0x08 * 0x400
108         .long   gdt + 0x7C00
109
110 idt_48: .word   0x400
111         .long   0
112
113         #
114         # Be careful not to exceed 1F0h or the the bootsect.S
115         # parameters will be lost!
116         #
117
118 .end