Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,14 @@ config NOCACHE_MEMORY
transfers when cache coherence issues are not optimal or can not
be solved using cache maintenance operations.

DT_CHOSEN_Z_NOCACHE_SRAM := zephyr,sram-no-cache

config NOCACHE_SRAM_MEMORY_DEV_NAME
string "non-cacheable SRAM region"
default "$(dt_chosen_label,$(DT_CHOSEN_Z_NOCACHE_SRAM))" if HAS_DTS
help
Memory region used as non-cacheable memory pool.

menu "Interrupt Configuration"

config DYNAMIC_INTERRUPTS
Expand Down
4 changes: 4 additions & 0 deletions dts/bindings/sram/mmio-sram.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ properties:

label:
required: false

mpu-attr:
required: false
type: int
59 changes: 59 additions & 0 deletions include/linker/devicetree_sram.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2021, Carlo Caione <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

#define DT_DRV_COMPAT mmio_sram

#define _DT_SRAM_INST_NAME(inst) DT_STRING_TOKEN(DT_DRV_INST(inst), label)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of the label property for region naming was already discussed and rejected in #36365


#define DT_INST_SRAM_PREFIX(inst) UTIL_CAT(__, _DT_SRAM_INST_NAME(inst))
#define DT_INST_SRAM_START(inst) UTIL_CAT(DT_INST_SRAM_PREFIX(inst), _start)
#define DT_INST_SRAM_END(inst) UTIL_CAT(DT_INST_SRAM_PREFIX(inst), _end)

#define _DEFINE_SRAM_REGION(inst, ...) \
_DT_SRAM_INST_NAME(inst) : \
ORIGIN = DT_INST_REG_ADDR(inst), \
LENGTH = DT_INST_REG_SIZE(inst)

#define _DEFINE_SRAM_SECTION(inst, ...) \
SECTION_DATA_PROLOGUE(_DT_SRAM_INST_NAME(inst), (NOLOAD),) \
{ \
DT_INST_SRAM_START(inst) = .; \
KEEP(*(_DT_SRAM_INST_NAME(inst))) \
KEEP(*(_DT_SRAM_INST_NAME(inst).*)) \
DT_INST_SRAM_END(inst) = \
DT_INST_SRAM_START(inst) + DT_INST_REG_SIZE(inst); \
} GROUP_DATA_LINK_IN(_DT_SRAM_INST_NAME(inst), _DT_SRAM_INST_NAME(inst))

#define _CHECK_ATTR_FN(inst, FN, ...) \
COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, mpu_attr), \
(FN(inst, __VA_ARGS__)), \
())

#define _EXPAND_MPU_FN(inst, FN, ...) \
FN(DT_INST_PROP(inst, label), \
DT_INST_REG_ADDR(inst), \
DT_INST_REG_SIZE(inst), \
DT_INST_PROP(inst, mpu_attr))

#define _CHECK_APPLY_FN(FN, ...) \
DT_INST_FOREACH_STATUS_OKAY_VARGS(_CHECK_ATTR_FN, FN, __VA_ARGS__)


/* Add the SRAM sections to the linker script */
#define LINKER_DT_SRAM_SECTIONS() _CHECK_APPLY_FN(_DEFINE_SRAM_SECTION)

/* Add the SRAM regions to the linker script */
#define LINKER_DT_SRAM_REGIONS() _CHECK_APPLY_FN(_DEFINE_SRAM_REGION)

/*
* Helper macro to apply an MPU_FN macro to all the SRAM regions declared with
* an 'mpu-attr' property.
*
* MPU_FN must take the form:
*
* #define MPU_FN(name, base, size, attr) ...
*/
#define DT_SRAM_INST_FOREACH(MPU_FN) _CHECK_APPLY_FN(_EXPAND_MPU_FN, MPU_FN)
7 changes: 7 additions & 0 deletions include/linker/section_tags.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@
#define __nocache
#endif /* CONFIG_NOCACHE_MEMORY */

#if defined(CONFIG_NOCACHE_SRAM_MEMORY_DEV_NAME)
/* Do not use Z_GENERIC_SECTION */
#define __nocache_sram __attribute((__section__(CONFIG_NOCACHE_SRAM_MEMORY_DEV_NAME)))
#else
#define __nocache_sram
#endif /* CONFIG_NOCACHE_SRAM_MEMORY_DEV_NAME */

#if defined(CONFIG_KERNEL_COHERENCE)
#define __incoherent __in_section_unique(cached)
#define __stackmem __incoherent
Expand Down
4 changes: 4 additions & 0 deletions include/linker/sections.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
#define _NOCACHE_SECTION_NAME nocache
#endif

#ifdef CONFIG_NOCACHE_SRAM_MEMORY_DEV_NAME
#define _NOCACHE_SRAM_SECTION_NAME CONFIG_NOCACHE_SRAM_MEMORY_DEV_NAME
#endif

#if defined(CONFIG_LINKER_USE_BOOT_SECTION)
#define BOOT_TEXT_SECTION_NAME boot_text
#define BOOT_BSS_SECTION_NAME boot_bss
Expand Down
8 changes: 8 additions & 0 deletions samples/memory/sram_regions/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3.20 should be enough here. I think.


find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(sram_mpu)

target_sources(app PRIVATE src/main.c src/arm_mpu_regions.c)
47 changes: 47 additions & 0 deletions samples/memory/sram_regions/boards/dt_mpu_attr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 Carlo Caione <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifdef __DTS__

#define DT_256B (0x07U)
#define DT_512B (0x08U)
#define DT_1KB (0x09U)
#define DT_2KB (0x0aU)
#define DT_4KB (0x0bU)
#define DT_8KB (0x0cU)
#define DT_16KB (0x0dU)
#define DT_32KB (0x0eU)
#define DT_64KB (0x0fU)
#define DT_128KB (0x10U)
#define DT_256KB (0x11U)
#define DT_512KB (0x12U)
#define DT_1MB (0x13U)
#define DT_2MB (0x14U)
#define DT_4MB (0x15U)
#define DT_8MB (0x16U)
#define DT_16MB (0x17U)
#define DT_32MB (0x18U)
#define DT_64MB (0x19U)
#define DT_128MB (0x1aU)
#define DT_256MB (0x1bU)
#define DT_512MB (0x1cU)
#define DT_1GB (0x1dU)
#define DT_2GB (0x1eU)
#define DT_4GB (0x1fU)

/*
* NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE |
* MPU_RASR_XN_Msk | P_RW_U_NA_Msk
*/
#define DT_SRAM_ATTR(size) (0x110b0000 | size)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#define DT_SRAM_ATTR(size) ((MPU_RASR_XN_Msk | P_RW_U_NA_Msk) | size)

Wouldn't be it better to use mask defines with corresponding values?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes but it's not easy. A lot of things in the .h files where the masks are defined doesn't get along well with DT, so you cannot just include the .h files into the DTS file. I tried to fix the header files where the masks are defined to be more compatible with DT but I gave up after a while and I just decided to go this way.


/*
* NORMAL_OUTER_INNER_NON_CACHEABLE_NON_SHAREABLE |
* MPU_RASR_XN_Msk | P_RW_U_NA_Msk
*/
#define DT_SRAM_NOCACHE_ATTR(size) (0x11080000 | size)

#endif /* __DTS__ */
34 changes: 34 additions & 0 deletions samples/memory/sram_regions/boards/mps2_an385.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2021 Carlo Caione <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "dt_mpu_attr.h"

/ {
/delete-node/ memory@20000000;

chosen {
zephyr,sram-no-cache = &sram_no_cache;
};

sram0: memory@20000000 {
compatible = "mmio-sram";
reg = <0x20000000 0x200000>;
};

sram_attr_0: memory@20200000 {
compatible = "mmio-sram";
reg = <0x20200000 0x100000>;
mpu-attr = <DT_SRAM_ATTR(DT_1MB)>;
Copy link
Contributor

@KozhinovAlexander KozhinovAlexander Nov 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks for me that dt_mpu_attr.h header belongs somewhere else but not into samples directory or am I missing something?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. This is a POC so I wanted to keep everything in one place.

label = "region0";
};

sram_no_cache: memory@20300000 {
compatible = "mmio-sram";
reg = <0x20300000 0x100000>;
mpu-attr = <DT_SRAM_NOCACHE_ATTR(DT_1MB)>;
label = "region1";
};
};
26 changes: 26 additions & 0 deletions samples/memory/sram_regions/linker_sram_regions.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) Carlo Caione <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <autoconf.h>
#include <linker/sections.h>
#include <devicetree.h>

#include <linker/linker-defs.h>
#include <linker/linker-tool.h>

#include <linker/devicetree_sram.h>

MEMORY
{
LINKER_DT_SRAM_REGIONS()
}

SECTIONS
{
LINKER_DT_SRAM_SECTIONS()
}

#include <arch/arm/aarch32/cortex_m/scripts/linker.ld>
3 changes: 3 additions & 0 deletions samples/memory/sram_regions/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS=y
CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y
CONFIG_CUSTOM_LINKER_SCRIPT="linker_sram_regions.ld"
8 changes: 8 additions & 0 deletions samples/memory/sram_regions/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
sample:
description: SRAM MPU sample application
name: sram_mpu
tests:
sample.memory.sram_regions:
platform_allow: mps2_an385
tags: sample board sram mpu
build_only: true
35 changes: 35 additions & 0 deletions samples/memory/sram_regions/src/arm_mpu_regions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2021 Carlo Caione <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <sys/slist.h>
#include <arch/arm/aarch32/mpu/arm_mpu.h>
#include <linker/devicetree_sram.h>

#define BUILD_MPU_REGION(p_name, p_base, p_size, p_attr) \
{ .name = p_name, \
.base = p_base, \
.attr.rasr = p_attr, \
},

static const struct arm_mpu_region mpu_regions[] = {
/* FLASH */
MPU_REGION_ENTRY("FLASH_0",
CONFIG_FLASH_BASE_ADDRESS,
REGION_FLASH_ATTR(REGION_4M)),

/* SRAM0 */
MPU_REGION_ENTRY("SRAM_0",
CONFIG_SRAM_BASE_ADDRESS,
REGION_RAM_ATTR(REGION_2M)),

/* Generated SRAM regions */
DT_SRAM_INST_FOREACH(BUILD_MPU_REGION)
};

const struct arm_mpu_config mpu_config = {
.num_regions = ARRAY_SIZE(mpu_regions),
.mpu_regions = mpu_regions,
};
22 changes: 22 additions & 0 deletions samples/memory/sram_regions/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2021 Carlo Caione <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr.h>
#include <linker/linker-defs.h>
#include <linker/devicetree_sram.h>

uint32_t var_in_region0 __attribute((__section__("region0"))) = 0xaabbccdd;
uint32_t var_in_region1 __attribute((__section__("region1"))) = 0xddccbbaa;

uint32_t buf_in_nocache[0xA] __nocache_sram;

void main(void)
{
printk("Address of var_in_region0: %p\n", &var_in_region0);
printk("Address of var_in_region1: %p\n", &var_in_region1);

printk("Address of buf_in_nocache: %p\n", buf_in_nocache);
}