[Skiboot] [PATCH] DT: Add ibm,firmware-versions node

Samuel Mendoza-Jonas sam at mendozajonas.com
Fri Aug 11 15:04:22 AEST 2017


On Fri, 2017-07-07 at 14:33 +0530, Vasant Hegde wrote:
> In P8, hostboot provides mini device tree. It contains /ibm,firmware-versions
> node which has various firmware component version details.
> 
> In P9, OPAL is building device tree. This patch adds support to parse VERSION
> section of PNOR and create "/ibm,firmware-versions" device tree node.
> 
> Sample output:
> 	/sys/firmware/devicetree/base/ibm,firmware-versions # lsprop .
> 	occ              "6a00709"
> 	skiboot          "v5.7-rc1-p344fb62"
> 	buildroot        "2017.02.2-7-g23118ce"
> 	capp-ucode       "9c73e9f"
> 	petitboot        "v1.4.3-p98b6d83"
> 	sbe              "02021c6"
> 	open-power       "witherspoon-v1.17-128-gf1b53c7-dirty"
> 	....
> 	....
> 
> Signed-off-by: Vasant Hegde <hegdevasant at linux.vnet.ibm.com>
> Signed-off-by: Mukesh Ojha <mukesh02 at linux.vnet.ibm.com>

Acked-By: Samuel Mendoza-Jonas <sam at mendozajonas.com>

> ---
>  core/flash.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 102 insertions(+)
> 
> diff --git a/core/flash.c b/core/flash.c
> index 8a908e5..219e6e0 100644
> --- a/core/flash.c
> +++ b/core/flash.c
> @@ -148,6 +148,107 @@ out:
>  	return rc;
>  }
>  
> +static void flash_dt_add_fw_version(struct dt_node *fw_version, char* data)
> +{
> +	char *prop;
> +	int version_len, i;
> +	int len = strlen(data);
> +	const char * version_str[] = {"open-power", "buildroot", "skiboot",
> +				      "hostboot-binaries", "hostboot", "linux",
> +				      "petitboot", "occ", "capp-ucode", "sbe"};
> +	/*
> +	 * PNOR version strings are not easily consumable. Split them into
> +	 * property, value.
> +	 *
> +	 * Example input from PNOR :
> +	 *   "open-power-firestone-v1.8"
> +	 *   "linux-4.4.6-openpower1-8420e0f"
> +	 *
> +	 * Desired output in device tree:
> +	 *   open-power = "firestone-v1.8";
> +	 *   linux = "4.4.6-openpower1-8420e0f";
> +	 */
> +	for(i = 0; i < ARRAY_SIZE(version_str); i++)
> +	{
> +		version_len = strlen(version_str[i]);
> +		if (len < version_len)
> +			continue;
> +
> +		if (memcmp(data, version_str[i], version_len) != 0)
> +			continue;
> +
> +		/* Found a match, add property */
> +		if (dt_find_property(fw_version, version_str[i]))
> +			continue;
> +
> +		/* Increment past "key-" */
> +		prop = data + version_len + 1;
> +		dt_add_property_string(fw_version, version_str[i], prop);
> +	}
> +}
> +
> +static int flash_fw_version_probe(struct flash *flash, struct ffs_handle *ffs)
> +{
> +	bool ecc;
> +	char *buf;
> +	uint8_t version_data[80];
> +	int rc;
> +	int numbytes = 0, i = 0;
> +	uint32_t start, size, part, version_size;
> +	struct dt_node *fw_version;
> +
> +	if (proc_gen < proc_gen_p9)
> +		return 0;
> +
> +	prlog(PR_INFO, "FLASH: probing for VERSION\n");
> +
> +	rc = ffs_lookup_part(ffs, "VERSION", &part);
> +	if (rc) {
> +		prlog(PR_WARNING, "FLASH: No VERSION partition found\n");
> +		return OPAL_HARDWARE;
> +	}
> +
> +	rc = ffs_part_info(ffs, part, NULL, &start, &size, NULL, &ecc);
> +	if (rc) {
> +		prlog(PR_WARNING, "FLASH: Can't parse ffs info for VERSION\n");
> +		return OPAL_HARDWARE;
> +	}
> +
> +	buf = malloc(size);
> +	if (!buf) {
> +                prlog(PR_WARNING, "FLASH: Failed to allocate memory\n");
> +		return OPAL_RESOURCE;
> +	}
> +
> +	rc = blocklevel_read(flash->bl, start, buf, size);
> +	if (rc) {
> +		prlog(PR_WARNING, "FLASH: Couldn't read from flash at 0x%08x "
> +		      "for len 0x%08x [rc = %d]\n", start, size, rc);
> +		return rc;
> +	}
> +
> +	version_size = ecc ? ecc_buffer_size_minus_ecc(size) : size;
> +	fw_version = dt_new(dt_root, "ibm,firmware-versions");
> +	assert(fw_version);
> +
> +	for ( ; (numbytes < version_size) && buf[numbytes]; numbytes++) {
> +		if (buf[numbytes] == '\n') {
> +			version_data[i] = '\0';
> +			flash_dt_add_fw_version(fw_version, version_data);
> +			memset(version_data, 0, sizeof(version_data));
> +			i = 0;
> +			continue;
> +		} else if (buf[numbytes] == '\t') {
> +			continue; /* skip tabs */
> +		}
> +
> +		version_data[i++] = buf[numbytes];
> +	}
> +
> +	free(buf);
> +	return 0;
> +}
> +
>  static int flash_nvram_probe(struct flash *flash, struct ffs_handle *ffs)
>  {
>  	uint32_t start, size, part;
> @@ -238,6 +339,7 @@ static void setup_system_flash(struct flash *flash, struct dt_node *node,
>  
>  	prlog(PR_INFO, "FLASH: registered system flash device %s\n", name);
>  
> +	flash_fw_version_probe(flash, ffs);
>  	flash_nvram_probe(flash, ffs);
>  }
>  



More information about the Skiboot mailing list