386BSD 0.1 development
[unix-history] / usr / src / sys.386bsd / i386 / stand / fdbootblk.c
CommitLineData
986db2a9
WJ
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * William Jolitz.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * @(#)fdbootblk.c 7.2 (Berkeley) 5/4/91
37 */
38
39/*
40 * fdbootblk.s:
41 * Written 10/6/90 by William F. Jolitz
42 * Initial block boot for AT/386 with typical stupid NEC controller
43 *
44 * Goal is to read in sucessive 7.5Kbytes of bootstrap to
45 * execute.
46 *
47 * No attempt is made to handle disk errors.
48 */
49/*#include "/sys/i386/isa/isa.h"
50#include "/sys/i386/isa/fdreg.h"*/
51#define NOP inb $0x84,%al
52#define BIOSRELOC 0x7c00
53#define start RELOC+0x400
54
55 /* mumbo-jumbo to pacify DOS, in the hope of getting diskcopy to work */
56 jmp 1f
57 .asciz "386BSD "
58 .byte 1 # sectors per allocation
59 .word 15 # additional sectors for bootstrap
60 .word 0 # number of DOS fat sectors
61 .word 0 # number of DOS rootdir entries
62 .byte 0xf0 # media descriptor
63 .word 0 # number of sectors per a DOS fat entry
64 .word 18 # number of sectors per track
65 .word 2 # number of heads
66 .long 0 # number of hidden sectors
67 .long 2880-18 # logical sectors per volume
68 .byte 0 # physical drive
69 .byte 0x29 # ?
70 .long 137 # binary id
71 .ascii "Release 0.1" # volume label
72 .space 5
731:
74 /* step 0 force descriptors to bottom of address space */
75
76 cli
77 .byte 0xb8,0x30,0x00 /* mov $0x30,%ax */
78 mov %ax, %ss
79 .byte 0xbc,0x00,0x01 /* mov $0x100,%sp */
80
81 xorl %eax,%eax
82 movl %ax,%ds
83 movl %ax,%es
84
85 /* obtain BIOS parameters for hard disk XXX */
86 movb $0x9f,%ah /* write to 0x9ff00 XXX */
87 movb $0xf0,%al
88 mov %ax,%es
89 xor %edi,%edi
90
91 .byte 0xf, 0xb4, 0x36 ; .word 0x41*4 /* lfs 0x41*4, %si */
92 xorb %ch,%ch
93 movb $0x10,%cl
94 fs
95 rep
96 movsb
97
98 .byte 0xf, 0xb4, 0x36 ; .word 0x46*4 /* lfs 0x46*4, %si */
99 xorb %ch,%ch
100 movb $0x10,%cl
101 fs
102 rep
103 movsb
104
105 xorl %eax,%eax
106 movl %ax,%es
107
108 /* step 1 load new descriptor table */
109
110 .byte 0x2E,0x0F,1,0x16 /* word aword cs lgdt GDTptr */
111 .word BIOSRELOC+0xa4 #GDTptr
112
113 /* step 2 turn on protected mode */
114
115 smsw %ax
116 orb $1,%al
117 lmsw %ax
118 jmp 1f
119 nop
120
121 /* step 3 reload segment descriptors */
122
123 1:
124 xorl %eax,%eax
125 movb $0x10,%al
126 movl %ax,%ds
127 movl %ax,%es
128 movl %ax,%ss
129 word
130 ljmp $0x8,$ BIOSRELOC+0xb3 /* would be nice if .-RELOC+0x7c00 worked */
131
132 /* Global Descriptor Table contains three descriptors:
133 * 0x00: Null: not used
134 * 0x08: Code: code segment starts at 0 and extents for 4 gigabytes
135 * 0x10: Data: data segment starts at 0 and extends for 4 gigabytes
136 * (overlays code)
137 */
138GDT:
139NullDesc: .word 0,0,0,0 # null descriptor - not used
140CodeDesc: .word 0xFFFF # limit at maximum: (bits 15:0)
141 .byte 0,0,0 # base at 0: (bits 23:0)
142 .byte 0x9f # present/priv level 0/code/conforming/readable
143 .byte 0xcf # page granular/default 32-bit/limit(bits 19:16)
144 .byte 0 # base at 0: (bits 31:24)
145DataDesc: .word 0xFFFF # limit at maximum: (bits 15:0)
146 .byte 0,0,0 # base at 0: (bits 23:0)
147 .byte 0x93 # present/priv level 0/data/expand-up/writeable
148 .byte 0xcf # page granular/default 32-bit/limit(bits 19:16)
149 .byte 0 # base at 0: (bits 31:24)
150
151/* Global Descriptor Table pointer
152 * contains 6-byte pointer information for LGDT
153 */
154GDTptr: .word 0x17 # limit to three 8 byte selectors(null,code,data)
155 .long BIOSRELOC+0x8c # GDT -- arrgh, gas again!
156readcmd: .byte 0xe6,0,0,0,0,2,18,0x1b,0xff
157
158 /* step 4 relocate to final bootstrap address. */
159reloc:
160 movl $ BIOSRELOC,%esi
161 movl $ RELOC,%edi
162 movl $512,%ecx
163 rep
164 movsb
165 movl $0xa0000, %esp
166 pushl $dodisk
167 ret
168
169 /* step 5 load remaining 15 sectors off disk */
170dodisk:
171 movl $ RELOC+0x200, %edi
172 xorl %ebx, %ebx
173 incb %bl # shl $1,%bl
174 incb %bl
175 movb $0x20,%al # do a eoi
176 outb %al,$0x20
177
178 NOP
179 movb $0x07,%al
180 outb %al,$0x21
181 NOP
182 8:
183 movb %bl,readcmd+4
184 movl %edi,%ecx
185
186 /* Set read/write bytes */
187 xorl %edx,%edx
188 movb $0x0c,%dl # outb(0xC,0x46); outb(0xB,0x46);
189 movb $0x46,%al
190 outb %al,%dx
191 NOP
192 decb %dx
193 outb %al,%dx
194
195 /* Send start address */
196 movb $0x04,%dl # outb(0x4, addr);
197 movb %cl,%al
198 outb %al,%dx
199 NOP
200 movb %ch,%al # outb(0x4, addr>>8);
201 outb %al,%dx
202 NOP
203 rorl $8,%ecx # outb(0x81, addr>>16);
204 movb %ch,%al
205 outb %al,$0x81
206 NOP
207
208 /* Send count */
209 movb $0x05,%dl # outb(0x5, 0);
210 xorl %eax,%eax
211 outb %al,%dx
212 NOP
213 movb $2,%al # outb(0x5,2);
214 outb %al,%dx
215 NOP
216
217 /* set channel 2 */
218 movb $2,%al # outb(0x0A,2);
219 outb %al,$0x0A
220 NOP
221
222 /* issue read command to fdc */
223 movw $0x3f4,%dx
224 movl $readcmd,%esi
225 xorl %ecx,%ecx
226 movb $9,%cl
227
228 2: NOP
229 inb %dx,%al
230 testb $0x80,%al
231 jz 2b
232
233 incb %dx
234 NOP
235 movl (%esi),%al
236 outb %al,%dx
237 NOP
238 incl %esi
239 decb %dx
240 loop 2b
241
242 /* watch the icu looking for an interrupt signalling completion */
243 xorl %edx,%edx
244 movb $0x20,%dl
245 2:
246 NOP
247 movb $0xc,%al
248 outb %al,%dx
249 NOP
250 inb %dx,%al
251 andb $0x7f,%al
252 cmpb $6,%al
253 jne 2b
254 NOP
255 movb $0x20,%al # do a eoi
256 outb %al,%dx
257 NOP
258
259 movl $0x3f4,%edx
260 xorl %ecx,%ecx
261 movb $7,%cl
262 2:
263 NOP
264 inb %dx,%al
265 andb $0xC0,%al
266 cmpb $0xc0,%al
267 jne 2b
268 incb %dx
269 inb %dx,%al
270 decb %dx
271 loop 2b
272
273 /* extract the status bytes after the read. must we do this? */
274 addw $0x200,%edi # next addr to load to
275 incb %bl
276 cmpb $15,%bl
277 jle 8b
278
279 /* for clever bootstrap, dig out boot unit and cylinder */
280 pushl $0
281 pushl $0
282
283 /* fd controller is major device 2 */
284 pushl $2 /* dev */
285
286 /* sorry, no flags at this point! */
287
288 movl $ start, %eax
289 call %eax /* main (dev, unit, off) */
290
291ebootblkcode:
292
293 /* remaining space usable for a disk label */
294
295 .org 0x1fe
296 .word 0xaa55 /* signature -- used by BIOS ROM */
297
298ebootblk: /* MUST BE EXACTLY 0x200 BIG FOR SURE */