]>
Commit | Line | Data |
---|---|---|
14c7c974 | 1 | /* |
57c72a9a | 2 | * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. |
14c7c974 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
57c72a9a | 6 | * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights |
4f6e3300 A |
7 | * Reserved. This file contains Original Code and/or Modifications of |
8 | * Original Code as defined in and that are subject to the Apple Public | |
57c72a9a | 9 | * Source License Version 2.0 (the "License"). You may not use this file |
4f6e3300 A |
10 | * except in compliance with the License. Please obtain a copy of the |
11 | * License at http://www.apple.com/publicsource and read it before using | |
12 | * this file. | |
14c7c974 A |
13 | * |
14 | * The Original Code and all software distributed under the License are | |
4f6e3300 | 15 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
14c7c974 A |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
4f6e3300 A |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the |
19 | * License for the specific language governing rights and limitations | |
20 | * under the License. | |
14c7c974 A |
21 | * |
22 | * @APPLE_LICENSE_HEADER_END@ | |
23 | */ | |
24 | /* | |
25 | * Mach Operating System | |
26 | * Copyright (c) 1990 Carnegie-Mellon University | |
27 | * Copyright (c) 1989 Carnegie-Mellon University | |
28 | * All rights reserved. The CMU software License Agreement specifies | |
29 | * the terms and conditions for use and redistribution. | |
30 | */ | |
31 | /* | |
32 | * HISTORY | |
33 | * $Log: asm.s,v $ | |
bba600dd A |
34 | * Revision 1.8 2005/06/24 22:47:12 curtisg |
35 | * Merging changes for 4159531 to pass data to the kernel in EFI format. | |
36 | * | |
57c72a9a A |
37 | * Revision 1.7 2004/05/13 17:58:38 curtisg |
38 | * Integrating: | |
39 | * <rdar://problem/3094680>: (Silent boot) | |
40 | * <rdar://problem/3363893>: (5 sec boot timeout is too short) | |
41 | * <rdar://problem/3533781>: (Boot option to display graphics modes) | |
42 | * <rdar://problem/3545539>: (Default graphics mode should be 32-bit) | |
43 | * <rdar://problem/3643065>: (Booter should always find a video mode) | |
44 | * <rdar://problem/3643815>: (Booter displays "0MB" VRAM) | |
45 | * | |
46 | * Revision 1.6 2003/11/05 20:51:02 curtisg | |
47 | * Integrated 3069695,3331770,3370488,3371823 | |
48 | * | |
49 | * Revision 1.5.26.1 2003/10/27 23:57:59 curtisg | |
50 | * Added printing of volume names, better handling of extended | |
51 | * partitions, and updated Apple license strings. | |
52 | * New chain booter should work better with foreign operating | |
53 | * systems. | |
54 | * | |
f083c6c3 A |
55 | * Revision 1.5 2002/11/05 20:34:26 jliu |
56 | * Integrating: | |
57 | * 3051234 boot shouldnt require Graphics = Yes | |
58 | * 3091627 Need support for refresh rate adjustment | |
59 | * | |
60 | * Revision 1.4 2002/10/02 00:06:18 curtisg | |
61 | * Integrating PR-3032510. | |
62 | * | |
63 | * Revision 1.3.6.1 2002/08/30 21:16:29 curtisg | |
64 | * KERNBOOTSTRUCT is going away in favor of KernelBootArgs_t in <pexpert/i386/boot.h>. | |
65 | * | |
75b89a82 A |
66 | * Revision 1.3 2002/07/09 14:06:21 jliu |
67 | * Merging changes from PR-2954224 branch in boot/i386. | |
68 | * | |
69 | * Revision 1.2.30.1 2002/07/05 16:24:51 jliu | |
70 | * Merged UFS/HFS/HFS+ filesystem support from BootX. | |
71 | * Moved boot2 load address due to increased size. boot0/boot1 also changed. | |
72 | * Updated boot graphics and CLUT. | |
73 | * Added support to chain load foreign booters. | |
74 | * Fixed param passing bug in network loader. | |
75 | * Misc cleanup in libsaio. | |
76 | * | |
14c7c974 A |
77 | * Revision 1.2 2000/05/23 23:01:11 lindak |
78 | * Merged PR-2309530 into Kodiak (liu i386 booter: does not support label-less | |
79 | * ufs partitions) | |
80 | * | |
81 | * Revision 1.1.1.2.4.1 2000/05/13 17:07:39 jliu | |
82 | * New boot0 (boot1 has been deprecated). Booter must now reside in its own partition, no disk label required. | |
83 | * | |
84 | * Revision 1.1.1.2 1999/08/04 21:16:57 wsanchez | |
85 | * Impoort of boot-66 | |
86 | * | |
87 | * Revision 1.3 1999/08/04 21:12:12 wsanchez | |
88 | * Update APSL | |
89 | * | |
90 | * Revision 1.2 1999/03/25 05:48:30 wsanchez | |
91 | * Add APL. | |
92 | * Remove unused gzip code. | |
93 | * Remove unused Adobe fonts. | |
94 | * | |
95 | * Revision 1.1.1.1.66.2 1999/03/16 16:08:54 wsanchez | |
96 | * Substitute License | |
97 | * | |
98 | * Revision 1.1.1.1.66.1 1999/03/16 07:33:21 wsanchez | |
99 | * Add APL | |
100 | * | |
101 | * Revision 1.1.1.1 1997/12/05 21:57:57 wsanchez | |
102 | * Import of boot-25 (~mwatson) | |
103 | * | |
104 | * Revision 2.1.1.2 90//03//22 17:59:50 rvb | |
75b89a82 | 105 | * Added _sp() => where is the stack at. [kupfer] |
14c7c974 A |
106 | * |
107 | * Revision 2.1.1.1 90//02//09 17:25:04 rvb | |
75b89a82 A |
108 | * Add Intel copyright |
109 | * [90//02//09 rvb] | |
14c7c974 A |
110 | * |
111 | */ | |
112 | ||
113 | ||
114 | // INTEL CORPORATION PROPRIETARY INFORMATION | |
115 | // | |
116 | // This software is supplied under the terms of a license agreement or | |
117 | // nondisclosure agreement with Intel Corporation and may not be copied | |
118 | // nor disclosed except in accordance with the terms of that agreement. | |
119 | // | |
120 | // Copyright 1988 Intel Corporation | |
121 | // Copyright 1988, 1989 by Intel Corporation | |
122 | // | |
123 | ||
124 | #include <architecture/i386/asm_help.h> | |
125 | #include "memory.h" | |
126 | ||
127 | #define data32 .byte 0x66 | |
128 | #define addr32 .byte 0x67 | |
129 | ||
130 | .file "asm.s" | |
131 | ||
75b89a82 | 132 | CR0_PE_ON = 0x1 |
f083c6c3 | 133 | CR0_PE_OFF = 0x7ffffff0 |
14c7c974 | 134 | |
75b89a82 A |
135 | STACK32_BASE = ADDR32(STACK_SEG, 0) |
136 | STACK16_SEG = STACK_SEG | |
137 | CODE32_BASE = ADDR32(BASE_SEG, 0) | |
138 | CODE16_SEG = BASE_SEG | |
139 | ||
140 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
141 | // Pointer to 6-bytes in memory that contains the base address and the limit | |
142 | // (size of GDT table in bytes) of the GDT. The LGDT is the only instruction | |
143 | // that directly loads a linear address (not a segment relative address) and | |
144 | // a limit in protected mode. | |
14c7c974 A |
145 | |
146 | .globl _Gdtr | |
147 | .data | |
75b89a82 | 148 | .align 2, 0x90 |
14c7c974 | 149 | _Gdtr: |
75b89a82 | 150 | .word GDTLIMIT |
14c7c974 A |
151 | .long vtop(_Gdt) |
152 | ||
153 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
154 | // Data area for __switch_stack. | |
155 | // | |
75b89a82 A |
156 | save_sp: .long STACK_OFS |
157 | save_ss: .long STACK_SEG | |
14c7c974 A |
158 | |
159 | .text | |
160 | ||
161 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
162 | // real_to_prot() | |
75b89a82 A |
163 | // |
164 | // Transfer from real mode to protected mode. | |
165 | // Preserves all registers except EAX. | |
14c7c974 A |
166 | // |
167 | LABEL(__real_to_prot) | |
75b89a82 A |
168 | |
169 | // Interrupts are disabled in protected mode. | |
170 | ||
14c7c974 A |
171 | cli |
172 | ||
75b89a82 A |
173 | // Load the Global Descriptor Table Register (GDTR). |
174 | ||
175 | addr32 | |
14c7c974 | 176 | data32 |
75b89a82 | 177 | lgdt OFFSET16(_Gdtr) |
14c7c974 | 178 | |
75b89a82 | 179 | // Enter protected mode by setting the PE bit in CR0. |
14c7c974 A |
180 | |
181 | mov %cr0, %eax | |
182 | data32 | |
183 | or $CR0_PE_ON, %eax | |
75b89a82 | 184 | mov %eax, %cr0 |
14c7c974 | 185 | |
75b89a82 A |
186 | // Make intrasegment jump to flush the processor pipeline and |
187 | // reload CS register. | |
14c7c974 A |
188 | |
189 | data32 | |
190 | ljmp $0x08, $xprot | |
191 | ||
192 | xprot: | |
193 | // we are in USE32 mode now | |
75b89a82 | 194 | // set up the protected mode segment registers : DS, SS, ES, FS, GS |
14c7c974 A |
195 | |
196 | mov $0x10, %eax | |
197 | movw %ax, %ds | |
198 | movw %ax, %ss | |
199 | movw %ax, %es | |
75b89a82 A |
200 | movw %ax, %fs |
201 | movw %ax, %gs | |
202 | ||
203 | // Convert STACK_SEG:SP to 32-bit linear stack pointer. | |
14c7c974 | 204 | |
75b89a82 A |
205 | movzwl %sp, %eax |
206 | addl $STACK32_BASE, %eax | |
14c7c974 A |
207 | movl %eax, %esp |
208 | ||
75b89a82 A |
209 | // Convert STACK_SEG:BP to 32-bit linear base pointer. |
210 | ||
211 | movzwl %bp, %eax | |
212 | addl $STACK32_BASE, %eax | |
213 | movl %eax, %ebp | |
214 | ||
215 | // Modify the caller's return address on the stack from | |
216 | // segment offset to linear address. | |
217 | ||
218 | popl %eax | |
219 | addl $CODE32_BASE, %eax | |
220 | pushl %eax | |
221 | ||
14c7c974 A |
222 | ret |
223 | ||
224 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
225 | // prot_to_real() | |
75b89a82 A |
226 | // |
227 | // Transfer from protected mode to real mode. | |
228 | // Preserves all registers except EAX. | |
14c7c974 A |
229 | // |
230 | LABEL(__prot_to_real) | |
231 | ||
75b89a82 A |
232 | // Set up segment registers appropriate for real mode. |
233 | ||
234 | movw $0x30, %ax | |
235 | movw %ax, %ds | |
236 | movw %ax, %es | |
237 | movw %ax, %fs | |
238 | movw %ax, %gs | |
239 | movw %ax, %ss | |
240 | ||
14c7c974 A |
241 | ljmp $0x18, $x16 // change to USE16 mode |
242 | ||
243 | x16: | |
244 | mov %cr0, %eax // clear the PE bit of CR0 | |
245 | data32 | |
246 | and $CR0_PE_OFF, %eax | |
247 | mov %eax, %cr0 | |
248 | ||
249 | // make intersegment jmp to flush the processor pipeline | |
250 | // and reload CS register | |
251 | ||
252 | data32 | |
75b89a82 | 253 | ljmp $CODE16_SEG, $xreal - CODE32_BASE |
14c7c974 A |
254 | |
255 | xreal: | |
256 | // we are in real mode now | |
75b89a82 | 257 | // set up the real mode segment registers : DS, DS, ES, FS, GS |
14c7c974 A |
258 | |
259 | movw %cs, %ax | |
260 | movw %ax, %ds | |
14c7c974 | 261 | movw %ax, %es |
75b89a82 A |
262 | movw %ax, %fs |
263 | movw %ax, %gs | |
264 | ||
265 | // load stack segment register SS. | |
14c7c974 A |
266 | |
267 | data32 | |
75b89a82 A |
268 | movl $STACK16_SEG, %eax |
269 | movw %ax, %ss | |
14c7c974 | 270 | |
75b89a82 | 271 | // clear top 16-bits of ESP and EBP. |
14c7c974 | 272 | |
75b89a82 A |
273 | data32 |
274 | movzwl %sp, %esp | |
275 | data32 | |
276 | movzwl %bp, %ebp | |
14c7c974 | 277 | |
75b89a82 A |
278 | // Modify caller's return address on the stack |
279 | // from linear address to segment offset. | |
14c7c974 | 280 | |
75b89a82 A |
281 | data32 |
282 | popl %eax | |
283 | data32 | |
284 | movzwl %ax, %eax | |
285 | data32 | |
286 | pushl %eax | |
14c7c974 | 287 | |
75b89a82 | 288 | // Reenable maskable interrupts. |
14c7c974 | 289 | |
75b89a82 | 290 | sti |
14c7c974 | 291 | |
75b89a82 | 292 | data32 |
14c7c974 A |
293 | ret |
294 | ||
14c7c974 A |
295 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
296 | // halt() | |
297 | // | |
298 | LABEL(_halt) | |
bba600dd | 299 | call _bgetc |
14c7c974 A |
300 | jmp _halt |
301 | ||
302 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
f083c6c3 | 303 | // startprog(phyaddr, arg) |
75b89a82 | 304 | // Start the program on protected mode where phyaddr is the entry point. |
f083c6c3 | 305 | // Passes arg to the program in %eax. |
14c7c974 A |
306 | // |
307 | LABEL(_startprog) | |
308 | push %ebp | |
309 | mov %esp, %ebp | |
310 | ||
f083c6c3 | 311 | mov 0xc(%ebp), %eax // argument to program |
75b89a82 A |
312 | mov 0x8(%ebp), %ecx // entry offset |
313 | mov $0x28, %ebx // segment | |
14c7c974 A |
314 | push %ebx |
315 | push %ecx | |
316 | ||
317 | // set up %ds and %es | |
318 | ||
319 | mov $0x20, %ebx | |
320 | movw %bx, %ds | |
321 | movw %bx, %es | |
322 | ||
323 | lret | |
324 | ||
325 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
326 | // Returns the current stack pointer. | |
327 | // | |
328 | LABEL(__sp) | |
329 | mov %esp, %eax | |
330 | ret | |
331 | ||
332 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
75b89a82 | 333 | // Returns the current frame pointer. |
14c7c974 A |
334 | // |
335 | LABEL(__bp) | |
336 | mov %ebp, %eax | |
337 | ret | |
338 | ||
75b89a82 A |
339 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
340 | // switch_stack() | |
341 | // | |
342 | // Switches stack pointer between SS:SP and memory save_ss:save_sp. | |
343 | // Call this function from real mode only!!! | |
344 | // | |
345 | // AX, DI, and SI are clobbered. | |
346 | // | |
14c7c974 | 347 | LABEL(__switch_stack) |
75b89a82 A |
348 | popl %eax # save return address |
349 | popl %edi # discard upper 16-bit | |
350 | ||
351 | data32 | |
352 | addr32 | |
353 | movl OFFSET16(save_ss), %esi # new SS to SI | |
354 | ||
355 | data32 | |
356 | addr32 | |
357 | movl OFFSET16(save_sp), %edi # new SP to DI | |
358 | ||
359 | addr32 | |
360 | mov %ss, OFFSET16(save_ss) # save current SS to memory | |
361 | ||
362 | data32 | |
363 | addr32 | |
364 | movl %esp, OFFSET16(save_sp) # save current SP to memory | |
365 | ||
366 | cli | |
367 | mov %si, %ss # switch stack | |
368 | mov %di, %sp | |
369 | sti | |
370 | ||
371 | pushl %eax # push IP of caller onto the new stack | |
372 | ||
373 | xorl %eax, %eax | |
374 | xorl %esi, %esi | |
375 | xorl %edi, %edi | |
376 | ||
377 | ret | |
378 | ||
379 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
380 | // loader() | |
381 | // | |
382 | // Issue a request to the network loader. | |
383 | // | |
14c7c974 | 384 | LABEL(_loader) |
75b89a82 A |
385 | enter $0, $0 |
386 | pushal | |
387 | ||
388 | # | |
389 | # Pass a far pointer to the command structure | |
390 | # to the INT call through DX:CX. | |
391 | # | |
392 | # The command code is in BX. | |
393 | # | |
394 | ||
395 | movw 8(%ebp), %bx # 8[EBP] = command code | |
396 | movw 12(%ebp), %cx # 12[EBP] = command structure offset | |
397 | movw 14(%ebp), %dx # 14[EBP] = command structure segment | |
14c7c974 | 398 | |
75b89a82 | 399 | call __prot_to_real # Revert to real mode |
14c7c974 | 400 | |
75b89a82 | 401 | ###### Real Mode Begin ###### |
14c7c974 | 402 | |
75b89a82 A |
403 | data32 |
404 | call __switch_stack # Switch to NBP stack | |
14c7c974 | 405 | |
75b89a82 | 406 | int $0x2b # Call NBP |
14c7c974 | 407 | |
75b89a82 A |
408 | data32 |
409 | call __switch_stack # Restore stack | |
14c7c974 | 410 | |
75b89a82 A |
411 | data32 |
412 | call __real_to_prot # Back to protected mode | |
14c7c974 | 413 | |
75b89a82 | 414 | ###### Real Mode End ###### |
14c7c974 | 415 | |
75b89a82 A |
416 | popal |
417 | leave | |
418 | ret | |
14c7c974 | 419 | |
57c72a9a | 420 | #if UNUSED |
14c7c974 A |
421 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
422 | // pcpy(src, dst, cnt) | |
423 | // where src is a virtual address and dst is a physical address | |
424 | // | |
425 | LABEL(_pcpy) | |
426 | push %ebp | |
427 | mov %esp, %ebp | |
428 | push %es | |
429 | push %esi | |
430 | push %edi | |
431 | push %ecx | |
432 | ||
433 | cld | |
434 | ||
435 | // set %es to point at the flat segment | |
436 | ||
437 | mov $0x20, %eax | |
438 | movw %ax , %es | |
439 | ||
440 | mov 0x8(%ebp), %esi // source | |
441 | mov 0xc(%ebp), %edi // destination | |
442 | mov 0x10(%ebp), %ecx // count | |
443 | ||
444 | rep | |
445 | movsb | |
446 | ||
447 | pop %ecx | |
448 | pop %edi | |
449 | pop %esi | |
450 | pop %es | |
451 | pop %ebp | |
452 | ||
453 | ret | |
454 | #endif |