]> git.saurik.com Git - apple/boot.git/blame - i386/libsaio/asm.s
boot-132.tar.gz
[apple/boot.git] / i386 / libsaio / asm.s
CommitLineData
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 132CR0_PE_ON = 0x1
f083c6c3 133CR0_PE_OFF = 0x7ffffff0
14c7c974 134
75b89a82
A
135STACK32_BASE = ADDR32(STACK_SEG, 0)
136STACK16_SEG = STACK_SEG
137CODE32_BASE = ADDR32(BASE_SEG, 0)
138CODE16_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
156save_sp: .long STACK_OFS
157save_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//
167LABEL(__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
192xprot:
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//
230LABEL(__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
243x16:
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
255xreal:
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//
298LABEL(_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//
307LABEL(_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//
328LABEL(__sp)
329 mov %esp, %eax
330 ret
331
332// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
75b89a82 333// Returns the current frame pointer.
14c7c974
A
334//
335LABEL(__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 347LABEL(__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 384LABEL(_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//
425LABEL(_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