LCOV - code coverage report
Current view: top level - zephyr/linker - devicetree_regions.h Coverage Total Hit
Test: new.info Lines: 83.3 % 6 5
Test Date: 2025-03-11 06:50:38

            Line data    Source code
       1            0 : /*
       2              :  * Copyright (c) 2021, Commonwealth Scientific and Industrial Research
       3              :  * Organisation (CSIRO) ABN 41 687 119 230.
       4              :  *
       5              :  * SPDX-License-Identifier: Apache-2.0
       6              :  *
       7              :  * Generate memory regions from devicetree nodes.
       8              :  */
       9              : 
      10              : #ifndef ZEPHYR_INCLUDE_LINKER_DEVICETREE_REGIONS_H_
      11              : #define ZEPHYR_INCLUDE_LINKER_DEVICETREE_REGIONS_H_
      12              : 
      13              : #include <zephyr/devicetree.h>
      14              : #include <zephyr/sys/util.h>
      15              : #include <zephyr/toolchain.h>
      16              : 
      17              : /**
      18              :  * @brief Get the linker memory-region name in a token form
      19              :  *
      20              :  * This attempts to use the zephyr,memory-region property (with
      21              :  * non-alphanumeric characters replaced with underscores) returning a token.
      22              :  *
      23              :  * Example devicetree fragment:
      24              :  *
      25              :  * @code{.dts}
      26              :  *     / {
      27              :  *             soc {
      28              :  *                     sram1: memory@2000000 {
      29              :  *                         zephyr,memory-region = "MY_NAME";
      30              :  *                     };
      31              :  *                     sram2: memory@2001000 {
      32              :  *                         zephyr,memory-region = "MY@OTHER@NAME";
      33              :  *                     };
      34              :  *             };
      35              :  *     };
      36              :  * @endcode
      37              :  *
      38              :  * Example usage:
      39              :  *
      40              :  * @code{.c}
      41              :  *    LINKER_DT_NODE_REGION_NAME_TOKEN(DT_NODELABEL(sram1)) // MY_NAME
      42              :  *    LINKER_DT_NODE_REGION_NAME_TOKEN(DT_NODELABEL(sram2)) // MY_OTHER_NAME
      43              :  * @endcode
      44              :  *
      45              :  * @param node_id node identifier
      46              :  * @return the name of the memory memory region the node will generate
      47              :  */
      48            1 : #define LINKER_DT_NODE_REGION_NAME_TOKEN(node_id) \
      49              :         DT_STRING_TOKEN(node_id, zephyr_memory_region)
      50              : 
      51              : /**
      52              :  * @brief Get the linker memory-region name
      53              :  *
      54              :  * This attempts to use the zephyr,memory-region property (with
      55              :  * non-alphanumeric characters replaced with underscores).
      56              :  *
      57              :  * Example devicetree fragment:
      58              :  *
      59              :  * @code{.dts}
      60              :  *     / {
      61              :  *             soc {
      62              :  *                     sram1: memory@2000000 {
      63              :  *                         zephyr,memory-region = "MY_NAME";
      64              :  *                     };
      65              :  *                     sram2: memory@2001000 {
      66              :  *                         zephyr,memory-region = "MY@OTHER@NAME";
      67              :  *                     };
      68              :  *             };
      69              :  *     };
      70              :  * @endcode
      71              :  *
      72              :  * Example usage:
      73              :  *
      74              :  * @code{.c}
      75              :  *    LINKER_DT_NODE_REGION_NAME(DT_NODELABEL(sram1)) // "MY_NAME"
      76              :  *    LINKER_DT_NODE_REGION_NAME(DT_NODELABEL(sram2)) // "MY_OTHER_NAME"
      77              :  * @endcode
      78              :  *
      79              :  * @param node_id node identifier
      80              :  * @return the name of the memory memory region the node will generate
      81              :  */
      82            1 : #define LINKER_DT_NODE_REGION_NAME(node_id) \
      83              :         STRINGIFY(LINKER_DT_NODE_REGION_NAME_TOKEN(node_id))
      84              : 
      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            1 : #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              : 
     145              : /** @cond INTERNAL_HIDDEN */
     146              : 
     147              : #define _DT_COMPATIBLE  zephyr_memory_region
     148              : 
     149              : #define _DT_SECTION_PREFIX(node_id)     UTIL_CAT(__, LINKER_DT_NODE_REGION_NAME_TOKEN(node_id))
     150              : #define _DT_SECTION_START(node_id)      UTIL_CAT(_DT_SECTION_PREFIX(node_id), _start)
     151              : #define _DT_SECTION_END(node_id)        UTIL_CAT(_DT_SECTION_PREFIX(node_id), _end)
     152              : #define _DT_SECTION_SIZE(node_id)       UTIL_CAT(_DT_SECTION_PREFIX(node_id), _size)
     153              : #define _DT_SECTION_LOAD(node_id)       UTIL_CAT(_DT_SECTION_PREFIX(node_id), _load_start)
     154              : 
     155              : /**
     156              :  * @brief Declare a memory region
     157              :  *
     158              :  * Example devicetree fragment:
     159              :  *
     160              :  * @code{.dts}
     161              :  *    test_sram: sram@20010000 {
     162              :  *        compatible = "zephyr,memory-region", "mmio-sram";
     163              :  *        reg = < 0x20010000 0x1000 >;
     164              :  *        zephyr,memory-region = "FOOBAR";
     165              :  *        zephyr,memory-region-flags = "rw";
     166              :  *    };
     167              :  * @endcode
     168              :  *
     169              :  * will result in:
     170              :  *
     171              :  * @code{.unparsed}
     172              :  *    FOOBAR (rw) : ORIGIN = (0x20010000), LENGTH = (0x1000)
     173              :  * @endcode
     174              :  *
     175              :  * @param node_id devicetree node identifier
     176              :  * @param attr region attributes
     177              :  */
     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)
     183              : 
     184              : /**
     185              :  * @brief Declare a memory section from the device tree nodes with
     186              :  *        compatible 'zephyr,memory-region'
     187              :  *
     188              :  * Example devicetree fragment:
     189              :  *
     190              :  * @code{.dts}
     191              :  *    test_sram: sram@20010000 {
     192              :  *        compatible = "zephyr,memory-region", "mmio-sram";
     193              :  *        reg = < 0x20010000 0x1000 >;
     194              :  *        zephyr,memory-region = "FOOBAR";
     195              :  *    };
     196              :  * @endcode
     197              :  *
     198              :  * will result in:
     199              :  *
     200              :  * @code{.unparsed}
     201              :  *    FOOBAR (NOLOAD) :
     202              :  *    {
     203              :  *        __FOOBAR_start = .;
     204              :  *        KEEP(*(FOOBAR))
     205              :  *        KEEP(*(FOOBAR.*))
     206              :  *        __FOOBAR_end = .;
     207              :  *    } > FOOBAR
     208              :  *    __FOOBAR_size = __FOOBAR_end - __FOOBAR_start;
     209              :  *    __FOOBAR_load_start = LOADADDR(FOOBAR);
     210              :  * @endcode
     211              :  *
     212              :  * @param node_id devicetree node identifier
     213              :  */
     214              : #define _SECTION_DECLARE(node_id)                                                               \
     215              :         LINKER_DT_NODE_REGION_NAME_TOKEN(node_id) (NOLOAD) :                                    \
     216              :         {                                                                                       \
     217              :                 _DT_SECTION_START(node_id) = .;                                                 \
     218              :                 KEEP(*(LINKER_DT_NODE_REGION_NAME_TOKEN(node_id)))                              \
     219              :                 KEEP(*(LINKER_DT_NODE_REGION_NAME_TOKEN(node_id).*))                            \
     220              :                 _DT_SECTION_END(node_id) = .;                                                   \
     221              :         } > LINKER_DT_NODE_REGION_NAME_TOKEN(node_id)                                                \
     222              :         _DT_SECTION_SIZE(node_id) = _DT_SECTION_END(node_id) - _DT_SECTION_START(node_id);      \
     223              :         _DT_SECTION_LOAD(node_id) = LOADADDR(LINKER_DT_NODE_REGION_NAME_TOKEN(node_id));
     224              : 
     225              : /** @endcond */
     226              : 
     227              : /**
     228              :  * @brief Generate linker memory regions from the device tree nodes with
     229              :  *        compatible 'zephyr,memory-region'
     230              :  *
     231              :  * Note: for now we do not deal with MEMORY attributes since those are
     232              :  * optional, not actually used by Zephyr and they will likely conflict with the
     233              :  * MPU configuration.
     234              :  */
     235            1 : #define LINKER_DT_REGIONS() \
     236              :         DT_FOREACH_STATUS_OKAY(_DT_COMPATIBLE, _REGION_DECLARE)
     237              : 
     238              : /**
     239              :  * @brief Generate linker memory sections from the device tree nodes with
     240              :  *        compatible 'zephyr,memory-region'
     241              :  */
     242            1 : #define LINKER_DT_SECTIONS() \
     243              :         DT_FOREACH_STATUS_OKAY(_DT_COMPATIBLE, _SECTION_DECLARE)
     244              : 
     245              : #endif /* ZEPHYR_INCLUDE_LINKER_DEVICETREE_REGIONS_H_ */
        

Generated by: LCOV version 2.0-1