flash_map: distinguish between areas and sectors
The current flash_map.h API treats flash areas and flash sectors
synonymously. This isn't totally accurate; a flash area comprises one
or more sectors.
To distinguish them, add a new struct flash_sector, and a new
flash_area_get_sectors() which initializes an array of struct
flash_sector instead of struct flash area.
That done, deprecate flash_area_to_sectors().
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
diff --git a/boot/zephyr/flash_map.c b/boot/zephyr/flash_map.c
index d3c1598..2c5a9c9 100644
--- a/boot/zephyr/flash_map.c
+++ b/boot/zephyr/flash_map.c
@@ -155,19 +155,8 @@
#define FLASH_AREA_IMAGE_SECTOR_SIZE FLASH_AREA_IMAGE_SCRATCH_SIZE
#endif
-/*
- * Lookup the sector map for a given flash area. This should fill in
- * `ret` with all of the sectors in the area. `*cnt` will be set to
- * the storage at `ret` and should be set to the final number of
- * sectors in this area.
- */
-int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
+static int validate_idx(int idx, uint32_t *off, uint32_t *len)
{
- uint32_t off;
- uint32_t len;
- uint32_t max_cnt = *cnt;
- uint32_t rem_len;
-
/*
* This simple layout has uniform slots, so just fill in the
* right one.
@@ -176,30 +165,44 @@
return -1;
}
- if (*cnt < 1) {
- return -1;
- }
-
switch (idx) {
case FLASH_AREA_IMAGE_0:
- off = FLASH_AREA_IMAGE_0_OFFSET;
- len = FLASH_AREA_IMAGE_0_SIZE;
- break;
+ *off = FLASH_AREA_IMAGE_0_OFFSET;
+ *len = FLASH_AREA_IMAGE_0_SIZE;
+ goto done;
case FLASH_AREA_IMAGE_1:
- off = FLASH_AREA_IMAGE_1_OFFSET;
- len = FLASH_AREA_IMAGE_1_SIZE;
- break;
+ *off = FLASH_AREA_IMAGE_1_OFFSET;
+ *len = FLASH_AREA_IMAGE_1_SIZE;
+ goto done;
case FLASH_AREA_IMAGE_SCRATCH:
- off = FLASH_AREA_IMAGE_SCRATCH_OFFSET;
- len = FLASH_AREA_IMAGE_SCRATCH_SIZE;
- break;
+ *off = FLASH_AREA_IMAGE_SCRATCH_OFFSET;
+ *len = FLASH_AREA_IMAGE_SCRATCH_SIZE;
+ goto done;
default:
BOOT_LOG_ERR("unknown flash area %d", idx);
return -1;
}
+ done:
BOOT_LOG_DBG("area %d: offset=0x%x, length=0x%x, sector size=0x%x",
- idx, off, len, FLASH_AREA_IMAGE_SECTOR_SIZE);
+ idx, *off, *len, FLASH_AREA_IMAGE_SECTOR_SIZE);
+ return 0;
+}
+
+int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
+{
+ uint32_t off;
+ uint32_t len;
+ uint32_t max_cnt = *cnt;
+ uint32_t rem_len;
+
+ if (validate_idx(idx, &off, &len)) {
+ return -1;
+ }
+
+ if (*cnt < 1) {
+ return -1;
+ }
rem_len = len;
*cnt = 0;
@@ -226,3 +229,47 @@
return 0;
}
+
+/*
+ * Lookup the sector map for a given flash area. This should fill in
+ * `ret` with all of the sectors in the area. `*cnt` will be set to
+ * the storage at `ret` and should be set to the final number of
+ * sectors in this area.
+ */
+int flash_area_get_sectors(int idx, uint32_t *cnt, struct flash_sector *ret)
+{
+ uint32_t off;
+ uint32_t len;
+ uint32_t max_cnt = *cnt;
+ uint32_t rem_len;
+
+ if (validate_idx(idx, &off, &len)) {
+ return -1;
+ }
+
+ if (*cnt < 1) {
+ return -1;
+ }
+
+ rem_len = len;
+ *cnt = 0;
+ while (rem_len > 0 && *cnt < max_cnt) {
+ if (rem_len < FLASH_AREA_IMAGE_SECTOR_SIZE) {
+ BOOT_LOG_ERR("area %d size 0x%x not divisible by sector size 0x%x",
+ idx, len, FLASH_AREA_IMAGE_SECTOR_SIZE);
+ return -1;
+ }
+
+ ret[*cnt].fs_off = FLASH_AREA_IMAGE_SECTOR_SIZE * (*cnt);
+ ret[*cnt].fs_size = FLASH_AREA_IMAGE_SECTOR_SIZE;
+ *cnt = *cnt + 1;
+ rem_len -= FLASH_AREA_IMAGE_SECTOR_SIZE;
+ }
+
+ if (*cnt >= max_cnt) {
+ BOOT_LOG_ERR("flash area %d sector count overflow", idx);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/boot/zephyr/include/flash_map/flash_map.h b/boot/zephyr/include/flash_map/flash_map.h
index 605fd73..506f266 100644
--- a/boot/zephyr/include/flash_map/flash_map.h
+++ b/boot/zephyr/include/flash_map/flash_map.h
@@ -75,6 +75,25 @@
uint32_t fa_size;
};
+/**
+ * @brief Structure describing a sector within a flash area.
+ *
+ * Each sector has an offset relative to the start of its flash area
+ * (NOT relative to the start of its flash device), and a size. A
+ * flash area may contain sectors with different sizes.
+ */
+struct flash_sector {
+ /**
+ * Offset of this sector, from the start of its flash area (not device).
+ */
+ uint32_t fs_off;
+
+ /**
+ * Size of this sector, in bytes.
+ */
+ uint32_t fs_size;
+};
+
/*
* Retrieve a memory-mapped flash device's base address.
*
@@ -107,8 +126,16 @@
uint8_t flash_area_align(const struct flash_area *);
/*
- * Given flash map index, return info about sectors within the area.
+ * Given flash area ID, return info about sectors within the area.
*/
+int flash_area_get_sectors(int fa_id, uint32_t *count,
+ struct flash_sector *sectors);
+
+/*
+ * Similar to flash_area_get_sectors(), but return the values in an
+ * array of struct flash_area instead.
+ */
+__attribute__((deprecated))
int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret);
int flash_area_id_from_image_slot(int slot);