Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / sys / boot / arc / loader / main.c
1 /*-
2  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3  * Copyright (c) 1998 Doug Rabson <dfr@freebsd.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD: src/sys/boot/arc/loader/main.c,v 1.3 1999/08/28 00:39:42 peter Exp $
28  * $DragonFly: src/sys/boot/arc/loader/Attic/main.c,v 1.2 2003/06/17 04:28:16 dillon Exp $
29  */
30
31
32 #include <stand.h>
33 #include <string.h>
34 #include <setjmp.h>
35
36 #include <sys/param.h>
37 #include "bootstrap.h"
38 #include "libarc.h"
39 #include "arctypes.h"
40 #include "arcfuncs.h"
41
42 extern  char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
43
44 struct arc_devdesc      currdev;        /* our current device */
45 struct arch_switch      archsw;         /* MI/MD interface boundary */
46
47 extern char end[];
48 extern void halt(void);
49
50 #define ARCENV_BOOTFILE         "OSLoadFilename"
51
52 static char *MemoryTypes[] = {
53     "MemoryExceptionBlock",
54     "MemorySystemBlock",
55     "MemoryFree",
56     "MemoryBad",
57     "MemoryLoadedProgram",
58     "MemoryFirmwareTemporary",
59     "MemoryFirmwarePermanent",
60     "MemoryFreeContiguous",
61     "MemorySpecialMemory",
62     "MemoryMaximum",
63 };
64
65 #ifdef __alpha__
66 #define ptob(p) ((p) << 13)
67 #endif
68
69 unsigned long
70 memsize()
71 {
72     unsigned long amount = 0;
73     MEMORY_DESCRIPTOR *desc;
74
75     for (desc = GetMemoryDescriptor(NULL); desc;
76          desc = GetMemoryDescriptor(desc)) {
77         printf("%s at %x-%x\n", MemoryTypes[desc->Type],
78                ptob(desc->BasePage),
79                ptob(desc->BasePage + desc->PageCount));
80         if (desc->Type == MemoryFree
81             || desc->Type == MemoryFirmwareTemporary)
82             amount += (desc->PageCount << 13); /* XXX pagesize */
83     }
84
85     return amount;
86 }
87
88 static char *ConfigurationClasses[] = {
89     "SystemClass",
90     "ProcessorClass",
91     "CacheClass",
92     "AdapterClass",
93     "ControllerClass",
94     "PeripheralClass",
95     "MemoryClass",
96     "MaximumClass",
97 };
98
99
100 static char *ConfigurationTypes[] = {
101     "ArcSystem",
102     "CentralProcessor",
103     "FloatingPointProcessor",
104     "PrimaryIcache",
105     "PrimaryDcache",
106     "SecondaryIcache",
107     "SecondaryDcache",
108     "SecondaryCache",
109     "EisaAdapter",
110     "TcAdapter",
111     "ScsiAdapter",
112     "DtiAdapter",
113     "MultiFunctionAdapter",
114     "DiskController",
115     "TapeController",
116     "CdromController",
117     "WormController",
118     "SerialController",
119     "NetworkController",
120     "DisplayController",
121     "ParallelController",
122     "PointerController",
123     "KeyboardController",
124     "AudioController",
125     "OtherController",
126     "DiskPeripheral",
127     "FloppyDiskPeripheral",
128     "TapePeripheral",
129     "ModemPeripheral",
130     "MonitorPeripheral",
131     "PrinterPeripheral",
132     "PointerPeripheral",
133     "KeyboardPeripheral",
134     "TerminalPeripheral",
135     "OtherPeripheral",
136     "LinePeripheral",
137     "NetworkPeripheral",
138     "SystemMemory",
139     "MaximumType",
140 };
141
142 static char *ConfigurationTypeCodes[] = {
143     "ARC",
144     "CPU",
145     "FPC",
146     "PrimaryIcache",
147     "PrimaryDcache",
148     "SecondaryIcache",
149     "SecondaryDcache",
150     "SecondaryCache",
151     "eisa",
152     "tc",
153     "scsi",
154     "dti",
155     "multi",
156     "disk",
157     "tape",
158     "cdrom",
159     "worm",
160     "serial",
161     "network",
162     "video",
163     "par",
164     "point",
165     "key",
166     "audio",
167     "other",
168     "rdisk",
169     "fdisk",
170     "tape",
171     "modem",
172     "monitor",
173     "print",
174     "pointer",
175     "keyboard",
176     "term",
177     "other",
178     "line",
179     "network",
180     "Memory",
181     "MaximumType"
182 };
183
184 static void
185 indent(int level)
186 {
187     while (level--)
188         putchar(' ');
189 }
190
191 void
192 printconfig(unsigned int level, CONFIGURATION_COMPONENT *component)
193 {
194     CONFIGURATION_COMPONENT *child;
195
196     indent(level);
197     printf("%s(%s,%d)",
198            ConfigurationClasses[component->Class],
199            ConfigurationTypes[component->Type],
200            component->Key);
201 #if 1
202     if (component->IdentifierLength)
203         printf("=%d,%s\n", component->IdentifierLength,
204                ptr(component->Identifier));
205     else
206         putchar('\n');
207 #endif
208     getchar();
209     
210     for (child = GetChild(component); child; child = GetPeer(child)) {
211         printconfig(level + 2, child);
212     }
213 }
214
215 void
216 dumpdisk(const char *name)
217 {
218     u_int32_t fd, count;
219     unsigned char buf[512];
220     int i, j;
221
222     printf("dump first sector of %s\n", name);
223     if (Open(name, OpenReadOnly, &fd) != ESUCCESS) {
224         printf("can't open disk\n");
225         return;
226     }
227     if (Read(fd, buf, 512, &count) != ESUCCESS) {
228         printf("can't read from disk\n");
229         Close(fd);
230         return;
231     }
232     for (i = 0; i < 16; i++) {
233         for (j = 0; j < 32; j++)
234             printf("%02x", buf[i*32 + j]);
235         putchar('\n');
236     }
237     Close(fd);
238 }
239
240 void
241 listdisks(char *path, CONFIGURATION_COMPONENT *component)
242 {
243     CONFIGURATION_COMPONENT *child;
244     char newpath[80];
245     char keybuf[20];
246
247     if (path == NULL) {
248         printf("\nARC disk devices:\n");
249         newpath[0] = '\0';
250     } else {
251         strcpy(newpath, path);
252         strcat(newpath, ConfigurationTypeCodes[component->Type]);
253         sprintf(keybuf, "(%d)", component->Key);
254         strcat(newpath, keybuf);
255     }
256     if (!strcmp(ConfigurationTypeCodes[component->Type], "rdisk") ||
257         !strcmp(ConfigurationTypeCodes[component->Type], "fdisk")) {
258         printf("%s\n", newpath);
259     }
260     for (child = GetChild(component); child; child = GetPeer(child)) {
261         listdisks(newpath, child);
262     }
263 }
264
265 static int exit_code = 0;
266 jmp_buf exit_env;
267
268 void
269 exit(int code)
270 {
271     exit_code = 0;
272     longjmp(exit_env, 1);
273 }
274
275 int
276 main(int argc, int argv[], int envp[])
277 {
278     int         i;
279     char        *bootfile;
280     
281     if (setjmp(exit_env))
282         return exit_code;
283
284     /* 
285      * Initialise the heap as early as possible.  Once this is done,
286      * alloc() is usable. The stack is buried inside us, so this is
287      * safe.
288      */
289     setheap((void *)end, (void *)(end + 512*1024));
290
291     /* 
292      * XXX Chicken-and-egg problem; we want to have console output
293      * early, but some console attributes may depend on reading from
294      * eg. the boot device, which we can't do yet.  We can use
295      * printf() etc. once this is done.
296      */
297     cons_probe();
298
299 #if 0
300     printconfig(0, GetChild(NULL));
301     dumpdisk("scsi(0)disk(0)rdisk(0)partition(0)");
302 #endif
303     listdisks(NULL, GetChild(NULL));
304     printf("\n");
305
306     make_rpb();
307
308     /*
309      * Initialise the block cache
310      */
311     bcache_init(32, 512);       /* 16k XXX tune this */
312
313     /*
314      * March through the device switch probing for things.
315      */
316     for (i = 0; devsw[i] != NULL; i++)
317         if (devsw[i]->dv_init != NULL)
318             (devsw[i]->dv_init)();
319
320     printf("\n");
321     printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
322     printf("(%s, %s)\n", bootprog_maker, bootprog_date);
323     printf("Memory: %ld k\n", memsize() / 1024);
324     
325     /* We're booting from an SRM disk, try to spiff this */
326     /* XXX presumes that biosdisk is first in devsw */
327     currdev.d_dev = devsw[0];
328     currdev.d_type = currdev.d_dev->dv_type;
329     currdev.d_kind.arcdisk.unit = 0;
330     /* XXX should be able to detect this, default to autoprobe */
331     currdev.d_kind.arcdisk.slice = -1;
332     /* default to 'a' */
333     currdev.d_kind.arcdisk.partition = 0;
334
335     /* Create arc-specific variables */
336     bootfile = GetEnvironmentVariable(ARCENV_BOOTFILE);
337     if (bootfile)
338         setenv("bootfile", bootfile, 1);
339
340     env_setenv("currdev", EV_VOLATILE,
341                arc_fmtdev(&currdev), arc_setcurrdev, env_nounset);
342     env_setenv("loaddev", EV_VOLATILE,
343                arc_fmtdev(&currdev), env_noset, env_nounset);
344     setenv("LINES", "24", 1);                           /* optional */
345     
346     archsw.arch_autoload = arc_autoload;
347     archsw.arch_getdev = arc_getdev;
348     archsw.arch_copyin = arc_copyin;
349     archsw.arch_copyout = arc_copyout;
350     archsw.arch_readin = arc_readin;
351
352     interact();                 /* doesn't return */
353
354     return 0;                   /* keep compiler happy */
355 }
356
357 COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
358
359 static int
360 command_reboot(int argc, char *argv[])
361 {
362
363     printf("Rebooting...\n");
364     delay(1000000);
365     FwReboot();
366     /* Note: we shouldn't get to this point! */
367     panic("Reboot failed!");
368     exit(0);
369 }
370
371 COMMAND_SET(quit, "quit", "exit the loader", command_quit);
372
373 static int
374 command_quit(int argc, char *argv[])
375 {
376     exit(0);
377     return(CMD_OK);
378 }
379
380 #if 0
381
382 COMMAND_SET(stack, "stack", "show stack usage", command_stack);
383
384 static int
385 command_stack(int argc, char *argv[])
386 {
387     char        *cp;
388
389     for (cp = &stackbase; cp < &stacktop; cp++)
390         if (*cp != 0)
391             break;
392     
393     printf("%d bytes of stack used\n", &stacktop - cp);
394     return(CMD_OK);
395 }
396
397 #endif
398
399 COMMAND_SET(heap, "heap", "show heap usage", command_heap);
400
401 static int
402 command_heap(int argc, char *argv[])
403 {
404     printf("heap base at %p, top at %p, used %ld\n", end, sbrk(0), sbrk(0) - end);
405     return(CMD_OK);
406 }