diff options
Diffstat (limited to 'sys/boot/arc/loader/main.c')
-rw-r--r-- | sys/boot/arc/loader/main.c | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/sys/boot/arc/loader/main.c b/sys/boot/arc/loader/main.c new file mode 100644 index 0000000..ea0165b --- /dev/null +++ b/sys/boot/arc/loader/main.c @@ -0,0 +1,405 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * Copyright (c) 1998 Doug Rabson <dfr@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + + +#include <stand.h> +#include <string.h> +#include <setjmp.h> + +#include <sys/param.h> +#include "bootstrap.h" +#include "libarc.h" +#include "arctypes.h" +#include "arcfuncs.h" + +extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[]; + +struct arc_devdesc currdev; /* our current device */ +struct arch_switch archsw; /* MI/MD interface boundary */ + +extern char end[]; +extern void halt(void); + +#define ARCENV_BOOTFILE "OSLoadFilename" + +static char *MemoryTypes[] = { + "MemoryExceptionBlock", + "MemorySystemBlock", + "MemoryFree", + "MemoryBad", + "MemoryLoadedProgram", + "MemoryFirmwareTemporary", + "MemoryFirmwarePermanent", + "MemoryFreeContiguous", + "MemorySpecialMemory", + "MemoryMaximum", +}; + +#ifdef __alpha__ +#define ptob(p) ((p) << 13) +#endif + +unsigned long +memsize() +{ + unsigned long amount = 0; + MEMORY_DESCRIPTOR *desc; + + for (desc = GetMemoryDescriptor(NULL); desc; + desc = GetMemoryDescriptor(desc)) { + printf("%s at %x-%x\n", MemoryTypes[desc->Type], + ptob(desc->BasePage), + ptob(desc->BasePage + desc->PageCount)); + if (desc->Type == MemoryFree + || desc->Type == MemoryFirmwareTemporary) + amount += (desc->PageCount << 13); /* XXX pagesize */ + } + + return amount; +} + +static char *ConfigurationClasses[] = { + "SystemClass", + "ProcessorClass", + "CacheClass", + "AdapterClass", + "ControllerClass", + "PeripheralClass", + "MemoryClass", + "MaximumClass", +}; + + +static char *ConfigurationTypes[] = { + "ArcSystem", + "CentralProcessor", + "FloatingPointProcessor", + "PrimaryIcache", + "PrimaryDcache", + "SecondaryIcache", + "SecondaryDcache", + "SecondaryCache", + "EisaAdapter", + "TcAdapter", + "ScsiAdapter", + "DtiAdapter", + "MultiFunctionAdapter", + "DiskController", + "TapeController", + "CdromController", + "WormController", + "SerialController", + "NetworkController", + "DisplayController", + "ParallelController", + "PointerController", + "KeyboardController", + "AudioController", + "OtherController", + "DiskPeripheral", + "FloppyDiskPeripheral", + "TapePeripheral", + "ModemPeripheral", + "MonitorPeripheral", + "PrinterPeripheral", + "PointerPeripheral", + "KeyboardPeripheral", + "TerminalPeripheral", + "OtherPeripheral", + "LinePeripheral", + "NetworkPeripheral", + "SystemMemory", + "MaximumType", +}; + +static char *ConfigurationTypeCodes[] = { + "ARC", + "CPU", + "FPC", + "PrimaryIcache", + "PrimaryDcache", + "SecondaryIcache", + "SecondaryDcache", + "SecondaryCache", + "eisa", + "TcAdapter", /* XXX ? */ + "scsi", + "DtiAdapter", /* XXX ? */ + "multi", + "disk", + "TapeController", /* XXX ? */ + "CdromController", /* XXX ? */ + "WormController", /* XXX ? */ + "serial", + "NetworkController", /* XXX ? */ + "video", + "par", + "PointerController", /* XXX ? */ + "key", + "AudioController", /* XXX ? */ + "OtherController", /* XXX ? */ + "rdisk", + "fdisk", + "TapePeripheral", /* XXX ? */ + "ModemPeripheral", /* XXX ? */ + "MonitorPeripheral", /* XXX ? */ + "PrinterPeripheral", /* XXX ? */ + "PointerPeripheral", /* XXX ? */ + "keyboard", + "TerminalPeripheral", /* XXX ? */ + "OtherPeripheral", /* XXX ? */ + "LinePeripheral", /* XXX ? */ + "NetworkPeripheral", /* XXX ? */ + "Memory", + "MaximumType" +}; + +static void +indent(int level) +{ + while (level--) + putchar(' '); +} + +void +printconfig(unsigned int level, CONFIGURATION_COMPONENT *component) +{ + CONFIGURATION_COMPONENT *child; + + indent(level); + printf("%s(%s,%d)", + ConfigurationClasses[component->Class], + ConfigurationTypes[component->Type], + component->Key); +#if 1 + if (component->IdentifierLength) + printf("=%d,%s\n", component->IdentifierLength, + ptr(component->Identifier)); + else + putchar('\n'); +#endif + getchar(); + + for (child = GetChild(component); child; child = GetPeer(child)) { + printconfig(level + 2, child); + } +} + +void +dumpdisk(const char *name) +{ + u_int32_t fd, count; + unsigned char buf[512]; + int i, j; + + printf("dump first sector of %s\n", name); + if (Open(name, OpenReadOnly, &fd) != ESUCCESS) { + printf("can't open disk\n"); + return; + } + if (Read(fd, buf, 512, &count) != ESUCCESS) { + printf("can't read from disk\n"); + Close(fd); + return; + } + for (i = 0; i < 16; i++) { + for (j = 0; j < 32; j++) + printf("%02x", buf[i*32 + j]); + putchar('\n'); + } + Close(fd); +} + +void +listdisks(char *path, CONFIGURATION_COMPONENT *component) +{ + CONFIGURATION_COMPONENT *child; + char newpath[80]; + char keybuf[20]; + + if (path == NULL) { + printf("\nARC disk devices:\n"); + newpath[0] = '\0'; + } else { + strcpy(newpath, path); + strcat(newpath, ConfigurationTypeCodes[component->Type]); + sprintf(keybuf, "(%d)", component->Key); + strcat(newpath, keybuf); + } + if (!strcmp(ConfigurationTypeCodes[component->Type], "rdisk") || + !strcmp(ConfigurationTypeCodes[component->Type], "fdisk")) { + printf("%s\n", newpath); + } + for (child = GetChild(component); child; child = GetPeer(child)) { + listdisks(newpath, child); + } +} + +static int exit_code = 0; +jmp_buf exit_env; + +void +exit(int code) +{ + exit_code = 0; + longjmp(exit_env, 1); +} + +int +main(int argc, int argv[], int envp[]) +{ + int i; + char *bootfile; + + if (setjmp(exit_env)) + return exit_code; + + /* + * Initialise the heap as early as possible. Once this is done, + * alloc() is usable. The stack is buried inside us, so this is + * safe. + */ + setheap((void *)end, (void *)(end + 512*1024)); + + /* + * XXX Chicken-and-egg problem; we want to have console output + * early, but some console attributes may depend on reading from + * eg. the boot device, which we can't do yet. We can use + * printf() etc. once this is done. + */ + cons_probe(); + +#if 0 + printconfig(0, GetChild(NULL)); + dumpdisk("scsi(0)disk(0)rdisk(0)partition(0)"); +#endif + listdisks(NULL, GetChild(NULL)); + printf("\n"); + + make_rpb(); + + /* + * Initialise the block cache + */ + bcache_init(32, 512); /* 16k XXX tune this */ + + /* + * March through the device switch probing for things. + */ + for (i = 0; devsw[i] != NULL; i++) + if (devsw[i]->dv_init != NULL) + (devsw[i]->dv_init)(); + + printf("\n"); + printf("%s, Revision %s\n", bootprog_name, bootprog_rev); + printf("(%s, %s)\n", bootprog_maker, bootprog_date); + printf("Memory: %ld k\n", memsize() / 1024); + + /* We're booting from an SRM disk, try to spiff this */ + /* XXX presumes that biosdisk is first in devsw */ + currdev.d_dev = devsw[0]; + currdev.d_type = currdev.d_dev->dv_type; + currdev.d_kind.arcdisk.unit = 0; + /* XXX should be able to detect this, default to autoprobe */ + currdev.d_kind.arcdisk.slice = -1; + /* default to 'a' */ + currdev.d_kind.arcdisk.partition = 0; + + /* Create arc-specific variables */ + bootfile = GetEnvironmentVariable(ARCENV_BOOTFILE); + if (bootfile) + setenv("bootfile", bootfile, 1); + + env_setenv("currdev", EV_VOLATILE, + arc_fmtdev(&currdev), arc_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, + arc_fmtdev(&currdev), env_noset, env_nounset); + setenv("LINES", "24", 1); /* optional */ + + archsw.arch_autoload = arc_autoload; + archsw.arch_getdev = arc_getdev; + archsw.arch_copyin = arc_copyin; + archsw.arch_copyout = arc_copyout; + archsw.arch_readin = arc_readin; + + interact(); /* doesn't return */ + + return 0; /* keep compiler happy */ +} + +COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot); + +static int +command_reboot(int argc, char *argv[]) +{ + + printf("Rebooting...\n"); + delay(1000000); + FwReboot(); + /* Note: we shouldn't get to this point! */ + panic("Reboot failed!"); + exit(0); +} + +COMMAND_SET(quit, "quit", "exit the loader", command_quit); + +static int +command_quit(int argc, char *argv[]) +{ + exit(0); + return(CMD_OK); +} + +#if 0 + +COMMAND_SET(stack, "stack", "show stack usage", command_stack); + +static int +command_stack(int argc, char *argv[]) +{ + char *cp; + + for (cp = &stackbase; cp < &stacktop; cp++) + if (*cp != 0) + break; + + printf("%d bytes of stack used\n", &stacktop - cp); + return(CMD_OK); +} + +#endif + +COMMAND_SET(heap, "heap", "show heap usage", command_heap); + +static int +command_heap(int argc, char *argv[]) +{ + printf("heap base at %p, top at %p, used %ld\n", end, sbrk(0), sbrk(0) - end); + return(CMD_OK); +} |