Пример #1
0
int fit_add_verification_data(const char *keydir, void *keydest, void *fit,
			      const char *comment, int require_keys,
			      const char *engine_id)
{
	int images_noffset, confs_noffset;
	int noffset;
	int ret;

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

	/* Process its subnodes, print out component images details */
	for (noffset = fdt_first_subnode(fit, images_noffset);
	     noffset >= 0;
	     noffset = fdt_next_subnode(fit, noffset)) {
		/*
		 * Direct child node of the images parent node,
		 * i.e. component image node.
		 */
		ret = fit_image_add_verification_data(keydir, keydest,
				fit, noffset, comment, require_keys, engine_id);
		if (ret)
			return ret;
	}

	/* If there are no keys, we can't sign configurations */
	if (!IMAGE_ENABLE_SIGN || !keydir)
		return 0;

	/* Find configurations parent node offset */
	confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
	if (confs_noffset < 0) {
		printf("Can't find images parent node '%s' (%s)\n",
		       FIT_CONFS_PATH, fdt_strerror(confs_noffset));
		return -ENOENT;
	}

	/* Process its subnodes, print out component images details */
	for (noffset = fdt_first_subnode(fit, confs_noffset);
	     noffset >= 0;
	     noffset = fdt_next_subnode(fit, noffset)) {
		ret = fit_config_add_verification_data(keydir, keydest,
						       fit, noffset, comment,
						       require_keys,
						       engine_id);
		if (ret)
			return ret;
	}

	return 0;
}
Пример #2
0
/* Find the I2C buses selected by this mux */
static int i2c_mux_post_bind(struct udevice *mux)
{
	const void *blob = gd->fdt_blob;
	int ret;
	int offset;

	debug("%s: %s\n", __func__, mux->name);
	/*
	 * There is no compatible string in the sub-nodes, so we must manually
	 * bind these
	 */
	for (offset = fdt_first_subnode(blob, mux->of_offset);
	     offset > 0;
	     offset = fdt_next_subnode(blob, offset)) {
		struct udevice *dev;
		const char *name;

		name = fdt_get_name(blob, offset, NULL);
		ret = device_bind_driver_to_node(mux, "i2c_mux_bus_drv", name,
						 offset, &dev);
		debug("   - bind ret=%d, %s\n", ret, dev ? dev->name : NULL);
		if (ret)
			return ret;
	}

	return 0;
}
Пример #3
0
static int led_gpio_bind(struct udevice *parent)
{
	const void *blob = gd->fdt_blob;
	struct udevice *dev;
	int node;
	int ret;

	for (node = fdt_first_subnode(blob, dev_of_offset(parent));
	     node > 0;
	     node = fdt_next_subnode(blob, node)) {
		struct led_uclass_plat *uc_plat;
		const char *label;

		label = fdt_getprop(blob, node, "label", NULL);
		if (!label) {
			debug("%s: node %s has no label\n", __func__,
			      fdt_get_name(blob, node, NULL));
			return -EINVAL;
		}
		ret = device_bind_driver_to_node(parent, "gpio_led",
						 fdt_get_name(blob, node, NULL),
						 node, &dev);
		if (ret)
			return ret;
		uc_plat = dev_get_uclass_platdata(dev);
		uc_plat->label = label;
	}

	return 0;
}
Пример #4
0
int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset,
		     bool pre_reloc_only)
{
	int ret = 0, err;

	for (offset = fdt_first_subnode(blob, offset);
	     offset > 0;
	     offset = fdt_next_subnode(blob, offset)) {
		if (pre_reloc_only &&
		    !fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL))
			continue;
		if (!fdtdec_get_is_enabled(blob, offset)) {
			dm_dbg("   - ignoring disabled device\n");
			continue;
		}
		err = lists_bind_fdt(parent, blob, offset, NULL);
		if (err && !ret) {
			ret = err;
			debug("%s: ret=%d\n", fdt_get_name(blob, offset, NULL),
			      ret);
		}
	}

	if (ret)
		dm_warn("Some drivers failed to bind\n");

	return ret;
}
Пример #5
0
static void parse_node(const char *dtb, int node,
		void (*mem_cb)(uint32_t addr, uint32_t length))
{
	int parent = node;
	node = fdt_first_subnode(dtb, node);
	while(node >= 0)
	{
		const void *dt;
		int plen;

		dt = fdt_getprop(dtb, node, "device_type", &plen);

#ifdef DEBUG_DTB
		const char *nn;
		nn = fdt_get_name(dtb, node, NULL);
		if(dt != NULL && nn != NULL)
		{
			printf("DTB: found device_type property for %s: %s\n", nn, (const char *)dt);
		}
		else if(nn != NULL)
			printf("DTB: found node %s\n", nn);
		else
			printf("DTB: unknown node\n");
#endif
		if(dt != NULL && !strcmp((const char *)dt, "memory"))
		{
			parse_reg(dtb, node, parent, mem_cb);
		}

		parse_node(dtb, node, mem_cb);
		
		node = fdt_next_subnode(dtb, node);
	}
}
Пример #6
0
static int fit_config_add_verification_data(const char *keydir, void *keydest,
		void *fit, int conf_noffset, const char *comment,
		int require_keys)
{
	const char *conf_name;
	int noffset;

	conf_name = fit_get_name(fit, conf_noffset, NULL);

	/* Process all hash subnodes of the configuration node */
	for (noffset = fdt_first_subnode(fit, conf_noffset);
	     noffset >= 0;
	     noffset = fdt_next_subnode(fit, noffset)) {
		const char *node_name;
		int ret = 0;

		node_name = fit_get_name(fit, noffset, NULL);
		if (!strncmp(node_name, FIT_SIG_NODENAME,
			     strlen(FIT_SIG_NODENAME))) {
			ret = fit_config_process_sig(keydir, keydest,
				fit, conf_name, conf_noffset, noffset, comment,
				require_keys);
		}
		if (ret)
			return ret;
	}

	return 0;
}
Пример #7
0
static int do_pinctrl_pins(const void *blob, int node, const char *child_name)
{
	int child, len;
	const char *node_name;

	child = fdt_first_subnode(blob, node);

	if (child < 0)
		return -EINVAL;

	node_name = fdt_get_name(blob, child, &len);

	while (node_name) {
		if (!strcmp(child_name, node_name))
			return do_pinctr_pin(blob, child, node_name);

		child = fdt_next_subnode(blob, child);

		if (child < 0)
			break;

		node_name = fdt_get_name(blob, child, &len);
	}

	return -EFAULT;
}
int gpio_ich6_pinctrl_init(void)
{
	int pin_node;
	int node;
	int ret;
	int gpiobase;
	int iobase_offset;
	int iobase = -1;

	/*
	 * Get the memory/io base address to configure every pins.
	 * IOBASE is used to configure the mode/pads
	 * GPIOBASE is used to configure the direction and default value
	 */
	gpiobase = gpio_ich6_get_base(PCI_CFG_GPIOBASE);
	if (gpiobase < 0) {
		debug("%s: invalid GPIOBASE address (%08x)\n", __func__,
		      gpiobase);
		return -EINVAL;
	}

	/* This is not an error to not have a pinctrl node */
	node =
	    fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_INTEL_X86_PINCTRL);
	if (node <= 0) {
		debug("%s: no pinctrl node\n", __func__);
		return 0;
	}

	/*
	 * Get the IOBASE, this is not mandatory as this is not
	 * supported by all the CPU
	 */
	iobase_offset = fdtdec_get_int(gd->fdt_blob, node, "io-base", -1);
	if (iobase_offset == -1) {
		debug("%s: io-base offset not present\n", __func__);
	} else {
		iobase = gpio_ich6_get_base(iobase_offset);
		if (IS_ERR_VALUE(iobase)) {
			debug("%s: invalid IOBASE address (%08x)\n", __func__,
			      iobase);
			return -EINVAL;
		}
	}

	for (pin_node = fdt_first_subnode(gd->fdt_blob, node);
	     pin_node > 0;
	     pin_node = fdt_next_subnode(gd->fdt_blob, pin_node)) {
		/* Configure the pin */
		ret = _gpio_ich6_pinctrl_cfg_pin(gpiobase, iobase, pin_node);
		if (ret != 0) {
			debug("%s: invalid configuration for the pin %d\n",
			      __func__, pin_node);
			return ret;
		}
	}

	return 0;
}
Пример #9
0
static size_t remove_reserved_memory(
  const void *fdt,
  Heap_Area *areas,
  size_t area_count
)
{
  int node;

  node = fdt_path_offset_namelen(
    fdt,
    reserved_memory_path,
    (int) sizeof(reserved_memory_path) - 1
  );

  if (node >= 0) {
    node = fdt_first_subnode(fdt, node);

    while (node >= 0) {
      int len;
      const void *val;
      uintptr_t area_begin;
      uintptr_t area_end;
      uintptr_t hole_begin;
      uintptr_t hole_end;
      Heap_Area *area;

      val = fdt_getprop(fdt, node, "reg", &len);
      if (len == 8) {
        hole_begin = fdt32_to_cpu(((fdt32_t *) val)[0]);
        hole_end = hole_begin + fdt32_to_cpu(((fdt32_t *) val)[1]);
      } else {
        rtems_panic("unexpected reserved memory area");
      }

      area = find_area(areas, area_count, hole_begin);
      area_begin = (uintptr_t) area->begin;
      area_end = area_begin + (uintptr_t) area->size;
      area->size = hole_begin - area_begin;

      if (hole_end <= area_end) {
        if (area_count >= AREA_COUNT_MAX) {
          rtems_panic("too many reserved memory areas");
        }

        area = &areas[area_count];
        ++area_count;
        area->begin = (void *) hole_end;
        area->size = area_end - hole_end;
      }

      node = fdt_next_subnode(fdt, node);
    }
  }

  return area_count;
}
Пример #10
0
static void setup_axp803_rails(const void *fdt)
{
	int node;
	bool dc1sw = false;

	/* locate the PMIC DT node, bail out if not found */
	node = fdt_node_offset_by_compatible(fdt, -1, "x-powers,axp803");
	if (node == -FDT_ERR_NOTFOUND) {
		WARN("BL31: PMIC: No AXP803 DT node, skipping initial setup.\n");
		return;
	}

	if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) {
		axp_clrbits(0x8f, BIT(4));
		axp_setbits(0x30, BIT(2));
		INFO("PMIC: AXP803: Enabling DRIVEVBUS\n");
	}

	/* descend into the "regulators" subnode */
	node = fdt_first_subnode(fdt, node);

	/* iterate over all regulators to find used ones */
	for (node = fdt_first_subnode(fdt, node);
	     node != -FDT_ERR_NOTFOUND;
	     node = fdt_next_subnode(fdt, node)) {
		struct axp_regulator *reg;
		const char *name;
		int length;

		/* We only care if it's always on or referenced. */
		if (!should_enable_regulator(fdt, node))
			continue;

		name = fdt_get_name(fdt, node, &length);
		for (reg = regulators; reg->dt_name; reg++) {
			if (!strncmp(name, reg->dt_name, length)) {
				setup_regulator(fdt, node, reg);
				break;
			}
		}

		if (!strncmp(name, "dc1sw", length)) {
			/* Delay DC1SW enablement to avoid overheating. */
			dc1sw = true;
			continue;
		}
	}
	/*
	 * If DLDO2 is enabled after DC1SW, the PMIC overheats and shuts
	 * down. So always enable DC1SW as the very last regulator.
	 */
	if (dc1sw) {
		INFO("PMIC: AXP803: Enabling DC1SW\n");
		axp_setbits(0x12, BIT(7));
	}
}
Пример #11
0
static int copy_spd(struct pei_data *peid)
{
    const int gpio_vector[] = {41, 42, 43, 10, -1};
    int spd_index;
    const void *blob = gd->fdt_blob;
    int node, spd_node;
    int ret, i;

    for (i = 0; ; i++) {
        if (gpio_vector[i] == -1)
            break;
        ret = gpio_requestf(gpio_vector[i], "spd_id%d", i);
        if (ret) {
            debug("%s: Could not request gpio %d\n", __func__,
                  gpio_vector[i]);
            return ret;
        }
    }
    spd_index = gpio_get_values_as_int(gpio_vector);
    debug("spd index %d\n", spd_index);
    node = fdtdec_next_compatible(blob, 0, COMPAT_MEMORY_SPD);
    if (node < 0) {
        printf("SPD data not found.\n");
        return -ENOENT;
    }

    for (spd_node = fdt_first_subnode(blob, node);
            spd_node > 0;
            spd_node = fdt_next_subnode(blob, spd_node)) {
        const char *data;
        int len;

        if (fdtdec_get_int(blob, spd_node, "reg", -1) != spd_index)
            continue;
        data = fdt_getprop(blob, spd_node, "data", &len);
        if (len < sizeof(peid->spd_data[0])) {
            printf("Missing SPD data\n");
            return -EINVAL;
        }

        debug("Using SDRAM SPD data for '%s'\n",
              fdt_get_name(blob, spd_node, NULL));
        memcpy(peid->spd_data[0], data, sizeof(peid->spd_data[0]));
        break;
    }

    if (spd_node < 0) {
        printf("No SPD data found for index %d\n", spd_index);
        return -ENOENT;
    }

    return 0;
}
Пример #12
0
static int gpio_dwapb_bind(struct udevice *dev)
{
	struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
	const void *blob = gd->fdt_blob;
	struct udevice *subdev;
	fdt_addr_t base;
	int ret, node, bank = 0;

	/* If this is a child device, there is nothing to do here */
	if (plat)
		return 0;

	base = fdtdec_get_addr(blob, dev_of_offset(dev), "reg");
	if (base == FDT_ADDR_T_NONE) {
		debug("Can't get the GPIO register base address\n");
		return -ENXIO;
	}

	for (node = fdt_first_subnode(blob, dev_of_offset(dev));
	     node > 0;
	     node = fdt_next_subnode(blob, node)) {
		if (!fdtdec_get_bool(blob, node, "gpio-controller"))
			continue;

		plat = NULL;
		plat = calloc(1, sizeof(*plat));
		if (!plat)
			return -ENOMEM;

		plat->base = base;
		plat->bank = bank;
		plat->pins = fdtdec_get_int(blob, node, "snps,nr-gpios", 0);
		plat->name = fdt_stringlist_get(blob, node, "bank-name", 0,
						NULL);
		if (ret)
			goto err;

		ret = device_bind(dev, dev->driver, plat->name,
				  plat, -1, &subdev);
		if (ret)
			goto err;

		dev_set_of_offset(subdev, node);
		bank++;
	}

	return 0;

err:
	free(plat);
	return ret;
}
Пример #13
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;
}
Пример #14
0
/**
 * fit_image_add_verification_data() - calculate/set verig. data for image node
 *
 * This adds hash and signature values for an component image node.
 *
 * All existing hash subnodes are checked, if algorithm property is set to
 * one of the supported hash algorithms, hash value is computed and
 * corresponding hash node property is set, for example:
 *
 * Input component image node structure:
 *
 * o image@1 (at image_noffset)
 *   | - data = [binary data]
 *   o hash@1
 *     |- algo = "sha1"
 *
 * Output component image node structure:
 *
 * o image@1 (at image_noffset)
 *   | - data = [binary data]
 *   o hash@1
 *     |- algo = "sha1"
 *     |- value = sha1(data)
 *
 * For signature details, please see doc/uImage.FIT/signature.txt
 *
 * @keydir	Directory containing *.key and *.crt files (or NULL)
 * @keydest	FDT Blob to write public keys into (NULL if none)
 * @fit:	Pointer to the FIT format image header
 * @image_noffset: Requested component image node
 * @comment:	Comment to add to signature nodes
 * @require_keys: Mark all keys as 'required'
 * @return: 0 on success, <0 on failure
 */
int fit_image_add_verification_data(const char *keydir, void *keydest,
		void *fit, int image_noffset, const char *comment,
		int require_keys)
{
	const char *image_name;
	const void *data;
	size_t size;
	int noffset;

	/* Get image data and data length */
	if (fit_image_get_data(fit, image_noffset, &data, &size)) {
		printf("Can't get image data/size\n");
		return -1;
	}

	image_name = fit_get_name(fit, image_noffset, NULL);

	/* Process all hash subnodes of the component image node */
	for (noffset = fdt_first_subnode(fit, image_noffset);
	     noffset >= 0;
	     noffset = fdt_next_subnode(fit, noffset)) {
		const char *node_name;
		int ret = 0;

		/*
		 * Check subnode name, must be equal to "hash" or "signature".
		 * Multiple hash nodes require unique unit node
		 * names, e.g. hash@1, hash@2, signature@1, etc.
		 */
		node_name = fit_get_name(fit, noffset, NULL);
		if (!strncmp(node_name, FIT_HASH_NODENAME,
			     strlen(FIT_HASH_NODENAME))) {
			ret = fit_image_process_hash(fit, image_name, noffset,
						data, size);
		} else if (IMAGE_ENABLE_SIGN && keydir &&
			   !strncmp(node_name, FIT_SIG_NODENAME,
				strlen(FIT_SIG_NODENAME))) {
			ret = fit_image_process_sig(keydir, keydest,
				fit, image_name, noffset, data, size,
				comment, require_keys);
		}
		if (ret)
			return ret;
	}

	return 0;
}
Пример #15
0
int ft_board_setup(void *fdt, bd_t *bd)
{
	int offset, tmp, len;
	const struct fdt_property *prop;
	const char *cci_compatible = "arm,cci-400-ctrl-if";

#ifdef CONFIG_ARMV7_NONSEC
	if (!armv7_boot_nonsec())
		return 0;
#else
	return 0;
#endif
	/* Booting in nonsec mode, disable CCI access */
	offset = fdt_path_offset(fdt, "/cpus");
	if (offset < 0) {
		printf("couldn't find /cpus\n");
		return offset;
	}

	/* delete cci-control-port in each cpu node */
	for (tmp = fdt_first_subnode(fdt, offset); tmp >= 0;
	     tmp = fdt_next_subnode(fdt, tmp))
		fdt_delprop(fdt, tmp, "cci-control-port");

	/* disable all ace cci slave ports */
	offset = fdt_node_offset_by_prop_value(fdt, offset, "compatible",
					       cci_compatible, 20);
	while (offset > 0) {
		prop = fdt_get_property(fdt, offset, "interface-type",
					&len);
		if (!prop)
			continue;
		if (len < 4)
			continue;
		if (strcmp(prop->data, "ace"))
			continue;

		fdt_setprop_string(fdt, offset, "status", "disabled");

		offset = fdt_node_offset_by_prop_value(fdt, offset, "compatible",
						       cci_compatible, 20);
	}

	return 0;
}
Пример #16
0
/**
 * We have a top-level GPIO device with no actual GPIOs. It has a child
 * device for each Exynos GPIO bank.
 */
static int gpio_exynos_bind(struct udevice *parent)
{
	struct exynos_gpio_platdata *plat = parent->platdata;
	struct s5p_gpio_bank *bank, *base;
	const void *blob = gd->fdt_blob;
	int node;

	/* If this is a child device, there is nothing to do here */
	if (plat)
		return 0;

	base = (struct s5p_gpio_bank *)fdtdec_get_addr(gd->fdt_blob,
						   parent->of_offset, "reg");
	for (node = fdt_first_subnode(blob, parent->of_offset), bank = base;
	     node > 0;
	     node = fdt_next_subnode(blob, node), bank++) {
		struct exynos_gpio_platdata *plat;
		struct udevice *dev;
		fdt_addr_t reg;
		int ret;

		if (!fdtdec_get_bool(blob, node, "gpio-controller"))
			continue;
		plat = calloc(1, sizeof(*plat));
		if (!plat)
			return -ENOMEM;
		reg = fdtdec_get_addr(blob, node, "reg");
		if (reg != FDT_ADDR_T_NONE)
			bank = (struct s5p_gpio_bank *)((ulong)base + reg);
		plat->bank = bank;
		plat->bank_name = fdt_get_name(blob, node, NULL);
		debug("dev at %p: %s\n", bank, plat->bank_name);

		ret = device_bind(parent, parent->driver,
					plat->bank_name, plat, -1, &dev);
		if (ret)
			return ret;
		dev->of_offset = node;
	}

	return 0;
}
Пример #17
0
static uint32_t discover_processors(void)
{
#if defined(HAS_UBOOT)
  return QORIQ_CPU_COUNT;
#elif defined(U_BOOT_USE_FDT)
  const void *fdt = bsp_fdt_get();
  int cpus = fdt_path_offset(fdt, "/cpus");
  int node = fdt_first_subnode(fdt, cpus);
  uint32_t cpu = 0;
  uintptr_t last = 0;
  uintptr_t begin = last - 1;

  while (node >= 0) {
    int len;
    fdt64_t *addr_fdt = (fdt64_t *)
      fdt_getprop(fdt, node, "cpu-release-addr", &len);

    if (
      addr_fdt != NULL
        && cpu < RTEMS_ARRAY_SIZE(qoriq_start_spin_table_addr)
    ) {
      uintptr_t addr = (uintptr_t) fdt64_to_cpu(*addr_fdt);

      if (addr < begin) {
        begin = addr;
      }

      if (addr > last) {
        last = addr;
      }

      qoriq_start_spin_table_addr[cpu] = (qoriq_start_spin_table *) addr;
      ++cpu;
    }

    node = fdt_next_subnode(fdt, node);
  }

  return cpu * QORIQ_THREAD_COUNT;
#endif
}
Пример #18
0
/**
 * spl_fit_get_image_name(): 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.
 * @outname:	Name of the image
 *
 * Return:	0 on success, or a negative error number
 */
static int spl_fit_get_image_name(const void *fit, int images,
				  const char *type, int index,
				  char **outname)
{
	const char *name, *str;
	__maybe_unused int node;
	int conf_node;
	int len, i;

	conf_node = fit_find_config_node(fit);
	if (conf_node < 0) {
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
		printf("No matching DT out of these options:\n");
		for (node = fdt_first_subnode(fit, conf_node);
		     node >= 0;
		     node = fdt_next_subnode(fit, node)) {
			name = fdt_getprop(fit, node, "description", &len);
			printf("   %s\n", name);
		}
#endif
		return conf_node;
	}

	name = fdt_getprop(fit, conf_node, type, &len);
	if (!name) {
		debug("cannot find property '%s': %d\n", type, len);
		return -EINVAL;
	}

	str = name;
	for (i = 0; i < index; i++) {
		str = strchr(str, '\0') + 1;
		if (!str || (str - name >= len)) {
			debug("no string for index %d\n", index);
			return -E2BIG;
		}
	}

	*outname = (char *)str;
	return 0;
}
Пример #19
0
/* Find a device by matching its compatible property */
static void parse_dtb_compatible_helper(const char *dtb, const char *compat, int node,
		void (*cb)(const char *dtb, int node, int parent))
{
	int parent = node;
	node = fdt_first_subnode(dtb, node);
	while(node >= 0)
	{
		const char *haystack = fdt_getprop(dtb, node, "compatible", NULL);
		if(compat)
		{
			if(strstr(haystack, compat))
			{
				cb(dtb, node, parent);
			}
		}

		parse_dtb_compatible_helper(dtb, compat, node, cb);

		node = fdt_next_subnode(dtb, node);
	}
}
Пример #20
0
static dt_node_t add_device_fdt(dt_node_t parent, void *fdt, int fdt_node, int depth)
{
    const char *name = fdt_get_name(fdt, fdt_node, NULL);
    printf("%*cEnumerating \"%s\"\n", depth, ' ', name);
    dt_node_t n = dt_node_alloc(parent, name);
    if (!n)
        panic("Out of memory enumerating node \"%s\"\n", name);

    for (int propoff = fdt_first_property_offset(fdt, fdt_node);
             propoff >= 0;
             propoff = fdt_next_property_offset(fdt, propoff)) {
        int len;
        const struct fdt_property *fdt_prop =
            fdt_get_property_by_offset(fdt, propoff, &len);

        if (!fdt_prop) {
            panic("Error getting property of \"%s\": %s\n",
                name, fdt_strerror(len));
        }

        const char *prop_name = fdt_string(fdt, fdt32_to_cpu(fdt_prop->nameoff));

        printf("%*c \"%s\" = \"", depth, ' ', prop_name);
        print_dtval(fdt_prop->data, len);
        printf("\"\n");

        if (!dt_node_set_property(n, prop_name, fdt_prop->data, len))
            panic("Out of memory allocating \"%s\":\"%s\"",
                name, prop_name);
    }

    for (int suboff = fdt_first_subnode(fdt, fdt_node);
             suboff != -FDT_ERR_NOTFOUND;
             suboff = fdt_next_subnode(fdt, suboff)) {
        add_device_fdt(n, fdt, suboff, depth + 2);
    }

    return n;
}
Пример #21
0
const char *dpl_get_connection_endpoint(void *blob, char *endpoint)
{
	int connoffset = fdt_path_offset(blob, "/connections"), off;
	const char *s1, *s2;

	for (off = fdt_first_subnode(blob, connoffset);
	     off >= 0;
	     off = fdt_next_subnode(blob, off)) {
		s1 = fdt_stringlist_get(blob, off, "endpoint1", 0, NULL);
		s2 = fdt_stringlist_get(blob, off, "endpoint2", 0, NULL);

		if (!s1 || !s2)
			continue;

		if (strcmp(endpoint, s1) == 0)
			return s2;

		if (strcmp(endpoint, s2) == 0)
			return s1;
	}

	return NULL;
}
Пример #22
0
static int cpu_x86_get_count(struct udevice *dev)
{
	int node, cpu;
	int num = 0;

	node = fdt_path_offset(gd->fdt_blob, "/cpus");
	if (node < 0)
		return -ENOENT;

	for (cpu = fdt_first_subnode(gd->fdt_blob, node);
	     cpu >= 0;
	     cpu = fdt_next_subnode(gd->fdt_blob, cpu)) {
		const char *device_type;

		device_type = fdt_getprop(gd->fdt_blob, cpu,
					  "device_type", NULL);
		if (!device_type)
			continue;
		if (strcmp(device_type, "cpu") == 0)
			num++;
	}

	return num;
}
Пример #23
0
int fit_list_configs(void *fit, int configs_offset) {
	int node;
	int count;

	const char *default_cfg = fdt_getprop(fit, configs_offset, "default", NULL);
	printf("\n\n  Default configuration: %s\n", default_cfg);

	for(count = 0,node = fdt_first_subnode(fit, configs_offset); node >= 0; node = fdt_next_subnode(fit, node), count++) {
		printf("\n === Configuration (%d) - %s ===\n", count, fdt_get_name(fit, node, NULL));
		const char *description = fdt_getprop(fit, node, "description", NULL);
		printf("  Description   : %s\n", description);
		const char *kernel = fdt_getprop(fit, node, "kernel", NULL);
		printf("  Kernel        : %s\n", kernel);

		const char *fpga = fdt_getprop(fit, node, "fpga", NULL);
		if(fpga) {

			const char *fpga_device = fdt_getprop(fit, node, "fpga_device", NULL);
			printf("  fpga          : %s\n", fpga);
			printf("  fpga_device   : %s\n", fpga_device);
		}
	}

}
Пример #24
0
static int ti_musb_wrapper_bind(struct udevice *parent)
{
	const void *fdt = gd->fdt_blob;
	int node;
	int ret;

	for (node = fdt_first_subnode(fdt, parent->of_offset); node > 0;
	     node = fdt_next_subnode(fdt, node)) {
		struct udevice *dev;
		const char *name = fdt_get_name(fdt, node, NULL);
		enum usb_dr_mode dr_mode;
		struct driver *drv;

		if (strncmp(name, "usb@", 4))
			continue;

		dr_mode = usb_get_dr_mode(node);
		switch (dr_mode) {
		case USB_DR_MODE_PERIPHERAL:
			/* Bind MUSB device */
			break;
		case USB_DR_MODE_HOST:
			/* Bind MUSB host */
			ret = device_bind_driver_to_node(parent, "ti-musb-host",
							 name, node, &dev);
			if (ret) {
				error("musb - not able to bind usb host node\n");
				return ret;
			}
			break;
		default:
			break;
		};
	}
	return 0;
}
Пример #25
0
/**
 * at91_clk_sub_device_bind() - for the at91 clock driver
 * Recursively bind its children as clk devices.
 *
 * @return: 0 on success, or negative error code on failure
 */
int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
{
	const void *fdt = gd->fdt_blob;
	int offset = dev_of_offset(dev);
	bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
	const char *name;
	int ret;

	for (offset = fdt_first_subnode(fdt, offset);
	     offset > 0;
	     offset = fdt_next_subnode(fdt, offset)) {
		if (pre_reloc_only &&
		    !fdt_getprop(fdt, offset, "u-boot,dm-pre-reloc", NULL))
			continue;
		/*
		 * If this node has "compatible" property, this is not
		 * a clock sub-node, but a normal device. skip.
		 */
		fdt_get_property(fdt, offset, "compatible", &ret);
		if (ret >= 0)
			continue;

		if (ret != -FDT_ERR_NOTFOUND)
			return ret;

		name = fdt_get_name(fdt, offset, NULL);
		if (!name)
			return -EINVAL;
		ret = device_bind_driver_to_node(dev, drv_name, name,
						 offset, NULL);
		if (ret)
			return ret;
	}

	return 0;
}
Пример #26
0
static uint32_t discover_processors(void)
{
  const void *fdt = bsp_fdt_get();
  int cpus = fdt_path_offset(fdt, "/cpus");
  int node = fdt_first_subnode(fdt, cpus);
  uint32_t cpu = 0;

  while (node >= 0 && cpu < RTEMS_ARRAY_SIZE(qoriq_start_spin_table_addr)) {
    int len;
    fdt64_t *addr_fdt = (fdt64_t *)
      fdt_getprop(fdt, node, "cpu-release-addr", &len);

    if (addr_fdt != NULL) {
      uintptr_t addr = (uintptr_t) fdt64_to_cpu(*addr_fdt);

      qoriq_start_spin_table_addr[cpu] = (qoriq_start_spin_table *) addr;
    }

    ++cpu;
    node = fdt_next_subnode(fdt, node);
  }

  return cpu * QORIQ_THREAD_COUNT;
}
Пример #27
0
/**
 * fit_image_verify - verify data intergity
 * @fit: pointer to the FIT format image header
 * @image_noffset: component image node offset
 *
 * fit_image_verify() goes over component image hash nodes,
 * re-calculates each data hash and compares with the value stored in hash
 * node.
 *
 * returns:
 *     1, if all hashes are valid
 *     0, otherwise (or on error)
 */
int fit_image_verify(const void *fit, int image_noffset)
{
	const void	*data;
	size_t		size;
	int		noffset = 0;
	char		*err_msg = "";
	int verify_all = 1;
	int ret;

	/* Get image data and data length */
	if (fit_image_get_data(fit, image_noffset, &data, &size)) {
		err_msg = "Can't get image data/size";
		goto error;
	}

	/* Verify all required signatures */
	if (IMAGE_ENABLE_VERIFY &&
	    fit_image_verify_required_sigs(fit, image_noffset, data, size,
					   gd_fdt_blob(), &verify_all)) {
		err_msg = "Unable to verify required signature";
		goto error;
	}

	/* Process all hash subnodes of the component image node */
	for (noffset = fdt_first_subnode(fit, image_noffset);
	     noffset >= 0;
	     noffset = fdt_next_subnode(fit, noffset)) {
		const char *name = fit_get_name(fit, noffset, NULL);

		/*
		 * Check subnode name, must be equal to "hash".
		 * Multiple hash nodes require unique unit node
		 * names, e.g. hash@1, hash@2, etc.
		 */
		if (!strncmp(name, FIT_HASH_NODENAME,
			     strlen(FIT_HASH_NODENAME))) {
			if (fit_image_check_hash(fit, noffset, data, size,
						 &err_msg))
				goto error;
			puts("+ ");
		} else if (IMAGE_ENABLE_VERIFY && verify_all &&
				!strncmp(name, FIT_SIG_NODENAME,
					strlen(FIT_SIG_NODENAME))) {
			ret = fit_image_check_sig(fit, noffset, data,
							size, -1, &err_msg);
			if (ret)
				puts("- ");
			else
				puts("+ ");
		}
	}

	if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
		err_msg = "Corrupted or truncated tree";
		goto error;
	}

	return 1;

error:
	printf(" error!\n%s for '%s' hash node in '%s' image node\n",
	       err_msg, fit_get_name(fit, noffset, NULL),
	       fit_get_name(fit, image_noffset, NULL));
	return 0;
}
Пример #28
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;
}
Пример #29
0
static int fit_config_get_hash_list(void *fit, int conf_noffset,
				    int sig_offset, struct strlist *node_inc)
{
	int allow_missing;
	const char *prop, *iname, *end;
	const char *conf_name, *sig_name;
	char name[200], path[200];
	int image_count;
	int ret, len;

	conf_name = fit_get_name(fit, conf_noffset, NULL);
	sig_name = fit_get_name(fit, sig_offset, NULL);

	/*
	 * Build a list of nodes we need to hash. We always need the root
	 * node and the configuration.
	 */
	strlist_init(node_inc);
	snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH, conf_name);
	if (strlist_add(node_inc, "/") ||
	    strlist_add(node_inc, name))
		goto err_mem;

	/* Get a list of images that we intend to sign */
	prop = fit_config_get_image_list(fit, sig_offset, &len,
					&allow_missing);
	if (!prop)
		return 0;

	/* Locate the images */
	end = prop + len;
	image_count = 0;
	for (iname = prop; iname < end; iname += strlen(iname) + 1) {
		int noffset;
		int image_noffset;
		int hash_count;

		image_noffset = fit_conf_get_prop_node(fit, conf_noffset,
						       iname);
		if (image_noffset < 0) {
			printf("Failed to find image '%s' in  configuration '%s/%s'\n",
			       iname, conf_name, sig_name);
			if (allow_missing)
				continue;

			return -ENOENT;
		}

		ret = fdt_get_path(fit, image_noffset, path, sizeof(path));
		if (ret < 0)
			goto err_path;
		if (strlist_add(node_inc, path))
			goto err_mem;

		snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH,
			 conf_name);

		/* Add all this image's hashes */
		hash_count = 0;
		for (noffset = fdt_first_subnode(fit, image_noffset);
		     noffset >= 0;
		     noffset = fdt_next_subnode(fit, noffset)) {
			const char *name = fit_get_name(fit, noffset, NULL);

			if (strncmp(name, FIT_HASH_NODENAME,
				    strlen(FIT_HASH_NODENAME)))
				continue;
			ret = fdt_get_path(fit, noffset, path, sizeof(path));
			if (ret < 0)
				goto err_path;
			if (strlist_add(node_inc, path))
				goto err_mem;
			hash_count++;
		}

		if (!hash_count) {
			printf("Failed to find any hash nodes in configuration '%s/%s' image '%s' - without these it is not possible to verify this image\n",
			       conf_name, sig_name, iname);
			return -ENOMSG;
		}

		image_count++;
	}

	if (!image_count) {
		printf("Failed to find any images for configuration '%s/%s'\n",
		       conf_name, sig_name);
		return -ENOMSG;
	}

	return 0;

err_mem:
	printf("Out of memory processing configuration '%s/%s'\n", conf_name,
	       sig_name);
	return -ENOMEM;

err_path:
	printf("Failed to get path for image '%s' in configuration '%s/%s': %s\n",
	       iname, conf_name, sig_name, fdt_strerror(ret));
	return -ENOENT;
}
Пример #30
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;
}