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>
This commit is contained in:
parent
96f2b2f4bb
commit
624e051372
4 changed files with 112 additions and 29 deletions
|
@ -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 RAM FLAGS wx START ${RAM_ADDR} SIZE ${RAM_SIZE})
|
||||||
zephyr_linker_memory(NAME IDT_LIST FLAGS wx START ${IDT_ADDR} SIZE 2K)
|
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")
|
dt_comp_path(paths COMPATIBLE "zephyr,memory-region")
|
||||||
foreach(path IN LISTS paths)
|
foreach(path IN LISTS paths)
|
||||||
zephyr_linker_dts_memory(PATH ${path} FLAGS rw)
|
zephyr_linker_dts_memory(PATH ${path})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
if(CONFIG_XIP)
|
if(CONFIG_XIP)
|
||||||
|
|
|
@ -4633,7 +4633,7 @@ function(zephyr_linker)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# Usage:
|
# 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.
|
# Zephyr linker memory.
|
||||||
# This function specifies a memory region for the platform in use.
|
# This function specifies a memory region for the platform in use.
|
||||||
|
@ -4650,14 +4650,18 @@ endfunction()
|
||||||
# All the following are valid values:
|
# All the following are valid values:
|
||||||
# 1048576, 0x10000, 1024k, 1024K, 1m, and 1M.
|
# 1048576, 0x10000, 1024k, 1024K, 1m, and 1M.
|
||||||
# FLAGS <flags> : Flags describing properties of the memory region.
|
# FLAGS <flags> : Flags describing properties of the memory region.
|
||||||
# Currently supported:
|
|
||||||
# r: Read-only region
|
# r: Read-only region
|
||||||
# w: Read-write region
|
# w: Read-write region
|
||||||
# x: Executable 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)
|
function(zephyr_linker_memory)
|
||||||
set(single_args "FLAGS;NAME;SIZE;START")
|
set(req_single_args "NAME;SIZE;START")
|
||||||
cmake_parse_arguments(MEMORY "" "${single_args}" "" ${ARGN})
|
set(single_args "FLAGS")
|
||||||
|
cmake_parse_arguments(MEMORY "" "${req_single_args};${single_args}" "" ${ARGN})
|
||||||
|
|
||||||
if(MEMORY_UNPARSED_ARGUMENTS)
|
if(MEMORY_UNPARSED_ARGUMENTS)
|
||||||
message(FATAL_ERROR "zephyr_linker_memory(${ARGV0} ...) given unknown "
|
message(FATAL_ERROR "zephyr_linker_memory(${ARGV0} ...) given unknown "
|
||||||
|
@ -4665,7 +4669,7 @@ function(zephyr_linker_memory)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
foreach(arg ${single_args})
|
foreach(arg ${req_single_args})
|
||||||
if(NOT DEFINED MEMORY_${arg})
|
if(NOT DEFINED MEMORY_${arg})
|
||||||
message(FATAL_ERROR "zephyr_linker_memory(${ARGV0} ...) missing required "
|
message(FATAL_ERROR "zephyr_linker_memory(${ARGV0} ...) missing required "
|
||||||
"argument: ${arg}"
|
"argument: ${arg}"
|
||||||
|
@ -4674,6 +4678,7 @@ function(zephyr_linker_memory)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
set(MEMORY)
|
set(MEMORY)
|
||||||
|
zephyr_linker_arg_val_list(MEMORY "${req_single_args}")
|
||||||
zephyr_linker_arg_val_list(MEMORY "${single_args}")
|
zephyr_linker_arg_val_list(MEMORY "${single_args}")
|
||||||
|
|
||||||
string(REPLACE ";" "\;" MEMORY "${MEMORY}")
|
string(REPLACE ";" "\;" MEMORY "${MEMORY}")
|
||||||
|
@ -4683,7 +4688,7 @@ function(zephyr_linker_memory)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# Usage:
|
# 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.
|
# Will create memory region if <setting> is enabled.
|
||||||
#
|
#
|
||||||
|
@ -4746,9 +4751,9 @@ function(zephyr_linker_dts_section)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# Usage:
|
# Usage:
|
||||||
# zephyr_linker_dts_memory(PATH <path> FLAGS <flags>)
|
# zephyr_linker_dts_memory(PATH <path>)
|
||||||
# zephyr_linker_dts_memory(NODELABEL <nodelabel> FLAGS <flags>)
|
# zephyr_linker_dts_memory(NODELABEL <nodelabel>)
|
||||||
# zephyr_linker_dts_memory(CHOSEN <prop> FLAGS <flags>)
|
# zephyr_linker_dts_memory(CHOSEN <prop>)
|
||||||
#
|
#
|
||||||
# Zephyr linker devicetree memory.
|
# Zephyr linker devicetree memory.
|
||||||
# This function specifies a memory region for the platform in use based on its
|
# This function specifies a memory region for the platform in use based on its
|
||||||
|
@ -4763,15 +4768,9 @@ endfunction()
|
||||||
# NODELABEL <label>: Node label
|
# NODELABEL <label>: Node label
|
||||||
# CHOSEN <prop> : Chosen property, add memory section described by the
|
# CHOSEN <prop> : Chosen property, add memory section described by the
|
||||||
# /chosen property if it exists.
|
# /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)
|
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})
|
cmake_parse_arguments(DTS_MEMORY "" "${single_args}" "" ${ARGN})
|
||||||
|
|
||||||
if(DTS_MEMORY_UNPARSED_ARGUMENTS)
|
if(DTS_MEMORY_UNPARSED_ARGUMENTS)
|
||||||
|
@ -4814,12 +4813,28 @@ function(zephyr_linker_dts_memory)
|
||||||
endif()
|
endif()
|
||||||
zephyr_string(SANITIZE name ${name})
|
zephyr_string(SANITIZE name ${name})
|
||||||
|
|
||||||
zephyr_linker_memory(
|
dt_prop(flags PATH ${DTS_MEMORY_PATH} PROPERTY "zephyr,memory-region-flags")
|
||||||
NAME ${name}
|
if(NOT DEFINED flags)
|
||||||
START ${addr}
|
zephyr_linker_memory(
|
||||||
SIZE ${size}
|
NAME ${name}
|
||||||
FLAGS ${DTS_MEMORY_FLAGS}
|
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()
|
endfunction()
|
||||||
|
|
||||||
# Usage:
|
# Usage:
|
||||||
|
|
|
@ -12,6 +12,13 @@ properties:
|
||||||
is taken from the <reg> property, while the name is the value of
|
is taken from the <reg> property, while the name is the value of
|
||||||
this property.
|
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:
|
zephyr,memory-region-mpu:
|
||||||
type: string
|
type: string
|
||||||
deprecated: true
|
deprecated: true
|
||||||
|
|
|
@ -82,6 +82,66 @@
|
||||||
#define LINKER_DT_NODE_REGION_NAME(node_id) \
|
#define LINKER_DT_NODE_REGION_NAME(node_id) \
|
||||||
STRINGIFY(LINKER_DT_NODE_REGION_NAME_TOKEN(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 */
|
/** @cond INTERNAL_HIDDEN */
|
||||||
|
|
||||||
#define _DT_COMPATIBLE zephyr_memory_region
|
#define _DT_COMPATIBLE zephyr_memory_region
|
||||||
|
@ -102,6 +162,7 @@
|
||||||
* compatible = "zephyr,memory-region", "mmio-sram";
|
* compatible = "zephyr,memory-region", "mmio-sram";
|
||||||
* reg = < 0x20010000 0x1000 >;
|
* reg = < 0x20010000 0x1000 >;
|
||||||
* zephyr,memory-region = "FOOBAR";
|
* zephyr,memory-region = "FOOBAR";
|
||||||
|
* zephyr,memory-region-flags = "rw";
|
||||||
* };
|
* };
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
|
@ -114,10 +175,11 @@
|
||||||
* @param node_id devicetree node identifier
|
* @param node_id devicetree node identifier
|
||||||
* @param attr region attributes
|
* @param attr region attributes
|
||||||
*/
|
*/
|
||||||
#define _REGION_DECLARE(node_id) \
|
#define _REGION_DECLARE(node_id) \
|
||||||
LINKER_DT_NODE_REGION_NAME_TOKEN(node_id) : \
|
LINKER_DT_NODE_REGION_NAME_TOKEN(node_id) \
|
||||||
ORIGIN = DT_REG_ADDR(node_id), \
|
LINKER_DT_NODE_REGION_FLAGS(node_id) \
|
||||||
LENGTH = DT_REG_SIZE(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
|
* @brief Declare a memory section from the device tree nodes with
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue