xref: /reactos/boot/freeldr/freeldr/arch/amd64/entry.S (revision b524c18a)
1
2#include <asm.inc>
3#include <ksamd64.inc>
4#include <arch/pc/x86common.h>
5#include <arch/pc/pcbios.h>
6
7EXTERN BootMain:PROC
8EXTERN cmdline:DWORD
9
10EXTERN DiskStopFloppyMotor:PROC
11
12#ifdef _USE_ML
13EXTERN __bss_start__:FWORD
14EXTERN __bss_end__:FWORD
15#endif
16
17.code64
18
19PUBLIC RealEntryPoint
20RealEntryPoint:
21    /* Setup segment selectors */
22    mov ax, LMODE_DS
23    mov ds, ax
24    mov es, ax
25    mov fs, ax
26    mov gs, ax
27//    mov ss, ax
28
29    //mov word ptr [HEX(b8000)], HEX(0e00) + '1'
30
31    /* Setup long mode stack */
32    mov rsp, qword ptr [stack64]
33
34    /* Continue execution */
35    jmp qword ptr [ContinueAddress]
36
37ContinueAddress:
38    .quad FrldrStartup
39
40FrldrStartup:
41
42    /* Set up CR0 for SSE */
43    mov rax, cr0
44    and eax, not CR0_EM // Clear coprocessor emulation CR0.EM CR0.EM (bit 2)
45    or rax, CR0_MP // Set coprocessor monitoring CR0.MP (bit 1)
46    mov cr0, rax
47
48    /* Set up CR4 for SSE */
49    mov rax, cr4
50    or eax, CR4_FXSR // Enable fx save/restore CR4.OSFXSR (bit 9)
51    or eax, CR4_XMMEXCPT // Enable XMMI exceptions CR4.OSXMMEXCPT (bit 10)
52    mov cr4, rax
53
54    /* Store BootDrive and BootPartition */
55    mov al, byte ptr [BSS_BootDrive]
56    mov byte ptr [FrldrBootDrive], al
57    xor eax, eax
58    mov al, byte ptr [BSS_BootPartition]
59    mov dword ptr [FrldrBootPartition], eax
60
61    /* Patch long jump with real mode entry point */
62    mov eax, dword ptr [BSS_RealModeEntry]
63    mov dword ptr [AddressOfRealModeEntryPoint], eax
64
65    /* Clean out BSS */
66    xor rax, rax
67    mov rdi, offset __bss_start__
68    mov rcx, offset __bss_end__ + 7
69    sub rcx, rdi
70    shr rcx, 3
71    rep stosq
72
73    /* Pass the command line to BootMain */
74    mov rcx, offset cmdline
75
76    /* GO! */
77    call BootMain
78
79    /* We should never get here */
80stop:
81    jmp short stop
82    nop
83    nop
84
85
86PUBLIC Reboot
87Reboot:
88    /* Stop the floppy drive motor */
89    call DiskStopFloppyMotor
90
91    /* Set the function ID and switch to real mode (we don't return) */
92    mov bx, FNID_Reboot
93    jmp SwitchToReal
94
95
96/*
97 * VOID __cdecl Relocator16Boot(
98 *     IN REGS*  In<rcx>,
99 *     IN USHORT StackSegment<dx>,
100 *     IN USHORT StackPointer<r8w>,
101 *     IN USHORT CodeSegment<r9w>,
102 *     IN USHORT CodePointer<rsp+40>);
103 *
104 * RETURNS: Nothing.
105 *
106 * NOTE: The implementation of this function is similar to that of Int386(),
107 * with the proviso that no attempt is done to save the original values of
108 * the registers since we will not need them anyway, as we do not return back
109 * to the caller but instead place the machine in a permanent new CPU state.
110 */
111PUBLIC Relocator16Boot
112Relocator16Boot:
113
114    /* Save home registers */
115    mov qword ptr [rsp +  8], rcx
116    mov  word ptr [rsp + 16], dx
117    mov  word ptr [rsp + 24], r8w
118    mov  word ptr [rsp + 32], r9w
119
120#if 0
121    /* Save non-volatile registers */
122    push rbx
123    push rsi
124    push rdi
125#endif
126
127    /* Copy input registers */
128    mov rsi, qword ptr [rsp + 8]
129    mov rdi, BSS_RegisterSet
130    mov rcx, REGS_SIZE / 4
131    rep movsd
132
133    /* Set the stack segment/offset */
134    // Since BSS_CallbackReturn contains a ULONG, store in its high word
135    // the stack segment and in its low word the stack offset.
136    mov ax, word ptr [rsp + 16]
137    shl eax, 16
138    mov ax, word ptr [rsp + 24]
139    mov dword ptr [BSS_CallbackReturn], eax
140
141    /*
142     * Set the code segment/offset (Copy entry point)
143     * NOTE: We permanently *ERASE* the contents of ds:[BSS_RealModeEntry]
144     * but it is not a problem since we are going to place the machine in
145     * a permanent new CPU state.
146     */
147    // Since BSS_RealModeEntry contains a ULONG, store in its high word
148    // the code segment and in its low word the code offset.
149    mov ax, word ptr [rsp + 32]
150    shl eax, 16
151    mov ax, word ptr [rsp + 40]
152    mov dword ptr [BSS_RealModeEntry], eax
153
154    /* Set the function ID and switch to real mode (we don't return) */
155    mov bx, FNID_Relocator16Boot
156    jmp SwitchToReal
157
158
159/*
160 * U16 PxeCallApi(U16 Segment, U16 Offset, U16 Service, VOID *Parameter);
161 *
162 * RETURNS:
163 */
164PUBLIC PxeCallApi
165PxeCallApi:
166    xor eax, eax
167    ret
168
169
170/* Internal function for realmode calls
171 * bx must be set to the ID of the realmode function to call. */
172PUBLIC CallRealMode
173CallRealMode:
174    /* Save current stack pointer */
175    mov qword ptr [stack64], rsp
176
177    /* Set continue address and switch to real mode */
178    lea rax, [CallRealMode_return]
179    mov qword ptr [ContinueAddress], rax
180
181SwitchToReal:
182    /* Set sane segments */
183    mov ax, LMODE_DS
184    mov ds, ax
185    mov es, ax
186    mov fs, ax
187    mov gs, ax
188    //mov ss, ax
189
190    //mov word ptr [HEX(0b8008)], HEX(0e00) + '4'
191
192    /* Save 64-bit stack pointer */
193    mov qword ptr [stack64], rsp
194
195    /* Step 1 - jump to compatibility segment */
196    jmp fword ptr [jumpvector]
197
198jumpvector:
199    .long SwitchToRealCompSegment
200    .word CMODE_CS
201
202SwitchToRealCompSegment:
203    /* Note: In fact the CPU is in 32 bit mode here. But it will interpret
204       the generated instructions accordingly. rax will become eax */
205
206    /* Step 2 - deactivate long mode, by disabling paging */
207    mov rax, cr0
208    and eax, HEX(7fffffff) //~0x80000000, upper bits cleared
209    mov cr0, rax
210
211//    mov word ptr [HEX(0b800a)], HEX(0e00) + '5'
212
213    /* Step 3 - jump to 16-bit segment to set the limit correctly */
214    .byte HEX(0EA) // 32bit long jmp
215AddressOfRealModeEntryPoint:
216    .long 0 // receives address of RealModeEntryPoint
217    .word HEX(20)//RMODE_CS
218    nop
219
220CallRealMode_return:
221    /* restore stack pointer */
222    mov rsp, qword ptr [stack64]
223    ret
224
225/////////////////////////////////////////
226
227    /* 64-bit stack pointer */
228stack64:
229    .quad STACKADDR
230
231PUBLIC FrldrBootDrive
232FrldrBootDrive:
233    .byte 0
234
235PUBLIC FrldrBootPartition
236FrldrBootPartition:
237    .long 0
238
239END
240