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