]>
Commit | Line | Data |
---|---|---|
14c7c974 A |
1 | /* |
2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * Portions Copyright (c) 1999 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.1 (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 2000/05/23 23:01:11 lindak | |
35 | * Merged PR-2309530 into Kodiak (liu i386 booter: does not support label-less | |
36 | * ufs partitions) | |
37 | * | |
38 | * Revision 1.1.1.2.4.1 2000/05/13 17:07:39 jliu | |
39 | * New boot0 (boot1 has been deprecated). Booter must now reside in its own partition, no disk label required. | |
40 | * | |
41 | * Revision 1.1.1.2 1999/08/04 21:16:57 wsanchez | |
42 | * Impoort of boot-66 | |
43 | * | |
44 | * Revision 1.3 1999/08/04 21:12:12 wsanchez | |
45 | * Update APSL | |
46 | * | |
47 | * Revision 1.2 1999/03/25 05:48:30 wsanchez | |
48 | * Add APL. | |
49 | * Remove unused gzip code. | |
50 | * Remove unused Adobe fonts. | |
51 | * | |
52 | * Revision 1.1.1.1.66.2 1999/03/16 16:08:54 wsanchez | |
53 | * Substitute License | |
54 | * | |
55 | * Revision 1.1.1.1.66.1 1999/03/16 07:33:21 wsanchez | |
56 | * Add APL | |
57 | * | |
58 | * Revision 1.1.1.1 1997/12/05 21:57:57 wsanchez | |
59 | * Import of boot-25 (~mwatson) | |
60 | * | |
61 | * Revision 2.1.1.2 90//03//22 17:59:50 rvb | |
62 | * Added _sp() => where is the stack at. [kupfer] | |
63 | * | |
64 | * Revision 2.1.1.1 90//02//09 17:25:04 rvb | |
65 | * Add Intel copyright | |
66 | * [90//02//09 rvb] | |
67 | * | |
68 | */ | |
69 | ||
70 | ||
71 | // INTEL CORPORATION PROPRIETARY INFORMATION | |
72 | // | |
73 | // This software is supplied under the terms of a license agreement or | |
74 | // nondisclosure agreement with Intel Corporation and may not be copied | |
75 | // nor disclosed except in accordance with the terms of that agreement. | |
76 | // | |
77 | // Copyright 1988 Intel Corporation | |
78 | // Copyright 1988, 1989 by Intel Corporation | |
79 | // | |
80 | ||
81 | #include <architecture/i386/asm_help.h> | |
82 | #include "memory.h" | |
83 | ||
84 | #define data32 .byte 0x66 | |
85 | #define addr32 .byte 0x67 | |
86 | ||
87 | .file "asm.s" | |
88 | ||
89 | BOOTSEG = BASE_SEG | |
90 | ||
91 | CR0_PE_ON = 0x1 | |
92 | CR0_PE_OFF = 0xfffffffe | |
93 | ||
94 | .globl _Gdtr | |
95 | .data | |
96 | .align 2,0x90 | |
97 | _Gdtr: | |
98 | .word 0x2F | |
99 | // .long _Gdt+4096 | |
100 | .long vtop(_Gdt) | |
101 | ||
102 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
103 | // Data area for __switch_stack. | |
104 | // | |
105 | save_sp: .long STACK_ADDR | |
106 | save_ss: .long 0 | |
107 | ||
108 | ||
109 | .text | |
110 | ||
111 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
112 | // real_to_prot() | |
113 | // transfer from real mode to protected mode. | |
114 | // preserves all registers except eax | |
115 | // | |
116 | LABEL(__real_to_prot) | |
117 | // guarantee that interrupt is disabled when in prot mode | |
118 | cli | |
119 | ||
120 | addr32 // load the gdtr | |
121 | data32 | |
122 | lgdt _Gdtr | |
123 | ||
124 | // set the PE bit of CR0 to go to protected mode | |
125 | ||
126 | mov %cr0, %eax | |
127 | data32 | |
128 | or $CR0_PE_ON, %eax | |
129 | mov %eax, %cr0 | |
130 | ||
131 | // make intrasegment jump to flush the processor pipeline and | |
132 | // reload CS register | |
133 | ||
134 | data32 | |
135 | ljmp $0x08, $xprot | |
136 | ||
137 | xprot: | |
138 | // we are in USE32 mode now | |
139 | // set up the protected mode segment registers : DS, SS, ES | |
140 | ||
141 | mov $0x10, %eax | |
142 | movw %ax, %ds | |
143 | movw %ax, %ss | |
144 | movw %ax, %es | |
145 | ||
146 | xorl %eax, %eax // clear garbage from upper word of esp | |
147 | movw %sp, %ax | |
148 | movl %eax, %esp | |
149 | ||
150 | ret | |
151 | ||
152 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
153 | // prot_to_real() | |
154 | // transfer from protected mode to real mode | |
155 | // preserves all registers except eax | |
156 | // | |
157 | LABEL(__prot_to_real) | |
158 | ||
159 | ljmp $0x18, $x16 // change to USE16 mode | |
160 | ||
161 | x16: | |
162 | mov %cr0, %eax // clear the PE bit of CR0 | |
163 | data32 | |
164 | and $CR0_PE_OFF, %eax | |
165 | mov %eax, %cr0 | |
166 | ||
167 | // make intersegment jmp to flush the processor pipeline | |
168 | // and reload CS register | |
169 | ||
170 | data32 | |
171 | ljmp $BOOTSEG, $xreal | |
172 | ||
173 | xreal: | |
174 | // we are in real mode now | |
175 | // set up the real mode segment registers : DS, SS, ES | |
176 | ||
177 | movw %cs, %ax | |
178 | movw %ax, %ds | |
179 | movw %ax, %ss | |
180 | movw %ax, %es | |
181 | ||
182 | data32 | |
183 | ret | |
184 | ||
185 | #if defined(DEFINE_INLINE_FUNCTIONS) | |
186 | ||
187 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
188 | // outb(port, byte) | |
189 | // | |
190 | LABEL(_outb) | |
191 | push %ebp | |
192 | mov %esp, %ebp | |
193 | push %edx | |
194 | ||
195 | movw 8(%ebp), %dx | |
196 | movb 12(%ebp), %al | |
197 | outb %al, %dx | |
198 | ||
199 | pop %edx | |
200 | pop %ebp | |
201 | ret | |
202 | ||
203 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
204 | // inb(port) | |
205 | // | |
206 | LABEL(_inb) | |
207 | push %ebp | |
208 | mov %esp, %ebp | |
209 | push %edx | |
210 | ||
211 | movw 8(%ebp), %dx | |
212 | subw %ax, %ax | |
213 | inb %dx, %al | |
214 | ||
215 | pop %edx | |
216 | pop %ebp | |
217 | ret | |
218 | ||
219 | #endif /* DEFINE_INLINE_FUNCTIONS */ | |
220 | ||
221 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
222 | // halt() | |
223 | // | |
224 | LABEL(_halt) | |
225 | // call _getchar | |
226 | hlt | |
227 | jmp _halt | |
228 | ||
229 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
230 | // startprog(phyaddr) | |
231 | // Start the program on protected mode where phyaddr is the entry point | |
232 | // | |
233 | LABEL(_startprog) | |
234 | push %ebp | |
235 | mov %esp, %ebp | |
236 | ||
237 | mov 0x8(%ebp), %ecx // entry offset | |
238 | mov $0x28, %ebx // segment | |
239 | push %ebx | |
240 | push %ecx | |
241 | ||
242 | // set up %ds and %es | |
243 | ||
244 | mov $0x20, %ebx | |
245 | movw %bx, %ds | |
246 | movw %bx, %es | |
247 | ||
248 | lret | |
249 | ||
250 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
251 | // Returns the current stack pointer. | |
252 | // | |
253 | LABEL(__sp) | |
254 | mov %esp, %eax | |
255 | ret | |
256 | ||
257 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
258 | // Returns the current stack pointer. | |
259 | // | |
260 | LABEL(__bp) | |
261 | mov %ebp, %eax | |
262 | ret | |
263 | ||
264 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
265 | # Switch stack. | |
266 | # Switches between registers SS:SP and memory save_ss:save_sp. | |
267 | # Call this function from real mode only!!! | |
268 | # | |
269 | # AX, DI, and SI are modified. | |
270 | # | |
271 | LABEL(__switch_stack) | |
272 | popl %eax # save return address | |
273 | popl %edi # discard upper 16-bit | |
274 | ||
275 | data32 | |
276 | addr32 | |
277 | movl save_ss, %esi # copy new SS to ESI | |
278 | ||
279 | data32 | |
280 | addr32 | |
281 | movl save_sp, %edi # copy new SP to EDI | |
282 | ||
283 | addr32 | |
284 | mov %ss, save_ss # save current SS | |
285 | ||
286 | data32 | |
287 | addr32 | |
288 | movl %esp, save_sp # Save current SP | |
289 | ||
290 | cli | |
291 | mov %si, %ss # Perform stack switch | |
292 | mov %di, %sp | |
293 | sti | |
294 | ||
295 | pushl %eax # push IP of caller onto the new stack | |
296 | ||
297 | xorl %eax, %eax | |
298 | xorl %esi, %esi | |
299 | xorl %edi, %edi | |
300 | ||
301 | ret | |
302 | ||
303 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
304 | # Issue a request to the network loader. | |
305 | # | |
306 | LABEL(_loader) | |
307 | enter $0, $0 | |
308 | pushal | |
309 | ||
310 | # | |
311 | # Pass a far pointer to the command structure | |
312 | # to the INT call through DI:CX. | |
313 | # | |
314 | # The command code is in BX. | |
315 | # | |
316 | ||
317 | movw 8(%ebp), %bx # 8[EBP] = command code | |
318 | movw 12(%ebp), %cx # 12[EBP] = command structure offset | |
319 | movw 14(%ebp), %di # 14[EBP] = command structure segment | |
320 | ||
321 | call __prot_to_real # Revert to real mode | |
322 | ||
323 | ###### Real Mode Begin ###### | |
324 | ||
325 | data32 | |
326 | call __switch_stack # Switch to NBP stack | |
327 | ||
328 | int $0x2b # Call NBP | |
329 | ||
330 | data32 | |
331 | call __switch_stack # Restore stack | |
332 | ||
333 | data32 | |
334 | call __real_to_prot # Back to protected mode | |
335 | ||
336 | ###### Real Mode End ###### | |
337 | ||
338 | popal | |
339 | leave | |
340 | ret | |
341 | ||
342 | #if 0 | |
343 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
344 | // pcpy(src, dst, cnt) | |
345 | // where src is a virtual address and dst is a physical address | |
346 | // | |
347 | LABEL(_pcpy) | |
348 | push %ebp | |
349 | mov %esp, %ebp | |
350 | push %es | |
351 | push %esi | |
352 | push %edi | |
353 | push %ecx | |
354 | ||
355 | cld | |
356 | ||
357 | // set %es to point at the flat segment | |
358 | ||
359 | mov $0x20, %eax | |
360 | movw %ax , %es | |
361 | ||
362 | mov 0x8(%ebp), %esi // source | |
363 | mov 0xc(%ebp), %edi // destination | |
364 | mov 0x10(%ebp), %ecx // count | |
365 | ||
366 | rep | |
367 | movsb | |
368 | ||
369 | pop %ecx | |
370 | pop %edi | |
371 | pop %esi | |
372 | pop %es | |
373 | pop %ebp | |
374 | ||
375 | ret | |
376 | #endif |