final __P removal commit
[dragonfly.git] / sys / boot / alpha / boot1 / boot1.c
1 /*
2  * $FreeBSD: src/sys/boot/alpha/boot1/boot1.c,v 1.7.2.1 2000/10/28 01:03:33 gallatin Exp $
3  * $DragonFly: src/sys/boot/alpha/boot1/Attic/boot1.c,v 1.3 2003/08/27 11:42:33 rob Exp $
4  * From $NetBSD: bootxx.c,v 1.4 1997/09/06 14:08:29 drochner 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
37 #include <machine/prom.h>
38 #include <machine/rpb.h>
39
40 #define DEBUGxx
41
42 extern end[];
43 int errno;
44
45 char *heap = (char*) end;
46
47 void
48 putchar(int c)
49 {
50     if (c == '\n')
51         prom_putchar('\r');
52     prom_putchar(c);
53 }
54
55 int
56 getchar()
57 {
58     return prom_getchar();
59 }
60
61 int
62 ischar()
63 {
64     return prom_poll();
65 }
66
67 void
68 puts(const char *s)
69 {
70     while (*s)
71         putchar(*s++);
72 }
73
74 void *
75 malloc(size_t size)
76 {
77     char *p = heap;
78     size = (size + 7) & ~7;
79     heap += size;
80     return p;
81 }
82
83 void
84 free(void * p)
85 {
86 }
87
88 void
89 panic(const char *message, ...)
90 {
91     puts(message);
92     puts("\r\n");
93     halt();
94 }
95
96 int prom_fd = 0;
97
98 int
99 devopen()
100 {
101     prom_return_t ret;
102     char devname[64];
103     
104     if (prom_fd)
105         return;
106
107     ret.bits = prom_getenv(PROM_E_BOOTED_DEV, devname, sizeof devname);
108
109     ret.bits = prom_open(devname, ret.u.retval + 1);
110     if (ret.u.status)
111         panic("devopen: open failed\n");
112
113     prom_fd = ret.u.retval;
114
115     /* XXX read disklabel and setup partition offset */
116
117     return 0;
118 }
119
120 #ifdef DEBUG
121
122 void
123 puthex(u_long v)
124 {
125     int digit;
126     char hex[] = "0123456789abcdef";
127
128     if (!v) {
129         puts("0");
130         return;
131     }
132
133     for (digit = 0; v >= (0x10L << digit); digit += 4)
134         ;
135
136     for (; digit >= 0; digit -= 4)
137         putchar(hex[(v >> digit) & 0xf]);
138 }
139
140 #endif
141
142 void
143 devread(char *buf, int block, size_t size)
144 {
145 #ifdef DEBUG
146     puts("devread(");
147     puthex((u_long)buf);
148     puts(",");
149     puthex(block);
150     puts(",");
151     puthex(size);
152     puts(")\n");
153 #endif
154
155     prom_read(prom_fd, size, buf, block);
156 }
157
158 static inline void
159 devclose()
160 {
161     if (prom_fd) {
162         prom_close(prom_fd);
163         prom_fd = 0;
164     }
165 }
166
167 static inline void
168 getfilename(char *filename, const char *defname)
169 {
170     int c;
171     char *p = filename;
172
173     puts("Boot: ");
174
175     while ((c = getchar()) != '\r') {
176         if (c == '\b' || c == 0177) {
177             if (p > filename) {
178                 puts("\b \b");
179                 p--;
180             }
181         } else {
182             putchar(c);
183             *p++ = c;
184         }
185     }
186     putchar('\n');
187     *p = '\0';
188     if (!*filename)
189         strcpy(filename, defname);
190     return;
191 }
192
193 static inline void
194 loadfile(char *name, char *addr)
195 {
196     int n;
197     char *p;
198
199     puts("Loading ");
200     puts(name);
201     puts("\n");
202
203     if (openrd(name)) {
204         puts("Can't open file ");
205         puts(name);
206         puts("\n");
207         halt();
208     }
209
210     p = addr;
211     do {
212         n = readit(p, 1024);
213         p += n;
214         twiddle();
215     } while (n > 0);
216
217     devclose();
218 }
219
220 static inline u_long rpcc()
221 {
222     u_long v;
223     __asm__ __volatile__ ("rpcc %0" : "=r"(v));
224     return v & 0xffffffff;
225 }
226
227 int
228 main()
229 {
230     char *loadaddr = (char*) SECONDARY_LOAD_ADDRESS;
231     char *name = "/boot/loader";
232     char *p;
233     char filename[512];
234     void (*entry) (void);
235     u_long start, freq;
236     int i;
237
238     init_prom_calls();
239
240     start = rpcc();
241     freq = ((struct rpb *)HWRPB_ADDR)->rpb_cc_freq;
242     while (((rpcc() - start) & 0xffffffff) < freq) {
243         twiddle();
244         if (ischar()) {
245             getfilename(filename, name);
246             name = filename;
247             break;
248         }
249     }
250
251     loadfile(name, loadaddr);
252
253     entry = (void (*)())loadaddr;
254     (*entry)();
255
256     return 0;
257 }