示例#1
0
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);
	}
}
示例#2
0
/*
 * 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);
	}
}
示例#3
0
/*
 * 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);
		}
	}
}
示例#4
0
/*
 * 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);
}
示例#5
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;
	}
}
示例#6
0
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);
}
示例#7
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);
}
示例#8
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
}
示例#9
0
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);
}