2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3 * Copyright (c) 1998 Doug Rabson <dfr@freebsd.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
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 $
36 #include <sys/param.h>
37 #include "bootstrap.h"
42 extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
44 struct arc_devdesc currdev; /* our current device */
45 struct arch_switch archsw; /* MI/MD interface boundary */
48 extern void halt(void);
50 #define ARCENV_BOOTFILE "OSLoadFilename"
52 static char *MemoryTypes[] = {
53 "MemoryExceptionBlock",
57 "MemoryLoadedProgram",
58 "MemoryFirmwareTemporary",
59 "MemoryFirmwarePermanent",
60 "MemoryFreeContiguous",
61 "MemorySpecialMemory",
66 #define ptob(p) ((p) << 13)
72 unsigned long amount = 0;
73 MEMORY_DESCRIPTOR *desc;
75 for (desc = GetMemoryDescriptor(NULL); desc;
76 desc = GetMemoryDescriptor(desc)) {
77 printf("%s at %x-%x\n", MemoryTypes[desc->Type],
79 ptob(desc->BasePage + desc->PageCount));
80 if (desc->Type == MemoryFree
81 || desc->Type == MemoryFirmwareTemporary)
82 amount += (desc->PageCount << 13); /* XXX pagesize */
88 static char *ConfigurationClasses[] = {
100 static char *ConfigurationTypes[] = {
103 "FloatingPointProcessor",
113 "MultiFunctionAdapter",
121 "ParallelController",
123 "KeyboardController",
127 "FloppyDiskPeripheral",
133 "KeyboardPeripheral",
134 "TerminalPeripheral",
142 static char *ConfigurationTypeCodes[] = {
192 printconfig(unsigned int level, CONFIGURATION_COMPONENT *component)
194 CONFIGURATION_COMPONENT *child;
198 ConfigurationClasses[component->Class],
199 ConfigurationTypes[component->Type],
202 if (component->IdentifierLength)
203 printf("=%d,%s\n", component->IdentifierLength,
204 ptr(component->Identifier));
210 for (child = GetChild(component); child; child = GetPeer(child)) {
211 printconfig(level + 2, child);
216 dumpdisk(const char *name)
219 unsigned char buf[512];
222 printf("dump first sector of %s\n", name);
223 if (Open(name, OpenReadOnly, &fd) != ESUCCESS) {
224 printf("can't open disk\n");
227 if (Read(fd, buf, 512, &count) != ESUCCESS) {
228 printf("can't read from disk\n");
232 for (i = 0; i < 16; i++) {
233 for (j = 0; j < 32; j++)
234 printf("%02x", buf[i*32 + j]);
241 listdisks(char *path, CONFIGURATION_COMPONENT *component)
243 CONFIGURATION_COMPONENT *child;
248 printf("\nARC disk devices:\n");
251 strcpy(newpath, path);
252 strcat(newpath, ConfigurationTypeCodes[component->Type]);
253 sprintf(keybuf, "(%d)", component->Key);
254 strcat(newpath, keybuf);
256 if (!strcmp(ConfigurationTypeCodes[component->Type], "rdisk") ||
257 !strcmp(ConfigurationTypeCodes[component->Type], "fdisk")) {
258 printf("%s\n", newpath);
260 for (child = GetChild(component); child; child = GetPeer(child)) {
261 listdisks(newpath, child);
265 static int exit_code = 0;
272 longjmp(exit_env, 1);
276 main(int argc, int argv[], int envp[])
281 if (setjmp(exit_env))
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
289 setheap((void *)end, (void *)(end + 512*1024));
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.
300 printconfig(0, GetChild(NULL));
301 dumpdisk("scsi(0)disk(0)rdisk(0)partition(0)");
303 listdisks(NULL, GetChild(NULL));
309 * Initialise the block cache
311 bcache_init(32, 512); /* 16k XXX tune this */
314 * March through the device switch probing for things.
316 for (i = 0; devsw[i] != NULL; i++)
317 if (devsw[i]->dv_init != NULL)
318 (devsw[i]->dv_init)();
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);
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;
333 currdev.d_kind.arcdisk.partition = 0;
335 /* Create arc-specific variables */
336 bootfile = GetEnvironmentVariable(ARCENV_BOOTFILE);
338 setenv("bootfile", bootfile, 1);
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 */
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;
352 interact(); /* doesn't return */
354 return 0; /* keep compiler happy */
357 COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
360 command_reboot(int argc, char *argv[])
363 printf("Rebooting...\n");
366 /* Note: we shouldn't get to this point! */
367 panic("Reboot failed!");
371 COMMAND_SET(quit, "quit", "exit the loader", command_quit);
374 command_quit(int argc, char *argv[])
382 COMMAND_SET(stack, "stack", "show stack usage", command_stack);
385 command_stack(int argc, char *argv[])
389 for (cp = &stackbase; cp < &stacktop; cp++)
393 printf("%d bytes of stack used\n", &stacktop - cp);
399 COMMAND_SET(heap, "heap", "show heap usage", command_heap);
402 command_heap(int argc, char *argv[])
404 printf("heap base at %p, top at %p, used %ld\n", end, sbrk(0), sbrk(0) - end);