示例#1
0
static void
bcm2835_late_init(platform_t plat)
{
	phandle_t system;
	pcell_t cells[2];
	int len;

	system = OF_finddevice("/system");
	if (system != 0) {
		len = OF_getprop(system, "linux,serial", &cells, sizeof(cells));
		if (len > 0)
			board_set_serial(fdt64_to_cpu(*((uint64_t *)cells)));

		len = OF_getprop(system, "linux,revision", &cells, sizeof(cells));
		if (len > 0)
			board_set_revision(fdt32_to_cpu(*((uint32_t *)cells)));
	}
}
示例#2
0
static vm_offset_t
linux_parse_boot_param(struct arm_boot_params *abp)
{
	struct arm_lbabi_tag *walker;
	uint32_t revision;
	uint64_t serial;
	int size;
	vm_offset_t lastaddr;
#ifdef FDT
	struct fdt_header *dtb_ptr;
	uint32_t dtb_size;
#endif

	/*
	 * Linux boot ABI: r0 = 0, r1 is the board type (!= 0) and r2
	 * is atags or dtb pointer.  If all of these aren't satisfied,
	 * then punt. Unfortunately, it looks like DT enabled kernels
	 * doesn't uses board type and U-Boot delivers 0 in r1 for them.
	 */
	if (abp->abp_r0 != 0 || abp->abp_r2 == 0)
		return (0);
#ifdef FDT
	/* Test if r2 point to valid DTB. */
	dtb_ptr = (struct fdt_header *)abp->abp_r2;
	if (fdt_check_header(dtb_ptr) == 0) {
		dtb_size = fdt_totalsize(dtb_ptr);
		return (fake_preload_metadata(abp, dtb_ptr, dtb_size));
	}
#endif

	board_id = abp->abp_r1;
	walker = (struct arm_lbabi_tag *)abp->abp_r2;

	if (ATAG_TAG(walker) != ATAG_CORE)
		return 0;

	atag_list = walker;
	while (ATAG_TAG(walker) != ATAG_NONE) {
		switch (ATAG_TAG(walker)) {
		case ATAG_CORE:
			break;
		case ATAG_MEM:
			arm_physmem_hardware_region(walker->u.tag_mem.start,
			    walker->u.tag_mem.size);
			break;
		case ATAG_INITRD2:
			break;
		case ATAG_SERIAL:
			serial = walker->u.tag_sn.high;
			serial <<= 32;
			serial |= walker->u.tag_sn.low;
			board_set_serial(serial);
			break;
		case ATAG_REVISION:
			revision = walker->u.tag_rev.rev;
			board_set_revision(revision);
			break;
		case ATAG_CMDLINE:
			size = ATAG_SIZE(walker) -
			    sizeof(struct arm_lbabi_header);
			size = min(size, LBABI_MAX_COMMAND_LINE);
			strncpy(linux_command_line, walker->u.tag_cmd.command,
			    size);
			linux_command_line[size] = '\0';
			break;
		default:
			break;
		}
		walker = ATAG_NEXT(walker);
	}

	/* Save a copy for later */
	bcopy(atag_list, atags,
	    (char *)walker - (char *)atag_list + ATAG_SIZE(walker));

	lastaddr = fake_preload_metadata(abp, NULL, 0);
	cmdline_set_env(linux_command_line, CMDLINE_GUARD);
	return lastaddr;
}