stm32mp1: add trusted boot with TF-A

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>
This commit is contained in:
Patrick Delaunay 2019-02-12 11:44:39 +01:00
parent 48ff1bc4f0
commit abf2678f0f
10 changed files with 146 additions and 29 deletions

View File

@ -1406,8 +1406,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"

View File

@ -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

View File

@ -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)

View File

@ -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,8 +170,9 @@ 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 */
@ -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();

View File

@ -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: board/st/stm32mp1
F: include/configs/stm32mp1.h
F: configs/stm32mp15_basic_defconfig
F: arch/arm/dts/stm32mp157*
F: board/st/stm32mp1
F: configs/stm32mp15_basic_defconfig
F: configs/stm32mp15_trusted_defconfig
F: include/configs/stm32mp1.h

View File

@ -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

View File

@ -0,0 +1,58 @@
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_CLK=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

View File

@ -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

View File

@ -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

View File

@ -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