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