soc: arm: introduce support for NXP S32K344

The S32K3 MCUs are 32-bit Arm Cortex-M7-based microcontrollers with a
focus on automotive and industrial applications. The S32K344 features
a lock-step core, internal flash, RAM and TCM with ECC.

Co-authored-by: Dat Nguyen Duy <dat.nguyenduy@nxp.com>
Co-authored-by: Cong Nguyen Huu <cong.nguyenhuu@nxp.com>
Signed-off-by: Manuel Argüelles <manuel.arguelles@nxp.com>
This commit is contained in:
Manuel Arguelles 2023-05-26 00:00:00 +00:00 committed by Mahesh Mahadevan
commit d2985f118a
15 changed files with 432 additions and 2 deletions

View file

@ -0,0 +1,70 @@
/*
* Copyright 2023 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <arm/armv7-m.dtsi>
#include <mem.h>
/ {
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-m7";
reg = <0>;
};
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-m7";
reg = <1>;
};
mpu: mpu@e000ed90 {
compatible = "arm,armv7m-mpu";
reg = <0xe000ed90 0x40>;
arm,num-mpu-regions = <16>;
};
};
soc {
interrupt-parent = <&nvic>;
itcm: memory@0 {
compatible = "zephyr,memory-region", "arm,itcm";
reg = <0x00000000 DT_SIZE_K(64)>;
zephyr,memory-region = "ITCM";
};
dtcm: memory@20000000 {
compatible = "zephyr,memory-region", "arm,dtcm";
reg = <0x20000000 DT_SIZE_K(128)>;
zephyr,memory-region = "DTCM";
};
sram0_1: sram0_1@20400000 {
compatible = "mmio-sram";
reg = <0x20400000 DT_SIZE_K(320)>;
};
/*
* Last 48Kb is reserved by Secure BAF, application core cannot access it.
*
* Do not assign the compatible for this now, when Flash API is implemented,
* need to check if "soc-nv-flash" can be used or a new binding need to be
* created, based on it.
*/
flash0: flash@400000 {
reg = <0x00400000 DT_SIZE_K(4048)>;
status = "disabled";
};
};
};
&nvic {
arm,num-irq-priority-bits = <4>;
};

View file

@ -14,5 +14,6 @@ source "soc/arm/nxp_s32/*/Kconfig.soc"
config SOC_PART_NUMBER
default SOC_PART_NUMBER_S32ZE_R52 if SOC_SERIES_S32ZE_R52
default SOC_PART_NUMBER_S32K3 if SOC_SERIES_S32K3_M7
endif # SOC_FAMILY_S32

View file

@ -1,5 +1,5 @@
/*
* Copyright 2022 NXP
* Copyright 2022-2023 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -9,6 +9,8 @@
#if defined(CONFIG_SOC_S32Z27_R52)
#include <S32Z2_MSCM.h>
#elif defined(CONFIG_SOC_S32K344_M7)
#include <S32K344_MSCM.h>
#endif
/* Required by OsIf timer initialization but not used with Zephyr, so no values configured */

View file

@ -0,0 +1,9 @@
# Copyright 2023 NXP
# SPDX-License-Identifier: Apache-2.0
zephyr_library()
zephyr_library_sources(soc.c)
zephyr_library_sources_ifdef(CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS mpu_regions.c)
zephyr_linker_sources(SECTIONS sections.ld)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_SPECIFIC_INIT s32k3xx_startup.S)

View file

@ -0,0 +1,14 @@
# S32K344
# Copyright 2023 NXP
# SPDX-License-Identifier: Apache-2.0
if SOC_S32K344_M7
config SOC
default "s32k344"
config FPU
default y
endif # SOC_S32K344_M7

View file

@ -0,0 +1,27 @@
# S32 K M7 core series
# Copyright 2023 NXP
# SPDX-License-Identifier: Apache-2.0
if SOC_SERIES_S32K3_M7
config SOC_SERIES
default "s32k"
config SYS_CLOCK_HW_CYCLES_PER_SEC
default 2000000
config NUM_IRQS
# must be >= the highest interrupt number used
default 239
if !XIP
config FLASH_SIZE
default 0
config FLASH_BASE_ADDRESS
default 0
endif
source "soc/arm/nxp_s32/s32k/Kconfig.defconfig.s32k*"
endif # SOC_SERIES_S32K_M7

View file

@ -0,0 +1,17 @@
# NXP S32K3 MCUs family
# Copyright 2023 NXP
# SPDX-License-Identifier: Apache-2.0
config SOC_SERIES_S32K3_M7
bool "S32K3 M7 Core Series"
select ARM
select CPU_CORTEX_M7
select SOC_FAMILY_S32
select CPU_HAS_FPU
select CPU_HAS_ARM_MPU
select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS
select PLATFORM_SPECIFIC_INIT if XIP
select USE_DT_CODE_PARTITION if XIP
help
Enable support for NXP S32K3 MCUs family on Cortex-M7 cores

View file

@ -0,0 +1,43 @@
# NXP S32K MCUs family
# Copyright 2023 NXP
# SPDX-License-Identifier: Apache-2.0
choice
prompt "NXP S32K MCUs family SoC Selection"
depends on SOC_SERIES_S32K3_M7
config SOC_S32K344_M7
bool "SOC_S32K_M7"
select HAS_S32_HAL
endchoice
if SOC_SERIES_S32K3_M7
config SOC_PART_NUMBER_S32K344
bool
config SOC_PART_NUMBER_S32K3
string
default "S32K344" if SOC_PART_NUMBER_S32K344
help
This string holds the full part number of the SoC. It is a hidden option
that you should not set directly. The part number selection choice defines
the default value for this string.
config IVT_HEADER_OFFSET
hex
depends on XIP
default $(dt_node_reg_addr_hex,$(dt_nodelabel_path,ivt_header))
help
The offset address from flash base address for ivt header
config IVT_HEADER_SIZE
hex
depends on XIP
default $(dt_node_reg_size_hex,$(dt_nodelabel_path,ivt_header))
help
Size of ivt header region
endif

View file

@ -0,0 +1,15 @@
/*
* Copyright 2023 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef CONFIG_XIP
MEMORY
{
IVT_HEADER (r) : ORIGIN = CONFIG_FLASH_BASE_ADDRESS + CONFIG_IVT_HEADER_OFFSET,
LENGTH = CONFIG_IVT_HEADER_SIZE
}
#endif
#include <zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld>

View file

@ -0,0 +1,46 @@
/*
* Copyright 2023 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/devicetree.h>
#include <zephyr/linker/devicetree_regions.h>
#include "../../common/cortex_m/arm_mpu_mem_cfg.h"
#if !defined(CONFIG_XIP)
extern char _rom_attr[];
#endif
static struct arm_mpu_region mpu_regions[] = {
/* Keep before CODE region so it can be overlapped by SRAM CODE in non-XIP systems */
{
.name = "SRAM",
.base = CONFIG_SRAM_BASE_ADDRESS,
.attr = REGION_RAM_ATTR(REGION_SRAM_SIZE),
},
#ifdef CONFIG_XIP
{
.name = "FLASH",
.base = CONFIG_FLASH_BASE_ADDRESS,
.attr = REGION_FLASH_ATTR(REGION_FLASH_SIZE),
},
#else
/* Run from SRAM */
{
.name = "CODE",
.base = CONFIG_SRAM_BASE_ADDRESS,
.attr = {(uint32_t)_rom_attr},
},
#endif
/* DT-defined regions */
LINKER_DT_REGION_MPU(ARM_MPU_REGION_INIT)
};
const struct arm_mpu_config mpu_config = {
.num_regions = ARRAY_SIZE(mpu_regions),
.mpu_regions = mpu_regions,
};

View file

@ -0,0 +1,67 @@
/*
* Copyright 2023 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/devicetree.h>
#include <zephyr/toolchain.h>
#include <zephyr/linker/sections.h>
_ASM_FILE_PROLOGUE
GTEXT(z_arm_platform_init)
SECTION_FUNC(TEXT, z_arm_platform_init)
/*
* After chip power-on reset, SRAM must be initialized to a known value
* using a 64-bit master before 32-bit masters can read or write to RAM.
*
* This is implemented directly in ASM, to ensure no stack access is performed.
*/
ldr r1, = DT_REG_ADDR(DT_CHOSEN(zephyr_sram))
ldr r2, = DT_REG_SIZE(DT_CHOSEN(zephyr_sram))
subs r2, #1
ble SRAM_LOOP_END
movs r0, 0
movs r3, 0
SRAM_LOOP:
stm r1!, {r0,r3}
subs r2, 8
bge SRAM_LOOP
SRAM_LOOP_END:
#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay)
ldr r1, = DT_REG_ADDR(DT_CHOSEN(zephyr_itcm))
ldr r2, = DT_REG_SIZE(DT_CHOSEN(zephyr_itcm))
subs r2, #1
ITCM_LOOP:
stm r1!, {r0,r3}
subs r2, 8
bge ITCM_LOOP
#endif
#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay)
ldr r1, = DT_REG_ADDR(DT_CHOSEN(zephyr_dtcm))
ldr r2, = DT_REG_SIZE(DT_CHOSEN(zephyr_dtcm))
subs r2, #1
DTCM_LOOP:
stm r1!, {r0,r3}
subs r2, 8
bge DTCM_LOOP
#endif
bx lr

View file

@ -0,0 +1,22 @@
/*
* Copyright 2023 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef CONFIG_XIP
.ivt_header : {
KEEP(*(.ivt_header));
} > IVT_HEADER
#else
#define _NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE (1 << 17)
#define _RO_Msk (7 << 24)
/* ROM region size order for MPU configuration */
_rom_region_order = ((LOG2CEIL(__rom_region_end - __rom_region_start) - 1) << 1);
_rom_attr = (_NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | _rom_region_order | _RO_Msk);
#endif

View file

@ -0,0 +1,76 @@
/*
* Copyright 2023 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/arch/arm/aarch32/cortex_m/cmsis.h>
#include <OsIf.h>
#include <Clock_Ip.h>
#ifdef CONFIG_XIP
/* Image Vector Table structure definition for S32K3XX */
struct ivt {
uint32_t header;
uint32_t boot_configure;
const uint32_t reserved_1;
const uint32_t *cm7_0_start_address;
const uint32_t reserved_2;
const uint32_t *cm7_1_start_address;
const uint32_t reserved_3;
const uint32_t *cm7_2_start_address;
const uint32_t reserved_4;
const uint32_t *lc_configure;
uint8_t reserved7[216];
};
#define IVT_MAGIC_MARKER 0x5AA55AA5
extern char _vector_start[];
/*
* IVT for SoC S32K344, the minimal boot configuration is:
* - Watchdog (SWT0) is disabled (default value).
* - Non-Secure Boot is used (default value).
* - Ungate clock for Cortex-M7_0 after boot.
* - Application start address of Cortex-M7_0 is application's vector table.
*/
const struct ivt ivt_header __attribute__((section(".ivt_header"))) = {
.header = IVT_MAGIC_MARKER,
.boot_configure = 1,
.cm7_0_start_address = (const void *)_vector_start,
.cm7_1_start_address = NULL,
.cm7_2_start_address = NULL,
.lc_configure = NULL,
};
#endif /* CONFIG_XIP */
static int soc_init(void)
{
SCB_EnableICache();
if (IS_ENABLED(CONFIG_DCACHE)) {
if (!(SCB->CCR & SCB_CCR_DC_Msk)) {
SCB_EnableDCache();
}
}
OsIf_Init(NULL);
/*
* Clock for MSCM must be enabled first, before all clocks or peripherals
* are initialized. Because for now, RTD critical sections need access MSCM
* register to determine which core the code is running on.
*/
Clock_Ip_EnableModuleClock(MSCM_CLK);
Clock_Ip_Init(Clock_Ip_aClockConfig);
return 0;
}
SYS_INIT(soc_init, PRE_KERNEL_1, 0);

View file

@ -0,0 +1,21 @@
/*
* Copyright 2023 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _NXP_S32_S32K_SOC_H_
#define _NXP_S32_S32K_SOC_H_
#include <S32K344.h>
#if defined(CONFIG_CMSIS_RTOS_V2)
/*
* The HAL is defining these symbols already. To avoid redefinitions,
* let CMSIS RTOS wrapper define them.
*/
#undef TRUE
#undef FALSE
#endif
#endif /* _NXP_S32_S32K_SOC_H_ */

View file

@ -183,7 +183,7 @@ manifest:
groups:
- hal
- name: hal_nxp
revision: 904830e8f684a9fd573751a1cdecde877ec49242
revision: e0116b8eae46c2d90f2c1b23baef73bb082d00bd
path: modules/hal/nxp
groups:
- hal