Synchronize with trunk's revision r57652.
[reactos.git] / boot / freeldr / freeldr / arch / amd64 / entry.S
1
2
3 #include <asm.inc>
4 #include <arch/pc/x86common.h>
5
6 EXTERN BootMain:PROC
7
8 .code64
9
10 PUBLIC RealEntryPoint
11 RealEntryPoint:
12 /* Setup segment selectors */
13 mov ax, LMODE_DS
14 mov ds, ax
15 mov es, ax
16 mov fs, ax
17 mov gs, ax
18 // mov ss, ax
19
20 //mov word ptr [HEX(b8000)], HEX(0e00) + '1'
21
22 /* Setup long mode stack */
23 mov rsp, qword ptr [stack64]
24
25 /* Continue execution */
26 jmp qword ptr [ContinueAddress]
27
28 ContinueAddress:
29 .double offset FrldrStartup
30
31 FrldrStartup:
32
33 /* Store BootDrive and BootPartition */
34 mov al, byte ptr [BSS_BootDrive]
35 mov byte ptr [FrldrBootDrive], al
36 xor eax, eax
37 mov al, byte ptr [BSS_BootPartition]
38 mov dword ptr [FrldrBootPartition], eax
39
40 /* Patch long jump with real mode entry point */
41 mov eax, dword ptr [BSS_RealModeEntry]
42 mov dword ptr [AddressOfRealModeEntryPoint], eax
43
44 /* GO! */
45 xor rcx, rcx
46 call BootMain
47
48 /* We should never get here */
49 stop:
50 jmp stop
51 nop
52 nop
53
54
55 /* Internal function for realmode calls
56 * bx must be set to the ID of the realmode function to call. */
57 PUBLIC CallRealMode
58 CallRealMode:
59 /* Save current stack pointer */
60 mov qword ptr [stack64], rsp
61
62 /* Set continue address and switch to real mode */
63 lea rax, [CallRealMode_return]
64 mov qword ptr [ContinueAddress], rax
65
66 SwitchToReal:
67 /* Set sane segments */
68 mov ax, LMODE_DS
69 mov ds, ax
70 mov es, ax
71 mov fs, ax
72 mov gs, ax
73 //mov ss, ax
74
75 //mov word ptr [HEX(0b8008)], HEX(0e00) + '4'
76
77 /* Save 64-bit stack pointer */
78 mov qword ptr [stack64], rsp
79
80 /* Step 1 - jump to compatibility segment */
81 jmp fword ptr [jumpvector]
82
83 jumpvector:
84 .long offset SwitchToRealCompSegment
85 .word CMODE_CS
86
87 SwitchToRealCompSegment:
88 /* Note: In fact the CPU is in 32 bit mode here. But it will interprete
89 the generated instructions accordingly. rax will become eax */
90
91 /* Step 2 - deactivate long mode, by disabling paging */
92 mov rax, cr0
93 and eax, HEX(7fffffff) //~0x80000000, upper bits cleared
94 mov cr0, rax
95
96 // mov word ptr [HEX(0b800a)], HEX(0e00) + '5'
97
98 /* Step 3 - jump to 16-bit segment to set the limit correctly */
99 .byte HEX(0EA) // 32bit long jmp
100 AddressOfRealModeEntryPoint:
101 .long 0 // receives address of RealModeEntryPoint
102 .word HEX(20)//RMODE_CS
103 nop
104
105 CallRealMode_return:
106 /* restore stack pointer */
107 mov rsp, qword ptr [stack64]
108 ret
109
110 /////////////////////////////////////////
111
112
113 /* 64-bit stack pointer */
114 stack64:
115 .double STACK64ADDR
116
117 PUBLIC FrldrBootDrive
118 FrldrBootDrive:
119 .byte 0
120
121 PUBLIC FrldrBootPartition
122 FrldrBootPartition:
123 .long 0
124
125 PUBLIC PxeCallApi
126 PxeCallApi:
127 xor eax, eax
128 ret
129
130 //void __lgdt(void *Source);
131 PUBLIC __lgdt
132 __lgdt:
133 lgdt fword ptr [rcx]
134 ret
135
136 //void __ltr(unsigned short Source);
137 PUBLIC __ltr
138 __ltr:
139 ltr cx
140 ret
141
142
143 END