diff --git a/arch/arm/core/mpu/arm_mpu.c b/arch/arm/core/mpu/arm_mpu.c index ac28ab6b609..6c95fe044b2 100644 --- a/arch/arm/core/mpu/arm_mpu.c +++ b/arch/arm/core/mpu/arm_mpu.c @@ -11,6 +11,8 @@ #include "arm_core_mpu_dev.h" #include #include +#include +#include #define LOG_LEVEL CONFIG_MPU_LOG_LEVEL #include @@ -32,6 +34,13 @@ LOG_MODULE_DECLARE(mpu); #define NUM_MPU_REGIONS DT_PROP(MPU_NODEID, arm_num_mpu_regions) #endif +#define NODE_HAS_PROP_AND_OR(node_id, prop) \ + DT_NODE_HAS_PROP(node_id, prop) || + +BUILD_ASSERT((DT_FOREACH_STATUS_OKAY_NODE_VARGS( + NODE_HAS_PROP_AND_OR, zephyr_memory_region_mpu) false) == false, + "`zephyr,memory-region-mpu` was deprecated in favor of `zephyr,memory-attr`"); + /* * Global status variable holding the number of HW MPU region indices, which * have been reserved by the MPU driver to program the static (fixed) memory @@ -74,6 +83,79 @@ static int region_allocate_and_init(const uint8_t index, return index; } +#define _BUILD_REGION_CONF(reg, _ATTR) \ + (struct arm_mpu_region) ARM_MPU_REGION_INIT((reg).dt_name, \ + (reg).dt_addr, \ + (reg).dt_size, \ + _ATTR) + +/* This internal function programs the MPU regions defined in the DT when using + * the `zephyr,memory-attr = <( DT_MEM_ARM(...) )>` property. + */ +static int mpu_configure_regions_from_dt(uint8_t *reg_index) +{ + const struct mem_attr_region_t *region; + size_t num_regions; + + num_regions = mem_attr_get_regions(®ion); + + for (size_t idx = 0; idx < num_regions; idx++) { + struct arm_mpu_region region_conf; + + switch (DT_MEM_ARM_MASK(region[idx].dt_attr)) { + case DT_MEM_ARM_MPU_RAM: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_ATTR); + break; +#ifdef REGION_RAM_NOCACHE_ATTR + case DT_MEM_ARM_MPU_RAM_NOCACHE: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_NOCACHE_ATTR); + __ASSERT(!(region[idx].dt_attr & DT_MEM_CACHEABLE), + "RAM_NOCACHE with DT_MEM_CACHEABLE attribute\n"); + break; +#endif +#ifdef REGION_FLASH_ATTR + case DT_MEM_ARM_MPU_FLASH: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_FLASH_ATTR); + break; +#endif +#ifdef REGION_PPB_ATTR + case DT_MEM_ARM_MPU_PPB: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_PPB_ATTR); + break; +#endif +#ifdef REGION_IO_ATTR + case DT_MEM_ARM_MPU_IO: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_IO_ATTR); + break; +#endif +#ifdef REGION_EXTMEM_ATTR + case DT_MEM_ARM_MPU_EXTMEM: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_EXTMEM_ATTR); + break; +#endif + default: + /* Either the specified `ATTR_MPU_*` attribute does not + * exists or the `REGION_*_ATTR` macro is not defined + * for that attribute. + */ + LOG_ERR("Invalid attribute for the region\n"); + return -EINVAL; + } +#if defined(CONFIG_ARMV7_R) + region_conf.size = size_to_mpu_rasr_size(region[idx].dt_size); +#endif + + if (region_allocate_and_init((*reg_index), + (const struct arm_mpu_region *) ®ion_conf) < 0) { + return -EINVAL; + } + + (*reg_index)++; + } + + return 0; +} + /* This internal function programs an MPU region * of a given configuration at a given MPU index. */ @@ -375,6 +457,11 @@ int z_arm_mpu_init(void) /* Update the number of programmed MPU regions. */ static_regions_num = mpu_config.num_regions; + /* DT-defined MPU regions. */ + if (mpu_configure_regions_from_dt(&static_regions_num) == -EINVAL) { + __ASSERT(0, "Failed to allocate MPU regions from DT\n"); + return -EINVAL; + } arm_core_mpu_enable(); diff --git a/arch/arm/core/mpu/nxp_mpu.c b/arch/arm/core/mpu/nxp_mpu.c index eeed6383d83..71b55ae7c11 100644 --- a/arch/arm/core/mpu/nxp_mpu.c +++ b/arch/arm/core/mpu/nxp_mpu.c @@ -13,11 +13,20 @@ #include #include #include +#include +#include #define LOG_LEVEL CONFIG_MPU_LOG_LEVEL #include LOG_MODULE_DECLARE(mpu); +#define NODE_HAS_PROP_AND_OR(node_id, prop) \ + DT_NODE_HAS_PROP(node_id, prop) || + +BUILD_ASSERT((DT_FOREACH_STATUS_OKAY_NODE_VARGS( + NODE_HAS_PROP_AND_OR, zephyr_memory_region_mpu) false) == false, + "`zephyr,memory-region-mpu` was deprecated in favor of `zephyr,memory-attr`"); + /* * Global status variable holding the number of HW MPU region indices, which * have been reserved by the MPU driver to program the static (fixed) memory @@ -134,6 +143,60 @@ static int region_allocate_and_init(const uint8_t index, return index; } +#define _BUILD_REGION_CONF(reg, _ATTR) \ + (struct nxp_mpu_region) { .name = (reg).dt_name, \ + .base = (reg).dt_addr, \ + .end = (reg).dt_addr + (reg).dt_size, \ + .attr = _ATTR, \ + } + +/* This internal function programs the MPU regions defined in the DT when using + * the `zephyr,memory-attr = <( DT_MEM_ARM(...) )>` property. + */ +static int mpu_configure_regions_from_dt(uint8_t *reg_index) +{ + const struct mem_attr_region_t *region; + size_t num_regions; + + num_regions = mem_attr_get_regions(®ion); + + for (size_t idx = 0; idx < num_regions; idx++) { + struct nxp_mpu_region region_conf; + + switch (DT_MEM_ARM_MASK(region[idx].dt_attr)) { + case DT_MEM_ARM_MPU_RAM: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_ATTR); + break; +#ifdef REGION_FLASH_ATTR + case DT_MEM_ARM_MPU_FLASH: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_FLASH_ATTR); + break; +#endif +#ifdef REGION_IO_ATTR + case DT_MEM_ARM_MPU_IO: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_IO_ATTR); + break; +#endif + default: + /* Either the specified `ATTR_MPU_*` attribute does not + * exists or the `REGION_*_ATTR` macro is not defined + * for that attribute. + */ + LOG_ERR("Invalid attribute for the region\n"); + return -EINVAL; + } + + if (region_allocate_and_init((*reg_index), + (const struct nxp_mpu_region *) ®ion_conf) < 0) { + return -EINVAL; + } + + (*reg_index)++; + } + + return 0; +} + /** * This internal function is utilized by the MPU driver to combine a given * region attribute configuration and size and fill-in a driver-specific @@ -636,6 +699,11 @@ int z_arm_mpu_init(void) /* Update the number of programmed MPU regions. */ static_regions_num = mpu_config.num_regions; + /* DT-defined MPU regions. */ + if (mpu_configure_regions_from_dt(&static_regions_num) == -EINVAL) { + __ASSERT(0, "Failed to allocate MPU regions from DT\n"); + return -EINVAL; + } arm_core_mpu_enable(); diff --git a/arch/arm64/core/cortex_r/arm_mpu.c b/arch/arm64/core/cortex_r/arm_mpu.c index 2ecdb525715..7ee56c52ea4 100644 --- a/arch/arm64/core/cortex_r/arm_mpu.c +++ b/arch/arm64/core/cortex_r/arm_mpu.c @@ -15,9 +15,18 @@ #include #include #include +#include +#include LOG_MODULE_REGISTER(mpu, CONFIG_MPU_LOG_LEVEL); +#define NODE_HAS_PROP_AND_OR(node_id, prop) \ + DT_NODE_HAS_PROP(node_id, prop) || + +BUILD_ASSERT((DT_FOREACH_STATUS_OKAY_NODE_VARGS( + NODE_HAS_PROP_AND_OR, zephyr_memory_region_mpu) false) == false, + "`zephyr,memory-region-mpu` was deprecated in favor of `zephyr,memory-attr`"); + #define MPU_DYNAMIC_REGION_AREAS_NUM 1 #ifdef CONFIG_USERSPACE @@ -167,6 +176,64 @@ static ALWAYS_INLINE void region_init(const uint32_t index, mpu_set_region(index, rbar, rlar); } +#define _BUILD_REGION_CONF(reg, _ATTR) \ + (struct arm_mpu_region) { .name = (reg).dt_name, \ + .base = (reg).dt_addr, \ + .limit = (reg).dt_addr + (reg).dt_size, \ + .attr = _ATTR, \ + } + +/* This internal function programs the MPU regions defined in the DT when using + * the `zephyr,memory-attr = <( DT_MEM_ARM(...) )>` property. + */ +static int mpu_configure_regions_from_dt(uint8_t *reg_index) +{ + const struct mem_attr_region_t *region; + size_t num_regions; + + num_regions = mem_attr_get_regions(®ion); + + for (size_t idx = 0; idx < num_regions; idx++) { + struct arm_mpu_region region_conf; + + switch (DT_MEM_ARM_MASK(region[idx].dt_attr)) { + case DT_MEM_ARM_MPU_RAM: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_ATTR); + break; +#ifdef REGION_RAM_NOCACHE_ATTR + case DT_MEM_ARM_MPU_RAM_NOCACHE: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_NOCACHE_ATTR); + __ASSERT(!(region[idx].dt_attr & DT_MEM_CACHEABLE), + "RAM_NOCACHE with DT_MEM_CACHEABLE attribute\n"); + break; +#endif +#ifdef REGION_FLASH_ATTR + case DT_MEM_ARM_MPU_FLASH: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_FLASH_ATTR); + break; +#endif +#ifdef REGION_IO_ATTR + case DT_MEM_ARM_MPU_IO: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_IO_ATTR); + break; +#endif + default: + /* Either the specified `ATTR_MPU_*` attribute does not + * exists or the `REGION_*_ATTR` macro is not defined + * for that attribute. + */ + LOG_ERR("Invalid attribute for the region\n"); + return -EINVAL; + } + + region_init((*reg_index), (const struct arm_mpu_region *) ®ion_conf); + + (*reg_index)++; + } + + return 0; +} + /* * @brief MPU default configuration * @@ -222,6 +289,12 @@ FUNC_NO_STACK_PROTECTOR void z_arm64_mm_init(bool is_primary_core) /* Update the number of programmed MPU regions. */ static_regions_num = mpu_config.num_regions; + /* DT-defined MPU regions. */ + if (mpu_configure_regions_from_dt(&static_regions_num) == -EINVAL) { + __ASSERT(0, "Failed to allocate MPU regions from DT\n"); + return; + } + arm_core_mpu_enable(); if (!is_primary_core) { diff --git a/boards/arm/arduino_giga_r1/arduino_giga_r1_m7.dts b/boards/arm/arduino_giga_r1/arduino_giga_r1_m7.dts index 24e26e68fbe..ef3544ef958 100644 --- a/boards/arm/arduino_giga_r1/arduino_giga_r1_m7.dts +++ b/boards/arm/arduino_giga_r1/arduino_giga_r1_m7.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include +#include #include "arduino_giga_r1.dtsi" / { @@ -29,7 +30,7 @@ device_type = "memory"; reg = <0xc0000000 DT_SIZE_M(8)>; zephyr,memory-region = "SDRAM1"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; aliases { diff --git a/boards/arm/stm32f746g_disco/stm32f746g_disco.dts b/boards/arm/stm32f746g_disco/stm32f746g_disco.dts index f28c5857cbe..e81172d381b 100644 --- a/boards/arm/stm32f746g_disco/stm32f746g_disco.dts +++ b/boards/arm/stm32f746g_disco/stm32f746g_disco.dts @@ -9,6 +9,8 @@ #include #include "arduino_r3_connector.dtsi" #include +#include +#include / { model = "STMicroelectronics STM32F746G DISCOVERY board"; @@ -51,7 +53,7 @@ device_type = "memory"; reg = <0xc0000000 DT_SIZE_M(16)>; zephyr,memory-region = "SDRAM1"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; aliases { diff --git a/boards/arm/stm32f7508_dk/stm32f7508_dk.dts b/boards/arm/stm32f7508_dk/stm32f7508_dk.dts index 3969add4e28..8102e002863 100644 --- a/boards/arm/stm32f7508_dk/stm32f7508_dk.dts +++ b/boards/arm/stm32f7508_dk/stm32f7508_dk.dts @@ -8,6 +8,7 @@ /dts-v1/; #include #include +#include #include "arduino_r3_connector.dtsi" #include @@ -52,7 +53,7 @@ device_type = "memory"; reg = <0xc0000000 DT_SIZE_M(16)>; zephyr,memory-region = "SDRAM1"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; aliases { diff --git a/boards/arm/stm32f769i_disco/stm32f769i_disco.dts b/boards/arm/stm32f769i_disco/stm32f769i_disco.dts index fcd2197aa9d..0548cf06bd8 100644 --- a/boards/arm/stm32f769i_disco/stm32f769i_disco.dts +++ b/boards/arm/stm32f769i_disco/stm32f769i_disco.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include +#include #include "arduino_r3_connector.dtsi" #include @@ -28,7 +29,7 @@ device_type = "memory"; reg = <0xc0000000 DT_SIZE_M(16)>; zephyr,memory-region = "SDRAM1"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; leds { diff --git a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts index 918c61b9978..8f6f519186d 100644 --- a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts +++ b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include +#include #include "stm32h747i_disco.dtsi" / { @@ -27,7 +28,7 @@ device_type = "memory"; reg = <0xd0000000 DT_SIZE_M(32)>; zephyr,memory-region = "SDRAM2"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; leds { diff --git a/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts b/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts index 4183c4912bd..e9acb61b820 100644 --- a/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts +++ b/boards/arm/stm32h7b3i_dk/stm32h7b3i_dk.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include +#include #include "arduino_r3_connector.dtsi" #include @@ -54,7 +55,7 @@ device_type = "memory"; reg = <0xd0000000 DT_SIZE_M(16)>; zephyr,memory-region = "SDRAM2"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; transceiver0: can-phy0 { diff --git a/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r.dts b/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r.dts index eb49a3e3856..727e7b5d7a2 100644 --- a/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r.dts +++ b/boards/arm64/fvp_baser_aemv8r/fvp_baser_aemv8r.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include / { model = "FVP BaseR AEMv8R"; @@ -41,7 +42,7 @@ compatible = "zephyr,memory-region", "mmio-dram"; reg = <0x9a000000 0x66000000>; zephyr,memory-region = "DEVICE_REGION"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; }; diff --git a/doc/build/dts/api/api.rst b/doc/build/dts/api/api.rst index f3a8c2bcb0d..7d802838041 100644 --- a/doc/build/dts/api/api.rst +++ b/doc/build/dts/api/api.rst @@ -294,15 +294,6 @@ and properties related to them. .. doxygengroup:: devicetree-mbox -.. _devicetree-memory-attr-api: - -Memory attributes -================= - -These conveniences may be used for nodes with a memory attribute property. - -.. doxygengroup:: devicetree-memory-attr - .. _devicetree-pinctrl-api: Pinctrl (pin control) diff --git a/doc/hardware/arch/arm_cortex_m.rst b/doc/hardware/arch/arm_cortex_m.rst index 48e517259ed..b037896776f 100644 --- a/doc/hardware/arch/arm_cortex_m.rst +++ b/doc/hardware/arch/arm_cortex_m.rst @@ -457,10 +457,6 @@ region will be allocated and programmed during system boot. When used with the :dtcompatible:`zephyr,memory-region` devicetree compatible, it will result in a linker section being generated associated to that MPU region. -The property ``zephyr,memory-attr`` is a string carrying the attributes -for the MPU region. It is converted to a C token for use defining the attributes -of the MPU region. - For example, to define a new non-cacheable memory region in devicetree: .. code-block:: devicetree @@ -469,13 +465,11 @@ For example, to define a new non-cacheable memory region in devicetree: compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x20300000 0x100000>; zephyr,memory-region = "SRAM_NO_CACHE"; - zephyr,memory-attr = "RAM_NOCACHE"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; }; -This will automatically create a new MPU entry in -:zephyr_file:`soc/arm/common/cortex_m/arm_mpu_regions.c` with the correct name, base, -size and attributes gathered directly from the devicetree. See -:zephyr_file:`include/zephyr/linker/devicetree_regions.h` for more details. +This will automatically create a new MPU entry in with the correct name, base, +size and attributes gathered directly from the devicetree. Static MPU regions ------------------ diff --git a/doc/releases/migration-guide-3.5.rst b/doc/releases/migration-guide-3.5.rst index f3ae1852082..767c5378be1 100644 --- a/doc/releases/migration-guide-3.5.rst +++ b/doc/releases/migration-guide-3.5.rst @@ -34,6 +34,19 @@ Required changes SMP version 2 error code defines for in-tree modules have been updated to replace the ``*_RET_RC_*`` parts with ``*_ERR_*``. +* ``zephyr,memory-region-mpu`` was renamed ``zephyr,memory-attr`` and its type + moved from 'enum' to 'int'. To have a seamless conversion this is the + required change in the DT: + + .. code-block:: none + + - "RAM" -> <( DT_MEM_ARM(ATTR_MPU_RAM) )> + - "RAM_NOCACHE" -> <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )> + - "FLASH" -> <( DT_MEM_ARM(ATTR_MPU_FLASH) )> + - "PPB" -> <( DT_MEM_ARM(ATTR_MPU_PPB) )> + - "IO" -> <( DT_MEM_ARM(ATTR_MPU_IO) )> + - "EXTMEM" -> <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )> + Recommended Changes ******************* diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index 7b090e2c0fd..00e23f6d30b 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -284,16 +284,6 @@ USB Devicetree ********** -* ``zephyr,memory-region-mpu`` was renamed ``zephyr,memory-attr`` - -* The following macros were added: - :c:macro:`DT_FOREACH_NODE_VARGS`, - :c:macro:`DT_FOREACH_STATUS_OKAY_NODE_VARGS` - :c:macro:`DT_MEMORY_ATTR_FOREACH_NODE` - :c:macro:`DT_MEMORY_ATTR_APPLY` - :c:macro:`DT_MEM_FROM_FIXED_PARTITION` - :c:macro:`DT_FIXED_PARTITION_ADDR` - Libraries / Subsystems ********************** diff --git a/doc/services/index.rst b/doc/services/index.rst index 6ba8af68a67..990f0cfea49 100644 --- a/doc/services/index.rst +++ b/doc/services/index.rst @@ -18,6 +18,7 @@ OS Services logging/index.rst tracing/index.rst resource_management/index.rst + mem_mgmt/index.rst modbus/index.rst notify.rst pm/index.rst diff --git a/doc/services/mem_mgmt/index.rst b/doc/services/mem_mgmt/index.rst new file mode 100644 index 00000000000..eb689c409d1 --- /dev/null +++ b/doc/services/mem_mgmt/index.rst @@ -0,0 +1,90 @@ +.. _mem_mgmt_api: + +Memory Attributes +################# + +It is possible in the devicetree to mark the memory regions with attributes by +using the ``zephyr,memory-attr`` property. This property and the related memory +region can then be retrieved at run-time by leveraging a provided helper +library. + +The set of general attributes that can be specified in the property are defined +and explained in :zephyr_file:`include/zephyr/dt-bindings/memory-attr/memory-attr.h`. + +For example, to mark a memory region in the devicetree as non-volatile, cacheable, +out-of-order: + +.. code-block:: devicetree + + mem: memory@10000000 { + compatible = "mmio-sram"; + reg = <0x10000000 0x1000>; + zephyr,memory-attr = <( DT_MEM_NON_VOLATILE | DT_MEM_CACHEABLE | DT_MEM_OOO )>; + }; + +.. note:: + + The ``zephyr,memory-attr`` usage does not result in any memory region + actually created. When it is needed to create an actual section out of the + devicetree defined memory region, it is possible to use the compatible + :dtcompatible:`zephyr,memory-region` that will result (only when supported + by the architecture) in a new linker section and region. + +The ``zephyr,memory-attr`` property can also be used to set +architecture-specific and software-specific custom attributes that can be +interpreted at run time. This is leveraged, among other things, to create MPU +regions out of devicetree defined memory regions, for example: + +.. code-block:: devicetree + + mem: memory@10000000 { + compatible = "mmio-sram"; + reg = <0x10000000 0x1000>; + zephyr,memory-region = "NOCACHE_REGION"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; + }; + +See :zephyr_file:`include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h` and +:ref:`arm_cortex_m_developer_guide` for more details about MPU usage. + +The conventional and recommended way to deal and manage with memory regions +marked with attributes is by using the provided ``mem-attr`` helper library by +enabling :kconfig:option:`CONFIG_MEM_ATTR`. When this option is enabled the +list of memory regions and their attributes are compiled in a user-accessible +array and a set of functions is made available that can be used to query, probe +and act on regions and attributes (see next section for more details). + +.. note:: + + The ``zephyr,memory-attr`` property is only a descriptive property of the + capabilities of the associated memory region, but it does not result in any + actual setting for the memory to be set. The user, code or subsystem willing + to use this information to do some work (for example creating an MPU region + out of the property) must use either the provided ``mem-attr`` library or + the usual devicetree helpers to perform the required work / setting. + +A test for the ``mem-attr`` library and its usage is provided in +``tests/subsys/mem_mgmt/mem_attr/``. + +Migration guide from `zephyr,memory-region-mpu` +*********************************************** + +When the ``zephyr,memory-attr`` property was introduced, the +``zephyr,memory-region-mpu`` property was removed and deprecated. + +The developers that are still using the deprecated property can move to the new +one by renaming the property and changing its value according to the following list: + +.. code-block:: none + + "RAM" -> <( DT_ARM_MPU(ATTR_MPU_RAM) )> + "RAM_NOCACHE" -> <( DT_ARM_MPU(ATTR_MPU_RAM_NOCACHE) )> + "FLASH" -> <( DT_ARM_MPU(ATTR_MPU_FLASH) )> + "PPB" -> <( DT_ARM_MPU(ATTR_MPU_PPB) )> + "IO" -> <( DT_ARM_MPU(ATTR_MPU_IO) )> + "EXTMEM" -> <( DT_ARM_MPU(ATTR_MPU_EXTMEM) )> + +API Reference +************* + +.. doxygengroup:: memory_attr_interface diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index ad8fcdcb1fd..28a1df08ba6 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -42,6 +42,8 @@ LOG_MODULE_REGISTER(adc_stm32); #include #include #include +#include +#include #if defined(CONFIG_SOC_SERIES_STM32F3X) #if defined(ADC1_V2_5) @@ -253,27 +255,16 @@ static int adc_stm32_dma_start(const struct device *dev, * The entire buffer must be in a single region. * An example of how the SRAM region can be defined in the DTS: * &sram4 { - * zephyr,memory-attr = "RAM_NOCACHE"; + * zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) | ... )>; * }; */ static bool address_in_non_cacheable_sram(const uint16_t *buffer, const uint16_t size) { - /* Default if no valid SRAM region found or buffer+size not located in a single region */ - bool cachable = false; -#define IS_NON_CACHEABLE_REGION_FN(node_id) \ - COND_CODE_1(DT_NODE_HAS_PROP(node_id, zephyr_memory_attr), ({ \ - const uint32_t region_start = DT_REG_ADDR(node_id); \ - const uint32_t region_end = region_start + DT_REG_SIZE(node_id); \ - if (((uint32_t)buffer >= region_start) && \ - (((uint32_t)buffer + size) < region_end)) { \ - cachable = strcmp(DT_PROP(node_id, zephyr_memory_attr), \ - "RAM_NOCACHE") == 0; \ - } \ - }), \ - (EMPTY)) - DT_FOREACH_STATUS_OKAY(mmio_sram, IS_NON_CACHEABLE_REGION_FN); + if (mem_attr_check_buf((void *) buffer, (size_t) size, DT_MEM_ARM_MPU_RAM_NOCACHE) == 0) { + return true; + } - return cachable; + return false; } #endif /* defined(CONFIG_ADC_STM32_DMA) && defined(CONFIG_SOC_SERIES_STM32H7X) */ diff --git a/drivers/dma/dma_stm32_bdma.c b/drivers/dma/dma_stm32_bdma.c index 797ed9ed794..1df5746facb 100644 --- a/drivers/dma/dma_stm32_bdma.c +++ b/drivers/dma/dma_stm32_bdma.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -813,7 +814,7 @@ static int bdma_stm32_init(const struct device *dev) * }; */ #if DT_NODE_HAS_PROP(DT_NODELABEL(sram4), zephyr_memory_attr) - if (strcmp(DT_PROP(DT_NODELABEL(sram4), zephyr_memory_attr), "RAM_NOCACHE") != 0) { + if ((DT_PROP(DT_NODELABEL(sram4), zephyr_memory_attr) & DT_MEM_ARM_MPU_RAM_NOCACHE) == 0) { LOG_ERR("SRAM4 is not set as non-cachable."); return -EIO; } diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index 948b7641eaf..d4ad84fae77 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -25,6 +25,7 @@ LOG_MODULE_REGISTER(spi_ll_stm32); #include #include #include +#include #ifdef CONFIG_NOCACHE_MEMORY #include @@ -81,7 +82,7 @@ struct mem_region { }; static const struct mem_region nocache_mem_regions[] = { - DT_MEMORY_ATTR_FOREACH_NODE(GET_MEM_REGION_IF_NOCACHE) + DT_MEMORY_ATTR_FOREACH_STATUS_OKAY_NODE(GET_MEM_REGION_IF_NOCACHE) }; #endif /* CONFIG_SOC_SERIES_STM32H7X */ diff --git a/dts/arm/nxp/nxp_lpc55S1x_common.dtsi b/dts/arm/nxp/nxp_lpc55S1x_common.dtsi index bbd71e2afa1..c6b21b7495f 100644 --- a/dts/arm/nxp/nxp_lpc55S1x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S1x_common.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include #include / { @@ -61,7 +62,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x20010000 DT_SIZE_K(16)>; zephyr,memory-region = "USB_SRAM"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; }; diff --git a/dts/arm/nxp/nxp_lpc55S2x_common.dtsi b/dts/arm/nxp/nxp_lpc55S2x_common.dtsi index 1e9222f5d07..c429a4bd4ef 100644 --- a/dts/arm/nxp/nxp_lpc55S2x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S2x_common.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include #include / { @@ -75,7 +76,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x40100000 DT_SIZE_K(16)>; zephyr,memory-region = "USB_SRAM"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; }; diff --git a/dts/arm/nxp/nxp_lpc55S6x_common.dtsi b/dts/arm/nxp/nxp_lpc55S6x_common.dtsi index 23db8a86641..c7c7d238dc7 100644 --- a/dts/arm/nxp/nxp_lpc55S6x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S6x_common.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include #include / { @@ -95,7 +96,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x100000 DT_SIZE_K(16)>; zephyr,memory-region = "USB_SRAM"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; syscon: syscon@0 { diff --git a/dts/arm/nxp/nxp_rt5xx_common.dtsi b/dts/arm/nxp/nxp_rt5xx_common.dtsi index 5b24777f0c5..fa7936db9c2 100644 --- a/dts/arm/nxp/nxp_rt5xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt5xx_common.dtsi @@ -12,6 +12,7 @@ #include #include #include +#include / { chosen { @@ -78,7 +79,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x40140000 DT_SIZE_K(16)>; zephyr,memory-region = "SRAM1"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; }; diff --git a/dts/arm/nxp/nxp_rt6xx_common.dtsi b/dts/arm/nxp/nxp_rt6xx_common.dtsi index 59897efe2a5..5b8748c566f 100644 --- a/dts/arm/nxp/nxp_rt6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt6xx_common.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include / { chosen { @@ -62,7 +63,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x40140000 DT_SIZE_K(16)>; zephyr,memory-region = "SRAM1"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; }; diff --git a/dts/arm/st/f7/stm32f7.dtsi b/dts/arm/st/f7/stm32f7.dtsi index a92e5138ce1..addab096c9c 100644 --- a/dts/arm/st/f7/stm32f7.dtsi +++ b/dts/arm/st/f7/stm32f7.dtsi @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include / { @@ -47,7 +49,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x90000000 DT_SIZE_M(256)>; zephyr,memory-region = "QSPI"; - zephyr,memory-attr = "EXTMEM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )>; }; clocks { diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index c9f72afb784..ac0aefdb6f3 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include / { @@ -48,7 +50,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x90000000 DT_SIZE_M(256)>; zephyr,memory-region = "QSPI"; - zephyr,memory-attr = "EXTMEM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )>; }; clocks { diff --git a/dts/bindings/base/zephyr,memory-attr.yaml b/dts/bindings/base/zephyr,memory-attr.yaml index e3c19b9b288..1a5611b5258 100644 --- a/dts/bindings/base/zephyr,memory-attr.yaml +++ b/dts/bindings/base/zephyr,memory-attr.yaml @@ -4,17 +4,19 @@ include: [base.yaml] properties: - zephyr,memory-attr: + zephyr,memory-region-mpu: type: string - enum: - - "RAM" - - "RAM_NOCACHE" - - "FLASH" - - "PPB" - - "IO" - - "EXTMEM" + deprecated: true description: | - Attribute for the memory region. + Signify that this node should result in a dedicated MPU region. + Deprecated in favor of 'zephyr,memory-attr'. + + zephyr,memory-attr: + type: int + description: | + Attribute or set of attributes (bitmask) for the memory region. See + 'include/zephyr/dt-bindings/memory-attr/memory-attr.h' for a + comprehensive list with description of possible values. reg: required: true diff --git a/include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h b/include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h index 4f1132af6b0..7f0d3e3ef66 100644 --- a/include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h +++ b/include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h @@ -72,48 +72,6 @@ #error "Unsupported sram size configuration" #endif -#define MPU_REGION_SIZE_32 REGION_32B -#define MPU_REGION_SIZE_64 REGION_64B -#define MPU_REGION_SIZE_128 REGION_128B -#define MPU_REGION_SIZE_256 REGION_256B -#define MPU_REGION_SIZE_512 REGION_512B -#define MPU_REGION_SIZE_1024 REGION_1K -#define MPU_REGION_SIZE_2048 REGION_2K -#define MPU_REGION_SIZE_4096 REGION_4K -#define MPU_REGION_SIZE_8192 REGION_8K -#define MPU_REGION_SIZE_16384 REGION_16K -#define MPU_REGION_SIZE_32768 REGION_32K -#define MPU_REGION_SIZE_65536 REGION_64K -#define MPU_REGION_SIZE_131072 REGION_128K -#define MPU_REGION_SIZE_262144 REGION_256K -#define MPU_REGION_SIZE_524288 REGION_512K -#define MPU_REGION_SIZE_1048576 REGION_1M -#define MPU_REGION_SIZE_2097152 REGION_2M -#define MPU_REGION_SIZE_4194304 REGION_4M -#define MPU_REGION_SIZE_8388608 REGION_8M -#define MPU_REGION_SIZE_16777216 REGION_16M -#define MPU_REGION_SIZE_33554432 REGION_32M -#define MPU_REGION_SIZE_67108864 REGION_64M -#define MPU_REGION_SIZE_134217728 REGION_128M -#define MPU_REGION_SIZE_268435456 REGION_256M -#define MPU_REGION_SIZE_536870912 REGION_512M - -#define MPU_REGION_SIZE(x) MPU_REGION_SIZE_ ## x - -#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ - { .name = p_name, \ - .base = p_base, \ - .attr = p_attr(MPU_REGION_SIZE(p_size)), \ - } - -#else - -#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ - { .name = p_name, \ - .base = p_base, \ - .attr = p_attr(p_base, p_size), \ - } - #endif /* !ARMV8_M_BASELINE && !ARMV8_M_MAINLINE */ #endif /* _ARM_CORTEX_M_MPU_MEM_CFG_H_ */ diff --git a/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h b/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h index a3b61844368..1ed8636ec50 100644 --- a/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h +++ b/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h @@ -109,6 +109,12 @@ #define REGION_2G REGION_SIZE(2GB) #define REGION_4G REGION_SIZE(4GB) +#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ + { .name = p_name, \ + .base = p_base, \ + .attr = p_attr(size_to_mpu_rasr_size(p_size)), \ + } + /* Some helper defines for common regions */ /* On Cortex-M, we can only set the XN bit when CONFIG_XIP=y. When diff --git a/include/zephyr/arch/arm/mpu/arm_mpu_v8.h b/include/zephyr/arch/arm/mpu/arm_mpu_v8.h index ee8f2e8ac07..cf60cca99da 100644 --- a/include/zephyr/arch/arm/mpu/arm_mpu_v8.h +++ b/include/zephyr/arch/arm/mpu/arm_mpu_v8.h @@ -188,6 +188,13 @@ * that they do not overlap with other MPU regions). */ #if defined(CONFIG_AARCH32_ARMV8_R) + +#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ + { .name = p_name, \ + .base = p_base, \ + .attr = p_attr(p_base + p_size), \ + } + #define REGION_RAM_ATTR(limit) \ { \ .rbar = NOT_EXEC | \ @@ -246,6 +253,12 @@ } #else +#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ + { .name = p_name, \ + .base = p_base, \ + .attr = p_attr(p_base, p_size), \ + } + /* On Cortex-M, we can only set the XN bit when CONFIG_XIP=y. When * CONFIG_XIP=n, the entire image will be linked to SRAM, so we need to keep * the SRAM region XN bit clear or the application code will not be executable. diff --git a/include/zephyr/arch/arm64/cortex_r/arm_mpu.h b/include/zephyr/arch/arm64/cortex_r/arm_mpu.h index d208f2566a1..74426005fb7 100644 --- a/include/zephyr/arch/arm64/cortex_r/arm_mpu.h +++ b/include/zephyr/arch/arm64/cortex_r/arm_mpu.h @@ -227,14 +227,6 @@ struct arm_mpu_config { .attr = _attr, \ } -#define MPU_REGION_ENTRY_FROM_DTS(_name, _base, _size, _attr) \ - { \ - .name = _name, \ - .base = _base, \ - .limit = _base + _size, \ - .attr = _attr, \ - } - #define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \ {(P_RW_U_RW_Msk), MPU_MAIR_INDEX_SRAM}) #define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \ diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index 00cef4fb8aa..c249ad371e2 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -4315,6 +4315,5 @@ #include #include #include -#include #endif /* DEVICETREE_H */ diff --git a/include/zephyr/devicetree/memory-attr.h b/include/zephyr/devicetree/memory-attr.h deleted file mode 100644 index 65fcfe0ca50..00000000000 --- a/include/zephyr/devicetree/memory-attr.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2023 Carlo Caione - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_MEMORY_ATTR_H_ -#define ZEPHYR_INCLUDE_MEMORY_ATTR_H_ - -#include -#include -#include - -/** - * @file - * @brief Memory-attr helpers - */ - -/** - * @defgroup devicetree-memory-attr Memory attributes - * @ingroup devicetree - * @{ - */ - -/** @cond INTERNAL_HIDDEN */ - -#define _DT_MEM_ATTR zephyr_memory_attr -#define _DT_ATTR(token) UTIL_CAT(UTIL_CAT(REGION_, token), _ATTR) - -#define _UNPACK(node_id, fn) \ - fn(COND_CODE_1(DT_NODE_HAS_PROP(node_id, zephyr_memory_region), \ - (LINKER_DT_NODE_REGION_NAME(node_id)), \ - (DT_NODE_FULL_NAME(node_id))), \ - DT_REG_ADDR(node_id), \ - DT_REG_SIZE(node_id), \ - _DT_ATTR(DT_STRING_TOKEN(node_id, _DT_MEM_ATTR))), - -#define _APPLY(node_id, fn) \ - COND_CODE_1(DT_NODE_HAS_PROP(node_id, _DT_MEM_ATTR), \ - (_UNPACK(node_id, fn)), \ - ()) - - -#define _FILTER(node_id, fn) \ - COND_CODE_1(DT_NODE_HAS_PROP(node_id, _DT_MEM_ATTR), \ - (fn(node_id)), \ - ()) - -/** @endcond */ - -/** - * @brief Invokes @p fn for every node in the tree with property - * `zephyr,memory-attr` - * - * The macro @p fn must take one parameter, which will be a node identifier - * with the `zephyr,memory-attr` property. The macro is expanded once for each - * node in the tree. The order that nodes are visited in is not specified. - * - * @param fn macro to invoke - */ -#define DT_MEMORY_ATTR_FOREACH_NODE(fn) \ - DT_FOREACH_STATUS_OKAY_NODE_VARGS(_FILTER, fn) - -/** - * @brief Invokes @p fn for MPU/MMU regions generation from the device tree - * nodes with `zephyr,memory-attr` property. - * - * Helper macro to invoke a @p fn macro on all the memory regions declared - * using the `zephyr,memory-attr` property - * - * The macro @p fn must take the form: - * - * @code{.c} - * #define MPU_FN(name, base, size, attr) ... - * @endcode - * - * The @p name, @p base and @p size parameters are retrieved from the DT node. - * When the `zephyr,memory-region` property is present in the node, the @p name - * parameter is retrived from there, otherwise the full node name is used. - * - * The `zephyr,memory-attr` enum property is passed as an extended token - * to the @p fn macro using the @p attr parameter in the form of a macro - * REGION_{attr}_ATTR. - * - * The following enums are supported for the `zephyr,memory-attr` property (see - * `zephyr,memory-attr.yaml` for a complete list): - * - * - RAM - * - RAM_NOCACHE - * - FLASH - * - PPB - * - IO - * - EXTMEM - * - * This means that usually the user code would provide some macros or defines - * with the same name of the extended property, that is: - * - * - REGION_RAM_ATTR - * - REGION_RAM_NOCACHE_ATTR - * - REGION_FLASH_ATTR - * - REGION_PPB_ATTR - * - REGION_IO_ATTR - * - REGION_EXTMEM_ATTR - * - * Example devicetree fragment: - * - * @code{.dts} - * / { - * soc { - * res0: memory@20000000 { - * reg = <0x20000000 0x4000>; - * zephyr,memory-region = "MY_NAME"; - * zephyr,memory-attr = "RAM_NOCACHE"; - * }; - * - * res1: memory@30000000 { - * reg = <0x30000000 0x2000>; - * zephyr,memory-attr = "RAM"; - * }; - - * }; - * }; - * @endcode - * - * Example usage: - * - * @code{.c} - * #define REGION_RAM_NOCACHE_ATTR 0xAAAA - * #define REGION_RAM_ATTR 0xBBBB - * #define REGION_FLASH_ATTR 0xCCCC - * - * #define MPU_FN(p_name, p_base, p_size, p_attr) \ - * { \ - * .name = p_name, \ - * .base = p_base, \ - * .size = p_size, \ - * .attr = p_attr, \ - * } - * - * static const struct arm_mpu_region mpu_regions[] = { - * DT_MEMORY_ATTR_APPLY(MPU_FN) - * }; - * @endcode - * - * This expands to: - * - * @code{.c} - * static const struct arm_mpu_region mpu_regions[] = { - * { "MY_NAME", 0x20000000, 0x4000, 0xAAAA }, - * { "memory@30000000", 0x30000000, 0x2000, 0xBBBB }, - * }; - * @endcode - * - * @param fn macro to invoke - */ -#define DT_MEMORY_ATTR_APPLY(fn) \ - DT_FOREACH_STATUS_OKAY_NODE_VARGS(_APPLY, fn) - -/** - * @} - */ - -#endif /* ZEPHYR_INCLUDE_MEMORY_ATTR_H_ */ diff --git a/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h b/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h new file mode 100644 index 00000000000..5ffe1f3a3a8 --- /dev/null +++ b/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_ARM_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_ARM_H_ + +#include +#include + +/* + * Architecture specific ARM MPU related attributes. + * + * This list is to seamlessy support the MPU regions configuration using DT and + * the `zephyr,memory-attr` property. + * + * This is legacy and it should NOT be extended further. If new MPU region + * types must be added, these must rely on the generic memory attributes. + */ +#define DT_MEM_ARM_MASK(x) ((x) & DT_MEM_ARCH_ATTR_MASK) +#define DT_MEM_ARM(x) ((x) << DT_MEM_ARCH_ATTR_SHIFT) + +#define ATTR_MPU_RAM BIT(0) +#define ATTR_MPU_RAM_NOCACHE BIT(1) +#define ATTR_MPU_FLASH BIT(2) +#define ATTR_MPU_PPB BIT(3) +#define ATTR_MPU_IO BIT(4) +#define ATTR_MPU_EXTMEM BIT(5) + +#define DT_MEM_ARM_MPU_RAM DT_MEM_ARM(ATTR_MPU_RAM) +#define DT_MEM_ARM_MPU_RAM_NOCACHE DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) +#define DT_MEM_ARM_MPU_FLASH DT_MEM_ARM(ATTR_MPU_FLASH) +#define DT_MEM_ARM_MPU_PPB DT_MEM_ARM(ATTR_MPU_PPB) +#define DT_MEM_ARM_MPU_IO DT_MEM_ARM(ATTR_MPU_IO) +#define DT_MEM_ARM_MPU_EXTMEM DT_MEM_ARM(ATTR_MPU_EXTMEM) +#define DT_MEM_ARM_MPU_UNKNOWN DT_MEM_ARCH_ATTR_UNKNOWN + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_ARM_H_ */ diff --git a/include/zephyr/dt-bindings/memory-attr/memory-attr-riscv.h b/include/zephyr/dt-bindings/memory-attr/memory-attr-riscv.h new file mode 100644 index 00000000000..c51cd010ef1 --- /dev/null +++ b/include/zephyr/dt-bindings/memory-attr/memory-attr-riscv.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_RISCV_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_RISCV_H_ + +#include +#include + +/* + * Architecture specific RISCV related attributes. + */ +#define DT_MEM_RISCV_MASK(x) ((x) & DT_MEM_ARCH_ATTR_MASK) +#define DT_MEM_RISCV(x) ((x) << DT_MEM_ARCH_ATTR_SHIFT) + +#define ATTR_RISCV_TYPE_MAIN BIT(0) +#define ATTR_RISCV_TYPE_IO BIT(1) +#define ATTR_RISCV_TYPE_EMPTY BIT(2) +#define ATTR_RISCV_AMO_SWAP BIT(3) +#define ATTR_RISCV_AMO_LOGICAL BIT(4) +#define ATTR_RISCV_AMO_ARITHMETIC BIT(5) +#define ATTR_RISCV_IO_IDEMPOTENT_READ BIT(6) +#define ATTR_RISCV_IO_IDEMPOTENT_WRITE BIT(7) + +#define DT_MEM_RISCV_TYPE_MAIN DT_MEM_RISCV(ATTR_RISCV_TYPE_MAIN) +#define DT_MEM_RISCV_TYPE_IO DT_MEM_RISCV(ATTR_RISCV_TYPE_IO) +#define DT_MEM_RISCV_TYPE_EMPTY DT_MEM_RISCV(ATTR_RISCV_TYPE_EMPTY) +#define DT_MEM_RISCV_AMO_SWAP DT_MEM_RISCV(ATTR_RISCV_AMO_SWAP) +#define DT_MEM_RISCV_AMO_LOGICAL DT_MEM_RISCV(ATTR_RISCV_AMO_LOGICAL) +#define DT_MEM_RISCV_AMO_ARITHMETIC DT_MEM_RISCV(ATTR_RISCV_AMO_ARITHMETIC) +#define DT_MEM_RISCV_IO_IDEMPOTENT_READ DT_MEM_RISCV(ATTR_RISCV_IO_IDEMPOTENT_READ) +#define DT_MEM_RISCV_IO_IDEMPOTENT_WRITE DT_MEM_RISCV(ATTR_RISCV_IO_IDEMPOTENT_WRITE) +#define DT_MEM_RISCV_UNKNOWN DT_MEM_ARCH_ATTR_UNKNOWN + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_RISCV_H_ */ diff --git a/include/zephyr/dt-bindings/memory-attr/memory-attr-xtensa.h b/include/zephyr/dt-bindings/memory-attr/memory-attr-xtensa.h new file mode 100644 index 00000000000..c845b071a6b --- /dev/null +++ b/include/zephyr/dt-bindings/memory-attr/memory-attr-xtensa.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_XTENSA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_XTENSA_H_ + +#include +#include + +/* + * Architecture specific Xtensa related attributes. + */ +#define DT_MEM_XTENSA_MASK(x) ((x) & DT_MEM_ARCH_ATTR_MASK) +#define DT_MEM_XTENSA(x) ((x) << DT_MEM_ARCH_ATTR_SHIFT) + +#define ATTR_XTENSA_INSTR_ROM BIT(0) +#define ATTR_XTENSA_INSTR_RAM BIT(1) +#define ATTR_XTENSA_DATA_ROM BIT(2) +#define ATTR_XTENSA_DATA_RAM BIT(3) +#define ATTR_XTENSA_XLMI BIT(4) + +#define DT_MEM_XTENSA_INSTR_ROM DT_MEM_XTENSA(ATTR_XTENSA_INSTR_ROM) +#define DT_MEM_XTENSA_INSTR_RAM DT_MEM_XTENSA(ATTR_XTENSA_INSTR_RAM) +#define DT_MEM_XTENSA_DATA_ROM DT_MEM_XTENSA(ATTR_XTENSA_DATA_ROM) +#define DT_MEM_XTENSA_DATA_RAM DT_MEM_XTENSA(ATTR_XTENSA_DATA_RAM) +#define DT_MEM_XTENSA_XLMI DT_MEM_XTENSA(ATTR_XTENSA_XLMI) +#define DT_MEM_XTENSA_UNKNOWN DT_MEM_ARCH_ATTR_UNKNOWN + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_XTENSA_H_ */ diff --git a/include/zephyr/dt-bindings/memory-attr/memory-attr.h b/include/zephyr/dt-bindings/memory-attr/memory-attr.h new file mode 100644 index 00000000000..ea4ac04cafe --- /dev/null +++ b/include/zephyr/dt-bindings/memory-attr/memory-attr.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_H_ + +#include + +/* + * Generic memory attributes. + * + * Generic memory attributes that should be common to all architectures. + */ +#define DT_MEM_ATTR_MASK GENMASK(15, 0) +#define DT_MEM_ATTR_SHIFT (0) + +#define DT_MEM_CACHEABLE BIT(0) /* cacheable */ +#define DT_MEM_NON_VOLATILE BIT(1) /* non-volatile */ +#define DT_MEM_OOO BIT(2) /* out-of-order */ +#define DT_MEM_DMA BIT(3) /* DMA-able */ +#define DT_MEM_UNKNOWN BIT(15) /* must be last */ +/* to be continued */ + +/* + * Software specific memory attributes. + * + * Software can define their own memory attributes if needed using the + * provided mask. + */ +#define DT_MEM_SW_ATTR_MASK GENMASK(19, 16) +#define DT_MEM_SW_ATTR_SHIFT (16) +#define DT_MEM_SW_ATTR_UNKNOWN BIT(19) + +/* + * Architecture specific memory attributes. + * + * Architectures can define their own memory attributes if needed using the + * provided mask. + * + * See for example `include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h` + */ +#define DT_MEM_ARCH_ATTR_MASK GENMASK(31, 20) +#define DT_MEM_ARCH_ATTR_SHIFT (20) +#define DT_MEM_ARCH_ATTR_UNKNOWN BIT(31) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_H_ */ diff --git a/include/zephyr/mem_mgmt/mem_attr.h b/include/zephyr/mem_mgmt/mem_attr.h new file mode 100644 index 00000000000..a8da629c3e3 --- /dev/null +++ b/include/zephyr/mem_mgmt/mem_attr.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_MEM_ATTR_H_ +#define ZEPHYR_INCLUDE_MEM_ATTR_H_ + +/** + * @brief Memory-Attr Interface + * @defgroup memory_attr_interface Memory-Attr Interface + * @ingroup mem_mgmt + * @{ + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +#define __MEM_ATTR zephyr_memory_attr + +#define _FILTER(node_id, fn) \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, __MEM_ATTR), \ + (fn(node_id)), \ + ()) + +/** @endcond */ + +/** + * @brief Invokes @p fn for every status `okay` node in the tree with property + * `zephyr,memory-attr` + * + * The macro @p fn must take one parameter, which will be a node identifier + * with the `zephyr,memory-attr` property. The macro is expanded once for each + * node in the tree with status `okay`. The order that nodes are visited in is + * not specified. + * + * @param fn macro to invoke + */ +#define DT_MEMORY_ATTR_FOREACH_STATUS_OKAY_NODE(fn) \ + DT_FOREACH_STATUS_OKAY_NODE_VARGS(_FILTER, fn) + +/** + * @brief memory-attr region structure. + * + * This structure represents the data gathered from DT about a memory-region + * marked with memory attributes. + */ +struct mem_attr_region_t { + /** Memory node full name */ + const char *dt_name; + /** Memory region physical address */ + uintptr_t dt_addr; + /** Memory region size */ + size_t dt_size; + /** Memory region attributes */ + uint32_t dt_attr; +}; + +/** + * @brief Get the list of memory regions. + * + * Get the list of enabled memory regions with their memory-attribute as + * gathered by DT. + * + * @param region Pointer to pointer to the list of memory regions. + * + * @retval Number of memory regions returned in the parameter. + */ +size_t mem_attr_get_regions(const struct mem_attr_region_t **region); + +/** + * @brief Check if a buffer has correct size and attributes. + * + * This function is used to check if a given buffer with a given set of + * attributes fully match a memory region in terms of size and attributes. + * + * This is usually used to verify that a buffer has the expected attributes + * (for example the buffer is cacheable / non-cacheable or belongs to RAM / + * FLASH, etc...) and it has been correctly allocated. + * + * The expected set of attributes for the buffer is and-matched against the + * full set of attributes for the memory region it belongs to (bitmask). So the + * buffer is considered matching when at least that set of attributes are valid + * for the memory region (but the region can be marked also with other + * attributes besides the one passed as parameter). + * + * @param addr Virtual address of the user buffer. + * @param size Size of the user buffer. + * @param attr Expected / desired attribute for the buffer. + * + * @retval 0 if the buffer has the correct size and attribute. + * @retval -ENOSYS if the operation is not supported (for example if the MMU is enabled). + * @retval -ENOTSUP if the wrong parameters were passed. + * @retval -EINVAL if the buffer has the wrong set of attributes. + * @retval -ENOSPC if the buffer is too big for the region it belongs to. + * @retval -ENOBUFS if the buffer is entirely allocated outside a memory region. + */ +int mem_attr_check_buf(void *addr, size_t size, uint32_t attr); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_MEM_ATTR_H_ */ diff --git a/include/zephyr/multi_heap/shared_multi_heap.h b/include/zephyr/multi_heap/shared_multi_heap.h index 0d5e66bf293..a9cdf120fae 100644 --- a/include/zephyr/multi_heap/shared_multi_heap.h +++ b/include/zephyr/multi_heap/shared_multi_heap.h @@ -88,7 +88,7 @@ enum shared_multi_heap_attr { */ struct shared_multi_heap_region { /** Memory heap attribute */ - unsigned int attr; + uint32_t attr; /** Memory heap starting virtual address */ uintptr_t addr; diff --git a/samples/subsys/ipc/openamp/boards/mimxrt1160_evk_cm7.overlay b/samples/subsys/ipc/openamp/boards/mimxrt1160_evk_cm7.overlay index 52c68fd5339..7facea692cb 100644 --- a/samples/subsys/ipc/openamp/boards/mimxrt1160_evk_cm7.overlay +++ b/samples/subsys/ipc/openamp/boards/mimxrt1160_evk_cm7.overlay @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + / { chosen { zephyr,ipc_shm = &ocram2_overlay; @@ -17,6 +19,6 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x202c0000 DT_SIZE_K(16)>; zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; diff --git a/samples/subsys/ipc/openamp/boards/mimxrt1170_evk_cm7.overlay b/samples/subsys/ipc/openamp/boards/mimxrt1170_evk_cm7.overlay index 52c68fd5339..7facea692cb 100644 --- a/samples/subsys/ipc/openamp/boards/mimxrt1170_evk_cm7.overlay +++ b/samples/subsys/ipc/openamp/boards/mimxrt1170_evk_cm7.overlay @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + / { chosen { zephyr,ipc_shm = &ocram2_overlay; @@ -17,6 +19,6 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x202c0000 DT_SIZE_K(16)>; zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; diff --git a/samples/subsys/ipc/openamp/boards/mimxrt1170_evkb_cm7.overlay b/samples/subsys/ipc/openamp/boards/mimxrt1170_evkb_cm7.overlay index a5d921810bb..584538a14f7 100644 --- a/samples/subsys/ipc/openamp/boards/mimxrt1170_evkb_cm7.overlay +++ b/samples/subsys/ipc/openamp/boards/mimxrt1170_evkb_cm7.overlay @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + / { chosen { zephyr,ipc_shm = &ocram2_overlay; @@ -17,6 +19,6 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x202c0000 DT_SIZE_K(16)>; zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.overlay b/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.overlay index fa4d29c3cd1..32d5003bb19 100644 --- a/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.overlay +++ b/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.overlay @@ -33,7 +33,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x202c0000 DT_SIZE_K(16)>; zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay index fa4d29c3cd1..32d5003bb19 100644 --- a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay +++ b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay @@ -33,7 +33,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x202c0000 DT_SIZE_K(16)>; zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.overlay b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.overlay index f4ee15de7ed..72510d26166 100644 --- a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.overlay +++ b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.overlay @@ -33,7 +33,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x202c0000 DT_SIZE_K(16)>; zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = "IO"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; }; diff --git a/soc/arm/common/cortex_m/arm_mpu_regions.c b/soc/arm/common/cortex_m/arm_mpu_regions.c index 7eb3eb24f1d..6af62f84078 100644 --- a/soc/arm/common/cortex_m/arm_mpu_regions.c +++ b/soc/arm/common/cortex_m/arm_mpu_regions.c @@ -6,7 +6,6 @@ #include #include -#include #include @@ -29,9 +28,6 @@ static const struct arm_mpu_region mpu_regions[] = { #else REGION_RAM_ATTR(REGION_SRAM_SIZE)), #endif - - /* DT-defined regions */ - DT_MEMORY_ATTR_APPLY(ARM_MPU_REGION_INIT) }; const struct arm_mpu_config mpu_config = { diff --git a/soc/arm/nxp_imx/rt/mpu_regions.c b/soc/arm/nxp_imx/rt/mpu_regions.c index dae25354155..51ce490eff1 100644 --- a/soc/arm/nxp_imx/rt/mpu_regions.c +++ b/soc/arm/nxp_imx/rt/mpu_regions.c @@ -7,7 +7,6 @@ #define SDRAM_BASE_ADDR 0x80000000 #include -#include #include static const struct arm_mpu_region mpu_regions[] = { @@ -28,9 +27,6 @@ static const struct arm_mpu_region mpu_regions[] = { */ MPU_REGION_ENTRY("SDRAM0", SDRAM_BASE_ADDR, REGION_IO_ATTR(REGION_512M)), #endif - - /* DT-defined regions */ - DT_MEMORY_ATTR_APPLY(ARM_MPU_REGION_INIT) }; const struct arm_mpu_config mpu_config = { diff --git a/soc/arm/nxp_s32/s32k/mpu_regions.c b/soc/arm/nxp_s32/s32k/mpu_regions.c index 48078bde6bf..acd3ee9d916 100644 --- a/soc/arm/nxp_s32/s32k/mpu_regions.c +++ b/soc/arm/nxp_s32/s32k/mpu_regions.c @@ -35,9 +35,6 @@ static struct arm_mpu_region mpu_regions[] = { .attr = {(uint32_t)_rom_attr}, }, #endif - - /* DT-defined regions */ - DT_MEMORY_ATTR_APPLY(ARM_MPU_REGION_INIT) }; const struct arm_mpu_config mpu_config = { diff --git a/soc/arm/st_stm32/stm32h7/mpu_regions.c b/soc/arm/st_stm32/stm32h7/mpu_regions.c index 01daccdd01d..29825ad226a 100644 --- a/soc/arm/st_stm32/stm32h7/mpu_regions.c +++ b/soc/arm/st_stm32/stm32h7/mpu_regions.c @@ -38,9 +38,6 @@ static const struct arm_mpu_region mpu_regions[] = { REGION_PPB_ATTR(REGION_256B)), #endif #endif - - /* DT-defined regions */ - DT_MEMORY_ATTR_APPLY(ARM_MPU_REGION_INIT) }; const struct arm_mpu_config mpu_config = { diff --git a/soc/arm64/arm/fvp_aemv8r/arm_mpu_regions.c b/soc/arm64/arm/fvp_aemv8r/arm_mpu_regions.c index 65400c67269..a36f53d4193 100644 --- a/soc/arm64/arm/fvp_aemv8r/arm_mpu_regions.c +++ b/soc/arm64/arm/fvp_aemv8r/arm_mpu_regions.c @@ -7,7 +7,6 @@ #include #include -#include #include static const struct arm_mpu_region mpu_regions[] = { @@ -39,9 +38,6 @@ static const struct arm_mpu_region mpu_regions[] = { #endif (uintptr_t)__kernel_ram_end, REGION_RAM_ATTR), - - /* Extra regions defined in device tree */ - DT_MEMORY_ATTR_APPLY(MPU_REGION_ENTRY_FROM_DTS) }; const struct arm_mpu_config mpu_config = { diff --git a/subsys/CMakeLists.txt b/subsys/CMakeLists.txt index e4f155ef0e2..f72add5d914 100644 --- a/subsys/CMakeLists.txt +++ b/subsys/CMakeLists.txt @@ -17,6 +17,7 @@ add_subdirectory(fb) add_subdirectory(fs) add_subdirectory(ipc) add_subdirectory(logging) +add_subdirectory(mem_mgmt) add_subdirectory(mgmt) add_subdirectory(modbus) add_subdirectory(pm) diff --git a/subsys/Kconfig b/subsys/Kconfig index 322ce245729..7121dc586fe 100644 --- a/subsys/Kconfig +++ b/subsys/Kconfig @@ -22,6 +22,7 @@ source "subsys/ipc/Kconfig" source "subsys/jwt/Kconfig" source "subsys/logging/Kconfig" source "subsys/lorawan/Kconfig" +source "subsys/mem_mgmt/Kconfig" source "subsys/mgmt/Kconfig" source "subsys/modbus/Kconfig" source "subsys/modem/Kconfig" diff --git a/subsys/mem_mgmt/CMakeLists.txt b/subsys/mem_mgmt/CMakeLists.txt new file mode 100644 index 00000000000..62e61fb4d1f --- /dev/null +++ b/subsys/mem_mgmt/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources_ifdef(CONFIG_MEM_ATTR mem_attr.c) diff --git a/subsys/mem_mgmt/Kconfig b/subsys/mem_mgmt/Kconfig new file mode 100644 index 00000000000..dda1a404167 --- /dev/null +++ b/subsys/mem_mgmt/Kconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Carlo Caione +# SPDX-License-Identifier: Apache-2.0 + +config MEM_ATTR + bool "Memory Attributes management library" + default y if ARM_MPU + help + Enable a small library to manage the memory regions defined in the DT + with a `zephyr,memory-attr` property. This library builds at build + time an array of the memory regions defined in the DT that can be + probed at run-time using several helper functions. Set to `N` if + unsure to save RODATA space. diff --git a/subsys/mem_mgmt/mem_attr.c b/subsys/mem_mgmt/mem_attr.c new file mode 100644 index 00000000000..c70a515dd81 --- /dev/null +++ b/subsys/mem_mgmt/mem_attr.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Carlo Caione, + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define _BUILD_MEM_ATTR_REGION(node_id) \ + { \ + .dt_name = DT_NODE_FULL_NAME(node_id), \ + .dt_addr = DT_REG_ADDR(node_id), \ + .dt_size = DT_REG_SIZE(node_id), \ + .dt_attr = DT_PROP(node_id, zephyr_memory_attr), \ + }, + +static const struct mem_attr_region_t mem_attr_region[] = { + DT_MEMORY_ATTR_FOREACH_STATUS_OKAY_NODE(_BUILD_MEM_ATTR_REGION) +}; + +size_t mem_attr_get_regions(const struct mem_attr_region_t **region) +{ + *region = mem_attr_region; + + return ARRAY_SIZE(mem_attr_region); +} + +int mem_attr_check_buf(void *v_addr, size_t size, uint32_t attr) +{ + uintptr_t addr = (uintptr_t) v_addr; + + /* + * If MMU is enabled the address of the buffer is a virtual address + * while the addresses in the DT are physical addresses. Given that we + * have no way of knowing whether a mapping exists, we simply bail out. + */ + if (IS_ENABLED(CONFIG_MMU)) { + return -ENOSYS; + } + + if (size == 0) { + return -ENOTSUP; + } + + for (size_t idx = 0; idx < ARRAY_SIZE(mem_attr_region); idx++) { + const struct mem_attr_region_t *region = &mem_attr_region[idx]; + size_t region_end = region->dt_addr + region->dt_size; + + /* Check if the buffer is in the region */ + if ((addr >= region->dt_addr) && (addr < region_end)) { + /* Check if the buffer is entirely contained in the region */ + if ((addr + size) <= region_end) { + /* check if the attribute is correct */ + return (region->dt_attr & attr) == attr ? 0 : -EINVAL; + } + return -ENOSPC; + } + } + return -ENOBUFS; +} diff --git a/tests/arch/arm/arm_mpu_regions/CMakeLists.txt b/tests/arch/arm/arm_mpu_regions/CMakeLists.txt deleted file mode 100644 index b847ef0b65d..00000000000 --- a/tests/arch/arm/arm_mpu_regions/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(arm_mpu_regions) - -target_sources(app PRIVATE src/main.c) diff --git a/tests/arch/arm/arm_mpu_regions/boards/mps2_an385.overlay b/tests/arch/arm/arm_mpu_regions/boards/mps2_an385.overlay deleted file mode 100644 index 4c9f1a5d5a8..00000000000 --- a/tests/arch/arm/arm_mpu_regions/boards/mps2_an385.overlay +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2021 Carlo Caione - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - /delete-node/ memory@20000000; - - sram0: memory@20000000 { - compatible = "mmio-sram"; - reg = <0x20000000 0x200000>; - }; - - sram_cache: memory@20200000 { - compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x20200000 0x100000>; - zephyr,memory-region = "SRAM_CACHE"; - zephyr,memory-attr = "RAM"; - }; - - sram_no_cache: memory@20300000 { - compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x20300000 0x100000>; - zephyr,memory-region = "SRAM_NO_CACHE"; - zephyr,memory-attr = "RAM_NOCACHE"; - }; - - sram_dtcm_fake: memory@abcdabcd { - compatible = "zephyr,memory-region", "arm,dtcm"; - reg = <0xabcdabcd 0x100000>; - zephyr,memory-region = "SRAM_DTCM_FAKE"; - zephyr,memory-attr = "RAM"; - }; - - sram_no_mpu: memory@deaddead { - compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0xdeaddead 0x100000>; - zephyr,memory-region = "SRAM_NO_MPU"; - }; -}; diff --git a/tests/arch/arm/arm_mpu_regions/src/main.c b/tests/arch/arm/arm_mpu_regions/src/main.c deleted file mode 100644 index 72df578f2c0..00000000000 --- a/tests/arch/arm/arm_mpu_regions/src/main.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2021 Carlo Caione - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include - -extern const struct arm_mpu_config mpu_config; - -static arm_mpu_region_attr_t cacheable = REGION_RAM_ATTR(REGION_1M); -static arm_mpu_region_attr_t noncacheable = REGION_RAM_NOCACHE_ATTR(REGION_1M); - -ZTEST(test_c_arm_mpu_regions, test_regions) -{ - int cnt = 0; - - for (size_t i = 0; i < mpu_config.num_regions; i++) { - const struct arm_mpu_region *r = &mpu_config.mpu_regions[i]; - - if (!strcmp(r->name, "SRAM_CACHE")) { - zassert_equal(r->base, 0x20200000, "Wrong base"); - zassert_equal(r->attr.rasr, cacheable.rasr, - "Wrong attr for SRAM_CACHE"); - cnt++; - } else if (!strcmp(r->name, "SRAM_NO_CACHE")) { - zassert_equal(r->base, 0x20300000, "Wrong base"); - zassert_equal(r->attr.rasr, noncacheable.rasr, - "Wrong attr for SRAM_NO_CACHE"); - cnt++; - } else if (!strcmp(r->name, "SRAM_DTCM_FAKE")) { - zassert_equal(r->base, 0xabcdabcd, "Wrong base"); - zassert_equal(r->attr.rasr, cacheable.rasr, - "Wrong attr for SRAM_DTCM_FAKE"); - cnt++; - } - } - - if (cnt != 3) { - /* - * SRAM0 and SRAM_NO_MPU should not create any MPU region. - * Check that. - */ - ztest_test_fail(); - } -} - -ZTEST_SUITE(test_c_arm_mpu_regions, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/arch/arm/arm_mpu_regions/testcase.yaml b/tests/arch/arm/arm_mpu_regions/testcase.yaml deleted file mode 100644 index b04c2689137..00000000000 --- a/tests/arch/arm/arm_mpu_regions/testcase.yaml +++ /dev/null @@ -1,6 +0,0 @@ -tests: - arch.mpu_regions.arm: - platform_allow: mps2_an385 - tags: - - sram - - mpu diff --git a/tests/drivers/adc/adc_dma/boards/nucleo_h743zi.overlay b/tests/drivers/adc/adc_dma/boards/nucleo_h743zi.overlay index 22590af7af4..fdedd2a4635 100644 --- a/tests/drivers/adc/adc_dma/boards/nucleo_h743zi.overlay +++ b/tests/drivers/adc/adc_dma/boards/nucleo_h743zi.overlay @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include + &adc1 { dmas = < &dmamux1 0 9 (STM32_DMA_PERIPH_TO_MEMORY | STM32_DMA_MEM_INC | STM32_DMA_MEM_16BITS | STM32_DMA_PERIPH_16BITS) >; @@ -22,7 +25,7 @@ /* ADC driver expects a buffer in a non-cachable memory region */ &sram4 { - zephyr,memory-attr = "RAM_NOCACHE"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; }; &dma1 { diff --git a/tests/drivers/dma/chan_blen_transfer/boards/nucleo_h743zi.overlay b/tests/drivers/dma/chan_blen_transfer/boards/nucleo_h743zi.overlay index 20c8062f325..35e5f3935d3 100644 --- a/tests/drivers/dma/chan_blen_transfer/boards/nucleo_h743zi.overlay +++ b/tests/drivers/dma/chan_blen_transfer/boards/nucleo_h743zi.overlay @@ -2,6 +2,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + &dma1 { status = "okay"; }; @@ -18,7 +20,7 @@ test_dma0: &dmamux1 { * to be non-cachable. */ &sram4 { - zephyr,memory-attr = "RAM_NOCACHE"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; }; &bdma1 { diff --git a/tests/drivers/dma/loop_transfer/boards/nucleo_h743zi.overlay b/tests/drivers/dma/loop_transfer/boards/nucleo_h743zi.overlay index 20c8062f325..eb94644f3f3 100644 --- a/tests/drivers/dma/loop_transfer/boards/nucleo_h743zi.overlay +++ b/tests/drivers/dma/loop_transfer/boards/nucleo_h743zi.overlay @@ -18,7 +18,7 @@ test_dma0: &dmamux1 { * to be non-cachable. */ &sram4 { - zephyr,memory-attr = "RAM_NOCACHE"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; }; &bdma1 { diff --git a/tests/kernel/mem_heap/shared_multi_heap/boards/mps2_an521.overlay b/tests/kernel/mem_heap/shared_multi_heap/boards/mps2_an521.overlay index c52183dfe81..fca88ad07fd 100644 --- a/tests/kernel/mem_heap/shared_multi_heap/boards/mps2_an521.overlay +++ b/tests/kernel/mem_heap/shared_multi_heap/boards/mps2_an521.overlay @@ -4,6 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include +#include + / { /delete-node/ memory@38000000; @@ -17,20 +20,20 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x38100000 0x1000>; zephyr,memory-region = "RES0"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; res1: memory@38200000 { compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x38200000 0x2000>; zephyr,memory-region = "RES1"; - zephyr,memory-attr = "RAM_NOCACHE"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; }; res2: memory@38300000 { compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x38300000 0x3000>; zephyr,memory-region = "RES2"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; }; diff --git a/tests/kernel/mem_heap/shared_multi_heap/boards/qemu_cortex_a53.overlay b/tests/kernel/mem_heap/shared_multi_heap/boards/qemu_cortex_a53.overlay index a4ec256ad17..e00b217a8eb 100644 --- a/tests/kernel/mem_heap/shared_multi_heap/boards/qemu_cortex_a53.overlay +++ b/tests/kernel/mem_heap/shared_multi_heap/boards/qemu_cortex_a53.overlay @@ -4,20 +4,23 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include +#include + / { soc { res0: memory@42000000 { compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x0 0x42000000 0x0 0x1000>; zephyr,memory-region = "RES0"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; res1: memory@43000000 { compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x0 0x43000000 0x0 0x2000>; zephyr,memory-region = "RES1"; - zephyr,memory-attr = "RAM_NOCACHE"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; }; res_no_mpu: memory@45000000 { @@ -30,7 +33,7 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x0 0x44000000 0x0 0x3000>; zephyr,memory-region = "RES2"; - zephyr,memory-attr = "RAM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; }; }; diff --git a/tests/kernel/mem_heap/shared_multi_heap/src/main.c b/tests/kernel/mem_heap/shared_multi_heap/src/main.c index d2169f9164a..ae324d10b22 100644 --- a/tests/kernel/mem_heap/shared_multi_heap/src/main.c +++ b/tests/kernel/mem_heap/shared_multi_heap/src/main.c @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -22,14 +23,14 @@ struct region_map { uintptr_t p_addr; }; -#define FOREACH_REG(n) \ - { \ - .region = { \ - .addr = (uintptr_t) DT_INST_REG_ADDR(n), \ - .size = DT_INST_REG_SIZE(n), \ - .attr = DT_INST_ENUM_IDX_OR(n, zephyr_memory_attr, \ - SMH_REG_ATTR_NUM), \ - }, \ +#define FOREACH_REG(n) \ + { \ + .region = { \ + .addr = (uintptr_t) DT_INST_REG_ADDR(n), \ + .size = DT_INST_REG_SIZE(n), \ + .attr = DT_INST_PROP_OR(n, zephyr_memory_attr, \ + DT_MEM_ARM_MPU_UNKNOWN), \ + }, \ }, struct region_map map[] = { @@ -66,7 +67,7 @@ static struct region_map *get_region_map(void *v_addr) return NULL; } -static inline enum shared_multi_heap_attr mpu_to_reg_attr(int mpu_attr) +static inline enum shared_multi_heap_attr mpu_to_reg_attr(uint32_t dt_attr) { /* * All the memory regions defined in the DT with the MPU property `RAM` @@ -82,10 +83,10 @@ static inline enum shared_multi_heap_attr mpu_to_reg_attr(int mpu_attr) * RAM -> SMH_REG_ATTR_CACHEABLE * RAM_NOCACHE -> SMH_REG_ATTR_NON_CACHEABLE */ - switch (mpu_attr) { - case 0: /* RAM */ + switch (DT_MEM_ARM_MASK(dt_attr)) { + case DT_MEM_ARM_MPU_RAM: return SMH_REG_ATTR_CACHEABLE; - case 1: /* RAM_NOCACHE */ + case DT_MEM_ARM_MPU_RAM_NOCACHE: return SMH_REG_ATTR_NON_CACHEABLE; default: /* How ? */ @@ -104,7 +105,7 @@ static void fill_multi_heap(void) reg_map = &map[idx]; /* zephyr,memory-attr property not found. Skip it. */ - if (reg_map->region.attr == SMH_REG_ATTR_NUM) { + if (reg_map->region.attr == DT_MEM_ARM_MPU_UNKNOWN) { continue; } diff --git a/tests/lib/devicetree/api/app.overlay b/tests/lib/devicetree/api/app.overlay index 508d84b39b4..2a5f4bd5135 100644 --- a/tests/lib/devicetree/api/app.overlay +++ b/tests/lib/devicetree/api/app.overlay @@ -645,18 +645,6 @@ val = "XA XPLUS XB", "XC XPLUS XD", "XA XMINUS XB", "XC XMINUS XD"; }; - test_mem_ram: memory@aabbccdd { - compatible = "vnd,memory-attr"; - reg = < 0xaabbccdd 0x4000 >; - zephyr,memory-attr = "RAM"; - }; - - test_mem_ram_nocache: memory@44332211 { - compatible = "vnd,memory-attr"; - reg = < 0x44332211 0x2000 >; - zephyr,memory-attr = "RAM_NOCACHE"; - }; - test-mtd@ffeeddcc { reg = < 0x0 0x1000 >; #address-cells = < 1 >; diff --git a/tests/lib/devicetree/api/src/main.c b/tests/lib/devicetree/api/src/main.c index aec48e6a9c9..255357e85e8 100644 --- a/tests/lib/devicetree/api/src/main.c +++ b/tests/lib/devicetree/api/src/main.c @@ -2717,70 +2717,6 @@ ZTEST(devicetree_api, test_mbox) DT_NODELABEL(test_mbox_zero_cell)), ""); } -ZTEST(devicetree_api, test_memory_attr) -{ - #define REGION_RAM_ATTR (0xDEDE) - #define REGION_RAM_NOCACHE_ATTR (0xCACA) - - #define TEST_FUNC(p_name, p_base, p_size, p_attr) \ - { .name = (p_name), \ - .base = (p_base), \ - .size = (p_size), \ - .attr = (p_attr), \ - } - - struct vnd_memory_binding { - char *name; - uintptr_t base; - size_t size; - unsigned int attr; - }; - - struct vnd_memory_binding val_apply[] = { - DT_MEMORY_ATTR_APPLY(TEST_FUNC) - }; - - zassert_true(!strcmp(val_apply[0].name, "memory@aabbccdd"), ""); - zassert_equal(val_apply[0].base, 0xaabbccdd, ""); - zassert_equal(val_apply[0].size, 0x4000, ""); - zassert_equal(val_apply[0].attr, 0xDEDE, ""); - - zassert_true(!strcmp(val_apply[1].name, "memory@44332211"), ""); - zassert_equal(val_apply[1].base, 0x44332211, ""); - zassert_equal(val_apply[1].size, 0x2000, ""); - zassert_equal(val_apply[1].attr, 0xCACA, ""); - - #undef TEST_FUNC - #undef REGION_RAM_ATTR - #undef REGION_RAM_NOCACHE_ATTR - - #define TEST_FUNC(node_id) DT_NODE_FULL_NAME(node_id), - - static const char * const val_func[] = { - DT_MEMORY_ATTR_FOREACH_NODE(TEST_FUNC) - }; - - zassert_true(!strcmp(val_func[0], "memory@aabbccdd"), ""); - zassert_true(!strcmp(val_func[1], "memory@44332211"), ""); - - #undef TEST_FUNC - - #define TEST_FUNC(node_id) \ - COND_CODE_1(DT_ENUM_HAS_VALUE(node_id, \ - zephyr_memory_attr, \ - RAM_NOCACHE), \ - (DT_REG_ADDR(node_id)), \ - ()) - - uintptr_t val_filt[] = { - DT_MEMORY_ATTR_FOREACH_NODE(TEST_FUNC) - }; - - zassert_equal(val_filt[0], 0x44332211, ""); - - #undef TEST_FUNC -} - ZTEST(devicetree_api, test_fixed_partitions) { /* Test finding fixed partitions by the 'label' property. */ diff --git a/tests/subsys/mem_mgmt/mem_attr/CMakeLists.txt b/tests/subsys/mem_mgmt/mem_attr/CMakeLists.txt new file mode 100644 index 00000000000..7b1f9a77f89 --- /dev/null +++ b/tests/subsys/mem_mgmt/mem_attr/CMakeLists.txt @@ -0,0 +1,8 @@ +#SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(test_mem_attr) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/subsys/mem_mgmt/mem_attr/app.overlay b/tests/subsys/mem_mgmt/mem_attr/app.overlay new file mode 100644 index 00000000000..26773fe2345 --- /dev/null +++ b/tests/subsys/mem_mgmt/mem_attr/app.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Carlo Caione + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + mem_ram: memory@10000000 { + compatible = "vnd,memory-attr"; + reg = <0x10000000 0x1000>; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_FLASH) | DT_MEM_NON_VOLATILE )>; + }; + + mem_ram_nocache: memory@20000000 { + compatible = "vnd,memory-attr"; + reg = <0x20000000 0x2000>; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; + }; + + mem_ram_disabled: memory@30000000 { + compatible = "vnd,memory-attr"; + reg = <0x30000000 0x3000>; + zephyr,memory-attr = <( DT_MEM_CACHEABLE | DT_MEM_OOO )>; + status = "disabled"; + }; +}; diff --git a/tests/arch/arm/arm_mpu_regions/prj.conf b/tests/subsys/mem_mgmt/mem_attr/prj.conf similarity index 67% rename from tests/arch/arm/arm_mpu_regions/prj.conf rename to tests/subsys/mem_mgmt/mem_attr/prj.conf index 9228251051e..2fcddad0bc8 100644 --- a/tests/arch/arm/arm_mpu_regions/prj.conf +++ b/tests/subsys/mem_mgmt/mem_attr/prj.conf @@ -1,2 +1,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y +CONFIG_MEM_ATTR=y diff --git a/tests/subsys/mem_mgmt/mem_attr/src/main.c b/tests/subsys/mem_mgmt/mem_attr/src/main.c new file mode 100644 index 00000000000..a05ea6dab20 --- /dev/null +++ b/tests/subsys/mem_mgmt/mem_attr/src/main.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2023 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +ZTEST(mem_attr, test_mem_attr) +{ + const struct mem_attr_region_t *region; + size_t num_regions; + + num_regions = mem_attr_get_regions(®ion); + zassert_equal(num_regions, 2, "No regions returned"); + + /* + * Check the data in the regions + */ + for (size_t idx = 0; idx < num_regions; idx++) { + if (region[idx].dt_size == 0x1000) { + zassert_equal(region[idx].dt_addr, 0x10000000, "Wrong region address"); + zassert_equal(region[idx].dt_size, 0x1000, "Wrong region size"); + zassert_equal(region[idx].dt_attr, DT_MEM_ARM_MPU_FLASH | + DT_MEM_NON_VOLATILE, + "Wrong region address"); + zassert_true((strcmp(region[idx].dt_name, "memory@10000000") == 0), + "Wrong name"); + } else { + zassert_equal(region[idx].dt_addr, 0x20000000, "Wrong region address"); + zassert_equal(region[idx].dt_size, 0x2000, "Wrong region size"); + zassert_equal(region[idx].dt_attr, DT_MEM_ARM_MPU_RAM_NOCACHE, + "Wrong region address"); + zassert_true((strcmp(region[idx].dt_name, "memory@20000000") == 0), + "Wrong name"); + } + } + + /* + * Check the input sanitization + */ + zassert_equal(mem_attr_check_buf((void *) 0x10000000, 0x0, DT_MEM_NON_VOLATILE), + -ENOTSUP, "Unexpected return value"); + + /* + * Check a buffer with the correct properties + */ + zassert_equal(mem_attr_check_buf((void *) 0x10000100, 0x100, + DT_MEM_ARM_MPU_FLASH | DT_MEM_NON_VOLATILE), + 0, "Unexpected return value"); + zassert_equal(mem_attr_check_buf((void *) 0x20000000, 0x2000, DT_MEM_ARM_MPU_RAM_NOCACHE), + 0, "Unexpected return value"); + + /* + * Check partial attributes + */ + zassert_equal(mem_attr_check_buf((void *) 0x10000100, 0x100, DT_MEM_NON_VOLATILE), + 0, "Unexpected return value"); + + /* + * Check a buffer with the wrong attribute + */ + zassert_equal(mem_attr_check_buf((void *) 0x20000000, 0x2000, DT_MEM_OOO), + -EINVAL, "Unexpected return value"); + + /* + * Check a buffer outsize the regions + */ + zassert_equal(mem_attr_check_buf((void *) 0x40000000, 0x1000, DT_MEM_NON_VOLATILE), + -ENOBUFS, "Unexpected return value"); + + /* + * Check a buffer too big for the region + */ + zassert_equal(mem_attr_check_buf((void *) 0x10000000, 0x2000, DT_MEM_NON_VOLATILE), + -ENOSPC, "Unexpected return value"); + + /* + * Check a buffer in a disabled region + */ + zassert_equal(mem_attr_check_buf((void *) 0x30000000, 0x1000, DT_MEM_OOO), + -ENOBUFS, "Unexpected return value"); +} + +ZTEST_SUITE(mem_attr, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/subsys/mem_mgmt/mem_attr/testcase.yaml b/tests/subsys/mem_mgmt/mem_attr/testcase.yaml new file mode 100644 index 00000000000..ecb445a077e --- /dev/null +++ b/tests/subsys/mem_mgmt/mem_attr/testcase.yaml @@ -0,0 +1,8 @@ +common: + platform_allow: + - native_posix + - native_posix_64 + integration_platforms: + - native_posix +tests: + mem_mgmt.mem_attr.default: {}