int x86_init_fdt(void) { void *dtbp, *mdp; int error; if (OF_install(OFW_FDT, 0) == FALSE) { error = ENXIO; goto out; } mdp = preload_search_by_type("elf kernel"); if (mdp == NULL) mdp = preload_search_by_type("elf32 kernel"); dtbp = (mdp != NULL) ? MD_FETCH(mdp, MODINFOMD_DTBP, void *) : NULL; #if defined(FDT_DTB_STATIC) /* * In case the device tree blob was not retrieved (from metadata) try * to use the statically embedded one. */ if (dtbp == NULL) dtbp = &fdt_static_dtb; #endif if (dtbp == NULL) { error = ENOENT; goto out; } error = OF_init(dtbp) ? ENXIO : 0; out: return (error); }
static void try_load_dtb(caddr_t kmdp) { vm_offset_t dtbp; dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t); if (dtbp == (vm_offset_t)NULL) { printf("ERROR loading DTB\n"); return; } if (OF_install(OFW_FDT, 0) == FALSE) panic("Cannot install FDT"); if (OF_init((void *)dtbp) != 0) panic("OF_init failed with the found device tree"); }
int main(int (*openfirm)(void *)) { char bootpath[64]; struct devsw **dp; phandle_t chosenh; /* * Tell the OpenFirmware functions where they find the ofw gate. */ OF_init(openfirm); archsw.arch_getdev = ofw_getdev; archsw.arch_copyin = sparc64_copyin; archsw.arch_copyout = ofw_copyout; archsw.arch_readin = sparc64_readin; archsw.arch_autoload = sparc64_autoload; init_heap(); setheap((void *)heapva, (void *)(heapva + HEAPSZ)); /* * Probe for a console. */ cons_probe(); tlb_init(); bcache_init(32, 512); /* * Initialize devices. */ for (dp = devsw; *dp != 0; dp++) { if ((*dp)->dv_init != 0) (*dp)->dv_init(); } /* * Set up the current device. */ chosenh = OF_finddevice("/chosen"); OF_getprop(chosenh, "bootpath", bootpath, sizeof(bootpath)); /* * Sun compatible bootable CD-ROMs have a disk label placed * before the cd9660 data, with the actual filesystem being * in the first partition, while the other partitions contain * pseudo disk labels with embedded boot blocks for different * architectures, which may be followed by UFS filesystems. * The firmware will set the boot path to the partition it * boots from ('f' in the sun4u case), but we want the kernel * to be loaded from the cd9660 fs ('a'), so the boot path * needs to be altered. */ if (bootpath[strlen(bootpath) - 2] == ':' && bootpath[strlen(bootpath) - 1] == 'f') { bootpath[strlen(bootpath) - 1] = 'a'; printf("Boot path set to %s\n", bootpath); } env_setenv("currdev", EV_VOLATILE, bootpath, ofw_setcurrdev, env_nounset); env_setenv("loaddev", EV_VOLATILE, bootpath, env_noset, env_nounset); printf("\n"); printf("%s, Revision %s\n", bootprog_name, bootprog_rev); printf("(%s, %s)\n", bootprog_maker, bootprog_date); printf("bootpath=\"%s\"\n", bootpath); /* Give control to the machine independent loader code. */ interact(); return 1; }
void platform_start(__register_t a0 __unused, __register_t a1 __unused, __register_t a2 __unused, __register_t a3 __unused) { vm_offset_t kernend; int argc = a0, i;//, res; uint32_t timer_clk; char **argv = (char **)MIPS_PHYS_TO_KSEG0(a1); char **envp = (char **)MIPS_PHYS_TO_KSEG0(a2); void *dtbp; phandle_t chosen; char buf[2048]; /* clear the BSS and SBSS segments */ kernend = (vm_offset_t)&end; memset(&edata, 0, kernend - (vm_offset_t)(&edata)); mips_postboot_fixup(); /* Initialize pcpu stuff */ mips_pcpu0_init(); dtbp = &fdt_static_dtb; if (OF_install(OFW_FDT, 0) == FALSE) while (1); if (OF_init((void *)dtbp) != 0) while (1); mtk_soc_try_early_detect(); if ((timer_clk = mtk_soc_get_timerclk()) == 0) timer_clk = 1000000000; /* no such speed yet */ mips_timer_early_init(timer_clk); /* initialize console so that we have printf */ boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */ boothowto |= (RB_VERBOSE); cninit(); init_static_kenv(boot1_env, sizeof(boot1_env)); /* * Get bsdbootargs from FDT if specified. */ chosen = OF_finddevice("/chosen"); if (OF_getprop(chosen, "bsdbootargs", buf, sizeof(buf)) != -1) _parse_bootargs(buf); printf("FDT DTB at: 0x%08x\n", (uint32_t)dtbp); printf("CPU clock: %4dMHz\n", mtk_soc_get_cpuclk()/(1000*1000)); printf("Timer clock: %4dMHz\n", timer_clk/(1000*1000)); printf("UART clock: %4dMHz\n\n", mtk_soc_get_uartclk()/(1000*1000)); printf("U-Boot args (from %d args):\n", argc - 1); if (argc == 1) printf("\tNone\n"); for (i = 1; i < argc; i++) { char *n = "argv ", *arg; if (i > 99) break; if (argv[i]) { arg = (char *)(intptr_t)MIPS_PHYS_TO_KSEG0(argv[i]); printf("\targv[%d] = %s\n", i, arg); sprintf(n, "argv%d", i); kern_setenv(n, arg); } } printf("Environment:\n"); for (i = 0; envp[i] && MIPS_IS_VALID_PTR(envp[i]); i++) { char *n, *arg; arg = (char *)(intptr_t)MIPS_PHYS_TO_KSEG0(envp[i]); if (! MIPS_IS_VALID_PTR(arg)) continue; printf("\t%s\n", arg); n = strsep(&arg, "="); if (arg == NULL) kern_setenv(n, "1"); else kern_setenv(n, arg); } mips_init(); mips_timer_init_params(timer_clk, 0); }
int main(int (*openfirm)(void *)) { phandle_t root; int i; char bootpath[64]; char *ch; int bargc; char **bargv; /* * Initialize the Open Firmware routines by giving them the entry point. */ OF_init(openfirm); root = OF_finddevice("/"); scells = acells = 1; OF_getprop(root, "#address-cells", &acells, sizeof(acells)); OF_getprop(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(); /* * 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: %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], ofw_setcurrdev, env_nounset); else env_setenv("currdev", EV_VOLATILE, bootpath, ofw_setcurrdev, env_nounset); env_setenv("loaddev", EV_VOLATILE, bootpath, env_noset, env_nounset); setenv("LINES", "24", 1); /* optional */ archsw.arch_getdev = ofw_getdev; archsw.arch_copyin = ofw_copyin; archsw.arch_copyout = ofw_copyout; archsw.arch_readin = ofw_readin; archsw.arch_autoload = ofw_autoload; interact(NULL); /* doesn't return */ OF_exit(); return 0; }
void platform_start(__register_t a0, __register_t a1, __register_t a2, __register_t a3) { struct bootinfo *bootinfop; vm_offset_t kernend; uint64_t platform_counter_freq; int argc = a0; char **argv = (char **)a1; char **envp = (char **)a2; long memsize; #ifdef FDT char buf[2048]; /* early stack supposedly big enough */ vm_offset_t dtbp = 0; phandle_t chosen; void *kmdp; int dtb_needs_swap = 0; /* error */ size_t dtb_size = 0; #ifndef FDT_DTB_STATIC_ONLY struct fdt_header *dtb_rom, *dtb; uint32_t *swapptr; #endif int fdt_source = FDT_SOURCE_NONE; #endif int i; /* clear the BSS and SBSS segments */ kernend = (vm_offset_t)&end; memset(&edata, 0, kernend - (vm_offset_t)(&edata)); mips_postboot_fixup(); mips_pcpu0_init(); /* * Over time, we've changed out boot-time binary interface for the * kernel. Miniboot simply provides a 'memsize' in a3, whereas the * FreeBSD boot loader provides a 'bootinfo *' in a3. While slightly * grody, we support both here by detecting 'pointer-like' values in * a3 and assuming physical memory can never be that big. * * XXXRW: Pull more values than memsize out of bootinfop -- e.g., * module information. */ if (a3 >= 0x9800000000000000ULL) { bootinfop = (void *)a3; memsize = bootinfop->bi_memsize; preload_metadata = (caddr_t)bootinfop->bi_modulep; } else { bootinfop = NULL; memsize = a3; } kmdp = preload_search_by_type("elf kernel"); /* * Configure more boot-time parameters passed in by loader. */ boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *), 0); #ifdef FDT #ifndef FDT_DTB_STATIC_ONLY /* * Find the dtb passed in by the boot loader (currently fictional). * * Prefer a dtb provided as a module to one from bootinfo as we may * have loaded an alternative one or created a modified version. */ dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t); if (dtbp == (vm_offset_t)NULL && bootinfop != NULL && bootinfop->bi_dtb != (bi_ptr_t)NULL) { dtbp = bootinfop->bi_dtb; fdt_source = FDT_SOURCE_LOADER; } /* Try to find an FDT directly in the hardware */ if (dtbp == (vm_offset_t)NULL) { dtb_rom = (void*)(intptr_t)0x900000007f010000; if (dtb_rom->magic == FDT_MAGIC) { dtb_needs_swap = 0; dtb_size = dtb_rom->totalsize; } else if (dtb_rom->magic == bswap32(FDT_MAGIC)) { dtb_needs_swap = 1; dtb_size = bswap32(dtb_rom->totalsize); } if (dtb_size != 0) { /* Steal a bit of memory... */ dtb = (void *)kernel_kseg0_end; /* Round alignment from linker script. */ kernel_kseg0_end += roundup2(dtb_size, 64 / 8); memcpy(dtb, dtb_rom, dtb_size); if (dtb_needs_swap) for (swapptr = (uint32_t *)dtb; swapptr < (uint32_t *)dtb + (dtb_size/sizeof(*dtb)); swapptr++) *swapptr = bswap32(*swapptr); dtbp = (vm_offset_t)dtb; fdt_source = FDT_SOURCE_ROM; } } #endif /* !FDT_DTB_STATIC_ONLY */ #if defined(FDT_DTB_STATIC) /* * In case the device tree blob was not retrieved (from metadata) try * to use the statically embedded one. */ if (dtbp == (vm_offset_t)NULL) { dtbp = (vm_offset_t)&fdt_static_dtb; fdt_source = FDT_SOURCE_STATIC; } #endif if (OF_install(OFW_FDT, 0) == FALSE) while (1); if (OF_init((void *)dtbp) != 0) while (1); /* * Get bootargs from FDT if specified. */ chosen = OF_finddevice("/chosen"); if (OF_getprop(chosen, "bootargs", buf, sizeof(buf)) != -1) _parse_bootargs(buf); #endif /* * XXXRW: We have no way to compare wallclock time to cycle rate on * BERI, so for now assume we run at the MALTA default (100MHz). */ platform_counter_freq = MIPS_DEFAULT_HZ; mips_timer_early_init(platform_counter_freq); cninit(); printf("entry: platform_start()\n"); #ifdef FDT if (dtbp != (vm_offset_t)NULL) { printf("Using FDT at %p from ", (void *)dtbp); switch (fdt_source) { case FDT_SOURCE_LOADER: printf("loader"); break; case FDT_SOURCE_ROM: printf("ROM"); break; case FDT_SOURCE_STATIC: printf("kernel"); break; default: printf("unknown source %d", fdt_source); break; } printf("\n"); } if (dtb_size != 0 && dtb_needs_swap) printf("FDT was byteswapped\n"); #endif bootverbose = 1; if (bootverbose) { printf("cmd line: "); for (i = 0; i < argc; i++) printf("%s ", argv[i]); printf("\n"); printf("envp:\n"); for (i = 0; envp[i]; i += 2) printf("\t%s = %s\n", envp[i], envp[i+1]); if (bootinfop != NULL) printf("bootinfo found at %p\n", bootinfop); printf("memsize = %p\n", (void *)memsize); } realmem = btoc(memsize); mips_init(); mips_timer_init_params(platform_counter_freq, 0); }
void platform_start(__register_t a0, __register_t a1, __register_t a2, __register_t a3) { struct bootinfo *bootinfop; vm_offset_t kernend; uint64_t platform_counter_freq; int argc = a0; char **argv = (char **)a1; char **envp = (char **)a2; long memsize; #ifdef FDT char buf[2048]; /* early stack supposedly big enough */ vm_offset_t dtbp; phandle_t chosen; void *kmdp; #endif int i; /* clear the BSS and SBSS segments */ kernend = (vm_offset_t)&end; memset(&edata, 0, kernend - (vm_offset_t)(&edata)); mips_postboot_fixup(); mips_pcpu0_init(); /* * Over time, we've changed out boot-time binary interface for the * kernel. Miniboot simply provides a 'memsize' in a3, whereas the * FreeBSD boot loader provides a 'bootinfo *' in a3. While slightly * grody, we support both here by detecting 'pointer-like' values in * a3 and assuming physical memory can never be that back. * * XXXRW: Pull more values than memsize out of bootinfop -- e.g., * module information. */ if (a3 >= 0x9800000000000000ULL) { bootinfop = (void *)a3; memsize = bootinfop->bi_memsize; preload_metadata = (caddr_t)bootinfop->bi_modulep; } else { bootinfop = NULL; memsize = a3; } #ifdef FDT /* * Find the dtb passed in by the boot loader (currently fictional). */ kmdp = preload_search_by_type("elf kernel"); dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t); #if defined(FDT_DTB_STATIC) /* * In case the device tree blob was not retrieved (from metadata) try * to use the statically embedded one. */ if (dtbp == (vm_offset_t)NULL) dtbp = (vm_offset_t)&fdt_static_dtb; #else #error "Non-static FDT not yet supported on BERI" #endif if (OF_install(OFW_FDT, 0) == FALSE) while (1); if (OF_init((void *)dtbp) != 0) while (1); /* * Configure more boot-time parameters passed in by loader. */ boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *), 0); /* * Get bootargs from FDT if specified. */ chosen = OF_finddevice("/chosen"); if (OF_getprop(chosen, "bootargs", buf, sizeof(buf)) != -1) _parse_bootargs(buf); #endif /* * XXXRW: We have no way to compare wallclock time to cycle rate on * BERI, so for now assume we run at the MALTA default (100MHz). */ platform_counter_freq = MIPS_DEFAULT_HZ; mips_timer_early_init(platform_counter_freq); cninit(); printf("entry: platform_start()\n"); bootverbose = 1; if (bootverbose) { printf("cmd line: "); for (i = 0; i < argc; i++) printf("%s ", argv[i]); printf("\n"); printf("envp:\n"); for (i = 0; envp[i]; i += 2) printf("\t%s = %s\n", envp[i], envp[i+1]); if (bootinfop != NULL) printf("bootinfo found at %p\n", bootinfop); printf("memsize = %p\n", (void *)memsize); } realmem = btoc(memsize); mips_init(); mips_timer_init_params(platform_counter_freq, 0); }
void platform_start(__register_t a0, __register_t a1, __register_t a2, __register_t a3) { vm_offset_t kernend; uint64_t platform_counter_freq; int argc = a0; char **argv = (char **)a1; char **envp = (char **)a2; unsigned int memsize = a3; #ifdef FDT char buf[2048]; /* early stack supposedly big enough */ vm_offset_t dtbp; phandle_t chosen; void *kmdp; #endif int i; /* clear the BSS and SBSS segments */ kernend = (vm_offset_t)&end; memset(&edata, 0, kernend - (vm_offset_t)(&edata)); mips_postboot_fixup(); mips_pcpu0_init(); #ifdef FDT /* * Find the dtb passed in by the boot loader (currently fictional). */ kmdp = preload_search_by_type("elf kernel"); if (kmdp != NULL) dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t); else dtbp = (vm_offset_t)NULL; #if defined(FDT_DTB_STATIC) /* * In case the device tree blob was not retrieved (from metadata) try * to use the statically embedded one. */ if (dtbp == (vm_offset_t)NULL) dtbp = (vm_offset_t)&fdt_static_dtb; #else #error "Non-static FDT not yet supported on BERI" #endif if (OF_install(OFW_FDT, 0) == FALSE) while (1); if (OF_init((void *)dtbp) != 0) while (1); /* * Get bootargs from FDT if specified. */ chosen = OF_finddevice("/chosen"); if (OF_getprop(chosen, "bootargs", buf, sizeof(buf)) != -1) _parse_bootargs(buf); #endif /* * XXXRW: We have no way to compare wallclock time to cycle rate on * BERI, so for now assume we run at the MALTA default (100MHz). */ platform_counter_freq = MIPS_DEFAULT_HZ; mips_timer_early_init(platform_counter_freq); cninit(); printf("entry: platform_start()\n"); bootverbose = 1; if (bootverbose) { printf("cmd line: "); for (i = 0; i < argc; i++) printf("%s ", argv[i]); printf("\n"); printf("envp:\n"); for (i = 0; envp[i]; i += 2) printf("\t%s = %s\n", envp[i], envp[i+1]); printf("memsize = %08x\n", memsize); } realmem = btoc(memsize); mips_init(); mips_timer_init_params(platform_counter_freq, 0); }