aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineering.com>2019-04-26 12:00:44 -0500
committerStewart Smith <stewart@linux.ibm.com>2019-05-02 09:57:15 +1000
commit27fcf2fa8350f4c326e37603674242d36e786975 (patch)
tree419d80ddd4ce1ac024a13e7b515c7c3bcbebe4b6
parent0634dd410daed2fe79a2125d759837030a41269e (diff)
downloadskiboot-27fcf2fa8350f4c326e37603674242d36e786975.zip
skiboot-27fcf2fa8350f4c326e37603674242d36e786975.tar.gz
skiboot-27fcf2fa8350f4c326e37603674242d36e786975.tar.bz2
Expose PNOR Flash partitions to host MTD driver via devicetree
This makes it possible for the host to directly address each partition without requiring each application to directly parse the FFS headers. This has been in use for some time already to allow BOOTKERNFW partition updates from the host. Signed-off-by: Timothy Pearson <tpearson@raptorengineering.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
-rw-r--r--core/flash.c76
-rw-r--r--include/platform.h1
2 files changed, 65 insertions, 12 deletions
diff --git a/core/flash.c b/core/flash.c
index 1ed4260..e775dd1 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -1,4 +1,5 @@
/* Copyright 2013-2018 IBM Corp.
+ * Copyright 2018 Raptor Engineering, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +42,19 @@ struct flash {
int id;
};
+static struct {
+ enum resource_id id;
+ uint32_t subid;
+ char name[PART_NAME_MAX+1];
+} part_name_map[] = {
+ { RESOURCE_ID_KERNEL, RESOURCE_SUBID_NONE, "BOOTKERNEL" },
+ { 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" },
+ { RESOURCE_ID_KERNEL_FW, RESOURCE_SUBID_NONE, "BOOTKERNFW" },
+};
+
static LIST_HEAD(flashes);
static struct flash *system_flash;
@@ -206,7 +220,15 @@ static int flash_nvram_probe(struct flash *flash, struct ffs_handle *ffs)
static struct dt_node *flash_add_dt_node(struct flash *flash, int id)
{
+ int i;
+ int rc;
+ const char *name;
+ bool ecc;
+ struct ffs_handle *ffs;
+ int ffs_part_num, ffs_part_start, ffs_part_size;
struct dt_node *flash_node;
+ struct dt_node *partition_container_node;
+ struct dt_node *partition_node;
flash_node = dt_new_addr(opal_node, "flash", id);
dt_add_property_strings(flash_node, "compatible", "ibm,opal-flash");
@@ -221,6 +243,48 @@ static struct dt_node *flash_add_dt_node(struct flash *flash, int id)
dt_add_property_cells(flash_node, "#address-cells", 1);
dt_add_property_cells(flash_node, "#size-cells", 1);
+ /* Add partition container node */
+ partition_container_node = dt_new(flash_node, "partitions");
+ dt_add_property_strings(partition_container_node, "compatible", "fixed-partitions");
+
+ /* we fix to 32-bits */
+ dt_add_property_cells(partition_container_node, "#address-cells", 1);
+ dt_add_property_cells(partition_container_node, "#size-cells", 1);
+
+ /* Add partitions */
+ for (i = 0, name = NULL; i < ARRAY_SIZE(part_name_map); i++) {
+ name = part_name_map[i].name;
+
+ rc = ffs_init(0, flash->size, flash->bl, &ffs, 1);
+ if (rc) {
+ prerror("FLASH: Can't open ffs handle\n");
+ continue;
+ }
+
+ rc = ffs_lookup_part(ffs, name, &ffs_part_num);
+ if (rc) {
+ /* This is not an error per-se, some partitions
+ * are purposefully absent, don't spam the logs
+ */
+ prlog(PR_DEBUG, "FLASH: No %s partition\n", name);
+ continue;
+ }
+ rc = ffs_part_info(ffs, ffs_part_num, NULL,
+ &ffs_part_start, NULL, &ffs_part_size, &ecc);
+ if (rc) {
+ prerror("FLASH: Failed to get %s partition info\n", name);
+ continue;
+ }
+
+ partition_node = dt_new_addr(partition_container_node, "partition", ffs_part_start);
+ dt_add_property_strings(partition_node, "label", name);
+ dt_add_property_cells(partition_node, "reg", ffs_part_start, ffs_part_size);
+ }
+
+ partition_node = dt_new_addr(partition_container_node, "partition", 0);
+ dt_add_property_strings(partition_node, "label", "PNOR");
+ dt_add_property_cells(partition_node, "reg", 0, flash->size);
+
return flash_node;
}
@@ -431,18 +495,6 @@ opal_call(OPAL_FLASH_WRITE, opal_flash_write, 5);
opal_call(OPAL_FLASH_ERASE, opal_flash_erase, 4);
/* flash resource API */
-static struct {
- enum resource_id id;
- uint32_t subid;
- char name[PART_NAME_MAX+1];
-} part_name_map[] = {
- { RESOURCE_ID_KERNEL, RESOURCE_SUBID_NONE, "BOOTKERNEL" },
- { 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" },
-};
-
const char *flash_map_resource_name(enum resource_id id)
{
int i;
diff --git a/include/platform.h b/include/platform.h
index de4638f..f63c24a 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -30,6 +30,7 @@ enum resource_id {
RESOURCE_ID_CAPP,
RESOURCE_ID_IMA_CATALOG,
RESOURCE_ID_VERSION,
+ RESOURCE_ID_KERNEL_FW,
};
#define RESOURCE_SUBID_NONE 0
#define RESOURCE_SUBID_SUPPORTED 1