Beispiel #1
0
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);
}
Beispiel #2
0
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");
}
Beispiel #3
0
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;
}
Beispiel #4
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);
}
Beispiel #5
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;
}
Beispiel #6
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);
}
Beispiel #7
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);
}
Beispiel #8
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);
}