1 /* 2 * Copyright (c) 2017-2024 Nordic Semiconductor ASA 3 * Copyright (c) 2015 Runtime Inc 4 * Copyright (c) 2023 Sensorfy B.V. 5 * 6 * SPDX-License-Identifier: Apache-2.0 7 */ 8 9 #include <zephyr/device.h> 10 #include <zephyr/kernel.h> 11 #include <zephyr/storage/flash_map.h> 12 13 #if CONFIG_FLASH_MAP_LABELS 14 #define FLASH_AREA_FOO(part, mtd_from_partition) \ 15 {.fa_id = DT_FIXED_PARTITION_ID(part), \ 16 .fa_off = DT_REG_ADDR(part), \ 17 .fa_dev = DEVICE_DT_GET(mtd_from_partition(part)), \ 18 .fa_size = DT_REG_SIZE(part), \ 19 .fa_label = DT_PROP_OR(part, label, NULL), }, 20 #else 21 #define FLASH_AREA_FOO(part, mtd_from_partition) \ 22 {.fa_id = DT_FIXED_PARTITION_ID(part), \ 23 .fa_off = DT_REG_ADDR(part), \ 24 .fa_dev = DEVICE_DT_GET(mtd_from_partition(part)), \ 25 .fa_size = DT_REG_SIZE(part), }, 26 #endif 27 28 #define FLASH_AREA_FOOO(part) \ 29 COND_CODE_1(DT_NODE_HAS_COMPAT(DT_PARENT(part), fixed_partitions), (\ 30 COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_MTD_FROM_FIXED_PARTITION(part)), \ 31 (FLASH_AREA_FOO(part, DT_MTD_FROM_FIXED_PARTITION)), ())), ( \ 32 COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_MTD_FROM_FIXED_SUBPARTITION(part)), \ 33 (FLASH_AREA_FOO(part, DT_MTD_FROM_FIXED_SUBPARTITION)), ()))) 34 35 #define FOREACH_PARTITION(n) DT_FOREACH_CHILD(n, FLASH_AREA_FOOO) 36 37 /* We iterate over all compatible 'fixed-partitions' nodes and 38 * use DT_FOREACH_CHILD to iterate over all the partitions for that 39 * 'fixed-partitions' node. This way we build a global partition map 40 */ 41 const struct flash_area default_flash_map[] = { 42 DT_FOREACH_STATUS_OKAY(fixed_partitions, FOREACH_PARTITION) 43 DT_FOREACH_STATUS_OKAY(fixed_subpartitions, FOREACH_PARTITION) 44 }; 45 46 const int flash_map_entries = ARRAY_SIZE(default_flash_map); 47 const struct flash_area *flash_map = default_flash_map; 48 49 /* Generate objects representing each partition in system. In the end only 50 * objects referenced by code will be included into build. 51 */ 52 #define DEFINE_PARTITION(part) DEFINE_PARTITION_1(part, DT_DEP_ORD(part)) 53 #define DEFINE_PARTITION_1(part, ord) \ 54 COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_MTD_FROM_FIXED_PARTITION(part)), \ 55 (DEFINE_PARTITION_0(part, ord)), ()) 56 #define DEFINE_PARTITION_0(part, ord) \ 57 const struct flash_area DT_CAT(global_fixed_partition_ORD_, ord) = { \ 58 .fa_id = DT_FIXED_PARTITION_ID(part), \ 59 .fa_off = DT_REG_ADDR(part), \ 60 .fa_dev = DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(part)), \ 61 .fa_size = DT_REG_SIZE(part), \ 62 }; 63 64 #define FOR_EACH_PARTITION_TABLE(table) DT_FOREACH_CHILD(table, DEFINE_PARTITION) 65 DT_FOREACH_STATUS_OKAY(fixed_partitions, FOR_EACH_PARTITION_TABLE) 66 67 #define DEFINE_SUBPARTITION(part) DEFINE_SUBPARTITION_1(part, DT_DEP_ORD(part)) 68 #define DEFINE_SUBPARTITION_1(part, ord) \ 69 COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_MTD_FROM_FIXED_SUBPARTITION(part)), \ 70 (DEFINE_SUBPARTITION_0(part, ord)), ()) 71 #define DEFINE_SUBPARTITION_0(part, ord) \ 72 const struct flash_area DT_CAT(global_fixed_subpartition_ORD_, ord) = { \ 73 .fa_id = DT_FIXED_PARTITION_ID(part), \ 74 .fa_off = DT_REG_ADDR(part), \ 75 .fa_dev = DEVICE_DT_GET(DT_MTD_FROM_FIXED_SUBPARTITION(part)), \ 76 .fa_size = DT_REG_SIZE(part), \ 77 }; 78 79 #define FOR_EACH_SUBPARTITION_TABLE(table) DT_FOREACH_CHILD(table, DEFINE_SUBPARTITION) 80 DT_FOREACH_STATUS_OKAY(fixed_subpartitions, FOR_EACH_SUBPARTITION_TABLE) 81