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:
parent
3a2c5bd56d
commit
da40ffb4a8
8 changed files with 137 additions and 0 deletions
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
|
d-cache-line-size = <32>;
|
||||||
|
|
||||||
mpu: mpu@e000ed90 {
|
mpu: mpu@e000ed90 {
|
||||||
compatible = "arm,armv7m-mpu";
|
compatible = "arm,armv7m-mpu";
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
device_type = "cpu";
|
device_type = "cpu";
|
||||||
compatible = "arm,cortex-m4f";
|
compatible = "arm,cortex-m4f";
|
||||||
reg = <1>;
|
reg = <1>;
|
||||||
|
d-cache-line-size = <32>;
|
||||||
|
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
|
|
|
@ -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
|
zephyr_linker_sources_ifdef(CONFIG_NXP_IMX_RT_BOOT_HEADER
|
||||||
ROM_START SORT_KEY 0 boot_header.ld)
|
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(
|
zephyr_linker_section_configure(
|
||||||
SECTION .rom_start
|
SECTION .rom_start
|
||||||
INPUT ".boot_hdr.conf"
|
INPUT ".boot_hdr.conf"
|
||||||
|
|
|
@ -698,4 +698,13 @@ config CODE_SRAM0
|
||||||
bool "Link code into RAM_L memory (RAM_L)"
|
bool "Link code into RAM_L memory (RAM_L)"
|
||||||
endchoice
|
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
|
endif # SOC_SERIES_IMX_RT
|
||||||
|
|
40
soc/arm/nxp_imx/rt/mpu_regions.c
Normal file
40
soc/arm/nxp_imx/rt/mpu_regions.c
Normal 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,
|
||||||
|
};
|
39
soc/arm/nxp_imx/rt/sections.ld
Normal file
39
soc/arm/nxp_imx/rt/sections.ld
Normal 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
|
|
@ -46,6 +46,21 @@ void imxrt_audio_codec_pll_init(uint32_t clock_name, uint32_t clk_src,
|
||||||
|
|
||||||
#endif
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -341,4 +341,18 @@ static int imxrt_init(const struct device *arg)
|
||||||
return 0;
|
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);
|
SYS_INIT(imxrt_init, PRE_KERNEL_1, 0);
|
||||||
|
|
|
@ -618,4 +618,18 @@ static int imxrt_init(const struct device *arg)
|
||||||
return 0;
|
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);
|
SYS_INIT(imxrt_init, PRE_KERNEL_1, 0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue