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