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

Vasant Hegde hegdevasant at linux.vnet.ibm.com
Tue Aug 29 14:12:18 AEST 2017


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>
Reviewed-by: Samuel Mendoza-Jonas <sam at mendozajonas.com>
---
Changes in v3:
  Addressed review comments from Sam and added Reviewed-by tag.

-Vasant

 core/flash.c              | 109 ++++++++++++++++++++++++++++++++++++++++++++++
 include/platform.h        |   1 +
 include/skiboot.h         |   3 ++
 platforms/astbmc/common.c |   6 +++
 4 files changed, 119 insertions(+)

diff --git a/core/flash.c b/core/flash.c
index 53e6eba..7e46f0a 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -19,6 +19,7 @@
 #include <lock.h>
 #include <opal.h>
 #include <opal-msg.h>
+#include <platform.h>
 #include <device.h>
 #include <libflash/libflash.h>
 #include <libflash/libffs.h>
@@ -47,6 +48,10 @@ static struct lock flash_lock;
 static struct flash *nvram_flash;
 static u32 nvram_offset, nvram_size;
 
+/* ibm,firmware-versions support */
+static char *version_buf;
+static size_t version_buf_size = 0x1000;
+
 bool flash_reserve(void)
 {
 	bool rc = false;
@@ -148,6 +153,109 @@ 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",
+				      "machine-xml"};
+
+	/*
+	 * 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);
+	}
+}
+
+void flash_dt_add_fw_version(void)
+{
+	uint8_t version_data[80];
+	int rc;
+	int numbytes = 0, i = 0;
+	struct dt_node *fw_version;
+
+	if (version_buf == NULL)
+		return;
+
+	rc = wait_for_resource_loaded(RESOURCE_ID_VERSION, RESOURCE_SUBID_NONE);
+	if (rc != OPAL_SUCCESS) {
+		prlog(PR_WARNING, "FLASH: Failed to load VERSION data\n");
+		free(version_buf);
+		return;
+	}
+
+	fw_version = dt_new(dt_root, "ibm,firmware-versions");
+	assert(fw_version);
+
+	for ( ; (numbytes < version_buf_size) && version_buf[numbytes]; numbytes++) {
+		if (version_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 (version_buf[numbytes] == '\t') {
+			continue; /* skip tabs */
+		}
+
+		version_data[i++] = version_buf[numbytes];
+	}
+
+	free(version_buf);
+}
+
+void flash_fw_version_preload(void)
+{
+	int rc;
+
+	if (proc_gen < proc_gen_p9)
+		return;
+
+	prlog(PR_INFO, "FLASH: Loading VERSION section\n");
+
+	version_buf = malloc(version_buf_size);
+	if (!version_buf) {
+		prlog(PR_WARNING, "FLASH: Failed to allocate memory\n");
+		return;
+	}
+
+	rc = start_preload_resource(RESOURCE_ID_VERSION, RESOURCE_SUBID_NONE,
+				    version_buf, &version_buf_size);
+	if (rc != OPAL_SUCCESS) {
+		prlog(PR_WARNING,
+		      "FLASH: Failed to start loading VERSION data\n");
+		free(version_buf);
+		version_buf = NULL;
+	}
+}
+
 static int flash_nvram_probe(struct flash *flash, struct ffs_handle *ffs)
 {
 	uint32_t start, size, part;
@@ -422,6 +530,7 @@ static struct {
 	{ RESOURCE_ID_INITRAMFS,RESOURCE_SUBID_NONE,		"ROOTFS" },
 	{ RESOURCE_ID_CAPP,	RESOURCE_SUBID_SUPPORTED,	"CAPP" },
 	{ RESOURCE_ID_IMA_CATALOG,  RESOURCE_SUBID_SUPPORTED,	"IMA_CATALOG" },
+	{ RESOURCE_ID_VERSION,	RESOURCE_SUBID_NONE,		"VERSION" },
 };
 
 
diff --git a/include/platform.h b/include/platform.h
index e6ebb13..f3af390 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -28,6 +28,7 @@ enum resource_id {
 	RESOURCE_ID_INITRAMFS,
 	RESOURCE_ID_CAPP,
 	RESOURCE_ID_IMA_CATALOG,
+	RESOURCE_ID_VERSION,
 };
 #define RESOURCE_SUBID_NONE 0
 #define RESOURCE_SUBID_SUPPORTED 1
diff --git a/include/skiboot.h b/include/skiboot.h
index 4b7d519..0ab9f38 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -243,6 +243,9 @@ extern int flash_subpart_info(void *part_header, uint32_t header_len,
 			      uint32_t part_size, uint32_t *part_actual,
 			      uint32_t subid, uint32_t *offset,
 			      uint32_t *size);
+extern void flash_fw_version_preload(void);
+extern void flash_dt_add_fw_version(void);
+
 /* NVRAM support */
 extern void nvram_init(void);
 extern void nvram_read_complete(bool success);
diff --git a/platforms/astbmc/common.c b/platforms/astbmc/common.c
index ed725ce..0f6b71f 100644
--- a/platforms/astbmc/common.c
+++ b/platforms/astbmc/common.c
@@ -134,6 +134,9 @@ void astbmc_init(void)
 	astbmc_fru_init();
 	ipmi_sensor_init();
 
+	/* Preload PNOR VERSION section */
+	flash_fw_version_preload();
+
 	/* As soon as IPMI is up, inform BMC we are in "S0" */
 	ipmi_set_power_state(IPMI_PWR_SYS_S0_WORKING, IPMI_PWR_NOCHANGE);
 
@@ -144,6 +147,9 @@ void astbmc_init(void)
 
 	/* Setup UART console for use by Linux via OPAL API */
 	set_opal_console(&uart_opal_con);
+
+	/* Add ibm,firmware-versions node */
+	flash_dt_add_fw_version();
 }
 
 int64_t astbmc_ipmi_power_down(uint64_t request)
-- 
2.9.3



More information about the Skiboot mailing list