|
|
1.1 root 1: /*
2: * sys/i386/stand/asbootblk.c
3: *
4: * Boot block for Adaptech 1542 SCSI
5: *
6: * April 10, 1992
7: * Pace Willisson
8: * [email protected]
9: *
10: * Placed in the public domain with NO WARRANTIES, not even the
11: * implied warranties for MERCHANTABILITY or FITNESS FOR A
12: * PARTICULAR PURPOSE.
13: *
14: * To compile:
15: *
16: * cc -O -c -DRELOC=0x70000 asbootblk.c
17: * ld -N -T 7c00 asbootblk.o
18: *
19: * This should result in a file with 512 bytes of text and no initialized
20: * data. Strip the 32 bit header and place in block 0.
21: *
22: * When run, this program copies at least the first 8 blocks of SCSI
23: * target 0 to the address specified by RELOC, then jumps to the
24: * address RELOC+1024 (skipping the boot block and disk label). Usually,
25: * disks have 512 bytes per block, but I don't think they ever have
26: * less, and it wont hurt if they are bigger, as long as RELOC + 8*SIZE
27: * is less than 0xa0000.
28: *
29: * This bootblock does not support fdisk partitions, and can only be used
30: * as the master boot block.
1.1.1.2 ! root 31: *
! 32: * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
! 33: * -------------------- ----- ----------------------
! 34: * CURRENT PATCH LEVEL: 1 00088
! 35: * -------------------- ----- ----------------------
! 36: *
! 37: * 23 Oct 92 Joerg Lohse changed ccb opcode for compatibility
! 38: * with Adaptec AHA-1542A
1.1 root 39: */
40:
41: #include "param.h"
42: #include "disklabel.h"
43: #include "i386/isa/asreg.h"
44:
45: /* RELOC should be defined with a -D flag to cc */
46:
47: #define SECOND_LEVEL_BOOT_START (RELOC + 0x400)
48: #define READ_SIZE 8192
49:
50: #define as_port 0x330
51: #define target 0
52:
53:
54: #define NBLOCKS (READ_SIZE / 512) /* how many logical blocks to read */
55:
56:
57: /* These are the parameters to pass to the second level boot */
58: #define dev 4 /* major device number of as driver in
59: i386/stand/conf.c and i386/i386/conf.c */
60: #define unit 0 /* partition number of root file system */
61: #define off 0 /* block offset of root file system */
62:
63: /* inline i/o borrowed from Roell X server */
64: static __inline__ void
65: outb(port, val)
66: short port;
67: char val;
68: {
69: __asm__ volatile("outb %%al, %1" : :"a" (val), "d" (port));
70: }
71:
72: static __inline__ unsigned int
73: inb(port)
74: short port;
75: {
76: unsigned int ret;
77: __asm__ volatile("xorl %%eax, %%eax; inb %1, %%al"
78: : "=a" (ret) : "d" (port));
79: return ret;
80: }
81:
82: /* this code is linked at 0x7c00 and is loaded there by the BIOS */
83:
84: asm ("
85: /* we're running in 16 real mode, so normal assembly doesn't work */
86: bootbase:
87: /* interrupts off */
88: cli
89:
90: /* load gdt */
91: .byte 0x2e,0x0f,0x01,0x16 /* lgdt %cs:$imm */
92: .word _gdtarg + 2
93:
94: /* turn on protected mode */
95: smsw %ax
96: orb $1,%al
97: lmsw %ax
98:
99: /* flush prefetch queue and reload %cs */
100: .byte 0xea /* ljmp $8, flush */
101: .word flush
102: .word 8
103:
104: flush:
105: /* now running in 32 bit mode */
106: movl $0x10,%eax
107: movl %ax,%ds
108: movl %ax,%es
109: movl %ax,%ss
110: movl $0x7c00,%esp
111: call _main
112: "); /* end of asm */
113:
114: const char gdt[] = {
115: 0, 0, 0, 0, 0, 0, 0, 0,
116: 0xff, 0xff, 0, 0, 0, 0x9f, 0xcf, 0, /* code segment */
117: 0xff, 0xff, 0, 0, 0, 0x93, 0xcf, 0, /* data segment */
118: };
119:
120: const struct {
121: short filler;
122: short size;
123: const char *gdt;
124: } gdtarg = { 0, sizeof gdt - 1, gdt };
125:
126: #define CRTBASE ((char *)0xb8000)
127: #define CHECKPOINT(x) (CRTBASE[0] = x)
128:
129: volatile struct mailbox_entry mailbox[2];
130: const char ccb[] = {
1.1.1.2 ! root 131: 0, /* opcode: normal read/write */
1.1 root 132: (target << 5) | 8, /* target num and read flag */
133: 10, /* scsi cmd len */
134: 1, /* no automatic request for sense */
135: READ_SIZE >> 16, /* data length */
136: READ_SIZE >> 8,
137: READ_SIZE,
138: RELOC >> 16, /* data pointer */
139: RELOC >> 8,
140: RELOC,
141: 0, 0, 0, /* link pointer */
142: 0, /* link id */
143: 0, /* host status */
144: 0, /* target status */
145: 0, 0, /* reserved */
146:
147: /* scsi cdb */
148: 0x28, /* read opcode */
149: 0, /* logical unit number */
150: 0, 0, 0, 0, /* logical block address */
151: 0, /* reserved */
152: 0, NBLOCKS, /* transfer length */
153: 0, /* link control */
154: };
155:
156: int (*f)();
157:
158: main ()
159: {
160: int i;
161: extern char edata[], end[];
162: char volatile * volatile p, *q;
163: int physaddr;
164:
165: CHECKPOINT ('a');
166:
167: /* clear bss */
168: for (p = edata; p < end; p++)
169: *p = 0;
170:
171: f = (int (*)())SECOND_LEVEL_BOOT_START;
172:
173: /* dma setup: see page 5-31 in the Adaptech manual */
174: /* this knows we are using drq 5 */
175: outb (0xd6, 0xc1);
176: outb (0xd4, 0x01);
177:
178: outb (as_port + AS_CONTROL, AS_CONTROL_SRST);
179:
180: /* delay a little */
181: inb (0x84);
182:
183: while (inb (as_port + AS_STATUS) != (AS_STATUS_INIT | AS_STATUS_IDLE))
184: ;
185:
186: CHECKPOINT ('b');
187:
188: as_put_byte (AS_CMD_MAILBOX_INIT);
189: as_put_byte (1); /* one mailbox out, one in */
190: as_put_byte ((int)mailbox >> 16);
191: as_put_byte ((int)mailbox >> 8);
192: as_put_byte ((int)mailbox);
193:
194: while (inb (as_port + AS_STATUS) & AS_STATUS_INIT)
195: ;
196:
197: CHECKPOINT ('c');
198:
199: mailbox[0].msb = (int)ccb >> 16;
200: mailbox[0].mid = (int)ccb >> 8;
201: mailbox[0].lsb = (int)ccb;
202: mailbox[0].cmd = 1;
203:
204: as_put_byte (AS_CMD_START_SCSI_COMMAND);
205:
206: /* wait for done */
207: while (mailbox[1].cmd == 0)
208: ;
209:
210: CHECKPOINT ('d');
211:
212: if (mailbox[1].cmd != 1) {
213: /* some error */
214: CHECKPOINT ('X');
215: while (1);
216: }
217:
218: CHECKPOINT ('e');
219:
220: /* the optimazation that gcc uses when it knows we are jumpping
221: * to a constant address is broken, so we have to use a variable
222: * here
223: */
224: (*f)(dev, unit, off);
225: }
226:
227: int
228: as_put_byte (val)
229: int val;
230: {
231: while (inb (as_port + AS_STATUS) & AS_STATUS_CDF)
232: ;
233: outb (as_port + AS_DATA_OUT, val);
234: }
235:
236: asm ("
237: ebootblkcode:
238: . = 510
239: .byte 0x55
240: .byte 0xaa
241: ebootblk: /* MUST BE EXACTLY 0x200 BIG FOR SURE */
242: ");
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.