diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S new file mode 100644 index 0000000..2b7c83d --- /dev/null +++ b/drivers/st/uart/aarch32/stm32_console.S @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + + .globl console_core_init + .globl console_core_putc + .globl console_core_getc + .globl console_core_flush + + /* ----------------------------------------------------------------- + * int console_core_init(uintptr_t base_addr, + * unsigned int uart_clk, + * unsigned int baud_rate) + * + * Function to initialize the console without a C Runtime to print + * debug information. This function will be accessed by console_init + * and crash reporting. + * + * In: r0 - console base address + * r1 - Uart clock in Hz + * r2 - Baud rate + * Out: return 1 on success else 0 on error + * Clobber list : r1, r2, r3 + * ----------------------------------------------------------------- + */ +func console_core_init + bx lr +endfunc console_core_init + + /* --------------------------------------------------------------- + * int console_core_putc(int c, uintptr_t base_addr) + * + * Function to output a character over the console. It returns the + * character printed on success or -1 on error. + * + * In : r0 - character to be printed + * r1 - console base address + * Out : return -1 on error else return character. + * Clobber list : r2 + * --------------------------------------------------------------- + */ +func console_core_putc + bx lr +endfunc console_core_putc + + /* ----------------------------------------------------------- + * int console_core_getc(uintptr_t base_addr) + * + * Function to get a character from the console. + * It returns the character grabbed on success or -1 on error. + * + * In : r0 - console base address + * Out : return -1. + * Clobber list : r0, r1 + * ----------------------------------------------------------- + */ +func console_core_getc + /* Not supported */ + mov r0, #-1 + bx lr +endfunc console_core_getc + + /* --------------------------------------------------------------- + * int console_core_flush(uintptr_t base_addr) + * + * Function to force a write of all buffered data that hasn't been + * output. + * + * In : r0 - console base address + * Out : return -1 on error else return 0. + * Clobber list : r0, r1 + * --------------------------------------------------------------- + */ +func console_core_flush + bx lr +endfunc console_core_flush diff --git a/include/drivers/st/stm32mp1_pwr.h b/include/drivers/st/stm32mp1_pwr.h new file mode 100644 index 0000000..e567042 --- /dev/null +++ b/include/drivers/st/stm32mp1_pwr.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __STM32MP1_PWR_H__ +#define __STM32MP1_PWR_H__ + +#include + +#define PWR_CR1 U(0x00) +#define PWR_CR2 U(0x08) +#define PWR_CR3 U(0x0C) +#define PWR_MPUCR U(0x10) +#define PWR_WKUPCR U(0x20) +#define PWR_MPUWKUPENR U(0x28) + +#define PWR_CR1_LPDS BIT(0) +#define PWR_CR1_LPCFG BIT(1) +#define PWR_CR1_LVDS BIT(2) +#define PWR_CR1_DBP BIT(8) + +#define PWR_CR3_DDRSREN BIT(10) +#define PWR_CR3_DDRSRDIS BIT(11) +#define PWR_CR3_DDRRETEN BIT(12) + +#define PWR_MPUCR_PDDS BIT(0) +#define PWR_MPUCR_CSTDBYDIS BIT(3) +#define PWR_MPUCR_CSSF BIT(9) + +#endif /* __STM32MP1_PWR_H__ */ diff --git a/include/drivers/st/stm32mp1_rcc.h b/include/drivers/st/stm32mp1_rcc.h new file mode 100644 index 0000000..e28ca97 --- /dev/null +++ b/include/drivers/st/stm32mp1_rcc.h @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __STM32MP1_RCC_H__ +#define __STM32MP1_RCC_H__ + +#include + +#define RCC_TZCR U(0x00) +#define RCC_OCENSETR U(0x0C) +#define RCC_OCENCLRR U(0x10) +#define RCC_HSICFGR U(0x18) +#define RCC_CSICFGR U(0x1C) +#define RCC_MPCKSELR U(0x20) +#define RCC_ASSCKSELR U(0x24) +#define RCC_RCK12SELR U(0x28) +#define RCC_MPCKDIVR U(0x2C) +#define RCC_AXIDIVR U(0x30) +#define RCC_APB4DIVR U(0x3C) +#define RCC_APB5DIVR U(0x40) +#define RCC_RTCDIVR U(0x44) +#define RCC_MSSCKSELR U(0x48) +#define RCC_PLL1CR U(0x80) +#define RCC_PLL1CFGR1 U(0x84) +#define RCC_PLL1CFGR2 U(0x88) +#define RCC_PLL1FRACR U(0x8C) +#define RCC_PLL1CSGR U(0x90) +#define RCC_PLL2CR U(0x94) +#define RCC_PLL2CFGR1 U(0x98) +#define RCC_PLL2CFGR2 U(0x9C) +#define RCC_PLL2FRACR U(0xA0) +#define RCC_PLL2CSGR U(0xA4) +#define RCC_I2C46CKSELR U(0xC0) +#define RCC_SPI6CKSELR U(0xC4) +#define RCC_UART1CKSELR U(0xC8) +#define RCC_RNG1CKSELR U(0xCC) +#define RCC_CPERCKSELR U(0xD0) +#define RCC_STGENCKSELR U(0xD4) +#define RCC_DDRITFCR U(0xD8) +#define RCC_MP_BOOTCR U(0x100) +#define RCC_MP_SREQSETR U(0x104) +#define RCC_MP_SREQCLRR U(0x108) +#define RCC_MP_GCR U(0x10C) +#define RCC_MP_APRSTCR U(0x110) +#define RCC_MP_APRSTSR U(0x114) +#define RCC_BDCR U(0x140) +#define RCC_RDLSICR U(0x144) +#define RCC_APB4RSTSETR U(0x180) +#define RCC_APB4RSTCLRR U(0x184) +#define RCC_APB5RSTSETR U(0x188) +#define RCC_APB5RSTCLRR U(0x18C) +#define RCC_AHB5RSTSETR U(0x190) +#define RCC_AHB5RSTCLRR U(0x194) +#define RCC_AHB6RSTSETR U(0x198) +#define RCC_AHB6RSTCLRR U(0x19C) +#define RCC_TZAHB6RSTSETR U(0x1A0) +#define RCC_TZAHB6RSTCLRR U(0x1A4) +#define RCC_MP_APB4ENSETR U(0x200) +#define RCC_MP_APB4ENCLRR U(0x204) +#define RCC_MP_APB5ENSETR U(0x208) +#define RCC_MP_APB5ENCLRR U(0x20C) +#define RCC_MP_AHB5ENSETR U(0x210) +#define RCC_MP_AHB5ENCLRR U(0x214) +#define RCC_MP_AHB6ENSETR U(0x218) +#define RCC_MP_AHB6ENCLRR U(0x21C) +#define RCC_MP_TZAHB6ENSETR U(0x220) +#define RCC_MP_TZAHB6ENCLRR U(0x224) +#define RCC_MP_APB4LPENSETR U(0x300) +#define RCC_MP_APB4LPENCLRR U(0x304) +#define RCC_MP_APB5LPENSETR U(0x308) +#define RCC_MP_APB5LPENCLRR U(0x30C) +#define RCC_MP_AHB5LPENSETR U(0x310) +#define RCC_MP_AHB5LPENCLRR U(0x314) +#define RCC_MP_AHB6LPENSETR U(0x318) +#define RCC_MP_AHB6LPENCLRR U(0x31C) +#define RCC_MP_TZAHB6LPENSETR U(0x320) +#define RCC_MP_TZAHB6LPENCLRR U(0x324) +#define RCC_BR_RSTSCLRR U(0x400) +#define RCC_MP_GRSTCSETR U(0x404) +#define RCC_MP_RSTSCLRR U(0x408) +#define RCC_MP_IWDGFZSETR U(0x40C) +#define RCC_MP_IWDGFZCLRR U(0x410) +#define RCC_MP_CIER U(0x414) +#define RCC_MP_CIFR U(0x418) +#define RCC_PWRLPDLYCR U(0x41C) +#define RCC_MP_RSTSSETR U(0x420) +#define RCC_MCO1CFGR U(0x800) +#define RCC_MCO2CFGR U(0x804) +#define RCC_OCRDYR U(0x808) +#define RCC_DBGCFGR U(0x80C) +#define RCC_RCK3SELR U(0x820) +#define RCC_RCK4SELR U(0x824) +#define RCC_TIMG1PRER U(0x828) +#define RCC_TIMG2PRER U(0x82C) +#define RCC_APB1DIVR U(0x834) +#define RCC_APB2DIVR U(0x838) +#define RCC_APB3DIVR U(0x83C) +#define RCC_PLL3CR U(0x880) +#define RCC_PLL3CFGR1 U(0x884) +#define RCC_PLL3CFGR2 U(0x888) +#define RCC_PLL3FRACR U(0x88C) +#define RCC_PLL3CSGR U(0x890) +#define RCC_PLL4CR U(0x894) +#define RCC_PLL4CFGR1 U(0x898) +#define RCC_PLL4CFGR2 U(0x89C) +#define RCC_PLL4FRACR U(0x8A0) +#define RCC_PLL4CSGR U(0x8A4) +#define RCC_I2C12CKSELR U(0x8C0) +#define RCC_I2C35CKSELR U(0x8C4) +#define RCC_SAI1CKSELR U(0x8C8) +#define RCC_SAI2CKSELR U(0x8CC) +#define RCC_SAI3CKSELR U(0x8D0) +#define RCC_SAI4CKSELR U(0x8D4) +#define RCC_SPI2S1CKSELR U(0x8D8) +#define RCC_SPI2S23CKSELR U(0x8DC) +#define RCC_SPI45CKSELR U(0x8E0) +#define RCC_UART6CKSELR U(0x8E4) +#define RCC_UART24CKSELR U(0x8E8) +#define RCC_UART35CKSELR U(0x8EC) +#define RCC_UART78CKSELR U(0x8F0) +#define RCC_SDMMC12CKSELR U(0x8F4) +#define RCC_SDMMC3CKSELR U(0x8F8) +#define RCC_ETHCKSELR U(0x8FC) +#define RCC_QSPICKSELR U(0x900) +#define RCC_FMCCKSELR U(0x904) +#define RCC_FDCANCKSELR U(0x90C) +#define RCC_SPDIFCKSELR U(0x914) +#define RCC_CECCKSELR U(0x918) +#define RCC_USBCKSELR U(0x91C) +#define RCC_RNG2CKSELR U(0x920) +#define RCC_DSICKSELR U(0x924) +#define RCC_ADCCKSELR U(0x928) +#define RCC_LPTIM45CKSELR U(0x92C) +#define RCC_LPTIM23CKSELR U(0x930) +#define RCC_LPTIM1CKSELR U(0x934) +#define RCC_APB1RSTSETR U(0x980) +#define RCC_APB1RSTCLRR U(0x984) +#define RCC_APB2RSTSETR U(0x988) +#define RCC_APB2RSTCLRR U(0x98C) +#define RCC_APB3RSTSETR U(0x990) +#define RCC_APB3RSTCLRR U(0x994) +#define RCC_AHB2RSTSETR U(0x998) +#define RCC_AHB2RSTCLRR U(0x99C) +#define RCC_AHB3RSTSETR U(0x9A0) +#define RCC_AHB3RSTCLRR U(0x9A4) +#define RCC_AHB4RSTSETR U(0x9A8) +#define RCC_AHB4RSTCLRR U(0x9AC) +#define RCC_MP_APB1ENSETR U(0xA00) +#define RCC_MP_APB1ENCLRR U(0xA04) +#define RCC_MP_APB2ENSETR U(0xA08) +#define RCC_MP_APB2ENCLRR U(0xA0C) +#define RCC_MP_APB3ENSETR U(0xA10) +#define RCC_MP_APB3ENCLRR U(0xA14) +#define RCC_MP_AHB2ENSETR U(0xA18) +#define RCC_MP_AHB2ENCLRR U(0xA1C) +#define RCC_MP_AHB3ENSETR U(0xA20) +#define RCC_MP_AHB3ENCLRR U(0xA24) +#define RCC_MP_AHB4ENSETR U(0xA28) +#define RCC_MP_AHB4ENCLRR U(0xA2C) +#define RCC_MP_MLAHBENSETR U(0xA38) +#define RCC_MP_MLAHBENCLRR U(0xA3C) +#define RCC_MP_APB1LPENSETR U(0xB00) +#define RCC_MP_APB1LPENCLRR U(0xB04) +#define RCC_MP_APB2LPENSETR U(0xB08) +#define RCC_MP_APB2LPENCLRR U(0xB0C) +#define RCC_MP_APB3LPENSETR U(0xB10) +#define RCC_MP_APB3LPENCLRR U(0xB14) +#define RCC_MP_AHB2LPENSETR U(0xB18) +#define RCC_MP_AHB2LPENCLRR U(0xB1C) +#define RCC_MP_AHB3LPENSETR U(0xB20) +#define RCC_MP_AHB3LPENCLRR U(0xB24) +#define RCC_MP_AHB4LPENSETR U(0xB28) +#define RCC_MP_AHB4LPENCLRR U(0xB2C) +#define RCC_MP_AXIMLPENSETR U(0xB30) +#define RCC_MP_AXIMLPENCLRR U(0xB34) +#define RCC_MP_MLAHBLPENSETR U(0xB38) +#define RCC_MP_MLAHBLPENCLRR U(0xB3C) +#define RCC_VERR U(0xFF4) +#define RCC_IDR U(0xFF8) +#define RCC_SIDR U(0xFFC) + +/* Values for RCC_TZCR register */ +#define RCC_TZCR_TZEN BIT(0) + +/* Used for most of RCC_SELR registers */ +#define RCC_SELR_SRC_MASK GENMASK(2, 0) +#define RCC_SELR_REFCLK_SRC_MASK GENMASK(1, 0) +#define RCC_SELR_SRCRDY BIT(31) + +/* Values of RCC_MPCKSELR register */ +#define RCC_MPCKSELR_HSI 0x00000000 +#define RCC_MPCKSELR_HSE 0x00000001 +#define RCC_MPCKSELR_PLL 0x00000002 +#define RCC_MPCKSELR_PLL_MPUDIV 0x00000003 + +/* Values of RCC_ASSCKSELR register */ +#define RCC_ASSCKSELR_HSI 0x00000000 +#define RCC_ASSCKSELR_HSE 0x00000001 +#define RCC_ASSCKSELR_PLL 0x00000002 + +/* Values of RCC_MSSCKSELR register */ +#define RCC_MSSCKSELR_HSI 0x00000000 +#define RCC_MSSCKSELR_HSE 0x00000001 +#define RCC_MSSCKSELR_CSI 0x00000002 +#define RCC_MSSCKSELR_PLL 0x00000003 + +/* Values of RCC_CPERCKSELR register */ +#define RCC_CPERCKSELR_HSI 0x00000000 +#define RCC_CPERCKSELR_CSI 0x00000001 +#define RCC_CPERCKSELR_HSE 0x00000002 + +/* Used for most of DIVR register: max div for RTC */ +#define RCC_DIVR_DIV_MASK GENMASK(5, 0) +#define RCC_DIVR_DIVRDY BIT(31) + +/* Masks for specific DIVR registers */ +#define RCC_APBXDIV_MASK GENMASK(2, 0) +#define RCC_MPUDIV_MASK GENMASK(2, 0) +#define RCC_AXIDIV_MASK GENMASK(2, 0) + +/* Offset between RCC_MP_xxxENSETR and RCC_MP_xxxENCLRR registers */ +#define RCC_MP_ENCLRR_OFFSET U(4) + +/* Fields of RCC_BDCR register */ +#define RCC_BDCR_LSEON BIT(0) +#define RCC_BDCR_LSEBYP BIT(1) +#define RCC_BDCR_LSERDY BIT(2) +#define RCC_BDCR_LSEDRV_MASK GENMASK(5, 4) +#define RCC_BDCR_LSEDRV_SHIFT 4 +#define RCC_BDCR_LSECSSON BIT(8) +#define RCC_BDCR_RTCCKEN BIT(20) +#define RCC_BDCR_RTCSRC_MASK GENMASK(17, 16) +#define RCC_BDCR_RTCSRC_SHIFT 16 +#define RCC_BDCR_VSWRST BIT(31) + +/* Fields of RCC_RDLSICR register */ +#define RCC_RDLSICR_LSION BIT(0) +#define RCC_RDLSICR_LSIRDY BIT(1) + +/* Used for all RCC_PLLCR registers */ +#define RCC_PLLNCR_PLLON BIT(0) +#define RCC_PLLNCR_PLLRDY BIT(1) +#define RCC_PLLNCR_DIVPEN BIT(4) +#define RCC_PLLNCR_DIVQEN BIT(5) +#define RCC_PLLNCR_DIVREN BIT(6) +#define RCC_PLLNCR_DIVEN_SHIFT 4 + +/* Used for all RCC_PLLCFGR1 registers */ +#define RCC_PLLNCFGR1_DIVM_SHIFT 16 +#define RCC_PLLNCFGR1_DIVM_MASK GENMASK(21, 16) +#define RCC_PLLNCFGR1_DIVN_SHIFT 0 +#define RCC_PLLNCFGR1_DIVN_MASK GENMASK(8, 0) +/* Only for PLL3 and PLL4 */ +#define RCC_PLLNCFGR1_IFRGE_SHIFT 24 +#define RCC_PLLNCFGR1_IFRGE_MASK GENMASK(25, 24) + +/* Used for all RCC_PLLCFGR2 registers */ +#define RCC_PLLNCFGR2_DIVX_MASK GENMASK(6, 0) +#define RCC_PLLNCFGR2_DIVP_SHIFT 0 +#define RCC_PLLNCFGR2_DIVP_MASK GENMASK(6, 0) +#define RCC_PLLNCFGR2_DIVQ_SHIFT 8 +#define RCC_PLLNCFGR2_DIVQ_MASK GENMASK(14, 8) +#define RCC_PLLNCFGR2_DIVR_SHIFT 16 +#define RCC_PLLNCFGR2_DIVR_MASK GENMASK(22, 16) + +/* Used for all RCC_PLLFRACR registers */ +#define RCC_PLLNFRACR_FRACV_SHIFT 3 +#define RCC_PLLNFRACR_FRACV_MASK GENMASK(15, 3) +#define RCC_PLLNFRACR_FRACLE BIT(16) + +/* Used for all RCC_PLLCSGR registers */ +#define RCC_PLLNCSGR_INC_STEP_SHIFT 16 +#define RCC_PLLNCSGR_INC_STEP_MASK GENMASK(30, 16) +#define RCC_PLLNCSGR_MOD_PER_SHIFT 0 +#define RCC_PLLNCSGR_MOD_PER_MASK GENMASK(12, 0) +#define RCC_PLLNCSGR_SSCG_MODE_SHIFT 15 +#define RCC_PLLNCSGR_SSCG_MODE_MASK BIT(15) + +/* Used for RCC_OCENSETR and RCC_OCENCLRR registers */ +#define RCC_OCENR_HSION BIT(0) +#define RCC_OCENR_CSION BIT(4) +#define RCC_OCENR_HSEON BIT(8) +#define RCC_OCENR_HSEBYP BIT(10) +#define RCC_OCENR_HSECSSON BIT(11) + +/* Fields of RCC_OCRDYR register */ +#define RCC_OCRDYR_HSIRDY BIT(0) +#define RCC_OCRDYR_HSIDIVRDY BIT(2) +#define RCC_OCRDYR_CSIRDY BIT(4) +#define RCC_OCRDYR_HSERDY BIT(8) + +/* Fields of RCC_DDRITFCR register */ +#define RCC_DDRITFCR_DDRC1EN BIT(0) +#define RCC_DDRITFCR_DDRC1LPEN BIT(1) +#define RCC_DDRITFCR_DDRC2EN BIT(2) +#define RCC_DDRITFCR_DDRC2LPEN BIT(3) +#define RCC_DDRITFCR_DDRPHYCEN BIT(4) +#define RCC_DDRITFCR_DDRPHYCLPEN BIT(5) +#define RCC_DDRITFCR_DDRCAPBEN BIT(6) +#define RCC_DDRITFCR_DDRCAPBLPEN BIT(7) +#define RCC_DDRITFCR_AXIDCGEN BIT(8) +#define RCC_DDRITFCR_DDRPHYCAPBEN BIT(9) +#define RCC_DDRITFCR_DDRPHYCAPBLPEN BIT(10) +#define RCC_DDRITFCR_DDRCAPBRST BIT(14) +#define RCC_DDRITFCR_DDRCAXIRST BIT(15) +#define RCC_DDRITFCR_DDRCORERST BIT(16) +#define RCC_DDRITFCR_DPHYAPBRST BIT(17) +#define RCC_DDRITFCR_DPHYRST BIT(18) +#define RCC_DDRITFCR_DPHYCTLRST BIT(19) +#define RCC_DDRITFCR_DDRCKMOD_MASK GENMASK(22, 20) +#define RCC_DDRITFCR_DDRCKMOD_SHIFT 20 +#define RCC_DDRITFCR_DDRCKMOD_SSR 0 +#define RCC_DDRITFCR_DDRCKMOD_ASR1 BIT(20) +#define RCC_DDRITFCR_DDRCKMOD_HSR1 BIT(21) +#define RCC_DDRITFCR_GSKPCTRL BIT(24) + +/* Fields of RCC_HSICFGR register */ +#define RCC_HSICFGR_HSIDIV_MASK GENMASK(1, 0) + +/* Used for RCC_MCO related operations */ +#define RCC_MCOCFG_MCOON BIT(12) +#define RCC_MCOCFG_MCODIV_MASK GENMASK(7, 4) +#define RCC_MCOCFG_MCODIV_SHIFT 4 +#define RCC_MCOCFG_MCOSRC_MASK GENMASK(2, 0) + +/* Fields of RCC_DBGCFGR register */ +#define RCC_DBGCFGR_DBGCKEN BIT(8) + +/* RCC register fields for reset reasons */ +#define RCC_MP_RSTSCLRR_PORRSTF BIT(0) +#define RCC_MP_RSTSCLRR_BORRSTF BIT(1) +#define RCC_MP_RSTSCLRR_PADRSTF BIT(2) +#define RCC_MP_RSTSCLRR_HCSSRSTF BIT(3) +#define RCC_MP_RSTSCLRR_VCORERSTF BIT(4) +#define RCC_MP_RSTSCLRR_MPSYSRSTF BIT(6) +#define RCC_MP_RSTSCLRR_IWDG1RSTF BIT(8) +#define RCC_MP_RSTSCLRR_IWDG2RSTF BIT(9) +#define RCC_MP_RSTSCLRR_STDBYRSTF BIT(11) +#define RCC_MP_RSTSCLRR_CSTDBYRSTF BIT(12) + +/* Global Reset Register */ +#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0) + +/* Clock Source Interrupt Flag Register */ +#define RCC_MP_CIFR_MASK U(0x110F1F) +#define RCC_MP_CIFR_WKUPF BIT(20) + +/* Stop Request Set Register */ +#define RCC_MP_SREQSETR_STPREQ_P0 BIT(0) +#define RCC_MP_SREQSETR_STPREQ_P1 BIT(1) + +/* Stop Request Clear Register */ +#define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0) +#define RCC_MP_SREQCLRR_STPREQ_P1 BIT(1) + +/* Values of RCC_UART24CKSELR register */ +#define RCC_UART24CKSELR_HSI 0x00000002 + +/* Values of RCC_MP_APB1ENSETR register */ +#define RCC_MP_APB1ENSETR_UART4EN BIT(16) + +/* Values of RCC_MP_AHB4ENSETR register */ +#define RCC_MP_AHB4ENSETR_GPIOGEN BIT(6) + +#endif /* __STM32MP1_RCC_H__ */ diff --git a/plat/st/stm32mp1/bl2_io_storage.c b/plat/st/stm32mp1/bl2_io_storage.c new file mode 100644 index 0000000..7346c0c --- /dev/null +++ b/plat/st/stm32mp1/bl2_io_storage.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* IO devices */ +static const io_dev_connector_t *dummy_dev_con; +static uintptr_t dummy_dev_handle; +static uintptr_t dummy_dev_spec; + +static const io_block_spec_t bl32_block_spec = { + .offset = BL32_BASE, + .length = STM32MP1_BL32_SIZE +}; + +static const io_block_spec_t bl2_block_spec = { + .offset = BL2_BASE, + .length = STM32MP1_BL2_SIZE, +}; + +static int open_dummy(const uintptr_t spec); + +struct plat_io_policy { + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +static const struct plat_io_policy policies[] = { + [BL2_IMAGE_ID] = { + .dev_handle = &dummy_dev_handle, + .image_spec = (uintptr_t)&bl2_block_spec, + .check = open_dummy + }, + [BL32_IMAGE_ID] = { + .dev_handle = &dummy_dev_handle, + .image_spec = (uintptr_t)&bl32_block_spec, + .check = open_dummy + }, +}; + +static int open_dummy(const uintptr_t spec) +{ + return io_dev_init(dummy_dev_handle, 0); +} + +static void print_boot_device(boot_api_context_t *boot_context) +{ + switch (boot_context->boot_interface_selected) { + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: + INFO("Using SDMMC\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: + INFO("Using EMMC\n"); + break; + default: + ERROR("Boot interface not found\n"); + panic(); + break; + } + + if (boot_context->boot_interface_instance != 0U) { + INFO(" Instance %d\n", boot_context->boot_interface_instance); + } +} + +static void print_reset_reason(void) +{ + uint32_t rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR); + + if (rstsr == 0U) { + WARN("Reset reason unknown\n"); + return; + } + + INFO("Reset reason (0x%x):\n", rstsr); + + if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U) { + if ((rstsr & RCC_MP_RSTSCLRR_STDBYRSTF) != 0U) { + INFO("System exits from STANDBY\n"); + return; + } + + if ((rstsr & RCC_MP_RSTSCLRR_CSTDBYRSTF) != 0U) { + INFO("MPU exits from CSTANDBY\n"); + return; + } + } + + if ((rstsr & RCC_MP_RSTSCLRR_PORRSTF) != 0U) { + INFO(" Power-on Reset (rst_por)\n"); + return; + } + + if ((rstsr & RCC_MP_RSTSCLRR_BORRSTF) != 0U) { + INFO(" Brownout Reset (rst_bor)\n"); + return; + } + + if ((rstsr & RCC_MP_RSTSCLRR_MPSYSRSTF) != 0U) { + INFO(" System reset generated by MPU (MPSYSRST)\n"); + return; + } + + if ((rstsr & RCC_MP_RSTSCLRR_HCSSRSTF) != 0U) { + INFO(" Reset due to a clock failure on HSE\n"); + return; + } + + if ((rstsr & RCC_MP_RSTSCLRR_IWDG1RSTF) != 0U) { + INFO(" IWDG1 Reset (rst_iwdg1)\n"); + return; + } + + if ((rstsr & RCC_MP_RSTSCLRR_IWDG2RSTF) != 0U) { + INFO(" IWDG2 Reset (rst_iwdg2)\n"); + return; + } + + if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) { + INFO(" Pad Reset from NRST\n"); + return; + } + + if ((rstsr & RCC_MP_RSTSCLRR_VCORERSTF) != 0U) { + INFO(" Reset due to a failure of VDD_CORE\n"); + return; + } + + ERROR(" Unidentified reset reason\n"); +} + +void stm32mp1_io_setup(void) +{ + int io_result __unused; + boot_api_context_t *boot_context = + (boot_api_context_t *)stm32mp1_get_boot_ctx_address(); + + print_reset_reason(); + + print_boot_device(boot_context); + + if ((boot_context->boot_partition_used_toboot == 1U) || + (boot_context->boot_partition_used_toboot == 2U)) { + INFO("Boot used partition fsbl%d\n", + boot_context->boot_partition_used_toboot); + } + + io_result = register_io_dev_dummy(&dummy_dev_con); + assert(io_result == 0); + + io_result = io_dev_open(dummy_dev_con, dummy_dev_spec, + &dummy_dev_handle); + assert(io_result == 0); +} + +/* + * Return an IO device handle and specification which can be used to access + * an image. Use this to enforce platform load policy. + */ +int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int rc; + const struct plat_io_policy *policy; + + assert(image_id < ARRAY_SIZE(policies)); + + policy = &policies[image_id]; + rc = policy->check(policy->image_spec); + if (rc == 0) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + } + + return rc; +} diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c new file mode 100644 index 0000000..d386202 --- /dev/null +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + stm32mp1_save_boot_ctx_address(arg0); +} + +void bl2_platform_setup(void) +{ + INFO("BL2 runs SP_MIN setup\n"); +} + +void bl2_el3_plat_arch_setup(void) +{ + /* + * Disable the backup domain write protection. + * The protection is enable at each reset by hardware + * and must be disabled by software. + */ + mmio_setbits_32(PWR_BASE + PWR_CR1, PWR_CR1_DBP); + + while ((mmio_read_32(PWR_BASE + PWR_CR1) & PWR_CR1_DBP) == 0U) { + ; + } + + /* Reset backup domain on cold boot cases */ + if ((mmio_read_32(RCC_BASE + RCC_BDCR) & RCC_BDCR_RTCSRC_MASK) == 0U) { + mmio_setbits_32(RCC_BASE + RCC_BDCR, RCC_BDCR_VSWRST); + + while ((mmio_read_32(RCC_BASE + RCC_BDCR) & RCC_BDCR_VSWRST) == + 0U) { + ; + } + + mmio_clrbits_32(RCC_BASE + RCC_BDCR, RCC_BDCR_VSWRST); + } + + mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, + BL_CODE_END - BL_CODE_BASE, + MT_CODE | MT_SECURE); + + /* Prevent corruption of preloaded BL32 */ + mmap_add_region(BL32_BASE, BL32_BASE, + BL32_LIMIT - BL32_BASE, + MT_MEMORY | MT_RO | MT_SECURE); + + /* Prevent corruption of preloaded Device Tree */ + mmap_add_region(DTB_BASE, DTB_BASE, + DTB_LIMIT - DTB_BASE, + MT_MEMORY | MT_RO | MT_SECURE); + + configure_mmu(); + + generic_delay_timer_init(); + + stm32mp1_io_setup(); +} diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h new file mode 100644 index 0000000..71c3593 --- /dev/null +++ b/plat/st/stm32mp1/include/boot_api.h @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2017, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __BOOT_API_H +#define __BOOT_API_H + +#include + +/* + * Possible value of boot context field 'boot_interface_sel' + */ + +/* Value of field 'boot_interface_sel' when no boot occurred */ +#define BOOT_API_CTX_BOOT_INTERFACE_SEL_NO 0x0U + +/* Boot occurred on SD */ +#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD 0x1U + +/* Boot occurred on EMMC */ +#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC 0x2U + +/** + * @brief Possible value of boot context field 'EmmcXferStatus' + */ +/* + * Possible value of boot context field 'emmc_xfer_status' + */ +#define BOOT_API_CTX_EMMC_XFER_STATUS_NOT_STARTED 0x0U +#define BOOT_API_CTX_EMMC_XFER_STATUS_DATAEND_DETECTED 0x1U +#define BOOT_API_CTX_EMMC_XFER_STATUS_XFER_OVERALL_TIMEOUT_DETECTED 0x2U +#define BOOT_API_CTX_EMMC_XFER_STATUS_XFER_DATA_TIMEOUT 0x3U + +/* + * Possible value of boot context field 'emmc_error_status' + */ +#define BOOT_API_CTX_EMMC_ERROR_STATUS_NONE 0x0U +#define BOOT_API_CTX_EMMC_ERROR_STATUS_CMD_TIMEOUT 0x1U +#define BOOT_API_CTX_EMMC_ERROR_STATUS_ACK_TIMEOUT 0x2U +#define BOOT_API_CTX_EMMC_ERROR_STATUS_DATA_CRC_FAIL 0x3U +#define BOOT_API_CTX_EMMC_ERROR_STATUS_NOT_ENOUGH_BOOT_DATA_RX 0x4U +#define BOOT_API_CTX_EMMC_ERROR_STATUS_HEADER_NOT_FOUND 0x5U +#define BOOT_API_CTX_EMMC_ERROR_STATUS_HEADER_SIZE_ZERO 0x6U +#define BOOT_API_CTX_EMMC_ERROR_STATUS_IMAGE_NOT_COMPLETE 0x7U + +/* Image Header related definitions */ + +/* Definition of header version */ +#define BOOT_API_HEADER_VERSION 0x00010000U + +/* + * Magic number used to detect header in memory + * Its value must be 'S' 'T' 'M' 0x32, i.e 0x324D5453 as field + * 'bootapi_image_header_t.magic' + * This identifies the start of a boot image. + */ +#define BOOT_API_IMAGE_HEADER_MAGIC_NB 0x324D5453U + +/* Definitions related to Authentication used in image header structure */ +#define BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES 64 +#define BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES 64 +#define BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES 32 + +/* Possible values of the field 'boot_api_image_header_t.ecc_algo_type' */ +#define BOOT_API_ECDSA_ALGO_TYPE_P256NIST 1 +#define BOOT_API_ECDSA_ALGO_TYPE_BRAINPOOL256 2 + +/* + * Cores secure magic numbers + * Constant to be stored in bakcup register + * BOOT_API_MAGIC_NUMBER_TAMP_BCK_REG_IDX + */ +#define BOOT_API_A7_CORE0_MAGIC_NUMBER 0xCA7FACE0U +#define BOOT_API_A7_CORE1_MAGIC_NUMBER 0xCA7FACE1U + +/* + * TAMP_BCK4R register index + * This register is used to write a Magic Number in order to restart + * Cortex A7 Core 1 and make it execute @ branch address from TAMP_BCK5R + */ +#define BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX 4U + +/* + * TAMP_BCK5R register index + * This register is used to contain the branch address of + * Cortex A7 Core 1 when restarted by a TAMP_BCK4R magic number writing + */ +#define BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX 5U + +/* + * Possible value of boot context field 'hse_clock_value_in_hz' + */ +#define BOOT_API_CTX_HSE_CLOCK_VALUE_UNDEFINED 0U +#define BOOT_API_CTX_HSE_CLOCK_VALUE_24_MHZ 24000000U +#define BOOT_API_CTX_HSE_CLOCK_VALUE_25_MHZ 25000000U +#define BOOT_API_CTX_HSE_CLOCK_VALUE_26_MHZ 26000000U + +/* + * Possible value of boot context field 'boot_partition_used_toboot' + */ +#define BOOT_API_CTX_BOOT_PARTITION_UNDEFINED 0U + +/* Used FSBL1 to boot */ +#define BOOT_API_CTX_BOOT_PARTITION_FSBL1 1U + +/* Used FSBL2 to boot */ +#define BOOT_API_CTX_BOOT_PARTITION_FSBL2 2U + +/* OTP_CFG0 */ +#define BOOT_API_OTP_MODE_WORD_NB 0 +/* Closed = OTP_CFG0[6] */ +#define BOOT_API_OTP_MODE_CLOSED_BIT_POS 6 + +/* + * Boot Context related definitions + */ + +/* + * Boot core boot configuration structure + * Specifies all items of the cold boot configuration + * Memory and peripheral part. + */ +typedef struct { + /* + * Boot interface used to boot : take values from defines + * BOOT_API_CTX_BOOT_INTERFACE_SEL_XXX above + */ + uint16_t boot_interface_selected; + uint16_t boot_interface_instance; + uint32_t reserved1[13]; + uint32_t otp_afmux_values[3]; + uint32_t reserved[9]; + /* + * Information specific to an SD boot + * Updated each time an SD boot is at least attempted, + * even if not successful + * Note : This is useful to understand why an SD boot failed + * in particular + */ + uint32_t sd_err_internal_timeout_cnt; + uint32_t sd_err_dcrc_fail_cnt; + uint32_t sd_err_dtimeout_cnt; + uint32_t sd_err_ctimeout_cnt; + uint32_t sd_err_ccrc_fail_cnt; + uint32_t sd_overall_retry_cnt; + /* + * Information specific to an eMMC boot + * Updated each time an eMMC boot is at least attempted, + * even if not successful + * Note : This is useful to understand why an eMMC boot failed + * in particular + */ + uint32_t emmc_xfer_status; + uint32_t emmc_error_status; + uint32_t emmc_nbbytes_rxcopied_tosysram_download_area; + uint32_t hse_clock_value_in_hz; + /* + * Boot partition : + * ie FSBL partition on which the boot was successful + */ + uint32_t boot_partition_used_toboot; + +} __packed boot_api_context_t; + +/* + * Image Header related definitions + */ + +/* + * Structure used to define the common Header format used for FSBL, xloader, + * ... and in particular used by bootROM for FSBL header readout. + * FSBL header size is 256 Bytes = 0x100 + */ +typedef struct { + /* BOOT_API_IMAGE_HEADER_MAGIC_NB */ + uint32_t magic; + uint8_t image_signature[BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES]; + /* + * Checksum of payload + * 32-bit sum all all payload bytes considered as 8 bit unigned numbers, + * discarding any overflow bits. + * Use to check UART/USB downloaded image integrity when signature + * is not used (i.e bit 0 : 'No_sig_check' = 1 in option flags) + */ + uint32_t payload_checksum; + /* Image header version : should have value BOOT_API_HEADER_VERSION */ + uint32_t header_version; + /* Image length in bytes */ + uint32_t image_length; + /* + * Image Entry point address : should be in the SYSRAM area + * and at least within the download area range + */ + uint32_t image_entry_point; + /* Reserved */ + uint32_t reserved1; + /* + * Image load address : not used by bootROM but to be consistent + * with header format for other packages (xloader, ...) + */ + uint32_t load_address; + /* Reserved */ + uint32_t reserved2; + /* Image version to be compared by bootROM with monotonic + * counter value in OTP_CFG4 prior executing the downloaded image + */ + uint32_t image_version; + /* + * Option flags: + * Bit 0 : No signature check request : 'No_sig_check' + * value 1 : for No signature check request + * value 0 : No request to bypass the signature check + * Note : No signature check is never allowed on a Secured chip + */ + uint32_t option_flags; + /* + * Type of ECC algorithm to use : + * value 1 : for P-256 NIST algorithm + * value 2 : for Brainpool 256 algorithm + * See definitions 'BOOT_API_ECDSA_ALGO_TYPE_XXX' above. + */ + uint32_t ecc_algo_type; + /* + * OEM ECC Public Key (aka Root pubk) provided in header on 512 bits. + * The SHA-256 hash of the OEM ECC pubk must match the one stored + * in OTP cells. + */ + uint8_t ecc_pubk[BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES]; + /* Pad up to 256 byte total size */ + uint8_t pad[84]; +} __packed boot_api_image_header_t; + +#endif /* __BOOT_API_H */ diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h new file mode 100644 index 0000000..9c148ad --- /dev/null +++ b/plat/st/stm32mp1/include/platform_def.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include +#include +#include +#include "../stm32mp1_def.h" + +/******************************************************************************* + * Generic platform constants + ******************************************************************************/ + +/* Size of cacheable stacks */ +#define PLATFORM_STACK_SIZE 0xC00 + +/* SSBL = second stage boot loader */ +#define BL33_IMAGE_NAME "ssbl" + +#define STM32MP1_PRIMARY_CPU U(0x0) + +#define PLATFORM_CACHE_LINE_SIZE 64 +#define PLATFORM_CLUSTER_COUNT ULL(1) +#define PLATFORM_CLUSTER0_CORE_COUNT U(2) +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ + PLATFORM_CLUSTER0_CORE_COUNT) +#define PLATFORM_MAX_CPUS_PER_CLUSTER 2 + +#define MAX_IO_DEVICES 4 +#define MAX_IO_HANDLES 4 + +/******************************************************************************* + * BL2 specific defines. + ******************************************************************************/ +/* + * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug + * size plus a little space for growth. + */ +#define BL2_BASE STM32MP1_BL2_BASE +#define BL2_LIMIT (STM32MP1_BL2_BASE + \ + STM32MP1_BL2_SIZE) + +/******************************************************************************* + * BL32 specific defines. + ******************************************************************************/ +#define BL32_BASE STM32MP1_BL32_BASE +#define BL32_LIMIT (STM32MP1_BL32_BASE + \ + STM32MP1_BL32_SIZE) + +/******************************************************************************* + * BL33 specific defines. + ******************************************************************************/ +#define BL33_BASE STM32MP1_BL33_BASE + +/* + * Load address of BL33 for this platform port + */ +#define PLAT_STM32MP1_NS_IMAGE_OFFSET BL33_BASE + +/******************************************************************************* + * DTB specific defines. + ******************************************************************************/ +#define DTB_BASE STM32MP1_DTB_BASE +#define DTB_LIMIT (STM32MP1_DTB_BASE + \ + STM32MP1_DTB_SIZE) + +/******************************************************************************* + * Platform specific page table and MMU setup constants + ******************************************************************************/ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) + +/******************************************************************************* + * Declarations and constants to access the mailboxes safely. Each mailbox is + * aligned on the biggest cache line size in the platform. This is known only + * to the platform as it might have a combination of integrated and external + * caches. Such alignment ensures that two maiboxes do not sit on the same cache + * line at any cache level. They could belong to different cpus/clusters & + * get written while being protected by different locks causing corruption of + * a valid mailbox address. + ******************************************************************************/ +#define CACHE_WRITEBACK_SHIFT 6 +#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT) + +/* + * Secure Interrupt: based on the standard ARM mapping + */ +#define ARM_IRQ_SEC_PHY_TIMER U(29) + +#define ARM_IRQ_SEC_SGI_0 U(8) +#define ARM_IRQ_SEC_SGI_1 U(9) +#define ARM_IRQ_SEC_SGI_2 U(10) +#define ARM_IRQ_SEC_SGI_3 U(11) +#define ARM_IRQ_SEC_SGI_4 U(12) +#define ARM_IRQ_SEC_SGI_5 U(13) +#define ARM_IRQ_SEC_SGI_6 U(14) +#define ARM_IRQ_SEC_SGI_7 U(15) + +#define STM32MP1_IRQ_TZC400 U(36) +#define STM32MP1_IRQ_TAMPSERRS U(229) +#define STM32MP1_IRQ_AXIERRIRQ U(244) + +/* + * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define PLATFORM_G1S_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, \ + GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(STM32MP1_IRQ_TAMPSERRS, \ + GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(STM32MP1_IRQ_AXIERRIRQ, \ + GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(STM32MP1_IRQ_TZC400, \ + GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, \ + GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, \ + GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, \ + GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, \ + GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, \ + GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, \ + GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE) + +#define PLATFORM_G0_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, \ + GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, \ + GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE) + +/* + * Power + */ +#define PLAT_MAX_PWR_LVL U(1) + +/* Local power state for power domains in Run state. */ +#define ARM_LOCAL_STATE_RUN U(0) +/* Local power state for retention. Valid only for CPU power domains */ +#define ARM_LOCAL_STATE_RET U(1) +/* Local power state for power-down. Valid for CPU and cluster power domains */ +#define ARM_LOCAL_STATE_OFF U(2) +/* + * This macro defines the deepest retention state possible. + * A higher state id will represent an invalid or a power down state. + */ +#define PLAT_MAX_RET_STATE ARM_LOCAL_STATE_RET +/* + * This macro defines the deepest power down states possible. Any state ID + * higher than this is invalid. + */ +#define PLAT_MAX_OFF_STATE ARM_LOCAL_STATE_OFF + +/******************************************************************************* + * Size of the per-cpu data in bytes that should be reserved in the generic + * per-cpu data structure for the FVP port. + ******************************************************************************/ +#define PLAT_PCPU_DATA_SIZE 2 + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h new file mode 100644 index 0000000..6a0449e --- /dev/null +++ b/plat/st/stm32mp1/include/stm32mp1_private.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __STM32MP1_PRIVATE_H__ +#define __STM32MP1_PRIVATE_H__ + +void stm32mp1_io_setup(void); +void configure_mmu(void); + +void stm32mp1_save_boot_ctx_address(uintptr_t address); +uintptr_t stm32mp1_get_boot_ctx_address(void); + +#endif /* __STM32MP1_PRIVATE_H__ */ diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c new file mode 100644 index 0000000..6f5bc4c --- /dev/null +++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +/******************************************************************************* + * Following descriptor provides BL image/ep information that gets used + * by BL2 to load the images and also subset of this information is + * passed to next BL image. The image loading sequence is managed by + * populating the images in required loading order. The image execution + * sequence is managed by populating the `next_handoff_image_id` with + * the next executable image id. + ******************************************************************************/ +static bl_mem_params_node_t bl2_mem_params_descs[] = { + /* Fill BL32 related information */ + { + .image_id = BL32_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | EXECUTABLE | EP_FIRST_EXE), + + .ep_info.pc = BL32_BASE, + .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, + SPSR_E_LITTLE, + DISABLE_ALL_EXCEPTIONS), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + IMAGE_ATTRIB_PLAT_SETUP), + + .image_info.image_base = BL32_BASE, + .image_info.image_max_size = BL32_LIMIT - BL32_BASE, + + .next_handoff_image_id = BL33_IMAGE_ID, + }, + + /* Fill BL33 related information */ + { + .image_id = BL33_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + NON_SECURE | EXECUTABLE), + + .ep_info.pc = PLAT_STM32MP1_NS_IMAGE_OFFSET, + .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, + SPSR_E_LITTLE, + DISABLE_ALL_EXCEPTIONS), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, 0), + + .image_info.image_base = PLAT_STM32MP1_NS_IMAGE_OFFSET, + .image_info.image_max_size = STM32MP1_DDR_MAX_SIZE - + (PLAT_STM32MP1_NS_IMAGE_OFFSET - STM32MP1_DDR_BASE), + + .next_handoff_image_id = INVALID_IMAGE_ID, + } +}; + +REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c new file mode 100644 index 0000000..3c6d677 --- /dev/null +++ b/plat/st/stm32mp1/plat_image_load.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/******************************************************************************* + * This function flushes the data structures so that they are visible + * in memory for the next BL image. + ******************************************************************************/ +void plat_flush_next_bl_params(void) +{ + flush_bl_params_desc(); +} + +/******************************************************************************* + * This function returns the list of loadable images. + ******************************************************************************/ +bl_load_info_t *plat_get_bl_image_load_info(void) +{ + return get_bl_load_info_from_mem_params_desc(); +} + +/******************************************************************************* + * This function returns the list of executable images. + ******************************************************************************/ +bl_params_t *plat_get_next_bl_params(void) +{ + return get_next_bl_params_from_mem_params_desc(); +} diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk new file mode 100644 index 0000000..ff390d5 --- /dev/null +++ b/plat/st/stm32mp1/platform.mk @@ -0,0 +1,55 @@ +# +# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +ARM_CORTEX_A7 := yes +ARM_WITH_NEON := yes +LOAD_IMAGE_V2 := 1 +BL2_AT_EL3 := 1 +ENABLE_PLAT_COMPAT := 0 +USE_COHERENT_MEM := 0 + +STM32_TF_VERSION ?= 0 + +# Not needed for Cortex-A7 +WORKAROUND_CVE_2017_5715:= 0 + +PLAT_INCLUDES := -Iplat/st/stm32mp1/include/ +PLAT_INCLUDES += -Iinclude/common/tbbr +PLAT_INCLUDES += -Iinclude/drivers/st + +include lib/libfdt/libfdt.mk + +PLAT_BL_COMMON_SOURCES := plat/st/stm32mp1/stm32mp1_common.c + +PLAT_BL_COMMON_SOURCES += drivers/console/aarch32/console.S \ + drivers/st/uart/aarch32/stm32_console.S + +ifneq (${ENABLE_STACK_PROTECTOR},0) +PLAT_BL_COMMON_SOURCES += plat/st/stm32mp1/stm32mp1_stack_protector.c +endif + +include lib/xlat_tables_v2/xlat_tables.mk +PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} + +PLAT_BL_COMMON_SOURCES += lib/cpus/aarch32/cortex_a7.S + +PLAT_BL_COMMON_SOURCES += ${LIBFDT_SRCS} \ + drivers/delay_timer/delay_timer.c \ + drivers/delay_timer/generic_delay_timer.c \ + plat/st/stm32mp1/stm32mp1_helper.S + +BL2_SOURCES += drivers/io/io_dummy.c \ + drivers/io/io_storage.c \ + plat/st/stm32mp1/bl2_io_storage.c \ + plat/st/stm32mp1/bl2_plat_setup.c + +BL2_SOURCES += common/desc_image_load.c \ + plat/st/stm32mp1/plat_bl2_mem_params_desc.c \ + plat/st/stm32mp1/plat_image_load.c + +# For memory footprint optimization, build with thumb and interwork support +ASFLAGS += -mthumb -mthumb-interwork +TF_CFLAGS += -mthumb -mthumb-interwork diff --git a/plat/st/stm32mp1/stm32mp1_common.c b/plat/st/stm32mp1/stm32mp1_common.c new file mode 100644 index 0000000..9f1126b --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_common.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAP_SRAM MAP_REGION_FLAT(STM32MP1_SRAM_BASE, \ + STM32MP1_SRAM_SIZE, \ + MT_MEMORY | \ + MT_RW | \ + MT_SECURE | \ + MT_EXECUTE_NEVER) + +#define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \ + STM32MP1_DEVICE1_SIZE, \ + MT_DEVICE | \ + MT_RW | \ + MT_SECURE | \ + MT_EXECUTE_NEVER) + +#define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \ + STM32MP1_DEVICE2_SIZE, \ + MT_DEVICE | \ + MT_RW | \ + MT_SECURE | \ + MT_EXECUTE_NEVER) + +static const mmap_region_t stm32mp1_mmap[] = { + MAP_SRAM, + MAP_DEVICE1, + MAP_DEVICE2, + {0} +}; + +void configure_mmu(void) +{ + mmap_add(stm32mp1_mmap); + init_xlat_tables(); + + enable_mmu_secure(0); +} + +uintptr_t plat_get_ns_image_entrypoint(void) +{ + return BL33_BASE; +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return read_cntfrq_el0(); +} + +/* Functions to save and get boot context address given by ROM code */ +static uintptr_t boot_ctx_address; + +void stm32mp1_save_boot_ctx_address(uintptr_t address) +{ + boot_ctx_address = address; +} + +uintptr_t stm32mp1_get_boot_ctx_address(void) +{ + return boot_ctx_address; +} diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h new file mode 100644 index 0000000..0b46bc5 --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STM32MP1_DEF_H +#define STM32MP1_DEF_H + +#include +#include +#include + +/******************************************************************************* + * STM32MP1 memory map related constants + ******************************************************************************/ + +#define STM32MP1_SRAM_BASE U(0x2FFC0000) +#define STM32MP1_SRAM_SIZE U(0x00040000) + +/* DDR configuration */ +#define STM32MP1_DDR_BASE U(0xC0000000) +#define STM32MP1_DDR_SIZE_DFLT U(0x20000000) /* 512 MB */ +#define STM32MP1_DDR_MAX_SIZE U(0x40000000) /* Max 1GB */ +#define STM32MP1_DDR_SPEED_DFLT 528 + +/* DDR power initializations */ +#ifndef __ASSEMBLY__ +enum ddr_type { + STM32MP_DDR3, + STM32MP_LPDDR2, +}; +#endif + +/* Section used inside TF binaries */ +#define STM32MP1_PARAM_LOAD_SIZE U(0x00002400) /* 9 Ko for param */ +/* 256 Octets reserved for header */ +#define STM32MP1_HEADER_SIZE U(0x00000100) + +#define STM32MP1_BINARY_BASE (STM32MP1_SRAM_BASE + \ + STM32MP1_PARAM_LOAD_SIZE + \ + STM32MP1_HEADER_SIZE) + +#define STM32MP1_BINARY_SIZE (STM32MP1_SRAM_SIZE - \ + (STM32MP1_PARAM_LOAD_SIZE + \ + STM32MP1_HEADER_SIZE)) + +#if STACK_PROTECTOR_ENABLED +#define STM32MP1_BL32_SIZE U(0x00012000) /* 72 Ko for BL32 */ +#else +#define STM32MP1_BL32_SIZE U(0x00011000) /* 68 Ko for BL32 */ +#endif + +#define STM32MP1_BL32_BASE (STM32MP1_SRAM_BASE + \ + STM32MP1_SRAM_SIZE - \ + STM32MP1_BL32_SIZE) + +#if STACK_PROTECTOR_ENABLED +#define STM32MP1_BL2_SIZE U(0x00015000) /* 84 Ko for BL2 */ +#else +#define STM32MP1_BL2_SIZE U(0x00013000) /* 76 Ko for BL2 */ +#endif + +#define STM32MP1_BL2_BASE (STM32MP1_BL32_BASE - \ + STM32MP1_BL2_SIZE) + +/* BL2 and BL32/sp_min require 5 tables */ +#define MAX_XLAT_TABLES 5 + +/* + * MAX_MMAP_REGIONS is usually: + * BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup + */ +#define MAX_MMAP_REGIONS 11 + +/* DTB initialization value */ +#define STM32MP1_DTB_SIZE U(0x00004000) /* 16Ko for DTB */ + +#define STM32MP1_DTB_BASE (STM32MP1_BL2_BASE - \ + STM32MP1_DTB_SIZE) + +#define STM32MP1_BL33_BASE (STM32MP1_DDR_BASE + U(0x100000)) + +/******************************************************************************* + * STM32MP1 device/io map related constants (used for MMU) + ******************************************************************************/ +#define STM32MP1_DEVICE1_BASE U(0x40000000) +#define STM32MP1_DEVICE1_SIZE U(0x40000000) + +#define STM32MP1_DEVICE2_BASE U(0x80000000) +#define STM32MP1_DEVICE2_SIZE U(0x40000000) + +/******************************************************************************* + * STM32MP1 RCC + ******************************************************************************/ +#define RCC_BASE U(0x50000000) + +/******************************************************************************* + * STM32MP1 PWR + ******************************************************************************/ +#define PWR_BASE U(0x50001000) + +/******************************************************************************* + * STM32MP1 UART + ******************************************************************************/ +#define USART1_BASE U(0x5C000000) +#define USART2_BASE U(0x4000E000) +#define USART3_BASE U(0x4000F000) +#define UART4_BASE U(0x40010000) +#define UART5_BASE U(0x40011000) +#define USART6_BASE U(0x44003000) +#define UART7_BASE U(0x40018000) +#define UART8_BASE U(0x40019000) +#define STM32MP1_DEBUG_USART_BASE UART4_BASE +#define STM32MP1_UART_BAUDRATE 115200 + +/******************************************************************************* + * STM32MP1 GIC-400 + ******************************************************************************/ +#define STM32MP1_GICD_BASE U(0xA0021000) +#define STM32MP1_GICC_BASE U(0xA0022000) +#define STM32MP1_GICH_BASE U(0xA0024000) +#define STM32MP1_GICV_BASE U(0xA0026000) + +/******************************************************************************* + * STM32MP1 TZC (TZ400) + ******************************************************************************/ +#define STM32MP1_TZC_BASE U(0x5C006000) + +#define STM32MP1_TZC_A7_ID U(0) +#define STM32MP1_TZC_LCD_ID U(3) +#define STM32MP1_TZC_GPU_ID U(4) +#define STM32MP1_TZC_MDMA_ID U(5) +#define STM32MP1_TZC_DMA_ID U(6) +#define STM32MP1_TZC_USB_HOST_ID U(7) +#define STM32MP1_TZC_USB_OTG_ID U(8) +#define STM32MP1_TZC_SDMMC_ID U(9) +#define STM32MP1_TZC_ETH_ID U(10) +#define STM32MP1_TZC_DAP_ID U(15) + +#define STM32MP1_MEMORY_NS 0 +#define STM32MP1_MEMORY_SECURE 1 + +#define STM32MP1_FILTER_BIT_ALL 3 + +/******************************************************************************* + * STM32MP1 SDMMC + ******************************************************************************/ +#define STM32MP1_SDMMC1_BASE U(0x58005000) +#define STM32MP1_SDMMC2_BASE U(0x58007000) +#define STM32MP1_SDMMC3_BASE U(0x48004000) + +#define STM32MP1_SD_INIT_FREQ 400000 /*400 KHz*/ +#define STM32MP1_SD_NORMAL_SPEED_MAX_FREQ 25000000 /*25 MHz*/ +#define STM32MP1_SD_HIGH_SPEED_MAX_FREQ 50000000 /*50 MHz*/ +#define STM32MP1_EMMC_INIT_FREQ STM32MP1_SD_INIT_FREQ +#define STM32MP1_EMMC_NORMAL_SPEED_MAX_FREQ 26000000 /*26 MHz*/ +#define STM32MP1_EMMC_HIGH_SPEED_MAX_FREQ 52000000 /*52 MHz*/ + +/******************************************************************************* + * STM32MP1 DDRCTRL + ******************************************************************************/ +#define DDRCTRL_BASE U(0x5A003000) + +/******************************************************************************* + * STM32MP1 DDRPHYC + ******************************************************************************/ +#define DDRPHYC_BASE U(0x5A004000) + +/******************************************************************************* + * STM32MP1 I2C4 + ******************************************************************************/ +#define I2C4_BASE U(0x5C002000) + +#endif /* STM32MP1_DEF_H */ diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S new file mode 100644 index 0000000..421d957 --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_helper.S @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + + .globl platform_mem_init + .globl plat_report_exception + .globl plat_get_my_entrypoint + .globl plat_secondary_cold_boot_setup + .globl plat_reset_handler + .globl plat_is_my_cpu_primary + .globl plat_my_core_pos + .globl plat_panic_handler + +func platform_mem_init + /* Nothing to do, don't need to init SYSRAM */ + bx lr +endfunc platform_mem_init + +func plat_report_exception + bx lr +endfunc plat_report_exception + +func plat_reset_handler + bx lr +endfunc plat_reset_handler + + /* ------------------------------------------------------------------ + * unsigned long plat_get_my_entrypoint (void); + * + * Main job of this routine is to distinguish between a cold and warm + * boot. + * + * Currently supports only cold boot + * ------------------------------------------------------------------ + */ +func plat_get_my_entrypoint + mov r0, #0 + bx lr +endfunc plat_get_my_entrypoint + + /* --------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * + * Cold-booting secondary CPUs is not supported. + * --------------------------------------------- + */ +func plat_secondary_cold_boot_setup + b . +endfunc plat_secondary_cold_boot_setup + + /* ----------------------------------------------------- + * unsigned int plat_is_my_cpu_primary (void); + * + * Find out whether the current cpu is the primary cpu. + * ----------------------------------------------------- + */ +func plat_is_my_cpu_primary + ldcopr r0, MPIDR + ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + and r0, r1 + cmp r0, #STM32MP1_PRIMARY_CPU + moveq r0, #1 + movne r0, #0 + bx lr +endfunc plat_is_my_cpu_primary + + /* ------------------------------------------- + * int plat_stm32mp1_get_core_pos(int mpidr); + * + * Return CorePos = (ClusterId * 4) + CoreId + * ------------------------------------------- + */ +func plat_stm32mp1_get_core_pos + and r1, r0, #MPIDR_CPU_MASK + and r0, r0, #MPIDR_CLUSTER_MASK + add r0, r1, r0, LSR #6 + bx lr +endfunc plat_stm32mp1_get_core_pos + + /* ------------------------------------ + * unsigned int plat_my_core_pos(void) + * ------------------------------------ + */ +func plat_my_core_pos + ldcopr r0, MPIDR + b plat_stm32mp1_get_core_pos +endfunc plat_my_core_pos diff --git a/plat/st/stm32mp1/stm32mp1_stack_protector.c b/plat/st/stm32mp1/stm32mp1_stack_protector.c new file mode 100644 index 0000000..c681300 --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_stack_protector.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#define RANDOM_CANARY_VALUE 2144346116U + +u_register_t plat_get_stack_protector_canary(void) +{ + /* + * Ideally, a random number should be returned instead of the + * combination of a timer's value and a compile-time constant. + */ + return RANDOM_CANARY_VALUE ^ (u_register_t)read_cntpct_el0(); +} +