1 /*
2  * Copyright (c) 2023 Carlo Caione <ccaione@baylibre.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_MEM_ATTR_H_
8 #define ZEPHYR_INCLUDE_MEM_ATTR_H_
9 
10 /**
11  * @brief Memory-Attr Interface
12  * @defgroup memory_attr_interface Memory-Attr Interface
13  * @ingroup mem_mgmt
14  * @{
15  */
16 
17 #include <stddef.h>
18 #include <zephyr/types.h>
19 #include <zephyr/dt-bindings/memory-attr/memory-attr.h>
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 /** @cond INTERNAL_HIDDEN */
26 
27 #define __MEM_ATTR	zephyr_memory_attr
28 
29 #define _FILTER(node_id, fn)						\
30 	COND_CODE_1(DT_NODE_HAS_PROP(node_id, __MEM_ATTR),		\
31 		    (fn(node_id)),					\
32 		    ())
33 
34 /** @endcond */
35 
36 /**
37  * @brief Invokes @p fn for every status `okay` node in the tree with property
38  *	  `zephyr,memory-attr`
39  *
40  * The macro @p fn must take one parameter, which will be a node identifier
41  * with the `zephyr,memory-attr` property. The macro is expanded once for each
42  * node in the tree with status `okay`. The order that nodes are visited in is
43  * not specified.
44  *
45  * @param fn macro to invoke
46  */
47 #define DT_MEMORY_ATTR_FOREACH_STATUS_OKAY_NODE(fn)			\
48 	DT_FOREACH_STATUS_OKAY_NODE_VARGS(_FILTER, fn)
49 
50 /**
51  * @brief memory-attr region structure.
52  *
53  * This structure represents the data gathered from DT about a memory-region
54  * marked with memory attributes.
55  */
56 struct mem_attr_region_t {
57 	/** Memory node full name */
58 	const char *dt_name;
59 	/** Memory region physical address */
60 	uintptr_t dt_addr;
61 	/** Memory region size */
62 	size_t dt_size;
63 	/** Memory region attributes */
64 	uint32_t dt_attr;
65 };
66 
67 /**
68  * @brief Get the list of memory regions.
69  *
70  * Get the list of enabled memory regions with their memory-attribute as
71  * gathered by DT.
72  *
73  * @param region Pointer to pointer to the list of memory regions.
74  *
75  * @retval Number of memory regions returned in the parameter.
76  */
77 size_t mem_attr_get_regions(const struct mem_attr_region_t **region);
78 
79 /**
80  * @brief Check if a buffer has correct size and attributes.
81  *
82  * This function is used to check if a given buffer with a given set of
83  * attributes fully match a memory region in terms of size and attributes.
84  *
85  * This is usually used to verify that a buffer has the expected attributes
86  * (for example the buffer is cacheable / non-cacheable or belongs to RAM /
87  * FLASH, etc...) and it has been correctly allocated.
88  *
89  * The expected set of attributes for the buffer is and-matched against the
90  * full set of attributes for the memory region it belongs to (bitmask). So the
91  * buffer is considered matching when at least that set of attributes are valid
92  * for the memory region (but the region can be marked also with other
93  * attributes besides the one passed as parameter).
94  *
95  * @param addr Virtual address of the user buffer.
96  * @param size Size of the user buffer.
97  * @param attr Expected / desired attribute for the buffer.
98  *
99  * @retval 0 if the buffer has the correct size and attribute.
100  * @retval -ENOSYS if the operation is not supported (for example if the MMU is enabled).
101  * @retval -ENOTSUP if the wrong parameters were passed.
102  * @retval -EINVAL if the buffer has the wrong set of attributes.
103  * @retval -ENOSPC if the buffer is too big for the region it belongs to.
104  * @retval -ENOBUFS if the buffer is entirely allocated outside a memory region.
105  */
106 int mem_attr_check_buf(void *addr, size_t size, uint32_t attr);
107 
108 #ifdef __cplusplus
109 }
110 #endif
111 
112 /** @} */
113 
114 #endif /* ZEPHYR_INCLUDE_MEM_ATTR_H_ */
115