26547c849dfacea5687bdac5bdf6f4c74048ce54
[reactos.git] / boot / freeldr / freeldr / arch / amd64 / entry.S
1
2 #include <asm.inc>
3 #include <arch/pc/x86common.h>
4
5 EXTERN BootMain:PROC
6 // EXTERN cmdline:DWORD
7
8 #ifdef _USE_ML
9 EXTERN __bss_start__:FWORD
10 EXTERN __bss_end__:FWORD
11 #endif
12
13 .code64
14
15 PUBLIC RealEntryPoint
16 RealEntryPoint:
17 /* Setup segment selectors */
18 mov ax, LMODE_DS
19 mov ds, ax
20 mov es, ax
21 mov fs, ax
22 mov gs, ax
23 // mov ss, ax
24
25 //mov word ptr [HEX(b8000)], HEX(0e00) + '1'
26
27 /* Setup long mode stack */
28 mov rsp, qword ptr [stack64]
29
30 /* Continue execution */
31 jmp qword ptr [ContinueAddress]
32
33 ContinueAddress:
34 .quad offset FrldrStartup
35
36 FrldrStartup:
37
38 /* Store BootDrive and BootPartition */
39 mov al, byte ptr [BSS_BootDrive]
40 mov byte ptr [FrldrBootDrive], al
41 xor eax, eax
42 mov al, byte ptr [BSS_BootPartition]
43 mov dword ptr [FrldrBootPartition], eax
44
45 /* Patch long jump with real mode entry point */
46 mov eax, dword ptr [BSS_RealModeEntry]
47 mov dword ptr [AddressOfRealModeEntryPoint], eax
48
49 /* Clean out BSS */
50 xor rax, rax
51 mov rdi, offset __bss_start__
52 mov rcx, offset __bss_end__ + 7
53 sub rcx, rdi
54 shr rcx, 3
55 rep stosq
56
57 /* Pass the command line to BootMain */
58 // mov rcx, offset cmdline
59 xor rcx, rcx
60
61 /* GO! */
62 call BootMain
63
64 /* We should never get here */
65 stop:
66 jmp short stop
67 nop
68 nop
69
70
71 PUBLIC Reboot
72 Reboot:
73 /* Set the function ID */
74 mov bx, FNID_Reboot
75
76 /* Switch to real mode (we don't return) */
77 jmp SwitchToReal
78
79
80 /*
81 * VOID __cdecl ChainLoadBiosBootSectorCode(
82 * IN UCHAR BootDrive OPTIONAL,
83 * IN ULONG BootPartition OPTIONAL);
84 *
85 * RETURNS: Nothing
86 */
87 PUBLIC ChainLoadBiosBootSectorCode
88 ChainLoadBiosBootSectorCode:
89 /* Set the boot drive */
90 mov dl, [esp + 4]
91 test dl, dl
92 jnz set_part
93 mov dl, byte ptr [FrldrBootDrive]
94
95 /* Set the boot partition */
96 set_part:
97 mov eax, [esp + 8]
98 test eax, eax
99 jnz continue
100 mov eax, dword ptr [FrldrBootPartition]
101 continue:
102 /* Store the 1-byte truncated partition number in DH */
103 mov dh, al
104
105 /* Set the function ID */
106 mov bx, FNID_ChainLoadBiosBootSectorCode
107
108 /* Switch to real mode (we don't return) */
109 jmp SwitchToReal
110
111
112 PUBLIC PxeCallApi
113 PxeCallApi:
114 xor eax, eax
115 ret
116
117
118 /* Internal function for realmode calls
119 * bx must be set to the ID of the realmode function to call. */
120 PUBLIC CallRealMode
121 CallRealMode:
122 /* Save current stack pointer */
123 mov qword ptr [stack64], rsp
124
125 /* Set continue address and switch to real mode */
126 lea rax, [CallRealMode_return]
127 mov qword ptr [ContinueAddress], rax
128
129 SwitchToReal:
130 /* Set sane segments */
131 mov ax, LMODE_DS
132 mov ds, ax
133 mov es, ax
134 mov fs, ax
135 mov gs, ax
136 //mov ss, ax
137
138 //mov word ptr [HEX(0b8008)], HEX(0e00) + '4'
139
140 /* Save 64-bit stack pointer */
141 mov qword ptr [stack64], rsp
142
143 /* Step 1 - jump to compatibility segment */
144 jmp fword ptr [jumpvector]
145
146 jumpvector:
147 .long offset SwitchToRealCompSegment
148 .word CMODE_CS
149
150 SwitchToRealCompSegment:
151 /* Note: In fact the CPU is in 32 bit mode here. But it will interprete
152 the generated instructions accordingly. rax will become eax */
153
154 /* Step 2 - deactivate long mode, by disabling paging */
155 mov rax, cr0
156 and eax, HEX(7fffffff) //~0x80000000, upper bits cleared
157 mov cr0, rax
158
159 // mov word ptr [HEX(0b800a)], HEX(0e00) + '5'
160
161 /* Step 3 - jump to 16-bit segment to set the limit correctly */
162 .byte HEX(0EA) // 32bit long jmp
163 AddressOfRealModeEntryPoint:
164 .long 0 // receives address of RealModeEntryPoint
165 .word HEX(20)//RMODE_CS
166 nop
167
168 CallRealMode_return:
169 /* restore stack pointer */
170 mov rsp, qword ptr [stack64]
171 ret
172
173 /////////////////////////////////////////
174
175
176 //void __lgdt(void *Source);
177 PUBLIC __lgdt
178 __lgdt:
179 lgdt fword ptr [rcx]
180 ret
181
182 //void __ltr(unsigned short Source);
183 PUBLIC __ltr
184 __ltr:
185 ltr cx
186 ret
187
188
189 /* 64-bit stack pointer */
190 stack64:
191 .quad STACKADDR
192
193 PUBLIC FrldrBootDrive
194 FrldrBootDrive:
195 .byte 0
196
197 PUBLIC FrldrBootPartition
198 FrldrBootPartition:
199 .long 0
200
201 END