123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- /*-
- * Copyright (c) 2000 Benno Rice <benno@jeamland.net>
- * Copyright (c) 2000 Stephane Potvin <sepotvin@videotron.ca>
- * 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 AUTHORS 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.
- */
- #include <sys/endian.h>
- #include <stand.h>
- #include "openfirm.h"
- #include "libofw.h"
- #include "bootstrap.h"
- #include <machine/asm.h>
- #include <machine/psl.h>
- struct arch_switch archsw; /* MI/MD interface boundary */
- extern char end[];
- uint32_t acells, scells;
- static char bootargs[128];
- #define HEAP_SIZE 0x800000
- static char heap[HEAP_SIZE]; // In BSS, so uses no space
- #define OF_puts(fd, text) OF_write(fd, text, strlen(text))
- static __inline register_t
- mfmsr(void)
- {
- register_t value;
- __asm __volatile ("mfmsr %0" : "=r"(value));
- return (value);
- }
- void
- init_heap(void)
- {
- bzero(heap, HEAP_SIZE);
- setheap(heap, (void *)((uintptr_t)heap + HEAP_SIZE));
- }
- uint64_t
- memsize(void)
- {
- phandle_t memoryp;
- cell_t reg[24];
- int i, sz;
- uint64_t memsz;
- memsz = 0;
- memoryp = OF_instance_to_package(memory);
- sz = OF_getencprop(memoryp, "reg", ®[0], sizeof(reg));
- sz /= sizeof(reg[0]);
- for (i = 0; i < sz; i += (acells + scells)) {
- if (scells > 1)
- memsz += (uint64_t)reg[i + acells] << 32;
- memsz += reg[i + acells + scells - 1];
- }
- return (memsz);
- }
- #ifdef CAS
- extern int ppc64_cas(void);
- static int
- ppc64_autoload(void)
- {
- const char *cas;
- if ((cas = getenv("cas")) && cas[0] == '1')
- if (ppc64_cas() != 0)
- return (-1);
- return (ofw_autoload());
- }
- #endif
- #if BYTE_ORDER == LITTLE_ENDIAN
- /*
- * In Little-endian, we cannot just branch to the client interface. Since
- * the client interface is big endian, we have to rfid to it.
- * Likewise, when execution resumes, we are in the wrong endianness so
- * we must do a fixup before returning to the caller.
- */
- static int (*openfirmware_entry)(void *);
- extern int openfirmware_trampoline(void *buf, int (*cb)(void *));
- /*
- * Wrapper to pass the real entry point to our trampoline.
- */
- static int
- openfirmware_docall(void *buf)
- {
- return openfirmware_trampoline(buf, openfirmware_entry);
- }
- #endif
- int
- main(int (*openfirm)(void *))
- {
- phandle_t root;
- int i;
- char bootpath[64];
- char *ch;
- int bargc;
- char **bargv;
- /*
- * Initialise the Open Firmware routines by giving them the entry point.
- */
- #if BYTE_ORDER == LITTLE_ENDIAN
- /*
- * Use a trampoline entry point for endian fixups.
- */
- openfirmware_entry = openfirm;
- OF_init(openfirmware_docall);
- #else
- OF_init(openfirm);
- #endif
- root = OF_finddevice("/");
- scells = acells = 1;
- OF_getencprop(root, "#address-cells", &acells, sizeof(acells));
- OF_getencprop(root, "#size-cells", &scells, sizeof(scells));
- /*
- * Initialise the heap as early as possible. Once this is done,
- * alloc() is usable. The stack is buried inside us, so this is
- * safe.
- */
- init_heap();
- /*
- * Set up console.
- */
- cons_probe();
- archsw.arch_getdev = ofw_getdev;
- archsw.arch_copyin = ofw_copyin;
- archsw.arch_copyout = ofw_copyout;
- archsw.arch_readin = ofw_readin;
- #ifdef CAS
- setenv("cas", "1", 0);
- archsw.arch_autoload = ppc64_autoload;
- #else
- archsw.arch_autoload = ofw_autoload;
- #endif
- /* Set up currdev variable to have hooks in place. */
- env_setenv("currdev", EV_VOLATILE, "", gen_setcurrdev, env_nounset);
- devinit();
- printf("\n%s", bootprog_info);
- printf("Memory: %lldKB\n", memsize() / 1024);
- OF_getprop(chosen, "bootpath", bootpath, 64);
- ch = strchr(bootpath, ':');
- *ch = '\0';
- printf("Booted from: %s\n", bootpath);
- printf("\n");
- /*
- * Only parse the first bootarg if present. It should
- * be simple to handle extra arguments
- */
- OF_getprop(chosen, "bootargs", bootargs, sizeof(bootargs));
- bargc = 0;
- parse(&bargc, &bargv, bootargs);
- if (bargc == 1)
- env_setenv("currdev", EV_VOLATILE, bargv[0], gen_setcurrdev,
- env_nounset);
- else
- env_setenv("currdev", EV_VOLATILE, bootpath,
- gen_setcurrdev, env_nounset);
- env_setenv("loaddev", EV_VOLATILE, bootpath, env_noset,
- env_nounset);
- setenv("LINES", "24", 1); /* optional */
- /*
- * On non-Apple hardware, where it works reliably, pass flattened
- * device trees to the kernel by default instead of OF CI pointers.
- * Apple hardware is the only virtual-mode OF implementation in
- * existence, so far as I am aware, so use that as a flag.
- */
- if (!(mfmsr() & PSL_DR))
- setenv("usefdt", "1", 1);
- interact(); /* doesn't return */
- OF_exit();
- return 0;
- }
- COMMAND_SET(halt, "halt", "halt the system", command_halt);
- static int
- command_halt(int argc, char *argv[])
- {
- OF_exit();
- return (CMD_OK);
- }
- COMMAND_SET(memmap, "memmap", "print memory map", command_memmap);
- int
- command_memmap(int argc, char **argv)
- {
- ofw_memmap(acells);
- return (CMD_OK);
- }
|