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 <ccaione@baylibre.com>
This commit is contained in:
parent
f4db14f349
commit
ae2be2db8a
4 changed files with 226 additions and 0 deletions
23
dts/bindings/reserved-memory/reserved-memory.yaml
Normal file
23
dts/bindings/reserved-memory/reserved-memory.yaml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
description: |
|
||||||
|
Reserved memory - Each child of the reserved-memory node specifies one or
|
||||||
|
more regions of reserved memory. Regions in the /reserved-memory node may be
|
||||||
|
referenced by other device nodes by adding a memory-region property to the
|
||||||
|
device node.
|
||||||
|
|
||||||
|
compatible: "reserved-memory"
|
||||||
|
|
||||||
|
include:
|
||||||
|
- name: base.yaml
|
||||||
|
property-allowlist: ['#address-cells', '#size-cells']
|
||||||
|
|
||||||
|
child-binding:
|
||||||
|
description: Regions
|
||||||
|
properties:
|
||||||
|
label:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
description: Human readable string describing the device (used as device_get_binding() argument)
|
||||||
|
reg:
|
||||||
|
type: array
|
||||||
|
description: register space
|
||||||
|
required: true
|
139
include/devicetree/memory.h
Normal file
139
include/devicetree/memory.h
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief reserved-memory Devicetree macro public API header file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Carlo Caione <ccaione@baylibre.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_INCLUDE_DEVICETREE_MEMORY_H_
|
||||||
|
#define ZEPHYR_INCLUDE_DEVICETREE_MEMORY_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup devicetree-reserved Devicetree reserved-memory API
|
||||||
|
* @ingroup devicetree
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the pointer to the reserved-memory region
|
||||||
|
*
|
||||||
|
* Example devicetree fragment:
|
||||||
|
*
|
||||||
|
* reserved: reserved-memory {
|
||||||
|
* compatible = "reserved-memory";
|
||||||
|
* ...
|
||||||
|
* n: node {
|
||||||
|
* reg = <0x42000000 0x1000>;
|
||||||
|
* };
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* DT_RESERVED_MEM_GET_PTR(DT_NODELABEL(n)) // (uint8_t *) 0x42000000
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return pointer to the beginning of the reserved-memory region
|
||||||
|
*/
|
||||||
|
#define DT_RESERVED_MEM_GET_PTR(node_id) _DT_RESERVED_START(node_id)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the size of the reserved-memory region
|
||||||
|
*
|
||||||
|
* Example devicetree fragment:
|
||||||
|
*
|
||||||
|
* reserved: reserved-memory {
|
||||||
|
* compatible = "reserved-memory";
|
||||||
|
* ...
|
||||||
|
* n: node {
|
||||||
|
* reg = <0x42000000 0x1000>;
|
||||||
|
* };
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* DT_RESERVED_MEM_GET_SIZE(DT_NODELABEL(n)) // 0x1000
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return the size of the reserved-memory region
|
||||||
|
*/
|
||||||
|
#define DT_RESERVED_MEM_GET_SIZE(node_id) DT_REG_SIZE(node_id)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the pointer to the reserved-memory region from a memory-reserved
|
||||||
|
* phandle
|
||||||
|
*
|
||||||
|
* Example devicetree fragment:
|
||||||
|
*
|
||||||
|
* reserved: reserved-memory {
|
||||||
|
* compatible = "reserved-memory";
|
||||||
|
* ...
|
||||||
|
* res0: res {
|
||||||
|
* reg = <0x42000000 0x1000>;
|
||||||
|
* label = "res0";
|
||||||
|
* };
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* n: node {
|
||||||
|
* memory-region = <&res0>;
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* DT_RESERVED_MEM_GET_PTR_BY_PHANDLE(DT_NODELABEL(n), memory_region) // (uint8_t *) 0x42000000
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @param ph phandle to reserved-memory region
|
||||||
|
*
|
||||||
|
* @return pointer to the beginning of the reserved-memory region
|
||||||
|
*/
|
||||||
|
#define DT_RESERVED_MEM_GET_PTR_BY_PHANDLE(node_id, ph) \
|
||||||
|
DT_RESERVED_MEM_GET_PTR(DT_PHANDLE(node_id, ph))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the size of the reserved-memory region from a memory-reserved
|
||||||
|
* phandle
|
||||||
|
*
|
||||||
|
* Example devicetree fragment:
|
||||||
|
*
|
||||||
|
* reserved: reserved-memory {
|
||||||
|
* compatible = "reserved-memory";
|
||||||
|
* ...
|
||||||
|
* res0: res {
|
||||||
|
* reg = <0x42000000 0x1000>;
|
||||||
|
* label = "res0";
|
||||||
|
* };
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* n: node {
|
||||||
|
* memory-region = <&res0>;
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* DT_RESERVED_MEM_GET_SIZE_BY_PHANDLE(DT_NODELABEL(n), memory_region) // (uint8_t *) 0x42000000
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @param ph phandle to reserved-memory region
|
||||||
|
*
|
||||||
|
* @return size of the reserved-memory region
|
||||||
|
*/
|
||||||
|
#define DT_RESERVED_MEM_GET_SIZE_BY_PHANDLE(node_id, ph) \
|
||||||
|
DT_RESERVED_MEM_GET_SIZE(DT_PHANDLE(node_id, ph))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZEPHYR_INCLUDE_DEVICETREE_MEMORY_H_ */
|
59
include/linker/devicetree_reserved.h
Normal file
59
include/linker/devicetree_reserved.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Carlo Caione <ccaione@baylibre.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Generate memory regions and sections from reserved-memory nodes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <devicetree.h>
|
||||||
|
|
||||||
|
/* Reserved memory node */
|
||||||
|
#define _NODE_RESERVED DT_INST(0, reserved_memory)
|
||||||
|
|
||||||
|
/* Unquoted region label */
|
||||||
|
#define _DT_LABEL_TOKEN(res) DT_STRING_TOKEN(res, label)
|
||||||
|
|
||||||
|
/* _start and _end section symbols */
|
||||||
|
#define _DT_RESERVED_PREFIX(res) UTIL_CAT(__, _DT_LABEL_TOKEN(res))
|
||||||
|
#define _DT_RESERVED_START(res) UTIL_CAT(_DT_RESERVED_PREFIX(res), _start)
|
||||||
|
#define _DT_RESERVED_END(res) UTIL_CAT(_DT_RESERVED_PREFIX(res), _end)
|
||||||
|
|
||||||
|
/* Declare a reserved memory region */
|
||||||
|
#define _RESERVED_REGION_DECLARE(res) DT_STRING_TOKEN(res, label) (rw) : \
|
||||||
|
ORIGIN = DT_REG_ADDR(res), \
|
||||||
|
LENGTH = DT_REG_SIZE(res)
|
||||||
|
|
||||||
|
/* Declare a reserved memory section */
|
||||||
|
#define _RESERVED_SECTION_DECLARE(res) SECTION_DATA_PROLOGUE(_DT_LABEL_TOKEN(res), ,) \
|
||||||
|
{ \
|
||||||
|
_DT_RESERVED_START(res) = .; \
|
||||||
|
KEEP(*(._DT_LABEL_TOKEN(res))) \
|
||||||
|
KEEP(*(._DT_LABEL_TOKEN(res).*)) \
|
||||||
|
_DT_RESERVED_END(res) = \
|
||||||
|
_DT_RESERVED_START(res) + DT_REG_SIZE(res); \
|
||||||
|
} GROUP_LINK_IN(_DT_LABEL_TOKEN(res))
|
||||||
|
|
||||||
|
/* Declare reserved memory linker symbols */
|
||||||
|
#define _RESERVED_SYMBOL_DECLARE(res) extern char _DT_RESERVED_START(res)[]; \
|
||||||
|
extern char _DT_RESERVED_END(res)[];
|
||||||
|
|
||||||
|
/* Apply a macro to a reserved memory region */
|
||||||
|
#define _RESERVED_REGION_APPLY(f) \
|
||||||
|
COND_CODE_1(IS_ENABLED(UTIL_CAT(_NODE_RESERVED, _EXISTS)), \
|
||||||
|
(DT_FOREACH_CHILD(_NODE_RESERVED, f)), ())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate region definitions for all the reserved memory regions
|
||||||
|
*/
|
||||||
|
#define DT_RESERVED_MEM_REGIONS() _RESERVED_REGION_APPLY(_RESERVED_REGION_DECLARE)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate section definitions for all the reserved memory regions
|
||||||
|
*/
|
||||||
|
#define DT_RESERVED_MEM_SECTIONS() _RESERVED_REGION_APPLY(_RESERVED_SECTION_DECLARE)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate linker script symbols for all the reserved memory regions
|
||||||
|
*/
|
||||||
|
#define DT_RESERVED_MEM_SYMBOLS() _RESERVED_REGION_APPLY(_RESERVED_SYMBOL_DECLARE)
|
|
@ -33,6 +33,7 @@
|
||||||
#ifdef ZTEST_UNITTEST
|
#ifdef ZTEST_UNITTEST
|
||||||
#define DT_NODE_HAS_STATUS(node, status) 0
|
#define DT_NODE_HAS_STATUS(node, status) 0
|
||||||
#else
|
#else
|
||||||
|
#include <linker/devicetree_reserved.h>
|
||||||
#include <devicetree.h>
|
#include <devicetree.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -213,6 +214,10 @@ extern char _image_rodata_size[];
|
||||||
extern char _vector_start[];
|
extern char _vector_start[];
|
||||||
extern char _vector_end[];
|
extern char _vector_end[];
|
||||||
|
|
||||||
|
#if DT_NODE_HAS_STATUS(_NODE_RESERVED, okay)
|
||||||
|
DT_RESERVED_MEM_SYMBOLS()
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SW_VECTOR_RELAY
|
#ifdef CONFIG_SW_VECTOR_RELAY
|
||||||
extern char __vector_relay_table[];
|
extern char __vector_relay_table[];
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue