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 };
44 
45 const int flash_map_entries = ARRAY_SIZE(default_flash_map);
46 const struct flash_area *flash_map = default_flash_map;
47 
48 /* Generate objects representing each partition in system. In the end only
49  * objects referenced by code will be included into build.
50  */
51 #define DEFINE_PARTITION(part) DEFINE_PARTITION_1(part, DT_DEP_ORD(part))
52 #define DEFINE_PARTITION_1(part, ord)								\
53 	COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_MTD_FROM_FIXED_PARTITION(part)),			\
54 		(DEFINE_PARTITION_0(part, ord)), ())
55 #define DEFINE_PARTITION_0(part, ord)								\
56 	const struct flash_area DT_CAT(global_fixed_partition_ORD_, ord) = {			\
57 		.fa_id = DT_FIXED_PARTITION_ID(part),						\
58 		.fa_off = DT_REG_ADDR(part),							\
59 		.fa_dev = DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(part)),			\
60 		.fa_size = DT_REG_SIZE(part),							\
61 	};
62 
63 #define FOR_EACH_PARTITION_TABLE(table) DT_FOREACH_CHILD(table, DEFINE_PARTITION)
64 DT_FOREACH_STATUS_OKAY(fixed_partitions, FOR_EACH_PARTITION_TABLE)
65 
66 #define DEFINE_SUB_PARTITION(part) DEFINE_SUB_PARTITION_1(part, DT_DEP_ORD(part))
67 #define DEFINE_SUB_PARTITION_1(part, ord)							\
68 	COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_MTD_FROM_FIXED_SUBPARTITION(part)),		\
69 		(DEFINE_SUB_PARTITION_0(part, ord)), ())
70 #define DEFINE_SUB_PARTITION_0(part, ord)							\
71 	const struct flash_area DT_CAT(global_fixed_subpartition_ORD_, ord) = {			\
72 		.fa_id = DT_FIXED_PARTITION_ID(part),						\
73 		.fa_off = DT_REG_ADDR(part),							\
74 		.fa_dev = DEVICE_DT_GET(DT_MTD_FROM_FIXED_SUBPARTITION(part)),			\
75 		.fa_size = DT_REG_SIZE(part),							\
76 	};
77 
78 #define FOR_EACH_SUB_PARTITION_TABLE(table) DT_FOREACH_CHILD(table, DEFINE_SUB_PARTITION)
79 DT_FOREACH_STATUS_OKAY(fixed_subpartitions, FOR_EACH_SUB_PARTITION_TABLE)
80