Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / sys / boot / pc98 / boot2 / sys.c
1 /*
2  * Mach Operating System
3  * Copyright (c) 1992, 1991 Carnegie Mellon University
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify and distribute this software and its
7  * documentation is hereby granted, provided that both the copyright
8  * notice and this permission notice appear in all copies of the
9  * software, derivative works or modified versions, and any portions
10  * thereof, and that both notices appear in supporting documentation.
11  *
12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15  *
16  * Carnegie Mellon requests users of this software to return to
17  *
18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19  *  School of Computer Science
20  *  Carnegie Mellon University
21  *  Pittsburgh PA 15213-3890
22  *
23  * any improvements or extensions that they make and grant Carnegie Mellon
24  * the rights to redistribute these changes.
25  *
26  *      from: Mach, Revision 2.2  92/04/04  11:36:34  rpd
27  * $FreeBSD: src/sys/boot/pc98/boot2/sys.c,v 1.2.2.1 2003/01/13 08:52:53 nyan Exp $
28  * $DragonFly: src/sys/boot/pc98/boot2/Attic/sys.c,v 1.2 2003/06/17 04:28:18 dillon Exp $
29  */
30
31 /*
32  * Ported to PC-9801 by Yoshio Kimura
33  */
34
35 #include "boot.h"
36 #include <sys/dirent.h>
37 #include <sys/reboot.h>
38
39 #if 0
40 /* #define BUFSIZE 4096 */
41 #define BUFSIZE MAXBSIZE
42 static char buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE];
43 #endif
44
45 static char biosdrivedigit;
46
47 #define BUFSIZE 8192
48 #define MAPBUFSIZE BUFSIZE
49 static char buf[BUFSIZE], fsbuf[BUFSIZE], iobuf[BUFSIZE];
50
51 static char mapbuf[MAPBUFSIZE];
52 static int mapblock;
53
54 int poff;
55
56 #ifdef RAWBOOT
57 #define STARTBYTE       8192    /* Where on the media the kernel starts */
58 #endif
59
60 static int block_map(int file_block);
61 static int find(char *path);
62
63 void
64 xread(char *addr, int size)
65 {
66         int count = BUFSIZE;
67         while (size > 0) {
68                 if (BUFSIZE > size)
69                         count = size;
70                 read(buf, count);
71                 pcpy(buf, addr, count);
72                 size -= count;
73                 addr += count;
74         }
75 }
76
77 #ifndef RAWBOOT
78 void
79 read(char *buffer, int count)
80 {
81         int logno, off, size;
82         int cnt2, bnum2;
83         struct fs *fs_copy;
84
85         while (count > 0 && poff < inode.i_size) {
86                 fs_copy = fs;
87                 off = blkoff(fs_copy, poff);
88                 logno = lblkno(fs_copy, poff);
89                 cnt2 = size = blksize(fs_copy, &inode, logno);
90                 bnum2 = fsbtodb(fs_copy, block_map(logno)) + boff;
91                 if (    (!off)  && (size <= count)) {
92                         devread(buffer, bnum2, cnt2);
93                 } else {
94                         size -= off;
95                         if (size > count)
96                                 size = count;
97                         devread(iobuf, bnum2, cnt2);
98                         bcopy(iobuf+off, buffer, size);
99                 }
100                 buffer += size;
101                 count -= size;
102                 poff += size;
103         }
104 }
105 #else
106 void
107 read(char *buffer, int count)
108 {
109         int cnt, bnum, off, size;
110
111         off = STARTBYTE + poff;
112         poff += count;
113
114         /* Read any unaligned bit at the front */
115         cnt = off & 511;
116         if (cnt) {
117                 size = 512-cnt;
118                 if (count < size)
119                         size = count;
120                 devread(iobuf, off >> 9, 512);
121                 bcopy(iobuf+cnt, buffer, size);
122                 count -= size;
123                 off += size;
124                 buffer += size;
125         }
126         size = count & (~511);
127         if (size && (off & (~511))) {
128                 devread(buffer, off >> 9, size);
129                 off += size;
130                 count -= size;
131                 buffer += size;
132         }
133         if (count) {
134                 devread(iobuf, off >> 9, 512);
135                 bcopy(iobuf, buffer, count);
136         }
137 }
138 #endif
139
140 static int
141 find(char *path)
142 {
143         char *rest, ch;
144         int block, off, loc, ino = ROOTINO;
145         struct dirent *dp;
146         char list_only;
147
148         list_only = (path[0] == '?' && path[1] == '\0');
149 loop:
150         devread(iobuf, fsbtodb(fs, ino_to_fsba(fs, ino)) + boff, fs->fs_bsize);
151         bcopy((void *)&((struct dinode *)iobuf)[ino % fs->fs_inopb],
152               (void *)&inode.i_din,
153               sizeof (struct dinode));
154         if (!*path)
155                 return 1;
156         while (*path == '/')
157                 path++;
158         if (!inode.i_size || ((inode.i_mode&IFMT) != IFDIR))
159                 return 0;
160         for (rest = path; (ch = *rest) && ch != '/'; rest++) ;
161         *rest = 0;
162         loc = 0;
163         do {
164                 if (loc >= inode.i_size) {
165                         if (list_only) {
166                                 putchar('\n');
167                                 return -1;
168                         } else {
169                                 return 0;
170                         }
171                 }
172                 if (!(off = blkoff(fs, loc))) {
173                         block = lblkno(fs, loc);
174                         devread(iobuf, fsbtodb(fs, block_map(block)) + boff,
175                                 blksize(fs, &inode, block));
176                 }
177                 dp = (struct dirent *)(iobuf + off);
178                 loc += dp->d_reclen;
179                 if (dp->d_fileno && list_only)
180                         printf("%s ", dp->d_name);
181         } while (!dp->d_fileno || strcmp(path, dp->d_name));
182         ino = dp->d_fileno;
183         *(path = rest) = ch;
184         goto loop;
185 }
186
187
188 static int
189 block_map(int file_block)
190 {
191         int bnum;
192         if (file_block < NDADDR)
193                 return(inode.i_db[file_block]);
194         if ((bnum=fsbtodb(fs, inode.i_ib[0])+boff) != mapblock) {
195                 devread(mapbuf, bnum, fs->fs_bsize);
196                 mapblock = bnum;
197         }
198         return (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
199 }
200
201
202 int
203 openrd(void)
204 {
205         char **devp, *name0 = name, *cp = name0;
206         int biosdrive, dosdev_copy, ret;
207
208         /*******************************************************\
209         * If bracket given look for preceding device name       *
210         \*******************************************************/
211         while (*cp && *cp!='(')
212                 cp++;
213         if (!*cp)
214         {
215                 cp = name0;
216         }
217         else
218         {
219                 /*
220                  * Look for a BIOS drive number (a leading digit followed
221                  * by a colon).
222                  */
223                 biosdrivedigit = '\0';
224                 if (*(name0 + 1) == ':' && *name0 >= '0' && *name0 <= '9') {
225                         biosdrivedigit = *name0;
226                         name0 += 2;
227                 }
228
229                 if (cp++ != name0)
230                 {
231                         for (devp = devs; *devp; devp++)
232                                 if (name0[0] == (*devp)[0] &&
233                                     name0[1] == (*devp)[1])
234                                         break;
235                         if (!*devp)
236                         {
237                                 printf("Unknown device\n");
238                                 return 1;
239                         }
240                         maj = devp-devs;
241                 }
242                 /*******************************************************\
243                 * Look inside brackets for unit number, and partition   *
244                 \*******************************************************/
245                 /*
246                  * Allow any valid digit as the unit number, as the BIOS
247                  * will complain if the unit number is out of range.
248                  * Restricting the range here prevents the possibilty of using
249                  * BIOSes that support more than 2 units.
250                  * XXX Bad values may cause strange errors, need to check if
251                  * what happens when a value out of range is supplied.
252                  */
253                 if (*cp >= '0' && *cp <= '9')
254                         unit = *cp++ - '0';
255                 if (!*cp || (*cp == ',' && !*++cp))
256                         return 1;
257                 if (*cp >= 'a' && *cp <= 'p')
258                         part = *cp++ - 'a';
259                 while (*cp && *cp++!=')') ;
260                 if (!*cp)
261                         return 1;
262         }
263         biosdrive = biosdrivedigit - '0';
264         if (biosdrivedigit == '\0') {
265 #ifdef PC98
266                 biosdrive = dosdev & 0x0f;
267 #else
268                 biosdrive = unit;
269 #endif
270 #if BOOT_HD_BIAS > 0
271                 /* XXX */
272                 if (maj == 4)
273                         biosdrive += BOOT_HD_BIAS;
274 #endif
275         }
276         switch(maj)
277         {
278 #ifdef PC98
279         case 4: /* da */
280                 dosdev_copy = biosdrive | 0xA0; /* SCSI HD or MO */
281 #else   /* IBM-PC */
282         case 0:
283         case 4:
284                 dosdev_copy = biosdrive | 0x80;
285 #endif
286                 break;
287 #ifdef PC98
288         case 0: /* wd */
289         case 2: /* 1200KB fd */
290                 dosdev_copy = (maj << 3) | unit | 0x80;
291 #else
292         case 2:
293                 dosdev_copy = biosdrive;
294 #endif
295                 break;
296 #ifdef PC98
297         case 6: /* 1440KB fd */
298                 dosdev_copy = (maj << 3) | unit;
299                 break;
300 #endif
301         default:
302                 printf("Unknown device\n");
303                 return 1;
304         }
305         dosdev = dosdev_copy;
306 #if 0
307         /* XXX this is useful, but misplaced. */
308         printf("dosdev= %x, biosdrive = %d, unit = %d, maj = %d\n",
309                 dosdev_copy, biosdrive, unit, maj);
310 #endif
311
312         /***********************************************\
313         * Now we know the disk unit and part,           *
314         * Load disk info, (open the device)             *
315         \***********************************************/
316         if (devopen())
317                 return 1;
318
319 #ifndef RAWBOOT
320         /***********************************************\
321         * Load Filesystem info (mount the device)       *
322         \***********************************************/
323         devread((char *)(fs = (struct fs *)fsbuf), SBLOCK + boff, SBSIZE);
324         /***********************************************\
325         * Find the actual FILE on the mounted device    *
326         \***********************************************/
327         ret = find(cp);
328         name = cp;
329         if (ret == 0)
330                 return 1;
331         if (ret < 0) {
332                 name = NULL;
333                 return -1;
334         }
335         poff = 0;
336 #endif /* RAWBOOT */
337         return 0;
338 }