static void _parse_bootarg(char *v) { char *n; if (*v == '-') { while (*v != '\0') { v++; switch (*v) { case 'a': boothowto |= RB_ASKNAME; break; /* Someone should simulate that ;-) */ case 'C': boothowto |= RB_CDROM; break; case 'd': boothowto |= RB_KDB; break; case 'D': boothowto |= RB_MULTIPLE; break; case 'm': boothowto |= RB_MUTE; break; case 'g': boothowto |= RB_GDB; break; case 'h': boothowto |= RB_SERIAL; break; case 'p': boothowto |= RB_PAUSE; break; case 'r': boothowto |= RB_DFLTROOT; break; case 's': boothowto |= RB_SINGLE; break; case 'v': boothowto |= RB_VERBOSE; break; } } } else { n = strsep(&v, "="); if (v == NULL) kern_setenv(n, "1"); else kern_setenv(n, v); } }
/* * The boot loader command line may specify kernel environment variables or * applicable boot flags of boot(8). */ static void octeon_init_kenv(register_t ptr) { int i; char *n; char *v; octeon_boot_descriptor_t *app_desc_ptr; app_desc_ptr = (octeon_boot_descriptor_t *)(intptr_t)ptr; memset(octeon_kenv, 0, sizeof(octeon_kenv)); init_static_kenv(octeon_kenv, sizeof(octeon_kenv)); for (i = 0; i < app_desc_ptr->argc; i++) { v = cvmx_phys_to_ptr(app_desc_ptr->argv[i]); if (v == NULL) continue; if (*v == '-') { boothowto_parse(v); continue; } n = strsep(&v, "="); if (v == NULL) kern_setenv(n, "1"); else kern_setenv(n, v); } }
/* * We get a string in from Redboot with the all the arguments together, * "foo=bar bar=baz". Split them up and save in kenv. */ static void parse_argv(char *str) { char *n, *v; while ((v = strsep(&str, " ")) != NULL) { if (*v == '\0') continue; if (*v == '-') { while (*v != '\0') { v++; switch (*v) { case 'a': boothowto |= RB_ASKNAME; break; case 'd': boothowto |= RB_KDB; break; case 'g': boothowto |= RB_GDB; break; case 's': boothowto |= RB_SINGLE; break; case 'v': boothowto |= RB_VERBOSE; break; } } } else { n = strsep(&v, "="); if (v == NULL) kern_setenv(n, "1"); else kern_setenv(n, v); } } }
/* * Populate a kenv hint for the given device based on the given * MAC address and offset. * * Returns 0 if ok, < 0 on error. */ static int ar71xx_platform_set_mac_hint(const char *dev, int unit, const uint8_t *macaddr, int offset, int islocal) { char macstr[32]; uint8_t lclmac[ETHER_ADDR_LEN]; char devstr[32]; /* Initialise the MAC address, plus/minus the offset */ if (ar71xx_mac_addr_init(lclmac, macaddr, offset, islocal) != 0) { return (-1); } /* Turn it into a string */ snprintf(macstr, 32, "%6D", lclmac, ":"); snprintf(devstr, 32, "hint.%s.%d.macaddr", dev, unit); printf(" %s => %s\n", devstr, macstr); /* Call setenv */ if (kern_setenv(devstr, macstr) != 0) { printf("%s: failed to set hint (%s => %s)\n", __func__, devstr, macstr); return (-1); } return (0); }
void cfe_env_init(void) { int idx; char name[KENV_MNAMELEN], val[KENV_MVALLEN]; init_static_kenv(cfe_env_buf, CFE_ENV_SIZE); idx = 0; while (1) { if (cfe_enumenv(idx, name, sizeof(name), val, sizeof(val)) != 0) break; if (kern_setenv(name, val) != 0) { printf("No space to store CFE env: \"%s=%s\"\n", name, val); } ++idx; } }
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); }
static int sysctl_hintmode(SYSCTL_HANDLER_ARGS) { const char *cp; char *line, *eq; int eqidx, error, from_kenv, i, value; from_kenv = 0; cp = kern_envp; value = hintmode; /* Fetch candidate for new hintmode value */ error = sysctl_handle_int(oidp, &value, 0, req); if (error || req->newptr == NULL) return (error); if (value != 2) /* Only accept swithing to hintmode 2 */ return (EINVAL); /* Migrate from static to dynamic hints */ switch (hintmode) { case 0: if (dynamic_kenv) { /* * Already here. But assign hintmode to 2, to not * check it in the future. */ hintmode = 2; return (0); } from_kenv = 1; cp = kern_envp; break; case 1: cp = static_hints; break; case 2: /* Nothing to do, hintmode already 2 */ return (0); } while (cp) { i = strlen(cp); if (i == 0) break; if (from_kenv) { if (strncmp(cp, "hint.", 5) != 0) /* kenv can have not only hints */ continue; } eq = strchr(cp, '='); if (eq == NULL) /* Bad hint value */ continue; eqidx = eq - cp; line = malloc(i+1, M_TEMP, M_WAITOK); strcpy(line, cp); line[eqidx] = '\0'; kern_setenv(line, line + eqidx + 1); free(line, M_TEMP); cp += i + 1; } hintmode = value; use_kenv = 1; return (0); }
void platform_start(__register_t a0 __unused, __register_t a1 __unused, __register_t a2 __unused, __register_t a3 __unused) { uint64_t platform_counter_freq; int argc = 0, i; char **argv = NULL, **envp = NULL; vm_offset_t kernend; /* * clear the BSS and SBSS segments, this should be first call in * the function */ kernend = (vm_offset_t)&end; memset(&edata, 0, kernend - (vm_offset_t)(&edata)); mips_postboot_fixup(); /* Initialize pcpu stuff */ mips_pcpu0_init(); /* * Until some more sensible abstractions for uboot/redboot * environment handling, we have to make this a compile-time * hack. The existing code handles the uboot environment * very incorrectly so we should just ignore initialising * the relevant pointers. */ #ifndef AR71XX_ENV_UBOOT argc = a0; argv = (char**)a1; envp = (char**)a2; #endif /* * Protect ourselves from garbage in registers */ if (MIPS_IS_VALID_PTR(envp)) { for (i = 0; envp[i]; i += 2) { if (strcmp(envp[i], "memsize") == 0) realmem = btoc(strtoul(envp[i+1], NULL, 16)); else if (strcmp(envp[i], "bootverbose") == 0) bootverbose = btoc(strtoul(envp[i+1], NULL, 10)); } } bootverbose = 1; #ifdef AR71XX_ENV_ROUTERBOOT /* * RouterBoot informs the board memory as a command line argument. */ if (realmem == 0) realmem = ar71xx_routerboot_get_mem(argc, argv); #endif /* * Just wild guess. RedBoot let us down and didn't reported * memory size */ if (realmem == 0) realmem = btoc(32*1024*1024); /* * Allow build-time override in case Redboot lies * or in other situations (eg where there's u-boot) * where there isn't (yet) a convienent method of * being told how much RAM is available. * * This happens on at least the Ubiquiti LS-SR71A * board, where redboot says there's 16mb of RAM * but in fact there's 32mb. */ #if defined(AR71XX_REALMEM) realmem = btoc(AR71XX_REALMEM); #endif /* phys_avail regions are in bytes */ phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); phys_avail[1] = ctob(realmem); dump_avail[0] = phys_avail[0]; dump_avail[1] = phys_avail[1] - phys_avail[0]; physmem = realmem; /* * ns8250 uart code uses DELAY so ticker should be inititalized * before cninit. And tick_init_params refers to hz, so * init_param1 * should be called first. */ init_param1(); /* Detect the system type - this is needed for subsequent chipset-specific calls */ ar71xx_detect_sys_type(); ar71xx_detect_sys_frequency(); platform_counter_freq = ar71xx_cpu_freq(); mips_timer_init_params(platform_counter_freq, 1); cninit(); init_static_kenv(boot1_env, sizeof(boot1_env)); printf("CPU platform: %s\n", ar71xx_get_system_type()); printf("CPU Frequency=%d MHz\n", u_ar71xx_cpu_freq / 1000000); printf("CPU DDR Frequency=%d MHz\n", u_ar71xx_ddr_freq / 1000000); printf("CPU AHB Frequency=%d MHz\n", u_ar71xx_ahb_freq / 1000000); printf("platform frequency: %lld MHz\n", platform_counter_freq / 1000000); printf("CPU reference clock: %d MHz\n", u_ar71xx_refclk / 1000000); printf("CPU MDIO clock: %d MHz\n", u_ar71xx_mdio_freq / 1000000); printf("arguments: \n"); printf(" a0 = %08x\n", a0); printf(" a1 = %08x\n", a1); printf(" a2 = %08x\n", a2); printf(" a3 = %08x\n", a3); strcpy(cpu_model, ar71xx_get_system_type()); /* * XXX this code is very redboot specific. */ printf("Cmd line:"); if (MIPS_IS_VALID_PTR(argv)) { for (i = 0; i < argc; i++) { printf(" %s", argv[i]); parse_argv(argv[i]); } } else printf ("argv is invalid"); printf("\n"); printf("Environment:\n"); if (MIPS_IS_VALID_PTR(envp)) { for (i = 0; envp[i]; i+=2) { printf(" %s = %s\n", envp[i], envp[i+1]); kern_setenv(envp[i], envp[i+1]); } } else printf ("envp is invalid\n"); /* Platform setup */ init_param2(physmem); mips_cpu_init(); pmap_bootstrap(); mips_proc0_init(); mutex_init(); /* * Reset USB devices */ ar71xx_init_usb_peripheral(); /* * Reset internal ethernet switch, if one exists */ ar71xx_reset_ethernet_switch(); /* * Initialise the gmac driver. */ ar71xx_init_gmac(); /* Redboot if_arge MAC address is in the environment */ (void) ar71xx_redboot_get_macaddr(); /* Various other boards need things to come out of EEPROM */ (void) ar71xx_platform_read_eeprom_mac(); /* Initialise the MAC address hint map */ ar71xx_platform_check_mac_hints(); kdb_init(); #ifdef KDB if (boothowto & RB_KDB) kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); #endif }
int nvram2env_attach(device_t dev) { struct nvram2env_softc *sc; struct nvram *nv; char *pair, *value, *assign; uint32_t sig, size, i, *tmp; sc = device_get_softc(dev); if (sc->bst == 0 || sc->addr == 0) return (ENXIO); if (bus_space_map(sc->bst, sc->addr, NVRAM_MAX_SIZE, 0, &sc->bsh) != 0) return (ENXIO); sig = read_4(sc, 0); size = read_4(sc, 4); if (bootverbose) device_printf(dev, " size=0x%05x maxsize=0x%05x\n", size, sc->maxsize); size = (size > sc->maxsize)?sc->maxsize:size; if (sig == sc->sig || (sc->flags & NVRAM_FLAGS_UBOOT)) { /* align size to 32bit size*/ size += 3; size &= ~3; nv = malloc(size, M_DEVBUF, M_WAITOK | M_ZERO); if (!nv) return (ENOMEM); /* set tmp pointer to begin of NVRAM */ tmp = (uint32_t *) nv; /* use read_4 to swap bytes if it's required */ for (i = 0; i < size; i += 4) { *tmp = read_4(sc, i); tmp++; } /* now tmp pointer is end of NVRAM */ if (sc->flags & NVRAM_FLAGS_BROADCOM) { device_printf(dev, "sig = %#x\n", nv->sig); device_printf(dev, "size = %#x\n", nv->size); } if (!(sc->flags & NVRAM_FLAGS_NOCHECK)) { /* TODO: need checksum verification */ } if (sc->flags & NVRAM_FLAGS_GENERIC) pair = (char*)nv+4; if (sc->flags & NVRAM_FLAGS_UBOOT) pair = (char*)nv+4; else if (sc->flags & NVRAM_FLAGS_BROADCOM) pair = (char*)nv+20; else pair = (char*)nv+4; /* iterate over buffer till end. tmp points to end of NVRAM */ for ( ; pair < (char*)tmp; pair += strlen(pair) + strlen(value) + 2 ) { if (!pair || (strlen(pair) == 0)) break; /* hint.nvram.0. */ assign = strchr(pair,'='); assign[0] = '\0'; value = assign+1; if (bootverbose) printf("ENV[%p]: %s=%s\n", (void*)((char*)pair - (char*)nv), pair, value); kern_setenv(pair, value); if (strcasecmp(pair, "WAN_MAC_ADDR") == 0) { /* Alias for MAC address of eth0 */ if (bootverbose) printf("ENV: aliasing " "WAN_MAC_ADDR to ethaddr" " = %s\n", value); kern_setenv("ethaddr", value); } else if (strcasecmp(pair, "LAN_MAC_ADDR") == 0){ /* Alias for MAC address of eth1 */ if (bootverbose) printf("ENV: aliasing " "LAN_MAC_ADDR to eth1addr" " = %s\n", value); kern_setenv("eth1addr", value); } if (strcmp(pair, "bootverbose") == 0) bootverbose = strtoul(value, 0, 0); if (strcmp(pair, "boothowto" ) == 0) boothowto = strtoul(value, 0, 0); } free(nv, M_DEVBUF); } bus_space_unmap(sc->bst, sc->bsh, NVRAM_MAX_SIZE); return (0); }