Skip to content

Commit ae2be2d

Browse files
carlocaionegalak
authored andcommitted
reserved-memory: Introduce support for reserved-memory node
Introduce a set of header files to be able to define and declare sections and regions in the linker script. Introduce also DT helpers to retrieve data back. Signed-off-by: Carlo Caione <[email protected]>
1 parent f4db14f commit ae2be2d

File tree

4 files changed

+226
-0
lines changed

4 files changed

+226
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
description: |
2+
Reserved memory - Each child of the reserved-memory node specifies one or
3+
more regions of reserved memory. Regions in the /reserved-memory node may be
4+
referenced by other device nodes by adding a memory-region property to the
5+
device node.
6+
7+
compatible: "reserved-memory"
8+
9+
include:
10+
- name: base.yaml
11+
property-allowlist: ['#address-cells', '#size-cells']
12+
13+
child-binding:
14+
description: Regions
15+
properties:
16+
label:
17+
type: string
18+
required: false
19+
description: Human readable string describing the device (used as device_get_binding() argument)
20+
reg:
21+
type: array
22+
description: register space
23+
required: true

include/devicetree/memory.h

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/**
2+
* @file
3+
* @brief reserved-memory Devicetree macro public API header file.
4+
*/
5+
6+
/*
7+
* Copyright (c) 2021 Carlo Caione <[email protected]>
8+
*
9+
* SPDX-License-Identifier: Apache-2.0
10+
*/
11+
12+
#ifndef ZEPHYR_INCLUDE_DEVICETREE_MEMORY_H_
13+
#define ZEPHYR_INCLUDE_DEVICETREE_MEMORY_H_
14+
15+
#ifdef __cplusplus
16+
extern "C" {
17+
#endif
18+
19+
/**
20+
* @defgroup devicetree-reserved Devicetree reserved-memory API
21+
* @ingroup devicetree
22+
* @{
23+
*/
24+
25+
/**
26+
* @brief Get the pointer to the reserved-memory region
27+
*
28+
* Example devicetree fragment:
29+
*
30+
* reserved: reserved-memory {
31+
* compatible = "reserved-memory";
32+
* ...
33+
* n: node {
34+
* reg = <0x42000000 0x1000>;
35+
* };
36+
* };
37+
*
38+
* Example usage:
39+
*
40+
* DT_RESERVED_MEM_GET_PTR(DT_NODELABEL(n)) // (uint8_t *) 0x42000000
41+
*
42+
* @param node_id node identifier
43+
* @return pointer to the beginning of the reserved-memory region
44+
*/
45+
#define DT_RESERVED_MEM_GET_PTR(node_id) _DT_RESERVED_START(node_id)
46+
47+
/**
48+
* @brief Get the size of the reserved-memory region
49+
*
50+
* Example devicetree fragment:
51+
*
52+
* reserved: reserved-memory {
53+
* compatible = "reserved-memory";
54+
* ...
55+
* n: node {
56+
* reg = <0x42000000 0x1000>;
57+
* };
58+
* };
59+
*
60+
* Example usage:
61+
*
62+
* DT_RESERVED_MEM_GET_SIZE(DT_NODELABEL(n)) // 0x1000
63+
*
64+
* @param node_id node identifier
65+
* @return the size of the reserved-memory region
66+
*/
67+
#define DT_RESERVED_MEM_GET_SIZE(node_id) DT_REG_SIZE(node_id)
68+
69+
/**
70+
* @brief Get the pointer to the reserved-memory region from a memory-reserved
71+
* phandle
72+
*
73+
* Example devicetree fragment:
74+
*
75+
* reserved: reserved-memory {
76+
* compatible = "reserved-memory";
77+
* ...
78+
* res0: res {
79+
* reg = <0x42000000 0x1000>;
80+
* label = "res0";
81+
* };
82+
* };
83+
*
84+
* n: node {
85+
* memory-region = <&res0>;
86+
* };
87+
*
88+
* Example usage:
89+
*
90+
* DT_RESERVED_MEM_GET_PTR_BY_PHANDLE(DT_NODELABEL(n), memory_region) // (uint8_t *) 0x42000000
91+
*
92+
* @param node_id node identifier
93+
* @param ph phandle to reserved-memory region
94+
*
95+
* @return pointer to the beginning of the reserved-memory region
96+
*/
97+
#define DT_RESERVED_MEM_GET_PTR_BY_PHANDLE(node_id, ph) \
98+
DT_RESERVED_MEM_GET_PTR(DT_PHANDLE(node_id, ph))
99+
100+
/**
101+
* @brief Get the size of the reserved-memory region from a memory-reserved
102+
* phandle
103+
*
104+
* Example devicetree fragment:
105+
*
106+
* reserved: reserved-memory {
107+
* compatible = "reserved-memory";
108+
* ...
109+
* res0: res {
110+
* reg = <0x42000000 0x1000>;
111+
* label = "res0";
112+
* };
113+
* };
114+
*
115+
* n: node {
116+
* memory-region = <&res0>;
117+
* };
118+
*
119+
* Example usage:
120+
*
121+
* DT_RESERVED_MEM_GET_SIZE_BY_PHANDLE(DT_NODELABEL(n), memory_region) // (uint8_t *) 0x42000000
122+
*
123+
* @param node_id node identifier
124+
* @param ph phandle to reserved-memory region
125+
*
126+
* @return size of the reserved-memory region
127+
*/
128+
#define DT_RESERVED_MEM_GET_SIZE_BY_PHANDLE(node_id, ph) \
129+
DT_RESERVED_MEM_GET_SIZE(DT_PHANDLE(node_id, ph))
130+
131+
/**
132+
* @}
133+
*/
134+
135+
#ifdef __cplusplus
136+
}
137+
#endif
138+
139+
#endif /* ZEPHYR_INCLUDE_DEVICETREE_MEMORY_H_ */
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2021, Carlo Caione <[email protected]>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Generate memory regions and sections from reserved-memory nodes.
7+
*/
8+
9+
#include <devicetree.h>
10+
11+
/* Reserved memory node */
12+
#define _NODE_RESERVED DT_INST(0, reserved_memory)
13+
14+
/* Unquoted region label */
15+
#define _DT_LABEL_TOKEN(res) DT_STRING_TOKEN(res, label)
16+
17+
/* _start and _end section symbols */
18+
#define _DT_RESERVED_PREFIX(res) UTIL_CAT(__, _DT_LABEL_TOKEN(res))
19+
#define _DT_RESERVED_START(res) UTIL_CAT(_DT_RESERVED_PREFIX(res), _start)
20+
#define _DT_RESERVED_END(res) UTIL_CAT(_DT_RESERVED_PREFIX(res), _end)
21+
22+
/* Declare a reserved memory region */
23+
#define _RESERVED_REGION_DECLARE(res) DT_STRING_TOKEN(res, label) (rw) : \
24+
ORIGIN = DT_REG_ADDR(res), \
25+
LENGTH = DT_REG_SIZE(res)
26+
27+
/* Declare a reserved memory section */
28+
#define _RESERVED_SECTION_DECLARE(res) SECTION_DATA_PROLOGUE(_DT_LABEL_TOKEN(res), ,) \
29+
{ \
30+
_DT_RESERVED_START(res) = .; \
31+
KEEP(*(._DT_LABEL_TOKEN(res))) \
32+
KEEP(*(._DT_LABEL_TOKEN(res).*)) \
33+
_DT_RESERVED_END(res) = \
34+
_DT_RESERVED_START(res) + DT_REG_SIZE(res); \
35+
} GROUP_LINK_IN(_DT_LABEL_TOKEN(res))
36+
37+
/* Declare reserved memory linker symbols */
38+
#define _RESERVED_SYMBOL_DECLARE(res) extern char _DT_RESERVED_START(res)[]; \
39+
extern char _DT_RESERVED_END(res)[];
40+
41+
/* Apply a macro to a reserved memory region */
42+
#define _RESERVED_REGION_APPLY(f) \
43+
COND_CODE_1(IS_ENABLED(UTIL_CAT(_NODE_RESERVED, _EXISTS)), \
44+
(DT_FOREACH_CHILD(_NODE_RESERVED, f)), ())
45+
46+
/**
47+
* @brief Generate region definitions for all the reserved memory regions
48+
*/
49+
#define DT_RESERVED_MEM_REGIONS() _RESERVED_REGION_APPLY(_RESERVED_REGION_DECLARE)
50+
51+
/**
52+
* @brief Generate section definitions for all the reserved memory regions
53+
*/
54+
#define DT_RESERVED_MEM_SECTIONS() _RESERVED_REGION_APPLY(_RESERVED_SECTION_DECLARE)
55+
56+
/**
57+
* @brief Generate linker script symbols for all the reserved memory regions
58+
*/
59+
#define DT_RESERVED_MEM_SYMBOLS() _RESERVED_REGION_APPLY(_RESERVED_SYMBOL_DECLARE)

include/linker/linker-defs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#ifdef ZTEST_UNITTEST
3434
#define DT_NODE_HAS_STATUS(node, status) 0
3535
#else
36+
#include <linker/devicetree_reserved.h>
3637
#include <devicetree.h>
3738
#endif
3839

@@ -213,6 +214,10 @@ extern char _image_rodata_size[];
213214
extern char _vector_start[];
214215
extern char _vector_end[];
215216

217+
#if DT_NODE_HAS_STATUS(_NODE_RESERVED, okay)
218+
DT_RESERVED_MEM_SYMBOLS()
219+
#endif
220+
216221
#ifdef CONFIG_SW_VECTOR_RELAY
217222
extern char __vector_relay_table[];
218223
#endif

0 commit comments

Comments
 (0)