Skip to content

Commit 624e051

Browse files
soburinashif
authored andcommitted
linker: devicetree_regions: Add support memory region flag setting
Add `zephyr,memory-region-flags` for supporting memory region flags setting. For example, when the below node is in the devicetree, ``` test_sram: sram@20010000 { compatible = "zephyr,memory-region", "mmio-sram"; reg = < 0x20010000 0x1000 >; zephyr,memory-region = "FOOBAR"; zephyr,memory-region-flags = "rw"; }; ``` We get the following line in MEMORY section of linker script. ``` FOOBAR (rw) : ORIGIN = (0x20010000), LENGTH = (0x1000) ``` Signed-off-by: TOKITA Hiroshi <[email protected]>
1 parent 96f2b2f commit 624e051

File tree

4 files changed

+112
-29
lines changed

4 files changed

+112
-29
lines changed

cmake/linker_script/arm/linker.cmake

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,9 @@ zephyr_linker_memory(NAME FLASH FLAGS rx START ${FLASH_ADDR} SIZE ${FLASH_SIZ
4141
zephyr_linker_memory(NAME RAM FLAGS wx START ${RAM_ADDR} SIZE ${RAM_SIZE})
4242
zephyr_linker_memory(NAME IDT_LIST FLAGS wx START ${IDT_ADDR} SIZE 2K)
4343

44-
# Only use 'rw' as FLAGS. It's not used anyway.
4544
dt_comp_path(paths COMPATIBLE "zephyr,memory-region")
4645
foreach(path IN LISTS paths)
47-
zephyr_linker_dts_memory(PATH ${path} FLAGS rw)
46+
zephyr_linker_dts_memory(PATH ${path})
4847
endforeach()
4948

5049
if(CONFIG_XIP)

cmake/modules/extensions.cmake

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4633,7 +4633,7 @@ function(zephyr_linker)
46334633
endfunction()
46344634

46354635
# Usage:
4636-
# zephyr_linker_memory(NAME <name> START <address> SIZE <size> FLAGS <flags>)
4636+
# zephyr_linker_memory(NAME <name> START <address> SIZE <size> [FLAGS <flags>])
46374637
#
46384638
# Zephyr linker memory.
46394639
# This function specifies a memory region for the platform in use.
@@ -4650,22 +4650,26 @@ endfunction()
46504650
# All the following are valid values:
46514651
# 1048576, 0x10000, 1024k, 1024K, 1m, and 1M.
46524652
# FLAGS <flags> : Flags describing properties of the memory region.
4653-
# Currently supported:
46544653
# r: Read-only region
46554654
# w: Read-write region
46564655
# x: Executable region
4657-
# The flags r and x, or w and x may be combined like: rx, wx.
4656+
# a: Allocatable region
4657+
# i: Initialized region
4658+
# l: Same as ‘i’
4659+
# !: Invert the sense of any of the attributes that follow
4660+
# The flags may be combined like: rx, rx!w.
46584661
function(zephyr_linker_memory)
4659-
set(single_args "FLAGS;NAME;SIZE;START")
4660-
cmake_parse_arguments(MEMORY "" "${single_args}" "" ${ARGN})
4662+
set(req_single_args "NAME;SIZE;START")
4663+
set(single_args "FLAGS")
4664+
cmake_parse_arguments(MEMORY "" "${req_single_args};${single_args}" "" ${ARGN})
46614665

46624666
if(MEMORY_UNPARSED_ARGUMENTS)
46634667
message(FATAL_ERROR "zephyr_linker_memory(${ARGV0} ...) given unknown "
46644668
"arguments: ${MEMORY_UNPARSED_ARGUMENTS}"
46654669
)
46664670
endif()
46674671

4668-
foreach(arg ${single_args})
4672+
foreach(arg ${req_single_args})
46694673
if(NOT DEFINED MEMORY_${arg})
46704674
message(FATAL_ERROR "zephyr_linker_memory(${ARGV0} ...) missing required "
46714675
"argument: ${arg}"
@@ -4674,6 +4678,7 @@ function(zephyr_linker_memory)
46744678
endforeach()
46754679

46764680
set(MEMORY)
4681+
zephyr_linker_arg_val_list(MEMORY "${req_single_args}")
46774682
zephyr_linker_arg_val_list(MEMORY "${single_args}")
46784683

46794684
string(REPLACE ";" "\;" MEMORY "${MEMORY}")
@@ -4683,7 +4688,7 @@ function(zephyr_linker_memory)
46834688
endfunction()
46844689

46854690
# Usage:
4686-
# zephyr_linker_memory_ifdef(<setting> NAME <name> START <address> SIZE <size> FLAGS <flags>)
4691+
# zephyr_linker_memory_ifdef(<setting> NAME <name> START <address> SIZE <size> [FLAGS <flags>])
46874692
#
46884693
# Will create memory region if <setting> is enabled.
46894694
#
@@ -4746,9 +4751,9 @@ function(zephyr_linker_dts_section)
47464751
endfunction()
47474752

47484753
# Usage:
4749-
# zephyr_linker_dts_memory(PATH <path> FLAGS <flags>)
4750-
# zephyr_linker_dts_memory(NODELABEL <nodelabel> FLAGS <flags>)
4751-
# zephyr_linker_dts_memory(CHOSEN <prop> FLAGS <flags>)
4754+
# zephyr_linker_dts_memory(PATH <path>)
4755+
# zephyr_linker_dts_memory(NODELABEL <nodelabel>)
4756+
# zephyr_linker_dts_memory(CHOSEN <prop>)
47524757
#
47534758
# Zephyr linker devicetree memory.
47544759
# This function specifies a memory region for the platform in use based on its
@@ -4763,15 +4768,9 @@ endfunction()
47634768
# NODELABEL <label>: Node label
47644769
# CHOSEN <prop> : Chosen property, add memory section described by the
47654770
# /chosen property if it exists.
4766-
# FLAGS <flags> : Flags describing properties of the memory region.
4767-
# Currently supported:
4768-
# r: Read-only region
4769-
# w: Read-write region
4770-
# x: Executable region
4771-
# The flags r and x, or w and x may be combined like: rx, wx.
47724771
#
47734772
function(zephyr_linker_dts_memory)
4774-
set(single_args "CHOSEN;FLAGS;PATH;NODELABEL")
4773+
set(single_args "CHOSEN;PATH;NODELABEL")
47754774
cmake_parse_arguments(DTS_MEMORY "" "${single_args}" "" ${ARGN})
47764775

47774776
if(DTS_MEMORY_UNPARSED_ARGUMENTS)
@@ -4814,12 +4813,28 @@ function(zephyr_linker_dts_memory)
48144813
endif()
48154814
zephyr_string(SANITIZE name ${name})
48164815

4817-
zephyr_linker_memory(
4818-
NAME ${name}
4819-
START ${addr}
4820-
SIZE ${size}
4821-
FLAGS ${DTS_MEMORY_FLAGS}
4822-
)
4816+
dt_prop(flags PATH ${DTS_MEMORY_PATH} PROPERTY "zephyr,memory-region-flags")
4817+
if(NOT DEFINED flags)
4818+
zephyr_linker_memory(
4819+
NAME ${name}
4820+
START ${addr}
4821+
SIZE ${size}
4822+
FLAGS "rw"
4823+
)
4824+
elseif("${flags}" STREQUAL "")
4825+
zephyr_linker_memory(
4826+
NAME ${name}
4827+
START ${addr}
4828+
SIZE ${size}
4829+
)
4830+
else()
4831+
zephyr_linker_memory(
4832+
NAME ${name}
4833+
START ${addr}
4834+
SIZE ${size}
4835+
FLAGS ${flags}
4836+
)
4837+
endif()
48234838
endfunction()
48244839

48254840
# Usage:

dts/bindings/base/zephyr,memory-common.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ properties:
1212
is taken from the <reg> property, while the name is the value of
1313
this property.
1414
15+
zephyr,memory-region-flags:
16+
type: string
17+
description: |
18+
Set attributes such as read-only or executable for the linker script
19+
memory region. The string set here will be specified in parentheses
20+
after the area name in the linker script.
21+
1522
zephyr,memory-region-mpu:
1623
type: string
1724
deprecated: true

include/zephyr/linker/devicetree_regions.h

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,66 @@
8282
#define LINKER_DT_NODE_REGION_NAME(node_id) \
8383
STRINGIFY(LINKER_DT_NODE_REGION_NAME_TOKEN(node_id))
8484

85+
#define _DT_MEMORY_REGION_FLAGS_TOKEN(n) DT_STRING_TOKEN(n, zephyr_memory_region_flags)
86+
#define _DT_MEMORY_REGION_FLAGS_UNQUOTED(n) DT_STRING_UNQUOTED(n, zephyr_memory_region_flags)
87+
88+
#define _LINKER_L_PAREN (
89+
#define _LINKER_R_PAREN )
90+
#define _LINKER_ENCLOSE_PAREN(x) _LINKER_L_PAREN x _LINKER_R_PAREN
91+
92+
#define _LINKER_IS_EMPTY_TOKEN_ 1
93+
#define _LINKER_IS_EMPTY_TOKEN_EXPAND(x) _LINKER_IS_EMPTY_TOKEN_##x
94+
#define _LINKER_IS_EMPTY_TOKEN(x) _LINKER_IS_EMPTY_TOKEN_EXPAND(x)
95+
96+
/**
97+
* @brief Get the linker memory-region flags with parentheses.
98+
*
99+
* This attempts to return the zephyr,memory-region-flags property
100+
* with parentheses.
101+
* Return empty string if not set the property.
102+
*
103+
* Example devicetree fragment:
104+
*
105+
* @code{.dts}
106+
* / {
107+
* soc {
108+
* rx: memory@2000000 {
109+
* zephyr,memory-region = "READ_EXEC";
110+
* zephyr,memory-region-flags = "rx";
111+
* };
112+
* rx_not_w: memory@2001000 {
113+
* zephyr,memory-region = "READ_EXEC_NOT_WRITE";
114+
* zephyr,memory-region-flags = "rx!w";
115+
* };
116+
* no_flags: memory@2001000 {
117+
* zephyr,memory-region = "NO_FLAGS";
118+
* };
119+
* };
120+
* };
121+
* @endcode
122+
*
123+
* Example usage:
124+
*
125+
* @code{.c}
126+
* LINKER_DT_NODE_REGION_FLAGS(DT_NODELABEL(rx)) // (rx)
127+
* LINKER_DT_NODE_REGION_FLAGS(DT_NODELABEL(rx_not_w)) // (rx!w)
128+
* LINKER_DT_NODE_REGION_FLAGS(DT_NODELABEL(no_flags)) // [flags will not be specified]
129+
* @endcode
130+
*
131+
* @param node_id node identifier
132+
* @return the value of the memory region flag specified in the device tree
133+
* enclosed in parentheses.
134+
*/
135+
136+
#define LINKER_DT_NODE_REGION_FLAGS(node_id) \
137+
COND_CODE_1(DT_NODE_HAS_PROP(node_id, zephyr_memory_region_flags), \
138+
(COND_CODE_1(_LINKER_IS_EMPTY_TOKEN(_DT_MEMORY_REGION_FLAGS_TOKEN(node_id)), \
139+
(), \
140+
(_LINKER_ENCLOSE_PAREN( \
141+
_DT_MEMORY_REGION_FLAGS_UNQUOTED(node_id)) \
142+
))), \
143+
(_LINKER_ENCLOSE_PAREN(rw)))
144+
85145
/** @cond INTERNAL_HIDDEN */
86146

87147
#define _DT_COMPATIBLE zephyr_memory_region
@@ -102,6 +162,7 @@
102162
* compatible = "zephyr,memory-region", "mmio-sram";
103163
* reg = < 0x20010000 0x1000 >;
104164
* zephyr,memory-region = "FOOBAR";
165+
* zephyr,memory-region-flags = "rw";
105166
* };
106167
* @endcode
107168
*
@@ -114,10 +175,11 @@
114175
* @param node_id devicetree node identifier
115176
* @param attr region attributes
116177
*/
117-
#define _REGION_DECLARE(node_id) \
118-
LINKER_DT_NODE_REGION_NAME_TOKEN(node_id) : \
119-
ORIGIN = DT_REG_ADDR(node_id), \
120-
LENGTH = DT_REG_SIZE(node_id)
178+
#define _REGION_DECLARE(node_id) \
179+
LINKER_DT_NODE_REGION_NAME_TOKEN(node_id) \
180+
LINKER_DT_NODE_REGION_FLAGS(node_id) \
181+
: ORIGIN = DT_REG_ADDR(node_id), \
182+
LENGTH = DT_REG_SIZE(node_id)
121183

122184
/**
123185
* @brief Declare a memory section from the device tree nodes with

0 commit comments

Comments
 (0)