/**
 * fdt_find_or_add_subnode() - find or possibly add a subnode of a given node
 *
 * @fdt: pointer to the device tree blob
 * @parentoffset: structure block offset of a node
 * @name: name of the subnode to locate
 *
 * fdt_subnode_offset() finds a subnode of the node with a given name.
 * If the subnode does not exist, it will be created.
 */
int fdt_find_or_add_subnode(void *fdt, int parentoffset, const char *name)
{
	int offset;

	offset = fdt_subnode_offset(fdt, parentoffset, name);

	if (offset == -FDT_ERR_NOTFOUND)
		offset = fdt_add_subnode(fdt, parentoffset, name);

	if (offset < 0)
		printf("%s: %s: %s\n", __func__, name, fdt_strerror(offset));

	return offset;
}
Esempio n. 2
0
/**
 * Decode the display controller information from the fdt.
 *
 * @param blob		fdt blob
 * @param config	structure to store fdt config into
 * @return 0 if ok, -ve on error
 */
static int tegra_display_decode_config(const void *blob,
				       struct fdt_disp_config *config)
{
	int node, rgb;
	int bpp, bit;

	/* TODO: Support multiple controllers */
	node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_DC);
	if (node < 0) {
		debug("%s: Cannot find display controller node in fdt\n",
		      __func__);
		return node;
	}
	config->disp = (struct disp_ctlr *)fdtdec_get_addr(blob, node, "reg");
	if (!config->disp) {
		debug("%s: No display controller address\n", __func__);
		return -1;
	}

	rgb = fdt_subnode_offset(blob, node, "rgb");

	config->panel_node = fdtdec_lookup_phandle(blob, rgb, "nvidia,panel");
	if (!config->panel_node < 0) {
		debug("%s: Cannot find panel information\n", __func__);
		return -1;
	}

	if (tegra_decode_panel(blob, config->panel_node, config)) {
		debug("%s: Failed to decode panel information\n", __func__);
		return -1;
	}

	bpp = fdtdec_get_int(blob, config->panel_node, "nvidia,bits-per-pixel",
			     -1);
	bit = ffs(bpp) - 1;
	if (bpp == (1 << bit))
		config->log2_bpp = bit;
	else
		config->log2_bpp = bpp;
	if (bpp == -1) {
		debug("%s: Pixel bpp parameters missing\n", __func__);
		return -FDT_ERR_NOTFOUND;
	}
	config->bpp = bpp;

	config->valid = 1;	/* we have a valid configuration */

	return 0;
}
Esempio n. 3
0
int cros_ec_decode_ec_flash(const void *blob, struct fdt_cros_ec *config)
{
	int flash_node, node;

	node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC);
	if (node < 0) {
		debug("Failed to find chrome-ec node'\n");
		return -1;
	}

	flash_node = fdt_subnode_offset(blob, node, "flash");
	if (flash_node < 0) {
		debug("Failed to find flash node\n");
		return -1;
	}

	if (fdtdec_read_fmap_entry(blob, flash_node, "flash",
				   &config->flash)) {
		debug("Failed to decode flash node in chrome-ec'\n");
		return -1;
	}

	config->flash_erase_value = fdtdec_get_int(blob, flash_node,
						    "erase-value", -1);
	for (node = fdt_first_subnode(blob, flash_node); node >= 0;
	     node = fdt_next_subnode(blob, node)) {
		const char *name = fdt_get_name(blob, node, NULL);
		enum ec_flash_region region;

		if (0 == strcmp(name, "ro")) {
			region = EC_FLASH_REGION_RO;
		} else if (0 == strcmp(name, "rw")) {
			region = EC_FLASH_REGION_RW;
		} else if (0 == strcmp(name, "wp-ro")) {
			region = EC_FLASH_REGION_WP_RO;
		} else {
			debug("Unknown EC flash region name '%s'\n", name);
			return -1;
		}

		if (fdtdec_read_fmap_entry(blob, node, "reg",
					   &config->region[region])) {
			debug("Failed to decode flash region in chrome-ec'\n");
			return -1;
		}
	}

	return 0;
}
Esempio n. 4
0
int main(int argc, char *argv[])
{
	const struct fdt_property *prop;
	void *fdt;
	int offset;
	int subnode1_offset;
	const void *val;
	int lenerr;

	test_init(argc, argv);
	fdt = load_blob_arg(argc, argv);

	prop = fdt_get_property(fdt, 0, "nonexistant-property", &lenerr);
	check_error("fdt_get_property(\"nonexistant-property\")", lenerr);

	val = fdt_getprop(fdt, 0, "nonexistant-property", &lenerr);
	check_error("fdt_getprop(\"nonexistant-property\"", lenerr);

	subnode1_offset = fdt_subnode_offset(fdt, 0, "subnode@1");
	if (subnode1_offset < 0)
		FAIL("Couldn't find subnode1: %s", fdt_strerror(subnode1_offset));

	val = fdt_getprop(fdt, subnode1_offset, "prop-str", &lenerr);
	check_error("fdt_getprop(\"prop-str\")", lenerr);

	offset = fdt_subnode_offset(fdt, 0, "nonexistant-subnode");
	check_error("fdt_subnode_offset(\"nonexistant-subnode\")", offset);

	offset = fdt_subnode_offset(fdt, 0, "subsubnode");
	check_error("fdt_subnode_offset(\"subsubnode\")", offset);

	offset = fdt_path_offset(fdt, "/nonexistant-subnode");
	check_error("fdt_path_offset(\"/nonexistant-subnode\")", offset);

	PASS();
}
Esempio n. 5
0
static int ft_fixup_clocks(void *fdt, const char **names, u32 *rates, int num)
{
	int offs, node_offs, ret, i;
	uint32_t phandle;

	offs = fdt_path_offset(fdt, "/ocp/l4@4a000000/cm_core_aon@5000/clocks");
	if (offs < 0) {
		debug("Could not find cm_core_aon clocks node path offset : %s\n",
		      fdt_strerror(offs));
		return offs;
	}

	for (i = 0; i < num; i++) {
		node_offs = fdt_subnode_offset(fdt, offs, names[i]);
		if (node_offs < 0) {
			debug("Could not find clock sub-node %s: %s\n",
			      names[i], fdt_strerror(node_offs));
			return offs;
		}

		phandle = fdt_get_phandle(fdt, node_offs);
		if (!phandle) {
			debug("Could not find phandle for clock %s\n",
			      names[i]);
			return -1;
		}

		ret = fdt_setprop_u32(fdt, node_offs, "assigned-clocks",
				      phandle);
		if (ret < 0) {
			debug("Could not add assigned-clocks property to clock node %s: %s\n",
			      names[i], fdt_strerror(ret));
			return ret;
		}

		ret = fdt_setprop_u32(fdt, node_offs, "assigned-clock-rates",
				      rates[i]);
		if (ret < 0) {
			debug("Could not add assigned-clock-rates property to clock node %s: %s\n",
			      names[i], fdt_strerror(ret));
			return ret;
		}
	}

	return 0;
}
Esempio n. 6
0
/*
 * Apply one overlay fragment
 */
static void
fdt_apply_fragment(void *main_fdtp, void *overlay_fdtp, int fragment_o)
{
	uint32_t target;
	const char *target_path;
	const void *val;
	int target_node_o, overlay_node_o;

	target_node_o = -1;
	val = fdt_getprop(overlay_fdtp, fragment_o, "target", NULL);
	if (val) {
		memcpy(&target, val, sizeof(target));
		target = fdt32_to_cpu(target);
		target_node_o = fdt_node_offset_by_phandle(main_fdtp, target);
		if (target_node_o < 0) {
			printf("failed to find target %04x\n", target);
			return;
		}
	}

	if (target_node_o < 0) {
		target_path = fdt_getprop(overlay_fdtp, fragment_o, "target-path", NULL);
		if (target_path == NULL)
			return;

		target_node_o = fdt_path_offset(main_fdtp, target_path);
		if (target_node_o < 0) {
			printf("failed to find target-path %s\n", target_path);
			return;
		}
	}

	if (target_node_o < 0)
		return;

	overlay_node_o = fdt_subnode_offset(overlay_fdtp, fragment_o, "__overlay__");
	if (overlay_node_o < 0) {
		printf("missing __overlay__ sub-node\n");
		return;
	}

	fdt_overlay_node(main_fdtp, target_node_o, overlay_fdtp, overlay_node_o);
}
Esempio n. 7
0
/**
 * fit_image_get_node - get node offset for component image of a given unit name
 * @fit: pointer to the FIT format image header
 * @image_uname: component image node unit name
 *
 * fit_image_get_node() finds a component image (withing the '/images'
 * node) of a provided unit name. If image is found its node offset is
 * returned to the caller.
 *
 * returns:
 *     image node offset when found (>=0)
 *     negative number on failure (FDT_ERR_* code)
 */
int fit_image_get_node(const void *fit, const char *image_uname)
{
	int noffset, images_noffset;

	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
	if (images_noffset < 0) {
		debug("Can't find images parent node '%s' (%s)\n",
		      FIT_IMAGES_PATH, fdt_strerror(images_noffset));
		return images_noffset;
	}

	noffset = fdt_subnode_offset(fit, images_noffset, image_uname);
	if (noffset < 0) {
		debug("Can't get node offset for image unit name: '%s' (%s)\n",
		      image_uname, fdt_strerror(noffset));
	}

	return noffset;
}
Esempio n. 8
0
static int fdt_offset(const void *fit)
{
	int images, node, fdt_len, fdt_node, fdt_offset;
	const char *fdt_name;

	node = fit_find_config_node(fit);
	if (node < 0)
		return node;

	images = fdt_path_offset(fit, FIT_IMAGES_PATH);
	if (images < 0) {
		debug("%s: Cannot find /images node: %d\n", __func__, images);
		return -EINVAL;
	}

	fdt_name = fdt_getprop(fit, node, FIT_FDT_PROP, &fdt_len);
	if (!fdt_name) {
		debug("%s: Cannot find fdt name property: %d\n",
		      __func__, fdt_len);
		return -EINVAL;
	}

	fdt_node = fdt_subnode_offset(fit, images, fdt_name);
	if (fdt_node < 0) {
		debug("%s: Cannot find fdt node '%s': %d\n",
		      __func__, fdt_name, fdt_node);
		return -EINVAL;
	}

	fdt_offset = fdt_getprop_u32(fit, fdt_node, "data-offset");

	if (fdt_offset == FDT_ERROR)
		return -ENOENT;

	fdt_len = fdt_getprop_u32(fit, fdt_node, "data-size");

	if (fdt_len < 0)
		return fdt_len;

	return fdt_offset;
}
Esempio n. 9
0
/**
 * spl_fit_get_image_node(): By using the matching configuration subnode,
 * retrieve the name of an image, specified by a property name and an index
 * into that.
 * @fit:	Pointer to the FDT blob.
 * @images:	Offset of the /images subnode.
 * @type:	Name of the property within the configuration subnode.
 * @index:	Index into the list of strings in this property.
 *
 * Return:	the node offset of the respective image node or a negative
 *		error number.
 */
static int spl_fit_get_image_node(const void *fit, int images,
				  const char *type, int index)
{
	char *str;
	int err;
	int node;

	err = spl_fit_get_image_name(fit, images, type, index, &str);
	if (err)
		return err;

	debug("%s: '%s'\n", type, str);

	node = fdt_subnode_offset(fit, images, str);
	if (node < 0) {
		debug("cannot find image node '%s': %d\n", str, node);
		return -EINVAL;
	}

	return node;
}
Esempio n. 10
0
static int lp873x_bind(struct udevice *dev)
{
	int regulators_node;
	const void *blob = gd->fdt_blob;
	int children;
	int node = dev->of_offset;

	regulators_node = fdt_subnode_offset(blob, node, "regulators");

	if (regulators_node <= 0) {
		printf("%s: %s reg subnode not found!", __func__, dev->name);
		return -ENXIO;
	}

	children = pmic_bind_children(dev, regulators_node, pmic_children_info);
	if (!children)
		printf("%s: %s - no child found\n", __func__, dev->name);

	/* Always return success for this device */
	return 0;
}
Esempio n. 11
0
static int mc_fixup_dpc_mac_addr(void *blob, int dpmac_id,
				 struct eth_device *eth_dev)
{
	int nodeoffset = fdt_path_offset(blob, "/board_info/ports"), noff;
	int err = 0;
	char mac_name[10];
	const char link_type_mode[] = "MAC_LINK_TYPE_FIXED";

	sprintf(mac_name, "mac@%d", dpmac_id);

	/* node not found - create it */
	noff = fdt_subnode_offset(blob, nodeoffset, (const char *)mac_name);
	if (noff < 0) {
		err = fdt_increase_size(blob, 200);
		if (err) {
			printf("fdt_increase_size: err=%s\n",
				fdt_strerror(err));
			return err;
		}

		noff = fdt_add_subnode(blob, nodeoffset, mac_name);
		if (noff < 0) {
			printf("fdt_add_subnode: err=%s\n",
			       fdt_strerror(err));
			return err;
		}

		/* add default property of fixed link */
		err = fdt_appendprop_string(blob, noff,
					    "link_type", link_type_mode);
		if (err) {
			printf("fdt_appendprop_string: err=%s\n",
				fdt_strerror(err));
			return err;
		}
	}

	return mc_fixup_mac_addr(blob, noff, "port_mac_address", eth_dev,
				 MC_FIXUP_DPC);
}
Esempio n. 12
0
static int s5m8767_bind(struct udevice *dev)
{
	int node;
	const void *blob = gd->fdt_blob;
	int children;

	node = fdt_subnode_offset(blob, dev->of_offset, "regulators");
	if (node <= 0) {
		debug("%s: %s regulators subnode not found!", __func__,
		      dev->name);
		return -ENXIO;
	}

	debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);

	children = pmic_bind_children(dev, node, pmic_children_info);
	if (!children)
		debug("%s: %s - no child found\n", __func__, dev->name);

	/* Always return success for this device */
	return 0;
}
Esempio n. 13
0
int fit_image_verify_required_sigs(const void *fit, int image_noffset,
		const char *data, size_t size, const void *sig_blob,
		int *no_sigsp)
{
	int verify_count = 0;
	int noffset;
	int sig_node;

	/* Work out what we need to verify */
	*no_sigsp = 1;
	sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
	if (sig_node < 0) {
		debug("%s: No signature node found: %s\n", __func__,
		      fdt_strerror(sig_node));
		return 0;
	}

	fdt_for_each_subnode(noffset, sig_blob, sig_node) {
		const char *required;
		int ret;

		required = fdt_getprop(sig_blob, noffset, "required", NULL);
		if (!required || strcmp(required, "image"))
			continue;
		ret = fit_image_verify_sig(fit, image_noffset, data, size,
					sig_blob, noffset);
		if (ret) {
			printf("Failed to verify required signature '%s'\n",
			       fit_get_name(sig_blob, noffset, NULL));
			return ret;
		}
		verify_count++;
	}

	if (verify_count)
		*no_sigsp = 0;

	return 0;
}
Esempio n. 14
0
/*
 * Overlay one node defined by <overlay_fdtp, overlay_o> over <main_fdtp, target_o>
 */
static void
fdt_overlay_node(void *main_fdtp, int target_o, void *overlay_fdtp, int overlay_o)
{
	int len, o, depth;
	const char *name;
	const void *val;
	int target_subnode_o;

	/* Overlay properties */
	for (o = fdt_first_property_offset(overlay_fdtp, overlay_o);
	    o >= 0; o = fdt_next_property_offset(overlay_fdtp, o)) {
		val = fdt_getprop_by_offset(overlay_fdtp, o, &name, &len);
		if (val)
			fdt_setprop(main_fdtp, target_o, name, val, len);
	}

	/* Now overlay nodes */
	o = overlay_o;
        for (depth = 0; (o >= 0) && (depth >= 0);
	    o = fdt_next_node(overlay_fdtp, o, &depth)) {
		if (depth != 1)
			continue;
		/* Check if there is node with the same name */
		name = fdt_get_name(overlay_fdtp, o, NULL);
		target_subnode_o = fdt_subnode_offset(main_fdtp, target_o, name);
		if (target_subnode_o < 0) {
			/* create new subnode and run merge recursively */
			target_subnode_o = fdt_add_subnode(main_fdtp, target_o, name);
			if (target_subnode_o < 0) {
				printf("failed to create subnode \"%s\": %d\n",
				    name, target_subnode_o);
				return;
			}
		}

		fdt_overlay_node(main_fdtp, target_subnode_o,
		    overlay_fdtp, o);
	}
}
Esempio n. 15
0
int mrccache_get_region(struct udevice **devp, struct mrc_region *entry)
{
	const void *blob = gd->fdt_blob;
	int node, mrc_node;
	u32 reg[2];
	int ret;

	/* Find the flash chip within the SPI controller node */
	node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH);
	if (node < 0)
		return -ENOENT;

	if (fdtdec_get_int_array(blob, node, "memory-map", reg, 2))
		return -FDT_ERR_NOTFOUND;
	entry->base = reg[0];

	/* Find the place where we put the MRC cache */
	mrc_node = fdt_subnode_offset(blob, node, "rw-mrc-cache");
	if (mrc_node < 0)
		return -EPERM;

	if (fdtdec_get_int_array(blob, mrc_node, "reg", reg, 2))
		return -FDT_ERR_NOTFOUND;
	entry->offset = reg[0];
	entry->length = reg[1];

	if (devp) {
		ret = uclass_get_device_by_of_offset(UCLASS_SPI_FLASH, node,
						     devp);
		debug("ret = %d\n", ret);
		if (ret)
			return ret;
	}

	return 0;
}
Esempio n. 16
0
static void compare_subnodes(const void *fdt1, int offset1,
			     const void *fdt2, int offset2,
			     int recurse)
{
	int coffset1, coffset2, depth;

	for (depth = 0, coffset1 = offset1;
	     (coffset1 >= 0) && (depth >= 0);
	      coffset1 = fdt_next_node(fdt1, coffset1, &depth))
		if (depth == 1) {
			const char *name = fdt_get_name(fdt1, coffset1, NULL);

			verbose_printf("Subnode %s\n", name);
			coffset2 = fdt_subnode_offset(fdt2, offset2, name);
			if (coffset2 == -FDT_ERR_NOTFOUND)
				MISMATCH("Subnode %s missing\n", name);
			else if (coffset2 < 0)
				FAIL("fdt_subnode_offset(): %s\n",
				     fdt_strerror(coffset2));

			if (recurse)
				compare_node(fdt1, coffset1, fdt2, coffset2);
		}
}
Esempio n. 17
0
/**
 * Modify the device tree to remove all unused interface types.
 */
int board_fixup_fdt(void)
{
	const char *fdt_key;
	int val;
	int rc;

	val = pca953x_get_val(0, 0x20);
	if (val & 4)
		fdt_key = "2,sata";
	else
		fdt_key = "2,pcie";
	octeon_fdt_patch(working_fdt, fdt_key, NULL);


	if (val & 1)
		fdt_key = "0,xaui";
	else
		fdt_key = "0,qsgmii";

	debug("%s: Patching DLM 0 for %s\n", __func__, fdt_key);
	octeon_fdt_patch(working_fdt, fdt_key, NULL);

	if (val & 8) {
		debug("PCM mode detected, disabling SPI NOR\n");
		octeon_fdt_patch(working_fdt, "0,pcm", "cavium,pcm-trim");
	} else {
		debug("SPI NOR mode selected\n");
		octeon_fdt_patch(working_fdt, "0,not-pcm", "cavium,pcm-trim");
	}

	/* Check if we need to swap the MMC slots or not. */
	if (val & 0x10) {
		int s0_offset, s1_offset, offset;

		debug("%s: Swapping mmc slots 0 and 1\n", __func__);
		/* Swap slot 0 and slot 1 in device tree */
		offset = fdt_path_offset(gd->fdt_blob, "/soc/mmc");
		if (offset < 0) {
			puts("Error accessing /soc/mmc in device tree\n");
			return -1;
		}
		s0_offset = fdt_subnode_offset(gd->fdt_blob, offset,
					       "mmc-slot@0");
		s1_offset = fdt_subnode_offset(gd->fdt_blob, offset,
					       "mmc-slot@1");
		debug("  slot 0 offset: %d, slot 1 offset: %d\n",
		      s0_offset, s1_offset);
		if (s0_offset < 0 || s1_offset < 0) {
			puts("Error accessing MMC in device tree\n");
			return -1;
		}
		rc = fdt_setprop_inplace_u32(gd->fdt_blob, s0_offset, "reg", 1);
		rc |= fdt_setprop_inplace_u32(gd->fdt_blob, s1_offset, "reg", 0);
		if (rc) {
			puts("Error changing reg property in mmc slot\n");
			return -1;
		}

		rc = fdt_set_name(gd->fdt_blob, s0_offset, "mmc-slot@1");
		rc |= fdt_set_name(gd->fdt_blob, s1_offset, "mmc-slot@0");
		if (rc) {
			puts("Error renaming MMC slot names\n");
			return -1;
		}
	}


	return 0;
}
Esempio n. 18
0
efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
			unsigned long orig_fdt_size,
			void *fdt, int new_fdt_size, char *cmdline_ptr,
			u64 initrd_addr, u64 initrd_size,
			efi_memory_desc_t *memory_map,
			unsigned long map_size, unsigned long desc_size,
			u32 desc_ver)
{
	int node, prev, num_rsv;
	int status;
	u32 fdt_val32;
	u64 fdt_val64;

	/* Do some checks on provided FDT, if it exists*/
	if (orig_fdt) {
		if (fdt_check_header(orig_fdt)) {
			pr_efi_err(sys_table, "Device Tree header not valid!\n");
			return EFI_LOAD_ERROR;
		}
		/*
		 * We don't get the size of the FDT if we get if from a
		 * configuration table.
		 */
		if (orig_fdt_size && fdt_totalsize(orig_fdt) > orig_fdt_size) {
			pr_efi_err(sys_table, "Truncated device tree! foo!\n");
			return EFI_LOAD_ERROR;
		}
	}

	if (orig_fdt)
		status = fdt_open_into(orig_fdt, fdt, new_fdt_size);
	else
		status = fdt_create_empty_tree(fdt, new_fdt_size);

	if (status != 0)
		goto fdt_set_fail;

	/*
	 * Delete any memory nodes present. We must delete nodes which
	 * early_init_dt_scan_memory may try to use.
	 */
	prev = 0;
	for (;;) {
		const char *type;
		int len;

		node = fdt_next_node(fdt, prev, NULL);
		if (node < 0)
			break;

		type = fdt_getprop(fdt, node, "device_type", &len);
		if (type && strncmp(type, "memory", len) == 0) {
			fdt_del_node(fdt, node);
			continue;
		}

		prev = node;
	}

	/*
	 * Delete all memory reserve map entries. When booting via UEFI,
	 * kernel will use the UEFI memory map to find reserved regions.
	 */
	num_rsv = fdt_num_mem_rsv(fdt);
	while (num_rsv-- > 0)
		fdt_del_mem_rsv(fdt, num_rsv);

	node = fdt_subnode_offset(fdt, 0, "chosen");
	if (node < 0) {
		node = fdt_add_subnode(fdt, 0, "chosen");
		if (node < 0) {
			status = node; /* node is error code when negative */
			goto fdt_set_fail;
		}
	}

	if ((cmdline_ptr != NULL) && (strlen(cmdline_ptr) > 0)) {
		status = fdt_setprop(fdt, node, "bootargs", cmdline_ptr,
				     strlen(cmdline_ptr) + 1);
		if (status)
			goto fdt_set_fail;
	}

	/* Set initrd address/end in device tree, if present */
	if (initrd_size != 0) {
		u64 initrd_image_end;
		u64 initrd_image_start = cpu_to_fdt64(initrd_addr);

		status = fdt_setprop(fdt, node, "linux,initrd-start",
				     &initrd_image_start, sizeof(u64));
		if (status)
			goto fdt_set_fail;
		initrd_image_end = cpu_to_fdt64(initrd_addr + initrd_size);
		status = fdt_setprop(fdt, node, "linux,initrd-end",
				     &initrd_image_end, sizeof(u64));
		if (status)
			goto fdt_set_fail;
	}

	/* Add FDT entries for EFI runtime services in chosen node. */
	node = fdt_subnode_offset(fdt, 0, "chosen");
	fdt_val64 = cpu_to_fdt64((u64)(unsigned long)sys_table);
	status = fdt_setprop(fdt, node, "linux,uefi-system-table",
			     &fdt_val64, sizeof(fdt_val64));
	if (status)
		goto fdt_set_fail;

	fdt_val64 = cpu_to_fdt64((u64)(unsigned long)memory_map);
	status = fdt_setprop(fdt, node, "linux,uefi-mmap-start",
			     &fdt_val64,  sizeof(fdt_val64));
	if (status)
		goto fdt_set_fail;

	fdt_val32 = cpu_to_fdt32(map_size);
	status = fdt_setprop(fdt, node, "linux,uefi-mmap-size",
			     &fdt_val32,  sizeof(fdt_val32));
	if (status)
		goto fdt_set_fail;

	fdt_val32 = cpu_to_fdt32(desc_size);
	status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-size",
			     &fdt_val32, sizeof(fdt_val32));
	if (status)
		goto fdt_set_fail;

	fdt_val32 = cpu_to_fdt32(desc_ver);
	status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-ver",
			     &fdt_val32, sizeof(fdt_val32));
	if (status)
		goto fdt_set_fail;

	/*
	 * Add kernel version banner so stub/kernel match can be
	 * verified.
	 */
	status = fdt_setprop_string(fdt, node, "linux,uefi-stub-kern-ver",
			     linux_banner);
	if (status)
		goto fdt_set_fail;

	return EFI_SUCCESS;

fdt_set_fail:
	if (status == -FDT_ERR_NOSPACE)
		return EFI_BUFFER_TOO_SMALL;

	return EFI_LOAD_ERROR;
}
Esempio n. 19
0
			*gbe_0 = slave;
		} else {
			/* Slave devices to be registered */
			slave_name = malloc(20);
			snprintf(slave_name, 20, "netcp@slave-%d", slave_no);
			ret = device_bind_driver_to_node(dev, "eth_ks2_sl",
							 slave_name, slave,
							 &sl_dev);
			if (ret) {
				error("ks2_net - not able to bind slave interfaces\n");
				return ret;
			}
		}
	}

	sec_slave = fdt_subnode_offset(fdt, gbe, "secondary-slave-ports");
	fdt_for_each_subnode(fdt, slave, sec_slave) {
		int slave_no;

		slave_no = fdtdec_get_int(fdt, slave, "slave-port", -ENOENT);
		if (slave_no == -ENOENT)
			continue;

		/* Slave devices to be registered */
		slave_name = malloc(20);
		snprintf(slave_name, 20, "netcp@slave-%d", slave_no);
		ret = device_bind_driver_to_node(dev, "eth_ks2_sl", slave_name,
						 slave, &sl_dev);
		if (ret) {
			error("ks2_net - not able to bind slave interfaces\n");
			return ret;
Esempio n. 20
0
int rsa_add_verify_data(struct image_sign_info *info, void *keydest)
{
	BIGNUM *modulus, *r_squared;
	uint64_t exponent;
	uint32_t n0_inv;
	int parent, node;
	char name[100];
	int ret;
	int bits;
	RSA *rsa;

	debug("%s: Getting verification data\n", __func__);
	ret = rsa_get_pub_key(info->keydir, info->keyname, &rsa);
	if (ret)
		return ret;
	ret = rsa_get_params(rsa, &exponent, &n0_inv, &modulus, &r_squared);
	if (ret)
		return ret;
	bits = BN_num_bits(modulus);
	parent = fdt_subnode_offset(keydest, 0, FIT_SIG_NODENAME);
	if (parent == -FDT_ERR_NOTFOUND) {
		parent = fdt_add_subnode(keydest, 0, FIT_SIG_NODENAME);
		if (parent < 0) {
			ret = parent;
			if (ret != -FDT_ERR_NOSPACE) {
				fprintf(stderr, "Couldn't create signature node: %s\n",
					fdt_strerror(parent));
			}
		}
	}
	if (ret)
		goto done;

	/* Either create or overwrite the named key node */
	snprintf(name, sizeof(name), "key-%s", info->keyname);
	node = fdt_subnode_offset(keydest, parent, name);
	if (node == -FDT_ERR_NOTFOUND) {
		node = fdt_add_subnode(keydest, parent, name);
		if (node < 0) {
			ret = node;
			if (ret != -FDT_ERR_NOSPACE) {
				fprintf(stderr, "Could not create key subnode: %s\n",
					fdt_strerror(node));
			}
		}
	} else if (node < 0) {
		fprintf(stderr, "Cannot select keys parent: %s\n",
			fdt_strerror(node));
		ret = node;
	}

	if (!ret) {
		ret = fdt_setprop_string(keydest, node, "key-name-hint",
				 info->keyname);
	}
	if (!ret)
		ret = fdt_setprop_u32(keydest, node, "rsa,num-bits", bits);
	if (!ret)
		ret = fdt_setprop_u32(keydest, node, "rsa,n0-inverse", n0_inv);
	if (!ret) {
		ret = fdt_setprop_u64(keydest, node, "rsa,exponent", exponent);
	}
	if (!ret) {
		ret = fdt_add_bignum(keydest, node, "rsa,modulus", modulus,
				     bits);
	}
	if (!ret) {
		ret = fdt_add_bignum(keydest, node, "rsa,r-squared", r_squared,
				     bits);
	}
	if (!ret) {
		ret = fdt_setprop_string(keydest, node, FIT_ALGO_PROP,
					 info->name);
	}
	if (!ret && info->require_keys) {
		ret = fdt_setprop_string(keydest, node, "required",
					 info->require_keys);
	}
done:
	BN_free(modulus);
	BN_free(r_squared);
	if (ret)
		return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;

	return 0;
}
Esempio n. 21
0
/**
 * fit_conf_find_compat
 * @fit: pointer to the FIT format image header
 * @fdt: pointer to the device tree to compare against
 *
 * fit_conf_find_compat() attempts to find the configuration whose fdt is the
 * most compatible with the passed in device tree.
 *
 * Example:
 *
 * / o image-tree
 *   |-o images
 *   | |-o fdt@1
 *   | |-o fdt@2
 *   |
 *   |-o configurations
 *     |-o config@1
 *     | |-fdt = fdt@1
 *     |
 *     |-o config@2
 *       |-fdt = fdt@2
 *
 * / o U-Boot fdt
 *   |-compatible = "foo,bar", "bim,bam"
 *
 * / o kernel fdt1
 *   |-compatible = "foo,bar",
 *
 * / o kernel fdt2
 *   |-compatible = "bim,bam", "baz,biz"
 *
 * Configuration 1 would be picked because the first string in U-Boot's
 * compatible list, "foo,bar", matches a compatible string in the root of fdt1.
 * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1.
 *
 * returns:
 *     offset to the configuration to use if one was found
 *     -1 otherwise
 */
int fit_conf_find_compat(const void *fit, const void *fdt)
{
	int ndepth = 0;
	int noffset, confs_noffset, images_noffset;
	const void *fdt_compat;
	int fdt_compat_len;
	int best_match_offset = 0;
	int best_match_pos = 0;

	confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
	if (confs_noffset < 0 || images_noffset < 0) {
		debug("Can't find configurations or images nodes.\n");
		return -1;
	}

	fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
	if (!fdt_compat) {
		debug("Fdt for comparison has no \"compatible\" property.\n");
		return -1;
	}

	/*
	 * Loop over the configurations in the FIT image.
	 */
	for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
			(noffset >= 0) && (ndepth > 0);
			noffset = fdt_next_node(fit, noffset, &ndepth)) {
		const void *kfdt;
		const char *kfdt_name;
		int kfdt_noffset;
		const char *cur_fdt_compat;
		int len;
		size_t size;
		int i;

		if (ndepth > 1)
			continue;

		kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
		if (!kfdt_name) {
			debug("No fdt property found.\n");
			continue;
		}
		kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
						  kfdt_name);
		if (kfdt_noffset < 0) {
			debug("No image node named \"%s\" found.\n",
			      kfdt_name);
			continue;
		}
		/*
		 * Get a pointer to this configuration's fdt.
		 */
		if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) {
			debug("Failed to get fdt \"%s\".\n", kfdt_name);
			continue;
		}

		len = fdt_compat_len;
		cur_fdt_compat = fdt_compat;
		/*
		 * Look for a match for each U-Boot compatibility string in
		 * turn in this configuration's fdt.
		 */
		for (i = 0; len > 0 &&
		     (!best_match_offset || best_match_pos > i); i++) {
			int cur_len = strlen(cur_fdt_compat) + 1;

			if (!fdt_node_check_compatible(kfdt, 0,
						       cur_fdt_compat)) {
				best_match_offset = noffset;
				best_match_pos = i;
				break;
			}
			len -= cur_len;
			cur_fdt_compat += cur_len;
		}
	}
	if (!best_match_offset) {
		debug("No match found.\n");
		return -1;
	}

	return best_match_offset;
}
Esempio n. 22
0
EFI_STATUS UpdateMemoryNode(VOID* Fdt)
{
    INTN                Error = 0;
    EFI_STATUS          Status = EFI_SUCCESS;
    UINT32              Index = 0;
    UINT32              MemIndex;
    INTN			    node;
    struct              fdt_property *m_prop;
    int                 m_oldlen;
    EFI_MEMORY_DESCRIPTOR *MemoryMap;
    EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;
    EFI_MEMORY_DESCRIPTOR *MemoryMapPtrCurrent;
    UINTN                 MemoryMapSize;
    UINTN                 Pages0 = 0;
    UINTN                 Pages1 = 0;
    UINTN                 MapKey;
    UINTN                 DescriptorSize;
    UINT32                DescriptorVersion;
    PHY_MEM_REGION        *mRegion;
    UINTN                 MemoryMapLastEndAddress ;
    UINTN                 MemoryMapcontinuousStartAddress ;
    UINTN                 MemoryMapCurrentStartAddress;
    BOOLEAN               FindMemoryRegionFlag = FALSE;
    node = fdt_subnode_offset(Fdt, 0, "memory");
    if (node < 0) 
    {
        // Create the memory node
        node = fdt_add_subnode(Fdt, 0, "memory");
        if(node < 0)
        {
          DEBUG((EFI_D_INFO, "[%a]:[%dL] fdt add subnode error\n", __FUNCTION__, __LINE__));
        }
    }
    //find the memory node property  
    m_prop = fdt_get_property_w(Fdt, node, "memory", &m_oldlen);
    if(m_prop)
        Error=fdt_delprop(Fdt, node, "reg");
    if (Error) 
    {
        DEBUG ((EFI_D_ERROR, "ERROR:fdt_delprop(): %a\n", fdt_strerror (Error)));
        Status = EFI_INVALID_PARAMETER;
        return Status;
    } 

    MemoryMap = NULL;
    MemoryMapSize = 0;
    MemIndex = 0;
 
    Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);
    if (Status == EFI_BUFFER_TOO_SMALL)
    {
        // The UEFI specification advises to allocate more memory for the MemoryMap buffer between successive
        // calls to GetMemoryMap(), since allocation of the new buffer may potentially increase memory map size.
        //DEBUG ((EFI_D_ERROR, "MemoryMapsize: 0x%lx\n",MemoryMapSize));
        Pages0 = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
        MemoryMap = AllocatePages (Pages0);
        if (MemoryMap == NULL)
        {
            Status = EFI_OUT_OF_RESOURCES;
            return Status;
        }
        Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);
    }

    if(MemoryMap == NULL)
    {
        Status = EFI_OUT_OF_RESOURCES;
        //goto EXIT;
        return Status;
    }

    mRegion = NULL;
    Pages1 = EFI_SIZE_TO_PAGES (sizeof(PHY_MEM_REGION) *( MemoryMapSize / DescriptorSize));
    mRegion = (PHY_MEM_REGION*)AllocatePages(Pages1);
    if (mRegion == NULL)
    {
      Status = EFI_OUT_OF_RESOURCES;
      return Status;
    }
	
    if (!EFI_ERROR(Status))
    {
        MemoryMapPtr = MemoryMap;
        MemoryMapPtrCurrent = MemoryMapPtr;
        MemoryMapLastEndAddress = 0;
        MemoryMapcontinuousStartAddress = 0;
        MemoryMapCurrentStartAddress = 0;
        for ( Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++)
        {
            MemoryMapPtrCurrent = (EFI_MEMORY_DESCRIPTOR*)((UINTN)MemoryMapPtr + Index*DescriptorSize);
            MemoryMapCurrentStartAddress = (UINTN)MemoryMapPtrCurrent->PhysicalStart;
       
            if (!IsMemMapRegion ((EFI_MEMORY_TYPE)MemoryMapPtrCurrent->Type))
            {
                continue;
            }
            else 
            {
                FindMemoryRegionFlag = TRUE;
                if(MemoryMapCurrentStartAddress != MemoryMapLastEndAddress)
                {
                    mRegion[MemIndex].BaseHigh= cpu_to_fdt32(MemoryMapcontinuousStartAddress>>32);
	                mRegion[MemIndex].BaseLow=cpu_to_fdt32(MemoryMapcontinuousStartAddress);
                    mRegion[MemIndex].LengthHigh= cpu_to_fdt32((MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress)>>32);
	                mRegion[MemIndex].LengthLow=cpu_to_fdt32(MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress);
                    MemIndex+=1;
                    MemoryMapcontinuousStartAddress=MemoryMapCurrentStartAddress;
                }
            }
            MemoryMapLastEndAddress = (UINTN)(MemoryMapPtrCurrent->PhysicalStart + MemoryMapPtrCurrent->NumberOfPages * EFI_PAGE_SIZE);
        }
Esempio n. 23
0
static int spl_fit_select_fdt(const void *fdt, int images, int *fdt_offsetp)
{
	const char *name, *fdt_name;
	int conf, node, fdt_node;
	int len;

	*fdt_offsetp = 0;
	conf = fdt_path_offset(fdt, FIT_CONFS_PATH);
	if (conf < 0) {
		debug("%s: Cannot find /configurations node: %d\n", __func__,
		      conf);
		return -EINVAL;
	}
	for (node = fdt_first_subnode(fdt, conf);
	     node >= 0;
	     node = fdt_next_subnode(fdt, node)) {
		name = fdt_getprop(fdt, node, "description", &len);
		if (!name) {
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
			printf("%s: Missing FDT description in DTB\n",
			       __func__);
#endif
			return -EINVAL;
		}
		if (board_fit_config_name_match(name))
			continue;

		debug("Selecting config '%s'", name);
		fdt_name = fdt_getprop(fdt, node, FIT_FDT_PROP, &len);
		if (!fdt_name) {
			debug("%s: Cannot find fdt name property: %d\n",
			      __func__, len);
			return -EINVAL;
		}

		debug(", fdt '%s'\n", fdt_name);
		fdt_node = fdt_subnode_offset(fdt, images, fdt_name);
		if (fdt_node < 0) {
			debug("%s: Cannot find fdt node '%s': %d\n",
			      __func__, fdt_name, fdt_node);
			return -EINVAL;
		}

		*fdt_offsetp = fdt_getprop_u32(fdt, fdt_node, "data-offset");
		len = fdt_getprop_u32(fdt, fdt_node, "data-size");
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
		printf("FIT: Selected '%s'\n", name);
#endif

		return len;
	}

#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
	printf("No matching DT out of these options:\n");
	for (node = fdt_first_subnode(fdt, conf);
	     node >= 0;
	     node = fdt_next_subnode(fdt, node)) {
		name = fdt_getprop(fdt, node, "name", &len);
		printf("   %s\n", name);
	}
#endif

	return -ENOENT;
}
Esempio n. 24
0
void fsl_sgmii_riser_fdt_fixup(void *fdt)
{
	struct eth_device *dev;
	int node;
	int mdio_node;
	int i = -1;
	int etsec_num = 0;

	node = fdt_path_offset(fdt, "/aliases");
	if (node < 0)
		return;

	while ((dev = eth_get_dev_by_index(++i)) != NULL) {
		struct tsec_private *priv;
		int phy_node;
		int enet_node;
		uint32_t ph;
		char sgmii_phy[16];
		char enet[16];
		const char *model;
		const char *path;

		if (!strstr(dev->name, "eTSEC"))
			continue;

		priv = dev->priv;
		if (!(priv->flags & TSEC_SGMII)) {
			etsec_num++;
			continue;
		}

		mdio_node = fdt_node_offset_by_compatible(fdt, -1, "fsl,gianfar-mdio");
		if (mdio_node < 0)
			return;

		sprintf(sgmii_phy, "sgmii-phy@%d", etsec_num);
		phy_node = fdt_subnode_offset(fdt, mdio_node, sgmii_phy);
		if (phy_node < 0)
			continue;

		fdt_increase_size(fdt, 32);
		ph = fdt_create_phandle(fdt, phy_node);
		if (!ph)
			continue;

		sprintf(enet, "ethernet%d", etsec_num++);
		path = fdt_getprop(fdt, node, enet, NULL);
		if (!path) {
			debug("No alias for %s\n", enet);
			continue;
		}

		enet_node = fdt_path_offset(fdt, path);
		if (enet_node < 0)
			continue;

		model = fdt_getprop(fdt, enet_node, "model", NULL);

		/*
		 * We only want to do this to eTSECs.  On some platforms
		 * there are more than one type of gianfar-style ethernet
		 * controller, and as we are creating an implicit connection
		 * between ethernet nodes and eTSEC devices, it is best to
		 * make the connection use as much explicit information
		 * as exists.
		 */
		if (!strstr(model, "TSEC"))
			continue;

		fdt_setprop(fdt, enet_node, "phy-handle", &ph, sizeof(ph));
		fdt_setprop_string(fdt, enet_node, "phy-connection-type",
			phy_string_for_interface(PHY_INTERFACE_MODE_SGMII));
	}
}
Esempio n. 25
0
int fdtdec_decode_display_timing(const void *blob, int parent, int index,
				 struct display_timing *dt)
{
	int i, node, timings_node;
	u32 val = 0;
	int ret = 0;

	timings_node = fdt_subnode_offset(blob, parent, "display-timings");
	if (timings_node < 0)
		return timings_node;

	for (i = 0, node = fdt_first_subnode(blob, timings_node);
	     node > 0 && i != index;
	     node = fdt_next_subnode(blob, node))
		i++;

	if (node < 0)
		return node;

	memset(dt, 0, sizeof(*dt));

	ret |= decode_timing_property(blob, node, "hback-porch",
				      &dt->hback_porch);
	ret |= decode_timing_property(blob, node, "hfront-porch",
				      &dt->hfront_porch);
	ret |= decode_timing_property(blob, node, "hactive", &dt->hactive);
	ret |= decode_timing_property(blob, node, "hsync-len", &dt->hsync_len);
	ret |= decode_timing_property(blob, node, "vback-porch",
				      &dt->vback_porch);
	ret |= decode_timing_property(blob, node, "vfront-porch",
				      &dt->vfront_porch);
	ret |= decode_timing_property(blob, node, "vactive", &dt->vactive);
	ret |= decode_timing_property(blob, node, "vsync-len", &dt->vsync_len);
	ret |= decode_timing_property(blob, node, "clock-frequency",
				      &dt->pixelclock);

	dt->flags = 0;
	val = fdtdec_get_int(blob, node, "vsync-active", -1);
	if (val != -1) {
		dt->flags |= val ? DISPLAY_FLAGS_VSYNC_HIGH :
				DISPLAY_FLAGS_VSYNC_LOW;
	}
	val = fdtdec_get_int(blob, node, "hsync-active", -1);
	if (val != -1) {
		dt->flags |= val ? DISPLAY_FLAGS_HSYNC_HIGH :
				DISPLAY_FLAGS_HSYNC_LOW;
	}
	val = fdtdec_get_int(blob, node, "de-active", -1);
	if (val != -1) {
		dt->flags |= val ? DISPLAY_FLAGS_DE_HIGH :
				DISPLAY_FLAGS_DE_LOW;
	}
	val = fdtdec_get_int(blob, node, "pixelclk-active", -1);
	if (val != -1) {
		dt->flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE :
				DISPLAY_FLAGS_PIXDATA_NEGEDGE;
	}

	if (fdtdec_get_bool(blob, node, "interlaced"))
		dt->flags |= DISPLAY_FLAGS_INTERLACED;
	if (fdtdec_get_bool(blob, node, "doublescan"))
		dt->flags |= DISPLAY_FLAGS_DOUBLESCAN;
	if (fdtdec_get_bool(blob, node, "doubleclk"))
		dt->flags |= DISPLAY_FLAGS_DOUBLECLK;

	return 0;
}
Esempio n. 26
0
int
fdt_fixup(void)
{
	const char *env;
	char *ethstr;
	int chosen, err, eth_no, len;
	struct sys_info *si;

	env = NULL;
	eth_no = 0;
	ethstr = NULL;
	len = 0;

	if (!fdtp) {
		err = fdt_setup_fdtp();
		if (err) {
			sprintf(command_errbuf, "Could not perform blob "
			    "fixups. Error code: %d\n", err);
			return (err);
		}
	}

	/* Create /chosen node (if not exists) */
	if ((chosen = fdt_subnode_offset(fdtp, 0, "chosen")) ==
	    -FDT_ERR_NOTFOUND)
		chosen = fdt_add_subnode(fdtp, 0, "chosen");

	/* Value assigned to fixup-applied does not matter. */
	if (fdt_getprop(fdtp, chosen, "fixup-applied", NULL))
		return (CMD_OK);

	/* Acquire sys_info */
	si = ub_get_sys_info();

	while ((env = ub_env_enum(env)) != NULL) {
		if (strncmp(env, "eth", 3) == 0 &&
		    strncmp(env + (strlen(env) - 4), "addr", 4) == 0) {
			/*
			 * Handle Ethernet addrs: parse uboot env eth%daddr
			 */

			if (!eth_no) {
				/*
				 * Check how many chars we will need to store
				 * maximal eth iface number.
				 */
				len = strlen(STRINGIFY(TMP_MAX_ETH)) +
				    strlen("ethernet");

				/*
				 * Reserve mem for string "ethernet" and len
				 * chars for iface no.
				 */
				ethstr = (char *)malloc(len * sizeof(char));
				bzero(ethstr, len * sizeof(char));
				strcpy(ethstr, "ethernet0");
			}

			/* Modify blob */
			fixup_ethernet(env, ethstr, &eth_no, len);

		} else if (strcmp(env, "consoledev") == 0)
			fixup_stdout(env);
	}

	/* Modify cpu(s) and bus clock frequenties in /cpus node [Hz] */
	fixup_cpubusfreqs(si->clk_cpu, si->clk_bus);

	/* Fixup memory regions */
	fixup_memory(si);

	fdt_setprop(fdtp, chosen, "fixup-applied", NULL, 0);

	return (CMD_OK);
}
Esempio n. 27
0
static int tegra_lcd_ofdata_to_platdata(struct udevice *dev)
{
    struct tegra_lcd_priv *priv = dev_get_priv(dev);
    struct fdtdec_phandle_args args;
    const void *blob = gd->fdt_blob;
    int node = dev->of_offset;
    int front, back, ref;
    int panel_node;
    int rgb;
    int bpp, bit;
    int ret;

    priv->disp = (struct disp_ctlr *)dev_get_addr(dev);
    if (!priv->disp) {
        debug("%s: No display controller address\n", __func__);
        return -EINVAL;
    }

    rgb = fdt_subnode_offset(blob, node, "rgb");

    panel_node = fdtdec_lookup_phandle(blob, rgb, "nvidia,panel");
    if (panel_node < 0) {
        debug("%s: Cannot find panel information\n", __func__);
        return -EINVAL;
    }

    priv->width = fdtdec_get_int(blob, panel_node, "xres", -1);
    priv->height = fdtdec_get_int(blob, panel_node, "yres", -1);
    priv->pixel_clock = fdtdec_get_int(blob, panel_node, "clock", 0);
    if (!priv->pixel_clock || priv->width == -1 || priv->height == -1) {
        debug("%s: Pixel parameters missing\n", __func__);
        return -EINVAL;
    }

    back = fdtdec_get_int(blob, panel_node, "left-margin", -1);
    front = fdtdec_get_int(blob, panel_node, "right-margin", -1);
    ref = fdtdec_get_int(blob, panel_node, "hsync-len", -1);
    if ((back | front | ref) == -1) {
        debug("%s: Horizontal parameters missing\n", __func__);
        return -EINVAL;
    }

    /* Use a ref-to-sync of 1 always, and take this from the front porch */
    priv->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1;
    priv->horiz_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
    priv->horiz_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
    priv->horiz_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
            priv->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC];
    debug_timing("horiz", priv->horiz_timing);

    back = fdtdec_get_int(blob, panel_node, "upper-margin", -1);
    front = fdtdec_get_int(blob, panel_node, "lower-margin", -1);
    ref = fdtdec_get_int(blob, panel_node, "vsync-len", -1);
    if ((back | front | ref) == -1) {
        debug("%s: Vertical parameters missing\n", __func__);
        return -EINVAL;
    }

    priv->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1;
    priv->vert_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
    priv->vert_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
    priv->vert_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
            priv->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC];
    debug_timing("vert", priv->vert_timing);

    bpp = fdtdec_get_int(blob, panel_node, "nvidia,bits-per-pixel", -1);
    bit = ffs(bpp) - 1;
    if (bpp == (1 << bit))
        priv->log2_bpp = bit;
    else
        priv->log2_bpp = bpp;
    if (bpp == -1) {
        debug("%s: Pixel bpp parameters missing\n", __func__);
        return -EINVAL;
    }

    if (fdtdec_parse_phandle_with_args(blob, panel_node, "nvidia,pwm",
                                       "#pwm-cells", 0, 0, &args)) {
        debug("%s: Unable to decode PWM\n", __func__);
        return -EINVAL;
    }

    ret = uclass_get_device_by_of_offset(UCLASS_PWM, args.node, &priv->pwm);
    if (ret) {
        debug("%s: Unable to find PWM\n", __func__);
        return -EINVAL;
    }
    priv->pwm_channel = args.args[0];

    priv->cache_type = fdtdec_get_int(blob, panel_node, "nvidia,cache-type",
                                      FDT_LCD_CACHE_WRITE_BACK_FLUSH);

    /* These GPIOs are all optional */
    gpio_request_by_name_nodev(blob, panel_node,
                               "nvidia,backlight-enable-gpios", 0,
                               &priv->backlight_en, GPIOD_IS_OUT);
    gpio_request_by_name_nodev(blob, panel_node,
                               "nvidia,lvds-shutdown-gpios", 0,
                               &priv->lvds_shutdown, GPIOD_IS_OUT);
    gpio_request_by_name_nodev(blob, panel_node,
                               "nvidia,backlight-vdd-gpios", 0,
                               &priv->backlight_vdd, GPIOD_IS_OUT);
    gpio_request_by_name_nodev(blob, panel_node,
                               "nvidia,panel-vdd-gpios", 0,
                               &priv->panel_vdd, GPIOD_IS_OUT);

    if (fdtdec_get_int_array(blob, panel_node, "nvidia,panel-timings",
                             priv->panel_timings, FDT_LCD_TIMINGS))
        return -EINVAL;

    return 0;
}
int board_prepare_usb(enum usb_init_type type)
{
	static struct udevice *pmic_gpio;
	static struct gpio_desc hub_reset, usb_sel;
	int ret = 0, node;

	if (!pmic_gpio) {
		ret = uclass_get_device_by_name(UCLASS_GPIO,
						"pm8916_gpios@c000",
						&pmic_gpio);
		if (ret < 0) {
			printf("Failed to find pm8916_gpios@c000 node.\n");
			return ret;
		}
	}

	/* Try to request gpios needed to start usb host on dragonboard */
	if (!dm_gpio_is_valid(&hub_reset)) {
		node = fdt_subnode_offset(gd->fdt_blob,
					  dev_of_offset(pmic_gpio),
					  "usb_hub_reset_pm");
		if (node < 0) {
			printf("Failed to find usb_hub_reset_pm dt node.\n");
			return node;
		}
		ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
						 "gpios", 0, &hub_reset, 0);
		if (ret < 0) {
			printf("Failed to request usb_hub_reset_pm gpio.\n");
			return ret;
		}
	}

	if (!dm_gpio_is_valid(&usb_sel)) {
		node = fdt_subnode_offset(gd->fdt_blob,
					  dev_of_offset(pmic_gpio),
					  "usb_sw_sel_pm");
		if (node < 0) {
			printf("Failed to find usb_sw_sel_pm dt node.\n");
			return 0;
		}
		ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
						 "gpios", 0, &usb_sel, 0);
		if (ret < 0) {
			printf("Failed to request usb_sw_sel_pm gpio.\n");
			return ret;
		}
	}

	if (type == USB_INIT_HOST) {
		/* Start USB Hub */
		dm_gpio_set_dir_flags(&hub_reset,
				      GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
		mdelay(100);
		/* Switch usb to host connectors */
		dm_gpio_set_dir_flags(&usb_sel,
				      GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
		mdelay(100);
	} else { /* Device */
		/* Disable hub */
		dm_gpio_set_dir_flags(&hub_reset, GPIOD_IS_OUT);
		/* Switch back to device connector */
		dm_gpio_set_dir_flags(&usb_sel, GPIOD_IS_OUT);
	}

	return 0;
}
Esempio n. 29
0
int rsa_verify(struct image_sign_info *info,
	       const struct image_region region[], int region_count,
	       uint8_t *sig, uint sig_len)
{
	const void *blob = info->fdt_blob;
	/* Reserve memory for maximum checksum-length */
	uint8_t hash[info->algo->checksum->pad_len];
	int ndepth, noffset;
	int sig_node, node;
	char name[100];
	int ret;

	/*
	 * Verify that the checksum-length does not exceed the
	 * rsa-signature-length
	 */
	if (info->algo->checksum->checksum_len >
	    info->algo->checksum->pad_len) {
		debug("%s: invlaid checksum-algorithm %s for %s\n",
		      __func__, info->algo->checksum->name, info->algo->name);
		return -EINVAL;
	}

	sig_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME);
	if (sig_node < 0) {
		debug("%s: No signature node found\n", __func__);
		return -ENOENT;
	}

	/* Calculate checksum with checksum-algorithm */
	ret = info->algo->checksum->calculate(info->algo->checksum->name,
					region, region_count, hash);
	if (ret < 0) {
		debug("%s: Error in checksum calculation\n", __func__);
		return -EINVAL;
	}

	/* See if we must use a particular key */
	if (info->required_keynode != -1) {
		ret = rsa_verify_with_keynode(info, hash, sig, sig_len,
			info->required_keynode);
		if (!ret)
			return ret;
	}

	/* Look for a key that matches our hint */
	snprintf(name, sizeof(name), "key-%s", info->keyname);
	node = fdt_subnode_offset(blob, sig_node, name);
	ret = rsa_verify_with_keynode(info, hash, sig, sig_len, node);
	if (!ret)
		return ret;

	/* No luck, so try each of the keys in turn */
	for (ndepth = 0, noffset = fdt_next_node(info->fit, sig_node, &ndepth);
			(noffset >= 0) && (ndepth > 0);
			noffset = fdt_next_node(info->fit, noffset, &ndepth)) {
		if (ndepth == 1 && noffset != node) {
			ret = rsa_verify_with_keynode(info, hash, sig, sig_len,
						      noffset);
			if (!ret)
				break;
		}
	}

	return ret;
}
Esempio n. 30
0
efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
			unsigned long orig_fdt_size,
			void *fdt, int new_fdt_size, char *cmdline_ptr,
			u64 initrd_addr, u64 initrd_size,
			efi_memory_desc_t *memory_map,
			unsigned long map_size, unsigned long desc_size,
			u32 desc_ver)
{
	int node, num_rsv;
	int status;
	u32 fdt_val32;
	u64 fdt_val64;

	/* Do some checks on provided FDT, if it exists*/
	if (orig_fdt) {
		if (fdt_check_header(orig_fdt)) {
			pr_efi_err(sys_table, "Device Tree header not valid!\n");
			return EFI_LOAD_ERROR;
		}
		/*
		 * We don't get the size of the FDT if we get if from a
		 * configuration table.
		 */
		if (orig_fdt_size && fdt_totalsize(orig_fdt) > orig_fdt_size) {
			pr_efi_err(sys_table, "Truncated device tree! foo!\n");
			return EFI_LOAD_ERROR;
		}
	}

	if (orig_fdt)
		status = fdt_open_into(orig_fdt, fdt, new_fdt_size);
	else
		status = fdt_create_empty_tree(fdt, new_fdt_size);

	if (status != 0)
		goto fdt_set_fail;

	/*
	 * Delete all memory reserve map entries. When booting via UEFI,
	 * kernel will use the UEFI memory map to find reserved regions.
	 */
	num_rsv = fdt_num_mem_rsv(fdt);
	while (num_rsv-- > 0)
		fdt_del_mem_rsv(fdt, num_rsv);

	node = fdt_subnode_offset(fdt, 0, "chosen");
	if (node < 0) {
		node = fdt_add_subnode(fdt, 0, "chosen");
		if (node < 0) {
			status = node; /* node is error code when negative */
			goto fdt_set_fail;
		}
	}

	if ((cmdline_ptr != NULL) && (strlen(cmdline_ptr) > 0)) {
		status = fdt_setprop(fdt, node, "bootargs", cmdline_ptr,
				     strlen(cmdline_ptr) + 1);
		if (status)
			goto fdt_set_fail;
	}

	/* Set initrd address/end in device tree, if present */
	if (initrd_size != 0) {
		u64 initrd_image_end;
		u64 initrd_image_start = cpu_to_fdt64(initrd_addr);

		status = fdt_setprop(fdt, node, "linux,initrd-start",
				     &initrd_image_start, sizeof(u64));
		if (status)
			goto fdt_set_fail;
		initrd_image_end = cpu_to_fdt64(initrd_addr + initrd_size);
		status = fdt_setprop(fdt, node, "linux,initrd-end",
				     &initrd_image_end, sizeof(u64));
		if (status)
			goto fdt_set_fail;
	}

	/* Add FDT entries for EFI runtime services in chosen node. */
	node = fdt_subnode_offset(fdt, 0, "chosen");
	fdt_val64 = cpu_to_fdt64((u64)(unsigned long)sys_table);
	status = fdt_setprop(fdt, node, "linux,uefi-system-table",
			     &fdt_val64, sizeof(fdt_val64));
	if (status)
		goto fdt_set_fail;

	fdt_val64 = cpu_to_fdt64((u64)(unsigned long)memory_map);
	status = fdt_setprop(fdt, node, "linux,uefi-mmap-start",
			     &fdt_val64,  sizeof(fdt_val64));
	if (status)
		goto fdt_set_fail;

	fdt_val32 = cpu_to_fdt32(map_size);
	status = fdt_setprop(fdt, node, "linux,uefi-mmap-size",
			     &fdt_val32,  sizeof(fdt_val32));
	if (status)
		goto fdt_set_fail;

	fdt_val32 = cpu_to_fdt32(desc_size);
	status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-size",
			     &fdt_val32, sizeof(fdt_val32));
	if (status)
		goto fdt_set_fail;

	fdt_val32 = cpu_to_fdt32(desc_ver);
	status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-ver",
			     &fdt_val32, sizeof(fdt_val32));
	if (status)
		goto fdt_set_fail;

	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
		efi_status_t efi_status;

		efi_status = efi_get_random_bytes(sys_table, sizeof(fdt_val64),
						  (u8 *)&fdt_val64);
		if (efi_status == EFI_SUCCESS) {
			status = fdt_setprop(fdt, node, "kaslr-seed",
					     &fdt_val64, sizeof(fdt_val64));
			if (status)
				goto fdt_set_fail;
		} else if (efi_status != EFI_NOT_FOUND) {
			return efi_status;
		}
	}
	return EFI_SUCCESS;

fdt_set_fail:
	if (status == -FDT_ERR_NOSPACE)
		return EFI_BUFFER_TOO_SMALL;

	return EFI_LOAD_ERROR;
}