Browse Source

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 <tokita.hiroshi@gmail.com>
pull/82607/head
TOKITA Hiroshi 1 year ago committed by Anas Nashif
parent
commit
624e051372
  1. 3
      cmake/linker_script/arm/linker.cmake
  2. 61
      cmake/modules/extensions.cmake
  3. 7
      dts/bindings/base/zephyr,memory-common.yaml
  4. 70
      include/zephyr/linker/devicetree_regions.h

3
cmake/linker_script/arm/linker.cmake

@ -41,10 +41,9 @@ zephyr_linker_memory(NAME FLASH FLAGS rx START ${FLASH_ADDR} SIZE ${FLASH_SIZ @@ -41,10 +41,9 @@ zephyr_linker_memory(NAME FLASH FLAGS rx START ${FLASH_ADDR} SIZE ${FLASH_SIZ
zephyr_linker_memory(NAME RAM FLAGS wx START ${RAM_ADDR} SIZE ${RAM_SIZE})
zephyr_linker_memory(NAME IDT_LIST FLAGS wx START ${IDT_ADDR} SIZE 2K)
# Only use 'rw' as FLAGS. It's not used anyway.
dt_comp_path(paths COMPATIBLE "zephyr,memory-region")
foreach(path IN LISTS paths)
zephyr_linker_dts_memory(PATH ${path} FLAGS rw)
zephyr_linker_dts_memory(PATH ${path})
endforeach()
if(CONFIG_XIP)

61
cmake/modules/extensions.cmake

@ -4633,7 +4633,7 @@ function(zephyr_linker) @@ -4633,7 +4633,7 @@ function(zephyr_linker)
endfunction()
# Usage:
# zephyr_linker_memory(NAME <name> START <address> SIZE <size> FLAGS <flags>)
# zephyr_linker_memory(NAME <name> START <address> SIZE <size> [FLAGS <flags>])
#
# Zephyr linker memory.
# This function specifies a memory region for the platform in use.
@ -4650,14 +4650,18 @@ endfunction() @@ -4650,14 +4650,18 @@ endfunction()
# All the following are valid values:
# 1048576, 0x10000, 1024k, 1024K, 1m, and 1M.
# FLAGS <flags> : Flags describing properties of the memory region.
# Currently supported:
# r: Read-only region
# w: Read-write region
# x: Executable region
# The flags r and x, or w and x may be combined like: rx, wx.
# a: Allocatable region
# i: Initialized region
# l: Same as i
# !: Invert the sense of any of the attributes that follow
# The flags may be combined like: rx, rx!w.
function(zephyr_linker_memory)
set(single_args "FLAGS;NAME;SIZE;START")
cmake_parse_arguments(MEMORY "" "${single_args}" "" ${ARGN})
set(req_single_args "NAME;SIZE;START")
set(single_args "FLAGS")
cmake_parse_arguments(MEMORY "" "${req_single_args};${single_args}" "" ${ARGN})
if(MEMORY_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "zephyr_linker_memory(${ARGV0} ...) given unknown "
@ -4665,7 +4669,7 @@ function(zephyr_linker_memory) @@ -4665,7 +4669,7 @@ function(zephyr_linker_memory)
)
endif()
foreach(arg ${single_args})
foreach(arg ${req_single_args})
if(NOT DEFINED MEMORY_${arg})
message(FATAL_ERROR "zephyr_linker_memory(${ARGV0} ...) missing required "
"argument: ${arg}"
@ -4674,6 +4678,7 @@ function(zephyr_linker_memory) @@ -4674,6 +4678,7 @@ function(zephyr_linker_memory)
endforeach()
set(MEMORY)
zephyr_linker_arg_val_list(MEMORY "${req_single_args}")
zephyr_linker_arg_val_list(MEMORY "${single_args}")
string(REPLACE ";" "\;" MEMORY "${MEMORY}")
@ -4683,7 +4688,7 @@ function(zephyr_linker_memory) @@ -4683,7 +4688,7 @@ function(zephyr_linker_memory)
endfunction()
# Usage:
# zephyr_linker_memory_ifdef(<setting> NAME <name> START <address> SIZE <size> FLAGS <flags>)
# zephyr_linker_memory_ifdef(<setting> NAME <name> START <address> SIZE <size> [FLAGS <flags>])
#
# Will create memory region if <setting> is enabled.
#
@ -4746,9 +4751,9 @@ function(zephyr_linker_dts_section) @@ -4746,9 +4751,9 @@ function(zephyr_linker_dts_section)
endfunction()
# Usage:
# zephyr_linker_dts_memory(PATH <path> FLAGS <flags>)
# zephyr_linker_dts_memory(NODELABEL <nodelabel> FLAGS <flags>)
# zephyr_linker_dts_memory(CHOSEN <prop> FLAGS <flags>)
# zephyr_linker_dts_memory(PATH <path>)
# zephyr_linker_dts_memory(NODELABEL <nodelabel>)
# zephyr_linker_dts_memory(CHOSEN <prop>)
#
# Zephyr linker devicetree memory.
# This function specifies a memory region for the platform in use based on its
@ -4763,15 +4768,9 @@ endfunction() @@ -4763,15 +4768,9 @@ endfunction()
# NODELABEL <label>: Node label
# CHOSEN <prop> : Chosen property, add memory section described by the
# /chosen property if it exists.
# FLAGS <flags> : Flags describing properties of the memory region.
# Currently supported:
# r: Read-only region
# w: Read-write region
# x: Executable region
# The flags r and x, or w and x may be combined like: rx, wx.
#
function(zephyr_linker_dts_memory)
set(single_args "CHOSEN;FLAGS;PATH;NODELABEL")
set(single_args "CHOSEN;PATH;NODELABEL")
cmake_parse_arguments(DTS_MEMORY "" "${single_args}" "" ${ARGN})
if(DTS_MEMORY_UNPARSED_ARGUMENTS)
@ -4814,12 +4813,28 @@ function(zephyr_linker_dts_memory) @@ -4814,12 +4813,28 @@ function(zephyr_linker_dts_memory)
endif()
zephyr_string(SANITIZE name ${name})
zephyr_linker_memory(
NAME ${name}
START ${addr}
SIZE ${size}
FLAGS ${DTS_MEMORY_FLAGS}
)
dt_prop(flags PATH ${DTS_MEMORY_PATH} PROPERTY "zephyr,memory-region-flags")
if(NOT DEFINED flags)
zephyr_linker_memory(
NAME ${name}
START ${addr}
SIZE ${size}
FLAGS "rw"
)
elseif("${flags}" STREQUAL "")
zephyr_linker_memory(
NAME ${name}
START ${addr}
SIZE ${size}
)
else()
zephyr_linker_memory(
NAME ${name}
START ${addr}
SIZE ${size}
FLAGS ${flags}
)
endif()
endfunction()
# Usage:

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

@ -12,6 +12,13 @@ properties: @@ -12,6 +12,13 @@ properties:
is taken from the <reg> property, while the name is the value of
this property.
zephyr,memory-region-flags:
type: string
description: |
Set attributes such as read-only or executable for the linker script
memory region. The string set here will be specified in parentheses
after the area name in the linker script.
zephyr,memory-region-mpu:
type: string
deprecated: true

70
include/zephyr/linker/devicetree_regions.h

@ -82,6 +82,66 @@ @@ -82,6 +82,66 @@
#define LINKER_DT_NODE_REGION_NAME(node_id) \
STRINGIFY(LINKER_DT_NODE_REGION_NAME_TOKEN(node_id))
#define _DT_MEMORY_REGION_FLAGS_TOKEN(n) DT_STRING_TOKEN(n, zephyr_memory_region_flags)
#define _DT_MEMORY_REGION_FLAGS_UNQUOTED(n) DT_STRING_UNQUOTED(n, zephyr_memory_region_flags)
#define _LINKER_L_PAREN (
#define _LINKER_R_PAREN )
#define _LINKER_ENCLOSE_PAREN(x) _LINKER_L_PAREN x _LINKER_R_PAREN
#define _LINKER_IS_EMPTY_TOKEN_ 1
#define _LINKER_IS_EMPTY_TOKEN_EXPAND(x) _LINKER_IS_EMPTY_TOKEN_##x
#define _LINKER_IS_EMPTY_TOKEN(x) _LINKER_IS_EMPTY_TOKEN_EXPAND(x)
/**
* @brief Get the linker memory-region flags with parentheses.
*
* This attempts to return the zephyr,memory-region-flags property
* with parentheses.
* Return empty string if not set the property.
*
* Example devicetree fragment:
*
* @code{.dts}
* / {
* soc {
* rx: memory@2000000 {
* zephyr,memory-region = "READ_EXEC";
* zephyr,memory-region-flags = "rx";
* };
* rx_not_w: memory@2001000 {
* zephyr,memory-region = "READ_EXEC_NOT_WRITE";
* zephyr,memory-region-flags = "rx!w";
* };
* no_flags: memory@2001000 {
* zephyr,memory-region = "NO_FLAGS";
* };
* };
* };
* @endcode
*
* Example usage:
*
* @code{.c}
* LINKER_DT_NODE_REGION_FLAGS(DT_NODELABEL(rx)) // (rx)
* LINKER_DT_NODE_REGION_FLAGS(DT_NODELABEL(rx_not_w)) // (rx!w)
* LINKER_DT_NODE_REGION_FLAGS(DT_NODELABEL(no_flags)) // [flags will not be specified]
* @endcode
*
* @param node_id node identifier
* @return the value of the memory region flag specified in the device tree
* enclosed in parentheses.
*/
#define LINKER_DT_NODE_REGION_FLAGS(node_id) \
COND_CODE_1(DT_NODE_HAS_PROP(node_id, zephyr_memory_region_flags), \
(COND_CODE_1(_LINKER_IS_EMPTY_TOKEN(_DT_MEMORY_REGION_FLAGS_TOKEN(node_id)), \
(), \
(_LINKER_ENCLOSE_PAREN( \
_DT_MEMORY_REGION_FLAGS_UNQUOTED(node_id)) \
))), \
(_LINKER_ENCLOSE_PAREN(rw)))
/** @cond INTERNAL_HIDDEN */
#define _DT_COMPATIBLE zephyr_memory_region
@ -102,6 +162,7 @@ @@ -102,6 +162,7 @@
* compatible = "zephyr,memory-region", "mmio-sram";
* reg = < 0x20010000 0x1000 >;
* zephyr,memory-region = "FOOBAR";
* zephyr,memory-region-flags = "rw";
* };
* @endcode
*
@ -114,10 +175,11 @@ @@ -114,10 +175,11 @@
* @param node_id devicetree node identifier
* @param attr region attributes
*/
#define _REGION_DECLARE(node_id) \
LINKER_DT_NODE_REGION_NAME_TOKEN(node_id) : \
ORIGIN = DT_REG_ADDR(node_id), \
LENGTH = DT_REG_SIZE(node_id)
#define _REGION_DECLARE(node_id) \
LINKER_DT_NODE_REGION_NAME_TOKEN(node_id) \
LINKER_DT_NODE_REGION_FLAGS(node_id) \
: ORIGIN = DT_REG_ADDR(node_id), \
LENGTH = DT_REG_SIZE(node_id)
/**
* @brief Declare a memory section from the device tree nodes with

Loading…
Cancel
Save