[U-Boot] [PATCH 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.
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 ---
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 d6b1629..2ee1dfe 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1351,8 +1351,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 cde5850..c2d74a0 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) += spl/u-boot-spl.stm32 +ifndef CONFIG_SPL +ALL-y += u-boot.stm32 +else +ifdef CONFIG_SPL_BUILD +ALL-y += spl/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

On Mon, Jan 28, 2019 at 11:25:05AM +0100, Patrick Delaunay wrote:
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
arch/arm/Kconfig | 6 ++-- arch/arm/mach-stm32mp/Kconfig | 17 +++++++++-- arch/arm/mach-stm32mp/config.mk | 15 +++++++++-
Sorry. My messing up of the patches to arch/arm/mach-stm32mp/config.mk before means this part doesn't apply cleanly and since I don't want to mess it up again and cause another round of changes here can you please rebase this series on master? Thanks and sorry for the trouble!

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 ---
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 ---
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 (2)
-
Patrick Delaunay
-
Tom Rini