soc: enable noncacheable OCRAM region for nxp iMX.RT

OCRAM can be used for DMA, and in this case it should be marked as
noncacheable. Add KConfig symbol and appropriate linker scripts to
enable OCRAM region to be defined as noncacheable, and initialized with
data from flash at boot.

Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
This commit is contained in:
Daniel DeGrasse 2022-03-16 12:14:00 -05:00 committed by Carles Cufí
commit da40ffb4a8
8 changed files with 137 additions and 0 deletions

View file

@ -23,6 +23,7 @@
#address-cells = <1>;
#size-cells = <1>;
d-cache-line-size = <32>;
mpu: mpu@e000ed90 {
compatible = "arm,armv7m-mpu";
@ -34,6 +35,7 @@
device_type = "cpu";
compatible = "arm,cortex-m4f";
reg = <1>;
d-cache-line-size = <32>;
#address-cells = <1>;
#size-cells = <1>;

View file

@ -9,6 +9,10 @@ zephyr_sources_ifdef(CONFIG_SOC_SERIES_IMX_RT10XX soc_rt10xx.c)
zephyr_linker_sources_ifdef(CONFIG_NXP_IMX_RT_BOOT_HEADER
ROM_START SORT_KEY 0 boot_header.ld)
# Enable custom OCRAM noncacheable region
zephyr_linker_sources_ifdef(CONFIG_OCRAM_NOCACHE SECTIONS sections.ld)
zephyr_sources_ifdef(CONFIG_OCRAM_NOCACHE mpu_regions.c)
zephyr_linker_section_configure(
SECTION .rom_start
INPUT ".boot_hdr.conf"

View file

@ -698,4 +698,13 @@ config CODE_SRAM0
bool "Link code into RAM_L memory (RAM_L)"
endchoice
config OCRAM_NOCACHE
bool "Create noncacheable OCRAM region"
select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS
select PLATFORM_SPECIFIC_INIT
help
Creates linker section and MPU region for OCRAM region with
noncacheable attribute. OCRAM memory is useful for fast DMA transfers.
endif # SOC_SERIES_IMX_RT

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2022 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <devicetree.h>
#include "../../common/cortex_m/arm_mpu_mem_cfg.h"
#define IS_CHOSEN_SRAM(x) (DT_DEP_ORD(DT_NODELABEL(x)) == DT_DEP_ORD(DT_CHOSEN(zephyr_sram)))
static const struct arm_mpu_region mpu_regions[] = {
/* Region 0 */
MPU_REGION_ENTRY("FLASH_0",
CONFIG_FLASH_BASE_ADDRESS,
REGION_FLASH_ATTR(REGION_FLASH_SIZE)),
#if IS_CHOSEN_SRAM(ocram)
/* Mark SRAM as noncacheable */
/* Region 1 */
MPU_REGION_ENTRY("SRAM_0",
CONFIG_SRAM_BASE_ADDRESS,
REGION_RAM_NOCACHE_ATTR(REGION_SRAM_SIZE)),
#else
/* Region 1 */
MPU_REGION_ENTRY("SRAM_0",
CONFIG_SRAM_BASE_ADDRESS,
REGION_RAM_ATTR(REGION_SRAM_SIZE)),
/* Region 2 - OCRAM. Noncacheable. */
#if DT_NODE_HAS_STATUS(DT_NODELABEL(ocram), okay)
MPU_REGION_ENTRY("OCRAM",
DT_REG_ADDR(DT_NODELABEL(ocram)),
REGION_RAM_NOCACHE_ATTR(REGION_256K)),
#endif
#endif
};
const struct arm_mpu_config mpu_config = {
.num_regions = ARRAY_SIZE(mpu_regions),
.mpu_regions = mpu_regions,
};

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2022 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <linker/linker-tool.h>
#define IS_CHOSEN_SRAM(x) (DT_DEP_ORD(DT_NODELABEL(x)) == DT_DEP_ORD(DT_CHOSEN(zephyr_sram)))
#if (DT_REG_SIZE(DT_NODELABEL(ocram)) > 0) && !IS_CHOSEN_SRAM(ocram)
GROUP_START(OCRAM)
__ocram_start = .;
SECTION_PROLOGUE(.ocram_bss,(NOLOAD),SUBALIGN(4))
{
__ocram_bss_start = .;
*(.ocram_bss)
*(".ocram_bss.*")
__ocram_bss_end = .;
__ocram_end = .;
} GROUP_LINK_IN(OCRAM)
SECTION_PROLOGUE(.ocram_noinit,(NOLOAD),SUBALIGN(4))
{
__ocram_noinit_start = .;
*(.ocram_noinit)
*(".ocram_noinit.*")
__ocram_noinit_end = .;
} GROUP_LINK_IN(OCRAM)
SECTION_PROLOGUE(.ocram_data,,SUBALIGN(4))
{
__ocram_data_start = .;
*(.ocram_data)
*(".ocram_data.*")
__ocram_data_end = .;
} GROUP_LINK_IN(OCRAM AT> ROMABLE_REGION)
__ocram_end = .;
__ocram_data_load_start = LOADADDR(.ocram_data);
#endif

View file

@ -46,6 +46,21 @@ void imxrt_audio_codec_pll_init(uint32_t clock_name, uint32_t clk_src,
#endif
#if (DT_DEP_ORD(DT_NODELABEL(ocram)) != DT_DEP_ORD(DT_CHOSEN(zephyr_sram))) && \
CONFIG_OCRAM_NOCACHE
/* OCRAM addresses will be defined by linker */
extern char __ocram_start;
extern char __ocram_bss_start;
extern char __ocram_bss_end;
extern char __ocram_noinit_start;
extern char __ocram_noinit_end;
extern char __ocram_data_start;
extern char __ocram_data_end;
extern char __ocram_end;
extern char __ocram_data_load_start;
#endif
#ifdef __cplusplus
}
#endif

View file

@ -341,4 +341,18 @@ static int imxrt_init(const struct device *arg)
return 0;
}
#ifdef CONFIG_PLATFORM_SPECIFIC_INIT
void z_arm_platform_init(void)
{
#if (DT_DEP_ORD(DT_NODELABEL(ocram)) != DT_DEP_ORD(DT_CHOSEN(zephyr_sram))) && \
CONFIG_OCRAM_NOCACHE
/* Copy data from flash to OCRAM */
memcpy(&__ocram_data_start, &__ocram_data_load_start,
(&__ocram_data_end - &__ocram_data_start));
/* Zero BSS region */
memset(&__ocram_bss_start, 0, (&__ocram_bss_end - &__ocram_bss_start));
#endif
}
#endif
SYS_INIT(imxrt_init, PRE_KERNEL_1, 0);

View file

@ -618,4 +618,18 @@ static int imxrt_init(const struct device *arg)
return 0;
}
#ifdef CONFIG_PLATFORM_SPECIFIC_INIT
void z_arm_platform_init(void)
{
#if (DT_DEP_ORD(DT_NODELABEL(ocram)) != DT_DEP_ORD(DT_CHOSEN(zephyr_sram))) && \
CONFIG_OCRAM_NOCACHE
/* Copy data from flash to OCRAM */
memcpy(&__ocram_data_start, &__ocram_data_load_start,
(&__ocram_data_end - &__ocram_data_start));
/* Zero BSS region */
memset(&__ocram_bss_start, 0, (&__ocram_bss_end - &__ocram_bss_start));
#endif
}
#endif
SYS_INIT(imxrt_init, PRE_KERNEL_1, 0);