feat(s32g274a): add S32G274ARDB2 board support

S32G274ARDB2 is a development board to showcase the capabilities of the
S32G2 SoC. It includes 4 ARM Cortex-A53 cores running at 1.0GHz, 4GBs
of DDR, accelerators for automotive networking and many other
peripherals.

The added support is minimal and only includes the BL2 stage, with no
MMU enabled. The FIP is preloaded by the BootROM in SRAM, and BL2 copies
BL31 and BL33 from FIP to their designated addresses.

Change-Id: Iedda23302768ab70d63787117c5f6f3c21eb9842
Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
Signed-off-by: Dan Nica <dan.nica@nxp.com>
Signed-off-by: Andra-Teodora Ilie <andra.ilie@nxp.com>
Signed-off-by: Bogdan Roman <bogdan-gabriel.roman@nxp.com>
Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
This commit is contained in:
Ghennadi Procopciuc 2024-01-30 16:19:47 +02:00
parent 306946b014
commit 8b81a39e28
14 changed files with 668 additions and 0 deletions

View file

@ -502,6 +502,13 @@ subsections:
- title: LS1088AQDS
scope: ls1088aqds
- title: S32G274A
scope: s32g274a
subsections:
- title: S32G274ARDB
scope: s32g274ardb
- title: QEMU
scope: qemu

View file

@ -710,6 +710,15 @@ NXP SoC Part LS1088A and its platform port
:|F|: plat/nxp/soc-ls1088a/ls1088ardb
:|F|: plat/nxp/soc-ls1088a/ls1088aqds
NXP SoC Part S32G274A and its platform port
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
:|G|: `gprocopciucnxp`_
:|F|: docs/plat/s32g274a.rst
:|F|: drivers/nxp/console/linflex_console.S
:|F|: include/drivers/nxp/console/linflex.h
:|F|: plat/nxp/s32
QEMU platform port
^^^^^^^^^^^^^^^^^^
:|M|: Jens Wiklander <jens.wiklander@linaro.org>
@ -983,6 +992,7 @@ Conventional Changelog Extensions
.. _davidvincze: https://github.com/davidvincze
.. _etienne-lms: https://github.com/etienne-lms
.. _glneo: https://github.com/glneo
.. _gprocopciucnxp: https://github.com/gprocopciucnxp
.. _grandpaul: https://github.com/grandpaul
.. _harrisonmutai-arm: https://github.com/harrisonmutai-arm
.. _hilamirandakuzi1: https://github.com/hilamirandakuzi1

View file

@ -29,6 +29,7 @@ Platform Ports
imx8m
imx8ulp
imx9
s32g274a
npcm845x
nxp/index
poplar

99
docs/plat/s32g274a.rst Normal file
View file

@ -0,0 +1,99 @@
NXP S32G274A
============
S32G2 is an NXP vehicle network processor combining ASIL D safety, hardware
security, high-performance real-time and application processing and network
acceleration. S32G2 supports the needs of new vehicle architectures:
service-oriented gateways, domain controllers, zonal processors, safety
processors and more. It is equipped with 4 Cortex-A53 cores operating at
1.0GHz.
The TF-A includes support for one single S32G2-based board called S32G274ARDB2.
The S32G-VNP-RDB2 is a compact, highly optimized and integrated board
engineering for vehicle service-oriented gateway (SoG), domain control
applications, high-performance processing, safety and security applications.
More details about this board can be found at `s32g274ardb2`_.
Boot Flow
---------
::
BootROM -> BL2 (SRAM) -> BL31 (SRAM) -> BL33 (DDR - TODO)
.. warning::
This boot flow is a preliminary version that will serve as a foundation for
upcoming S32G2 contributions. The execution will hang after the BL31 stage
due to U-Boot being deployed in SRAM instead of DDR. This issue will be
resolved with the addition of the DDR driver.
Code Locations
--------------
- Downstream TF-A:
`link: <https://github.com/nxp-auto-linux/arm-trusted-firmware>`__
- Downstream U-Boot:
`link <https://github.com/nxp-auto-linux/u-boot>`__
- Downstream Linux:
`link <https://github.com/nxp-auto-linux/linux>`__
How to build
------------
The port currently available on the S32G274ARDB2 platform is in its initial
stage. This means that important drivers like DDR and storage are not yet
available. Consequently, the boot process depends on BootROM to load all TF-A
stages in SRAM. To create a bootable image, the script below should be used.
This script makes use of the ``mkimage`` tool, which is part of the U-Boot drop
for S32G274A SoCs.
.. code:: bash
#!/bin/bash -xe
TF_A="${TF_A:-`pwd`}"
UBOOT="${UBOOT:-${TF_A}/../u-boot}"
DEBUG="${DEBUG:-1}"
FIP_BASE="0x34100000"
if [ "${DEBUG}" -eq "1" ]; then
BUILD="debug"
else
BUILD="release"
fi
BOOT_IMAGE="build/s32g274ardb2/${BUILD}/BOOT_IMAGE.bin"
BL2_BIN="build/s32g274ardb2/${BUILD}/bl2.bin"
FIP_BIN="build/s32g274ardb2/${BUILD}/fip.bin"
# Generate bl2, bl31 and fip image
make -C "${TF_A}" -j9 'PLAT=s32g274ardb2' \
BL33="${UBOOT}/u-boot-nodtb.bin" DEBUG="${DEBUG}" clean
make -C "${TF_A}" -j9 'PLAT=s32g274ardb2' \
BL33="${UBOOT}/u-boot-nodtb.bin" DEBUG="${DEBUG}" bl2
make -C "${TF_A}" -j9 'PLAT=s32g274ardb2' \
BL33="${UBOOT}/u-boot-nodtb.bin" DEBUG="${DEBUG}" fip
# Extract BL2 entry
BL2_START="0x$(poetry run memory -p s32g274ardb2 -b debug -f | \
grep BL2 | awk -F'|' '{print $3}' | xargs)"
# BL2 bin file size in bytes
BL2_SIZE="$(stat -c "%s" "${BL2_BIN}")"
# Pack bl2.bin and fip.bin by ensuring that the FIP image will start at FIP_BASE
cp -vf "${BL2_BIN}" "${BOOT_IMAGE}"
dd if="${FIP_BIN}" of="${BOOT_IMAGE}" seek="$((FIP_BASE - BL2_START))" bs=1
# Build a bootable image by appending the IVT
"${UBOOT}/tools/mkimage" \
-a "${BL2_START}" \
-e "${BL2_START}" \
-T s32ccimage \
-n "${UBOOT}/u-boot-s32.cfgout" \
-d "${BOOT_IMAGE}" \
fip.s32
.. _s32g2: https://www.nxp.com/products/processors-and-microcontrollers/s32-automotive-platform/s32g-vehicle-network-processors/s32g2-processors-for-vehicle-networking:S32G2
.. _s32g274ardb2: https://www.nxp.com/design/design-center/designs/s32g2-vehicle-networking-reference-design:S32G-VNP-RDB2

View file

@ -0,0 +1,12 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PLAT_CONSOLE_H
#define PLAT_CONSOLE_H
void console_s32g2_register(void);
#endif

View file

@ -0,0 +1,12 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PLAT_IO_STORAGE_H
#define PLAT_IO_STORAGE_H
void plat_s32g2_io_setup(void);
#endif

View file

@ -0,0 +1,22 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PLAT_MACROS_S
#define PLAT_MACROS_S
/* ---------------------------------------------
* The below required platform porting macro
* prints out relevant GIC and CCI registers
* whenever an unhandled exception is taken in
* BL31.
* Clobbers: x0 - x10, x16, x17, sp
* ---------------------------------------------
*/
.macro plat_crash_print_regs
.endm
#endif /* PLAT_MACROS_S */

View file

@ -0,0 +1,54 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PLATFORM_DEF_H
#define PLATFORM_DEF_H
#include <plat/common/common_def.h>
#define PLATFORM_STACK_SIZE U(0x1000)
/* Caches */
#define CACHE_WRITEBACK_SHIFT U(6)
#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT)
/* CPU Topology */
#define PLATFORM_CORE_COUNT U(4)
#define PLATFORM_SYSTEM_COUNT U(1)
#define PLATFORM_PRIMARY_CPU U(0)
#define PLATFORM_MPIDR_CPU_MASK_BITS U(1)
/* Power Domains */
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
#define PLAT_MAX_OFF_STATE U(2)
#define PLAT_MAX_RET_STATE U(1)
#define PLAT_MAX_PWR_LVL_STATES U(2)
/* BL2 stage */
#define BL2_BASE UL(0x34078000)
#define BL2_LIMIT UL(0x34100000)
/* BL31 stage */
#define BL31_BASE UL(0x34200000)
#define BL31_LIMIT UL(0x34300000)
/* It is a dummy value for now, given the missing DDR */
#define BL33_BASE UL(0x34500000)
#define BL33_LIMIT UL(0x345FF000)
/* Console settings */
#define UART_BASE UL(0x401C8000)
#define UART_BAUDRATE U(115200)
/* FIRC clock */
#define UART_CLOCK_HZ U(48000000)
#define S32G_FIP_BASE UL(0x34100000)
#define S32G_FIP_SIZE UL(0x100000)
#define MAX_IO_HANDLES U(2)
#define MAX_IO_DEVICES U(2)
#endif /* PLATFORM_DEF_H */

View file

@ -0,0 +1,62 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/desc_image_load.h>
#include <lib/mmio.h>
#include <plat/common/platform.h>
#include <plat_console.h>
#include <plat_io_storage.h>
#define SIUL2_PC09_MSCR UL(0x4009C2E4)
#define SIUL2_PC10_MSCR UL(0x4009C2E8)
#define SIUL2_PC10_LIN0_IMCR UL(0x4009CA40)
#define LIN0_TX_MSCR_CFG U(0x00214001)
#define LIN0_RX_MSCR_CFG U(0x00094000)
#define LIN0_RX_IMCR_CFG U(0x00000002)
struct bl_load_info *plat_get_bl_image_load_info(void)
{
return get_bl_load_info_from_mem_params_desc();
}
struct bl_params *plat_get_next_bl_params(void)
{
return get_next_bl_params_from_mem_params_desc();
}
void plat_flush_next_bl_params(void)
{
flush_bl_params_desc();
}
void bl2_platform_setup(void)
{
}
static void linflex_config_pinctrl(void)
{
/* set PC09 - MSCR[41] - for UART0 TXD */
mmio_write_32(SIUL2_PC09_MSCR, LIN0_TX_MSCR_CFG);
/* set PC10 - MSCR[42] - for UART0 RXD */
mmio_write_32(SIUL2_PC10_MSCR, LIN0_RX_MSCR_CFG);
/* set PC10 - MSCR[512]/IMCR[0] - for UART0 RXD */
mmio_write_32(SIUL2_PC10_LIN0_IMCR, LIN0_RX_IMCR_CFG);
}
void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
linflex_config_pinctrl();
console_s32g2_register();
plat_s32g2_io_setup();
}
void bl2_el3_plat_arch_setup(void)
{
}

View file

@ -0,0 +1,41 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/desc_image_load.h>
#include <plat/common/platform.h>
static bl_mem_params_node_t bl2_mem_params_descs[] = {
{
.image_id = BL31_IMAGE_ID,
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
entry_point_info_t,
SECURE | EXECUTABLE | EP_FIRST_EXE),
.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS),
.ep_info.pc = BL31_BASE,
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
.image_info.image_max_size = BL31_LIMIT - BL31_BASE,
.image_info.image_base = BL31_BASE,
.next_handoff_image_id = BL33_IMAGE_ID,
},
{
.image_id = BL33_IMAGE_ID,
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
entry_point_info_t,
NON_SECURE | EXECUTABLE),
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
image_info_t, 0),
.image_info.image_max_size = BL33_LIMIT - BL33_BASE,
.image_info.image_base = BL33_BASE,
.next_handoff_image_id = INVALID_IMAGE_ID,
},
};
REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)

View file

@ -0,0 +1,28 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <linflex.h>
#include <plat_console.h>
#include <platform_def.h>
void console_s32g2_register(void)
{
static console_t s32g2_console;
int ret;
(void)memset(&s32g2_console, 0, sizeof(s32g2_console));
ret = console_linflex_register(UART_BASE, UART_CLOCK_HZ,
UART_BAUDRATE, &s32g2_console);
if (ret == 0) {
panic();
}
console_set_scope(&s32g2_console,
CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH |
CONSOLE_FLAG_TRANSLATE_CRLF);
}

View file

@ -0,0 +1,129 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
#include <platform_def.h>
#define S32G_NCORE_CAIU0_BASE_ADDR UL(0x50400000)
#define S32G_NCORE_CAIUTC_OFF U(0x0)
#define S32G_NCORE_CAIUTC_ISOLEN_SHIFT U(1)
.globl plat_crash_console_flush
.globl plat_crash_console_init
.globl plat_crash_console_putc
.globl plat_is_my_cpu_primary
.globl plat_reset_handler
.globl plat_secondary_cold_boot_setup
.globl platform_mem_init
.globl s32g2_core_pos_by_mpidr
/* int plat_crash_console_init(void); */
func plat_crash_console_init
mov_imm x0, UART_BASE
mov_imm x1, UART_CLOCK_HZ
mov_imm x2, UART_BAUDRATE
b console_linflex_core_init
endfunc plat_crash_console_init
/* int plat_crash_console_putc(int); */
func plat_crash_console_putc
mov_imm x1, UART_BASE
b console_linflex_core_putc
ret
endfunc plat_crash_console_putc
/* void plat_crash_console_flush(void); */
func plat_crash_console_flush
ret
endfunc plat_crash_console_flush
/**
* unsigned int s32g2_core_pos_by_mpidr(u_register_t mpidr);
*
* In: x0 - MPIDR_EL1
* Out: x0
* Clobber list: x0, x1
*/
func s32g2_core_pos_by_mpidr
and x1, x0, #MPIDR_CPU_MASK
and x0, x0, #MPIDR_CLUSTER_MASK
lsr x0, x0, #MPIDR_AFF1_SHIFT
add x0, x1, x0, lsl #PLATFORM_MPIDR_CPU_MASK_BITS
ret
endfunc s32g2_core_pos_by_mpidr
/**
* unsigned int plat_my_core_pos(void);
*
* Out: x0
* Clobber list: x0, x1, x8
*/
func plat_my_core_pos
mov x8, x30
mrs x0, mpidr_el1
bl s32g2_core_pos_by_mpidr
mov x30, x8
ret
endfunc plat_my_core_pos
/**
* unsigned int plat_is_my_cpu_primary(void);
*
* Clobber list: x0, x1, x7, x8
*/
func plat_is_my_cpu_primary
mov x7, x30
bl plat_my_core_pos
cmp x0, #PLATFORM_PRIMARY_CPU
cset x0, eq
mov x30, x7
ret
endfunc plat_is_my_cpu_primary
/**
* void plat_secondary_cold_boot_setup (void);
*/
func plat_secondary_cold_boot_setup
ret
endfunc plat_secondary_cold_boot_setup
/**
* void plat_reset_handler(void);
*
* Set the CAIUTC[IsolEn] bit for the primary A53 cluster.
* This is so cache invalidate operations from the early TF-A boot code
* won't cause Ncore to crash.
*
* Clobber list: x0, x1, x2
*/
func plat_reset_handler
mov x0, #S32G_NCORE_CAIU0_BASE_ADDR
ldr w1, [x0, #S32G_NCORE_CAIUTC_OFF]
movz w2, #1
lsl w2, w2, #S32G_NCORE_CAIUTC_ISOLEN_SHIFT
orr w1, w1, w2
str w1, [x0, #S32G_NCORE_CAIUTC_OFF]
ret
endfunc plat_reset_handler
/* void platform_mem_init(void); */
func platform_mem_init
mov x10, x30
mov x0, #BL31_BASE
mov x1, #(BL31_LIMIT & 0xFFFFU)
movk x1, #(BL31_LIMIT >> 16), lsl #16
sub x1, x1, x0
bl zeromem
mov x0, #BL33_BASE
mov x1, #(BL33_LIMIT & 0xFFFFU)
movk x1, #(BL33_LIMIT >> 16), lsl #16
sub x1, x1, x0
bl zeromem
mov x30, x10
ret
endfunc platform_mem_init

View file

@ -0,0 +1,135 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_fip.h>
#include <drivers/io/io_memmap.h>
#include <plat/common/platform.h>
#include <tools_share/firmware_image_package.h>
#include <plat_io_storage.h>
struct plat_io_policy {
uintptr_t *dev_handle;
uintptr_t image_spec;
int (*check)(const uintptr_t spec);
};
static int open_memmap(const uintptr_t spec);
static int open_fip(const uintptr_t spec);
static uintptr_t fip_dev_handle;
static uintptr_t memmap_dev_handle;
static int open_memmap(const uintptr_t spec)
{
uintptr_t temp_handle = 0U;
int result;
result = io_dev_init(memmap_dev_handle, (uintptr_t)0);
if (result != 0) {
return result;
}
result = io_open(memmap_dev_handle, spec, &temp_handle);
if (result == 0) {
(void)io_close(temp_handle);
}
return result;
}
static int open_fip(const uintptr_t spec)
{
uintptr_t temp_handle = 0U;
int result;
/* See if a Firmware Image Package is available */
result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
if (result != 0) {
return result;
}
result = io_open(fip_dev_handle, spec, &temp_handle);
if (result == 0) {
(void)io_close(temp_handle);
}
return result;
}
void plat_s32g2_io_setup(void)
{
static const io_dev_connector_t *memmap_dev_con;
static const io_dev_connector_t *fip_dev_con;
int result __unused;
result = register_io_dev_memmap(&memmap_dev_con);
assert(result == 0);
result = io_dev_open(memmap_dev_con, (uintptr_t)0,
&memmap_dev_handle);
assert(result == 0);
result = register_io_dev_fip(&fip_dev_con);
assert(result == 0);
result = io_dev_open(fip_dev_con, (uintptr_t)0,
&fip_dev_handle);
assert(result == 0);
}
int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
uintptr_t *image_spec)
{
static const io_block_spec_t fip_block_spec = {
.offset = S32G_FIP_BASE,
.length = S32G_FIP_SIZE,
};
static const io_uuid_spec_t bl31_uuid_spec = {
.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
};
static const io_uuid_spec_t bl33_uuid_spec = {
.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
};
static const struct plat_io_policy policies[BL33_IMAGE_ID + 1] = {
[FIP_IMAGE_ID] = {
.dev_handle = &memmap_dev_handle,
.image_spec = (uintptr_t)&fip_block_spec,
.check = open_memmap,
},
[BL31_IMAGE_ID] = {
.dev_handle = &fip_dev_handle,
.image_spec = (uintptr_t)&bl31_uuid_spec,
.check = open_fip,
},
[BL33_IMAGE_ID] = {
.dev_handle = &fip_dev_handle,
.image_spec = (uintptr_t)&bl33_uuid_spec,
.check = open_fip,
},
};
const struct plat_io_policy *policy;
int result;
assert(image_id < ARRAY_SIZE(policies));
policy = &policies[image_id];
result = policy->check(policy->image_spec);
assert(result == 0);
*image_spec = policy->image_spec;
*dev_handle = *policy->dev_handle;
return result;
}

View file

@ -0,0 +1,56 @@
#
# Copyright 2024 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
include drivers/arm/gic/v3/gicv3.mk
include lib/xlat_tables_v2/xlat_tables.mk
PLAT_DRIVERS_PATH := drivers/nxp
PLAT_COMMON_PATH := plat/nxp/common
PLAT_S32G274ARDB2 := plat/nxp/s32/s32g274ardb2
CONSOLE := LINFLEX
include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk
PLAT_INCLUDES = \
-I${PLAT_S32G274ARDB2}/include
PROGRAMMABLE_RESET_ADDRESS := 1
COLD_BOOT_SINGLE_CPU := 0
ENABLE_SVE_FOR_NS := 0
RESET_TO_BL2 := 1
INIT_UNUSED_NS_EL2 := 1
ERRATA_A53_855873 := 1
ERRATA_A53_836870 := 1
ERRATA_A53_1530924 := 1
ERRATA_SPECULATIVE_AT := 1
# Selecting Drivers for SoC
$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
include ${PLAT_DRIVERS_PATH}/drivers.mk
BL_COMMON_SOURCES += \
${PLAT_S32G274ARDB2}/plat_console.c \
${PLAT_S32G274ARDB2}/plat_helpers.S \
BL2_SOURCES += \
${BL_COMMON_SOURCES} \
${PLAT_S32G274ARDB2}/plat_bl2_el3_setup.c \
${PLAT_S32G274ARDB2}/plat_bl2_image_desc.c \
${PLAT_S32G274ARDB2}/plat_io_storage.c \
common/desc_image_load.c \
drivers/io/io_fip.c \
drivers/io/io_memmap.c \
drivers/io/io_storage.c \
lib/cpus/aarch64/cortex_a53.S \