123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- /*
- * 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 LINKER_DT_RESERVED_MEM_REGIONS() _RESERVED_REGION_APPLY(_RESERVED_REGION_DECLARE)
- /**
- * @brief Generate section definitions for all the reserved memory regions
- */
- #define LINKER_DT_RESERVED_MEM_SECTIONS() _RESERVED_REGION_APPLY(_RESERVED_SECTION_DECLARE)
- /**
- * @brief Generate linker script symbols for all the reserved memory regions
- */
- #define LINKER_DT_RESERVED_MEM_SYMBOLS() _RESERVED_REGION_APPLY(_RESERVED_SYMBOL_DECLARE)
- /**
- * @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:
- *
- * LINKER_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 LINKER_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:
- *
- * LINKER_DT_RESERVED_MEM_GET_SIZE(DT_NODELABEL(n)) // 0x1000
- *
- * @param node_id node identifier
- * @return the size of the reserved-memory region
- */
- #define LINKER_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:
- *
- * LINKER_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 LINKER_DT_RESERVED_MEM_GET_PTR_BY_PHANDLE(node_id, ph) \
- LINKER_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:
- *
- * LINKER_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 LINKER_DT_RESERVED_MEM_GET_SIZE_BY_PHANDLE(node_id, ph) \
- LINKER_DT_RESERVED_MEM_GET_SIZE(DT_PHANDLE(node_id, ph))
|