diff options
author | Timothy Pearson <tpearson@raptorengineering.com> | 2019-04-26 12:00:44 -0500 |
---|---|---|
committer | Stewart Smith <stewart@linux.ibm.com> | 2019-05-02 09:57:15 +1000 |
commit | 27fcf2fa8350f4c326e37603674242d36e786975 (patch) | |
tree | 419d80ddd4ce1ac024a13e7b515c7c3bcbebe4b6 | |
parent | 0634dd410daed2fe79a2125d759837030a41269e (diff) | |
download | skiboot-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.c | 76 | ||||
-rw-r--r-- | include/platform.h | 1 |
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 |