Fully synchronize sys/boot from FreeBSD-5.x, but add / to the module path
[dragonfly.git] / sys / boot / alpha / boot1 / boot1.c
1 /*
2  * From $NetBSD: bootxx.c,v 1.4 1997/09/06 14:08:29 drochner Exp $ 
3  * $FreeBSD$
4  * $DragonFly: src/sys/boot/alpha/boot1/Attic/boot1.c,v 1.4 2003/11/10 06:08:25 dillon Exp $
5  */
6
7 /*
8  * Copyright (c) 1995 Carnegie-Mellon University.
9  * All rights reserved.
10  *
11  * Author: Chris G. Demetriou
12  *
13  * Permission to use, copy, modify and distribute this software and
14  * its documentation is hereby granted, provided that both the copyright
15  * notice and this permission notice appear in all copies of the
16  * software, derivative works or modified versions, and any portions
17  * thereof, and that both notices appear in supporting documentation.
18  *
19  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
20  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
21  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
22  *
23  * Carnegie Mellon requests users of this software to return to
24  *
25  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
26  *  School of Computer Science
27  *  Carnegie Mellon University
28  *  Pittsburgh PA 15213-3890
29  *
30  * any improvements or extensions that they make and grant Carnegie the
31  * rights to redistribute these changes.
32  */
33
34 #include <string.h>
35 #include <sys/param.h>
36 #include <sys/dirent.h>
37
38 #include <machine/prom.h>
39 #include <machine/rpb.h>
40
41 #define DEBUGxx
42
43 void puts(const char *s);
44 void puthex(u_long v);
45 static int dskread(void *, u_int64_t, size_t);
46
47 #define printf(...) \
48 while (0)
49
50 #define memcpy(dst, src, len) \
51 bcopy(src, dst, len)
52
53 #include "ufsread.c"
54
55 extern end[];
56 int errno;
57
58 char *heap = (char*) end;
59
60 void
61 bcopy(const void *src, void *dst, size_t len) 
62 {
63         const char *s;
64         char *d;
65                  
66         for (d = dst, s = src; len; len--)
67                 *d++ = *s++;
68 }
69
70 void
71 putchar(int c)
72 {
73     if (c == '\n')
74         prom_putchar('\r');
75     prom_putchar(c);
76 }
77
78 int
79 getchar()
80 {
81     return prom_getchar();
82 }
83
84 int
85 ischar()
86 {
87     return prom_poll();
88 }
89
90 void
91 puts(const char *s)
92 {
93     while (*s)
94         putchar(*s++);
95 }
96
97 void
98 panic(const char *message, ...)
99 {
100     puts(message);
101     puts("\r\n");
102     halt();
103 }
104
105 int prom_fd = 0;
106
107 int
108 devopen()
109 {
110     prom_return_t ret;
111     char devname[64];
112     
113     if (prom_fd)
114         return;
115
116     ret.bits = prom_getenv(PROM_E_BOOTED_DEV, devname, sizeof devname);
117
118     ret.bits = prom_open(devname, ret.u.retval + 1);
119     if (ret.u.status)
120         panic("devopen: open failed\n");
121
122     prom_fd = ret.u.retval;
123
124     /* XXX read disklabel and setup partition offset */
125
126     return 0;
127 }
128
129 #ifdef DEBUG
130
131 void
132 puthex(u_long v)
133 {
134     int digit;
135     char hex[] = "0123456789abcdef";
136
137     puts("0x");
138     if (!v) {
139         puts("0");
140         return;
141     }
142
143     for (digit = 0; v >= (0x10L << digit); digit += 4)
144         ;
145
146     for (; digit >= 0; digit -= 4)
147         putchar(hex[(v >> digit) & 0xf]);
148 }
149
150 #endif
151
152 int
153 dskread(void *buf, u_int64_t block, size_t size)
154 {
155 #ifdef DEBUG
156     puts("dskread(");
157     puthex((u_long)buf);
158     puts(",");
159     puthex(block);
160     puts(",");
161     puthex(size);
162     puts(")\n");
163 #endif
164
165     prom_read(prom_fd, size * DEV_BSIZE, buf, block);
166     return (0);
167 }
168
169 static inline void
170 devclose()
171 {
172     if (prom_fd) {
173         prom_close(prom_fd);
174         prom_fd = 0;
175     }
176 }
177
178 static inline void
179 getfilename(char *filename, const char *defname)
180 {
181     int c;
182     char *p = filename;
183
184     puts("Boot: ");
185
186     while ((c = getchar()) != '\r') {
187         if (c == '\b' || c == 0177) {
188             if (p > filename) {
189                 puts("\b \b");
190                 p--;
191             }
192         } else {
193             putchar(c);
194             *p++ = c;
195         }
196     }
197     putchar('\n');
198     *p = '\0';
199     if (!*filename)
200         strcpy(filename, defname);
201     return;
202 }
203
204 static struct dmadat __dmadat;
205
206 static inline void
207 loadfile(char *name, char *addr)
208 {
209     int n;
210     char *p;
211     ino_t ino;
212
213     puts("Loading ");
214     puts(name);
215     puts("\n");
216
217     dmadat = &__dmadat;
218
219     if (devopen() || (ino = lookup(name)) == 0) {
220         puts("Can't open file ");
221         puts(name);
222         puts("\n");
223         halt();
224     }
225
226     p = addr;
227     do {
228             n = fsread(ino, p, VBLKSIZE);
229             if (n < 0) {
230                 puts("Can't read file ");
231                 puts(name);
232                 puts("\n");
233                 halt();
234             }
235         p += n;
236         twiddle();
237     } while (n == VBLKSIZE);
238
239     devclose();
240 }
241
242 static inline u_long rpcc()
243 {
244     u_long v;
245     __asm__ __volatile__ ("rpcc %0" : "=r"(v));
246     return v & 0xffffffff;
247 }
248
249 int
250 main()
251 {
252     char *loadaddr = (char*) SECONDARY_LOAD_ADDRESS;
253     char *name = "/boot/loader";
254     char *p;
255     char filename[512];
256     void (*entry)(void);
257     u_long start, freq;
258     int i;
259
260     init_prom_calls();
261
262     start = rpcc();
263     freq = ((struct rpb *)HWRPB_ADDR)->rpb_cc_freq;
264     while (((rpcc() - start) & 0xffffffff) < freq) {
265         twiddle();
266         if (ischar()) {
267             getfilename(filename, name);
268             name = filename;
269             break;
270         }
271     }
272
273     loadfile(name, loadaddr);
274
275     entry = (void (*)())loadaddr;
276     (*entry)();
277
278     return 0;
279 }