[U-Boot] [PATCH v3 0/3] stm32mp1: add trusted boot with TF-A

This patch serie add a new configuration stm32mp15_trusted_defconfig to handle STM32MP157 boards with TF-A as secure first stage bootloader.
TF-A code is available in GitHub https://github.com/ARM-software/arm-trusted-firmware
With platform stm32mp1 platform https://github.com/ARM-software/arm-trusted-firmware/tree/master/plat/st/stm...
For details, see documentation https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/plat/s...
PS: upstream of trusted boot for TF-A is still in progress.
Changes in v3: - Remove patch 4/4 added by error in v2 and sent by other serie http://patchwork.ozlabs.org/patch/1033475/
Changes in v2: - Rebase and solve conflict on arch/arm/mach-stm32mp/config.mk
Patrick Delaunay (3): stm32mp1: add trusted boot with TF-A stm32mp1: bsec: access with SMC for trusted boot stm32mp1: display board information
arch/arm/Kconfig | 6 ++- arch/arm/mach-stm32mp/Kconfig | 17 ++++-- arch/arm/mach-stm32mp/bsec.c | 28 ++++++++++ arch/arm/mach-stm32mp/config.mk | 15 +++++- arch/arm/mach-stm32mp/cpu.c | 9 +++- arch/arm/mach-stm32mp/include/mach/stm32.h | 4 ++ arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h | 64 +++++++++++++++++++++++ board/st/stm32mp1/MAINTAINERS | 5 +- board/st/stm32mp1/README | 56 ++++++++++++++------ board/st/stm32mp1/stm32mp1.c | 44 +++++++++++++++- configs/stm32mp15_trusted_defconfig | 57 ++++++++++++++++++++ drivers/clk/clk_stm32mp1.c | 2 + drivers/ram/stm32mp1/stm32mp1_ram.c | 3 +- include/configs/stm32mp1.h | 2 + 14 files changed, 282 insertions(+), 30 deletions(-) create mode 100644 arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h create mode 100644 configs/stm32mp15_trusted_defconfig

Add support of trusted boot, using TF-A as first stage bootloader, The boot sequence is BootRom >=> TF-A.stm32 (clock & DDR) >=> U-Boot.stm32
The TF-A monitor provides secure monitor with support of SMC - proprietary to manage secure devices (BSEC for example) - PSCI for power
The same device tree is used for STMicroelectronics boards with basic boot and with trusted boot.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v3: - Remove patch 4/4 added by error in v2 and sent by other serie http://patchwork.ozlabs.org/patch/1033475/
Changes in v2: - Rebase and solve conflict on arch/arm/mach-stm32mp/config.mk
arch/arm/Kconfig | 6 ++-- arch/arm/mach-stm32mp/Kconfig | 17 +++++++++-- arch/arm/mach-stm32mp/config.mk | 15 +++++++++- arch/arm/mach-stm32mp/cpu.c | 9 ++++-- board/st/stm32mp1/MAINTAINERS | 5 ++-- board/st/stm32mp1/README | 56 +++++++++++++++++++++++++----------- configs/stm32mp15_trusted_defconfig | 57 +++++++++++++++++++++++++++++++++++++ drivers/clk/clk_stm32mp1.c | 2 ++ drivers/ram/stm32mp1/stm32mp1_ram.c | 3 +- include/configs/stm32mp1.h | 2 ++ 10 files changed, 144 insertions(+), 28 deletions(-) create mode 100644 configs/stm32mp15_trusted_defconfig
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index cefa8f4..9526cd2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1360,8 +1360,10 @@ config ARCH_STM32MP help Support for STM32MP SoC family developed by STMicroelectronics, MPUs based on ARM cortex A core - U-BOOT is running in DDR and SPL support is the unsecure First Stage - BootLoader (FSBL) + U-BOOT is running in DDR, loaded by the First Stage BootLoader (FSBL). + FSBL can be TF-A: Trusted Firmware for Cortex A, for trusted boot + chain. + SPL is the unsecure FSBL for the basic boot chain.
config ARCH_ROCKCHIP bool "Support Rockchip SoCs" diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig index 8a929fa..3101d80 100644 --- a/arch/arm/mach-stm32mp/Kconfig +++ b/arch/arm/mach-stm32mp/Kconfig @@ -25,19 +25,30 @@ config SYS_SOC
config TARGET_STM32MP1 bool "Support stm32mp1xx" - select ARCH_SUPPORT_PSCI + select ARCH_SUPPORT_PSCI if !STM32MP1_TRUSTED select CPU_V7A - select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_NONSEC if !STM32MP1_TRUSTED select CPU_V7_HAS_VIRT select PINCTRL_STM32 select STM32_RCC select STM32_RESET select SYS_ARCH_TIMER - select SYSRESET_SYSCON + imply SYSRESET_PSCI if STM32MP1_TRUSTED + imply SYSRESET_SYSCON if !STM32MP1_TRUSTED help target STMicroelectronics SOC STM32MP1 family STMicroelectronics MPU with core ARMv7
+config STM32MP1_TRUSTED + bool "Support trusted boot with TF-A" + default y if !SPL + select ARM_SMCCC + help + Say Y here to enable boot with TF-A + Trusted boot chain is : + BootRom => TF-A.stm32 (clock & DDR) => U-Boot.stm32 + TF-A monitor provides proprietary smc to manage secure devices + config SYS_TEXT_BASE prompt "U-Boot base address" default 0xC0100000 diff --git a/arch/arm/mach-stm32mp/config.mk b/arch/arm/mach-stm32mp/config.mk index f371aac..403af2a 100644 --- a/arch/arm/mach-stm32mp/config.mk +++ b/arch/arm/mach-stm32mp/config.mk @@ -3,7 +3,20 @@ # Copyright (C) 2018, STMicroelectronics - All Rights Reserved #
-ALL-$(CONFIG_SPL_BUILD) += u-boot-spl.stm32 +ifndef CONFIG_SPL +ALL-y += u-boot.stm32 +else +ifdef CONFIG_SPL_BUILD +ALL-y += u-boot-spl.stm32 +endif +endif + +MKIMAGEFLAGS_u-boot.stm32 = -T stm32image -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) + +u-boot.stm32: MKIMAGEOUTPUT = u-boot.stm32.log + +u-boot.stm32: u-boot.bin FORCE + $(call if_changed,mkimage)
MKIMAGEFLAGS_u-boot-spl.stm32 = -T stm32image -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE)
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c index b893358..b96720f 100644 --- a/arch/arm/mach-stm32mp/cpu.c +++ b/arch/arm/mach-stm32mp/cpu.c @@ -59,6 +59,7 @@ #define BSEC_OTP_MAC 57
#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) +#ifndef CONFIG_STM32MP1_TRUSTED static void security_init(void) { /* Disable the backup domain write protection */ @@ -114,6 +115,7 @@ static void security_init(void) */ writel(0x0, TAMP_CR1); } +#endif /* CONFIG_STM32MP1_TRUSTED */
/* * Debug init @@ -130,7 +132,8 @@ static void dbgmcu_init(void) static u32 get_bootmode(void) { u32 boot_mode; -#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) +#if !defined(CONFIG_STM32MP1_TRUSTED) && \ + (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) u32 bootrom_itf = readl(BOOTROM_PARAM_ADDR); u32 bootrom_device, bootrom_instance;
@@ -167,9 +170,10 @@ int arch_cpu_init(void)
#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) dbgmcu_init(); - +#ifndef CONFIG_STM32MP1_TRUSTED security_init(); #endif +#endif
/* get bootmode from BootRom context: saved in TAMP register */ boot_mode = get_bootmode(); @@ -177,6 +181,7 @@ int arch_cpu_init(void) if ((boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART) gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; #if defined(CONFIG_DEBUG_UART) && \ + !defined(CONFIG_STM32MP1_TRUSTED) && \ (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) else debug_uart_init(); diff --git a/board/st/stm32mp1/MAINTAINERS b/board/st/stm32mp1/MAINTAINERS index 48d8fd2..0a2eddb 100644 --- a/board/st/stm32mp1/MAINTAINERS +++ b/board/st/stm32mp1/MAINTAINERS @@ -2,7 +2,8 @@ STM32MP1 BOARD M: Patrick Delaunay patrick.delaunay@st.com L: uboot-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers) S: Maintained +F: arch/arm/dts/stm32mp157* F: board/st/stm32mp1 -F: include/configs/stm32mp1.h F: configs/stm32mp15_basic_defconfig -F: arch/arm/dts/stm32mp157* +F: configs/stm32mp15_trusted_defconfig +F: include/configs/stm32mp1.h diff --git a/board/st/stm32mp1/README b/board/st/stm32mp1/README index 174e6db..1c3e865 100644 --- a/board/st/stm32mp1/README +++ b/board/st/stm32mp1/README @@ -28,7 +28,6 @@ Everything is supported in Linux but U-Boot is limited to:
And the necessary drivers 1. I2C -2. STPMU1 2. STPMU1 (PMIC and regulator) 3. Clock, Reset, Sysreset 4. Fuse @@ -45,15 +44,22 @@ BootRom => FSBL in SYSRAM => SSBL in DDR => OS (Linux Kernel) with FSBL = First Stage Bootloader SSBL = Second Stage Bootloader
-One boot configuration is supported: +2 boot configurations are supported:
- The "Basic" boot chain (defconfig_file : stm32mp15_basic_defconfig) +1) The "Trusted" boot chain (defconfig_file : stm32mp15_trusted_defconfig) + BootRom => FSBL = Trusted Firmware-A (TF-A) => SSBL = U-Boot + TF-A performs a full initialization of Secure peripherals and installs a + secure monitor. + U-Boot is running in normal world and uses TF-A monitor + to access to secure resources + +2) The "Basic" boot chain (defconfig_file : stm32mp15_basic_defconfig) BootRom => FSBL = U-Boot SPL => SSBL = U-Boot SPL has limited security initialisation U-Boot is running in secure mode and provide a secure monitor to the kernel with only PSCI support (Power State Coordination Interface defined by ARM)
-All the STM32MP1 board supported by U-Boot use the same generic board +All the STM32MP1 boards supported by U-Boot use the same generic board stm32mp1 which support all the bootable devices.
Each board is configurated only with the associated device tree. @@ -90,12 +96,14 @@ the supported device trees for stm32mp157 are: # export KBUILD_OUTPUT=/path/to/output
for example: use one output directory for each configuration + # export KBUILD_OUTPUT=stm32mp15_trusted # export KBUILD_OUTPUT=stm32mp15_basic
-4. Configure the U-Boot: +4. Configure U-Boot:
# make <defconfig_file>
+ - For trusted boot mode : "stm32mp15_trusted_defconfig" - For basic boot mode: "stm32mp15_basic_defconfig"
5. Configure the device-tree and build the U-Boot image: @@ -104,12 +112,17 @@ the supported device trees for stm32mp157 are:
example: - basic boot on ev1 + a) trusted boot on ev1 + # export KBUILD_OUTPUT=stm32mp15_trusted + # make stm32mp15_trusted_defconfig + # make DEVICE_TREE=stm32mp157c-ev1 all + + b) basic boot on ev1 # export KBUILD_OUTPUT=stm32mp15_basic # make stm32mp15_basic_defconfig # make DEVICE_TREE=stm32mp157c-ev1 all
- basic boot on ed1 + c) basic boot on ed1 # export KBUILD_OUTPUT=stm32mp15_basic # make stm32mp15_basic_defconfig # make DEVICE_TREE=stm32mp157c-ed1 all @@ -122,6 +135,11 @@ the supported device trees for stm32mp157 are: So in the output directory (selected by KBUILD_OUTPUT), you can found the needed files:
+ a) For Trusted boot + + FSBL = tf-a.stm32 (provided by TF-A compilation) + + SSBL = u-boot.stm32 + + b) For Basic boot + FSBL = spl/u-boot-spl.stm32 + SSBL = u-boot.img
@@ -135,7 +153,6 @@ You can select the boot mode, on the board ed1 with the switch SW1 ----------------------------------- Reserved 0 0 0 NOR 0 0 1 - SD-Card 1 1 1 SD-Card 1 0 1 eMMC 0 1 0 NAND 0 1 1 @@ -158,14 +175,14 @@ The minimal requirements for STMP32MP1 boot up to U-Boot are: - one ssbl partition for U-Boot
Then the minimal GPT partition is: - ----- ------- --------- ------------- - | Num | Name | Size | Content | - ----- ------- -------- -------------- + ----- ------- --------- -------------- + | Num | Name | Size | Content | + ----- ------- -------- --------------- | 1 | fsbl1 | 256 KiB | TF-A or SPL | | 2 | fsbl2 | 256 KiB | TF-A or SPL | - | 3 | ssbl | enought | U-Boot | - | * | - | - | Boot/Rootfs| - ----- ------- --------- ------------- + | 3 | ssbl | enought | U-Boot | + | * | - | - | Boot/Rootfs | + ----- ------- --------- --------------
(*) add bootable partition for extlinux.conf following Generic Distribution @@ -189,7 +206,7 @@ for example: with gpt table with 128 entries
you can add other partitions for kernel one partition rootfs for example: - -n 3:5154: -c 4:rootfs + -n 4:5154: -c 4:rootfs \
c) copy the FSBL (2 times) and SSBL file on the correct partition. in this example in partition 1 to 3 @@ -199,6 +216,11 @@ for example: with gpt table with 128 entries # dd if=u-boot-spl.stm32 of=/dev/mmcblk0p2 # dd if=u-boot.img of=/dev/mmcblk0p3
+ for trusted boot mode : + # dd if=tf-a.stm32 of=/dev/mmcblk0p1 + # dd if=tf-a.stm32 of=/dev/mmcblk0p2 + # dd if=u-boot.stm32 of=/dev/mmcblk0p3 + To boot from SDCard, select BootPinMode = 1 1 1 and reset.
8. Prepare eMMC @@ -208,7 +230,7 @@ You can use U-Boot to copy binary in eMMC. In the next example, you need to boot from SDCARD and the images (u-boot-spl.stm32, u-boot.img) are presents on SDCARD (mmc 0) in ext4 partition 4 (bootfs).
-To boot from SDCard, select BootPinMode = 1 1 1 and reset. +To boot from SDCard, select BootPinMode = 1 0 1 and reset.
Then you update the eMMC with the next U-Boot command :
@@ -227,7 +249,7 @@ b) copy SPL on eMMC on firts boot partition # mmc write ${fileaddr} 0 200 # mmc partconf 1 1 1 0
-b) copy U-Boot in first GPT partition of eMMC +c) copy U-Boot in first GPT partition of eMMC
# ext4load mmc 0:4 0xC0000000 u-boot.img # mmc dev 1 diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig new file mode 100644 index 0000000..e905ae1 --- /dev/null +++ b/configs/stm32mp15_trusted_defconfig @@ -0,0 +1,57 @@ +CONFIG_ARM=y +CONFIG_ARCH_STM32MP=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_TARGET_STM32MP1=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_SYS_PROMPT="STM32MP> " +# CONFIG_CMD_BOOTD is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_ADC=y +CONFIG_CMD_FUSE=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" +CONFIG_STM32_ADC=y +CONFIG_DM_HWSPINLOCK=y +CONFIG_HWSPINLOCK_STM32=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_STM32F7=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_DM_MMC=y +CONFIG_STM32_SDMMC2=y +CONFIG_PHY=y +CONFIG_PHY_STM32_USBPHYC=y +# CONFIG_PINCTRL_FULL is not set +CONFIG_DM_PMIC=y +CONFIG_PMIC_STPMU1=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_DM_REGULATOR_STM32_VREFBUF=y +CONFIG_DM_REGULATOR_STPMU1=y +CONFIG_SERIAL_RX_BUFFER=y +CONFIG_STM32_SERIAL=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_DWC2=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics" +CONFIG_USB_GADGET_VENDOR_NUM=0x0483 +CONFIG_USB_GADGET_PRODUCT_NUM=0x5720 +CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_USB_GADGET_DOWNLOAD=y diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c index b7c5d34..9e9c667 100644 --- a/drivers/clk/clk_stm32mp1.c +++ b/drivers/clk/clk_stm32mp1.c @@ -15,10 +15,12 @@ #include <dt-bindings/clock/stm32mp1-clks.h> #include <dt-bindings/clock/stm32mp1-clksrc.h>
+#ifndef CONFIG_STM32MP1_TRUSTED #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) /* activate clock tree initialization in the driver */ #define STM32MP1_CLOCK_TREE_INIT #endif +#endif
#define MAX_HSI_HZ 64000000
diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c b/drivers/ram/stm32mp1/stm32mp1_ram.c index bd497a3..e45a3b2 100644 --- a/drivers/ram/stm32mp1/stm32mp1_ram.c +++ b/drivers/ram/stm32mp1/stm32mp1_ram.c @@ -157,7 +157,8 @@ static int stm32mp1_ddr_probe(struct udevice *dev)
priv->info.base = STM32_DDR_BASE;
-#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) +#if !defined(CONFIG_STM32MP1_TRUSTED) && \ + (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) priv->info.size = 0; return stm32mp1_ddr_setup(dev); #else diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h index 701298c..4722672 100644 --- a/include/configs/stm32mp1.h +++ b/include/configs/stm32mp1.h @@ -17,10 +17,12 @@ */ #define CONFIG_SYS_HZ 1000
+#ifndef CONFIG_STM32MP1_TRUSTED /* PSCI support */ #define CONFIG_ARMV7_PSCI_1_0 #define CONFIG_ARMV7_SECURE_BASE STM32_SYSRAM_BASE #define CONFIG_ARMV7_SECURE_MAX_SIZE STM32_SYSRAM_SIZE +#endif
/* * malloc() pool size

As BSEC is secure aware, all register access need to be done by TF-A for TRUSTED boot chain, when U-Boot is executed in normal world.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v3: None Changes in v2: None
arch/arm/mach-stm32mp/bsec.c | 28 ++++++++++ arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h | 64 +++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h
diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c index d087a31..920a6c9 100644 --- a/arch/arm/mach-stm32mp/bsec.c +++ b/arch/arm/mach-stm32mp/bsec.c @@ -8,9 +8,12 @@ #include <misc.h> #include <asm/io.h> #include <linux/iopoll.h> +#include <asm/arch/stm32mp1_smc.h> +#include <linux/arm-smccc.h>
#define BSEC_OTP_MAX_VALUE 95
+#ifndef CONFIG_STM32MP1_TRUSTED #define BSEC_TIMEOUT_US 10000
/* BSEC REGISTER OFFSET (base relative) */ @@ -270,6 +273,7 @@ static int bsec_program_otp(long base, u32 val, u32 otp)
return ret; } +#endif /* CONFIG_STM32MP1_TRUSTED */
/* BSEC MISC driver *******************************************************/ struct stm32mp_bsec_platdata { @@ -278,6 +282,11 @@ struct stm32mp_bsec_platdata {
static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp) { +#ifdef CONFIG_STM32MP1_TRUSTED + return stm32_smc(STM32_SMC_BSEC, + STM32_SMC_READ_OTP, + otp, 0, val); +#else struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); u32 tmp_data = 0; int ret; @@ -299,27 +308,46 @@ static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp) /* restore shadow value */ ret = bsec_write_shadow(plat->base, tmp_data, otp); return ret; +#endif }
static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp) { +#ifdef CONFIG_STM32MP1_TRUSTED + return stm32_smc(STM32_SMC_BSEC, + STM32_SMC_READ_SHADOW, + otp, 0, val); +#else struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
return bsec_read_shadow(plat->base, val, otp); +#endif }
static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp) { +#ifdef CONFIG_STM32MP1_TRUSTED + return stm32_smc_exec(STM32_SMC_BSEC, + STM32_SMC_PROG_OTP, + otp, val); +#else struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
return bsec_program_otp(plat->base, val, otp); +#endif }
static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp) { +#ifdef CONFIG_STM32MP1_TRUSTED + return stm32_smc_exec(STM32_SMC_BSEC, + STM32_SMC_WRITE_SHADOW, + otp, val); +#else struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
return bsec_write_shadow(plat->base, val, otp); +#endif }
static int stm32mp_bsec_read(struct udevice *dev, int offset, diff --git a/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h new file mode 100644 index 0000000..8130546 --- /dev/null +++ b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (C) 2019, STMicroelectronics - All Rights Reserved + */ + +#ifndef __STM32MP1_SMC_H__ +#define __STM32MP1_SMC_H__ + +#include <linux/arm-smccc.h> + +/* + * SMC function IDs for STM32 Service queries + * STM32 SMC services use the space between 0x82000000 and 0x8200FFFF + * like this is defined in SMC calling Convention by ARM + * for SiP (silicon Partner) + * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html + */ +#define STM32_SMC_VERSION 0x82000000 + +/* Secure Service access from Non-secure */ +#define STM32_SMC_BSEC 0x82001003 + +/* Service for BSEC */ +#define STM32_SMC_READ_SHADOW 0x01 +#define STM32_SMC_PROG_OTP 0x02 +#define STM32_SMC_WRITE_SHADOW 0x03 +#define STM32_SMC_READ_OTP 0x04 +#define STM32_SMC_READ_ALL 0x05 +#define STM32_SMC_WRITE_ALL 0x06 + +/* SMC error codes */ +#define STM32_SMC_OK 0x0 +#define STM32_SMC_NOT_SUPPORTED -1 +#define STM32_SMC_FAILED -2 +#define STM32_SMC_INVALID_PARAMS -3 + +#define stm32_smc_exec(svc, op, data1, data2) \ + stm32_smc(svc, op, data1, data2, NULL) + +#ifdef CONFIG_ARM_SMCCC +static inline u32 stm32_smc(u32 svc, u8 op, u32 data1, u32 data2, u32 *result) +{ + struct arm_smccc_res res; + + arm_smccc_smc(svc, op, data1, data2, 0, 0, 0, 0, &res); + + if (res.a0) { + pr_err("%s: Failed to exec in secure mode (err = %ld)\n", + __func__, res.a0); + return -EINVAL; + } + if (result) + *result = (u32)res.a1; + + return 0; +} +#else +static inline u32 stm32_smc(u32 svc, u8 op, u32 data1, u32 data2, u32 *result) +{ + return 0; +} +#endif + +#endif /* __STM32MP1_SMC_H__ */

Implement checkboard() function to display - the boot chain used: basic or trusted - the board compatible in device tree - the board identifier and revision, saved in OTP59 for ST boards
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v3: None Changes in v2: None
arch/arm/mach-stm32mp/include/mach/stm32.h | 4 +++ board/st/stm32mp1/stm32mp1.c | 44 ++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h index 5d0bdca..85d783c 100644 --- a/arch/arm/mach-stm32mp/include/mach/stm32.h +++ b/arch/arm/mach-stm32mp/include/mach/stm32.h @@ -98,7 +98,11 @@ enum boot_device {
/* offset used for BSEC driver: misc_read and misc_write */ #define STM32_BSEC_SHADOW_OFFSET 0x0 +#define STM32_BSEC_SHADOW(id) (STM32_BSEC_SHADOW_OFFSET + (id) * 4) #define STM32_BSEC_OTP_OFFSET 0x80000000 +#define STM32_BSEC_OTP(id) (STM32_BSEC_OTP_OFFSET + (id) * 4) + +#define BSEC_OTP_BOARD 59
#endif /* __ASSEMBLY__*/ #endif /* _MACH_STM32_H_ */ diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 54feca0..07d1add 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -3,11 +3,12 @@ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ #include <config.h> -#include <common.h> -#include <led.h> #include <clk.h> +#include <common.h> #include <dm.h> #include <generic-phy.h> +#include <led.h> +#include <misc.h> #include <phy.h> #include <reset.h> #include <usb.h> @@ -26,6 +27,45 @@ DECLARE_GLOBAL_DATA_PTR; #define STM32MP_GGPIO 0x38 #define STM32MP_GGPIO_VBUS_SENSING BIT(21)
+int checkboard(void) +{ + int ret; + char *mode; + u32 otp; + struct udevice *dev; + const char *fdt_compat; + int fdt_compat_len; + + if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED)) + mode = "trusted"; + else + mode = "basic"; + + printf("Board: stm32mp1 in %s mode", mode); + fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible", + &fdt_compat_len); + if (fdt_compat && fdt_compat_len) + printf(" (%s)", fdt_compat); + puts("\n"); + + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_GET_DRIVER(stm32mp_bsec), + &dev); + + if (!ret) + ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), + &otp, sizeof(otp)); + if (!ret && otp) { + printf("Board: MB%04x Var%d Rev.%c-%02d\n", + otp >> 16, + (otp >> 12) & 0xF, + ((otp >> 8) & 0xF) - 1 + 'A', + otp & 0xF); + } + + return 0; +} + static struct dwc2_plat_otg_data stm32mp_otg_data = { .usb_gusbcfg = STM32MP_GUSBCFG, };
participants (1)
-
Patrick Delaunay