This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / sys / i386 / boot / asm.S
CommitLineData
a27f4645
RM
1/*
2 * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
3 *
4 * Mach Operating System
5 * Copyright (c) 1992, 1991 Carnegie Mellon University
6 * All Rights Reserved.
7 *
8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
13 *
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 *
18 * Carnegie Mellon requests users of this software to return to
19 *
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
24 *
25 * any improvements or extensions that they make and grant Carnegie Mellon
26 * the rights to redistribute these changes.
27 */
28
29/*
30 * HISTORY
31 * $Log: asm.S,v $
32Revision 1.2 1993/07/11 12:02:19 andrew
33Fixes from bde, including support for loading @ any MB boundary (e.g. a
34kernel linked for 0xfe100000 will load at the 1MB mark) and read-ahead
35buffering to speed booting from floppies. Also works with aha174x
36controllers in enhanced mode.
37
38 *
39 * 93/06/28 bde
40 * Switch IDT for debugger.
41 *
42 * Change all addr16's to addr32's and all data16's to data32's.
43 *
44 * 93/06/26 bde
45 * Avoid "pushw $xreal". Gas botches it even for 32-bit mode.
46 *
47Revision 1.1 1993/03/21 18:08:21 cgd
48after 0.2.2 "stable" patches applied
49
50 * Revision 2.2 92/04/04 11:34:13 rpd
51 * Fix Intel Copyright as per B. Davies authorization.
52 * [92/04/03 rvb]
53 * From 2.5 boot: pruned inb(), outb(), and pzero().
54 * [92/03/30 rvb]
55 *
56 * Revision 2.2 91/04/02 14:35:10 mbj
57 * Added _sp() => where is the stack at. [kupfer]
58 * Add Intel copyright
59 * [90/02/09 rvb]
60 *
61 */
62
63/*
64 Copyright 1988, 1989, 1990, 1991, 1992
65 by Intel Corporation, Santa Clara, California.
66
67 All Rights Reserved
68
69Permission to use, copy, modify, and distribute this software and
70its documentation for any purpose and without fee is hereby
71granted, provided that the above copyright notice appears in all
72copies and that both the copyright notice and this permission notice
73appear in supporting documentation, and that the name of Intel
74not be used in advertising or publicity pertaining to distribution
75of the software without specific, written prior permission.
76
77INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
78INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
79IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
80CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
81LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
82NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
83WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
84*/
85
86 .file "asm.s"
87
88#include "asm.h"
89
90
91CR0_PE_ON = 0x1
92CR0_PE_OFF = 0xfffffffe
93
94.globl _ouraddr
95 .text
96
97/*
98#
99# real_to_prot()
100# transfer from real mode to protected mode.
101*/
102
103ENTRY(real_to_prot)
104 # guarantee that interrupt is disabled when in prot mode
105 cli
106
107 # load the gdtr
108 addr32
109 data32
110 lgdt EXT(Gdtr)
111
112 # set the PE bit of CR0
113 mov %cr0, %eax
114
115 data32
116 or $CR0_PE_ON, %eax
117 mov %eax, %cr0
118
119 # make intrasegment jump to flush the processor pipeline and
120 # reload CS register
121 data32
122 ljmp $0x18, $xprot
123
124xprot:
125 # we are in USE32 mode now
126 # set up the protected mode segment registers : DS, SS, ES
127 mov $0x20, %eax
128 movw %ax, %ds
129 movw %ax, %ss
130 movw %ax, %es
131
132 # load idtr so we can debug
133 lidt EXT(Idtr_prot)
134
135 ret
136
137/*
138#
139# prot_to_real()
140# transfer from protected mode to real mode
141#
142*/
143
144ENTRY(prot_to_real)
145
146 # set up a dummy stack frame for the second seg change.
147 movl _ouraddr, %eax
148 sarl $4, %eax
149 pushw %ax
150 movw $xreal, %ax # gas botches pushw $xreal - extra bytes 0, 0
151 pushw %ax # decode to add %al, (%eax) (%al usually 0)
152
153 # Change to use16 mode.
154 ljmp $0x28, $x16
155
156x16:
157 # clear the PE bit of CR0
158 mov %cr0, %eax
159 data32
160 and $CR0_PE_OFF, %eax
161 mov %eax, %cr0
162
163 # make intersegment jmp to flush the processor pipeline
164 # using the fake stack frame set up earlier
165 # and reload CS register
166 lret
167
168xreal:
169 # we are in real mode now
170 # set up the real mode segment registers : DS, SS, ES
171 movw %cs, %ax
172 movw %ax, %ds
173 movw %ax, %ss
174 movw %ax, %es
175
176 # load idtr so we can debug
177 addr32
178 data32
179 lidt EXT(Idtr_real)
180
181 data32
182 ret
183
184/*
185#
186# startprog(phyaddr)
187# start the program on protected mode where phyaddr is the entry point
188#
189*/
190
191ENTRY(startprog)
192 push %ebp
193 mov %esp, %ebp
194
195 # get things we need into registers
196 movl 0x8(%ebp), %ecx # entry offset
197 movl 0x0c(%ebp), %eax # &argv
198
199 # make a new stack at 0:0xa0000 (big segs)
200 mov $0x10, %ebx
201 movw %bx, %ss
202 movl $0xa0000, %ebx
203 movl %ebx, %esp
204
205 # push some number of args onto the stack
206 pushl $0 # nominally a cyl offset in the boot.
207 pushl 0x8(%eax) # argv[2] = bootdev
208 pushl 0x4(%eax) # argv[1] = howto
209 pushl $0 # dummy 'return' address
210
211 # push on our entry address
212 mov $0x08, %ebx # segment
213 pushl %ebx
214 pushl %ecx
215
216 # convert over the other data segs
217 mov $0x10, %ebx
218 movw %bx, %ds
219 movw %bx, %es
220
221 # convert the PC (and code seg)
222 lret
223/*
224#
225# pbzero( dst, cnt)
226# where src is a virtual address and dst is a physical address
227*/
228
229ENTRY(pbzero)
230 push %ebp
231 mov %esp, %ebp
232 push %es
233 push %esi
234 push %edi
235 push %ecx
236
237 cld
238
239 # set %es to point at the flat segment
240 mov $0x10, %eax
241 movw %ax, %es
242
243 mov 0x8(%ebp), %edi # destination
244 mov 0xc(%ebp), %ecx # count
245 mov $0x0, %eax # value
246
247 rep
248 stosb
249
250 pop %ecx
251 pop %edi
252 pop %esi
253 pop %es
254 pop %ebp
255
256 ret
257/*
258#
259# pcpy(src, dst, cnt)
260# where src is a virtual address and dst is a physical address
261#
262*/
263
264ENTRY(pcpy)
265 push %ebp
266 mov %esp, %ebp
267 push %es
268 push %esi
269 push %edi
270 push %ecx
271
272 cld
273
274 # set %es to point at the flat segment
275 mov $0x10, %eax
276 movw %ax, %es
277
278 mov 0x8(%ebp), %esi # source
279 mov 0xc(%ebp), %edi # destination
280 mov 0x10(%ebp), %ecx # count
281
282 rep
283 movsb
284
285 pop %ecx
286 pop %edi
287 pop %esi
288 pop %es
289 pop %ebp
290
291 ret
292