diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/include/asm/arch-am33xx/cpu.h | 48 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-omap5/cpu.h | 3 | ||||
-rw-r--r-- | arch/arm/include/asm/ti-common/omap_wdt.h | 60 | ||||
-rw-r--r-- | arch/arm/mach-keystone/config.mk | 6 | ||||
-rw-r--r-- | arch/arm/mach-keystone/mon.c | 73 | ||||
-rw-r--r-- | arch/arm/mach-omap2/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clocks-common.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-omap2/config_secure.mk | 6 |
8 files changed, 156 insertions, 52 deletions
diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h index dbed7764aa..54f449f6e6 100644 --- a/arch/arm/include/asm/arch-am33xx/cpu.h +++ b/arch/arm/include/asm/arch-am33xx/cpu.h @@ -66,29 +66,9 @@ #define PRM_RSTCTRL_RESET 0x01 #define PRM_RSTST_WARM_RESET_MASK 0x232 -/* - * Watchdog: - * Using the prescaler, the OMAP watchdog could go for many - * months before firing. These limits work without scaling, - * with the 60 second default assumed by most tools and docs. - */ -#define TIMER_MARGIN_MAX (24 * 60 * 60) /* 1 day */ -#define TIMER_MARGIN_DEFAULT 60 /* 60 secs */ -#define TIMER_MARGIN_MIN 1 - -#define PTV 0 /* prescale */ -#define GET_WLDR_VAL(secs) (0xffffffff - ((secs) * (32768/(1<<PTV))) + 1) -#define WDT_WWPS_PEND_WCLR BIT(0) -#define WDT_WWPS_PEND_WLDR BIT(2) -#define WDT_WWPS_PEND_WTGR BIT(3) -#define WDT_WWPS_PEND_WSPR BIT(4) - -#define WDT_WCLR_PRE BIT(5) -#define WDT_WCLR_PTV_OFF 2 - #ifndef __KERNEL_STRICT_NAMES #ifndef __ASSEMBLY__ - +#include <asm/ti-common/omap_wdt.h> #ifndef CONFIG_AM43XX /* Encapsulating core pll registers */ @@ -422,32 +402,6 @@ struct cm_rtc { unsigned int clkstctrl; /* offset 0x4 */ }; -/* Watchdog timer registers */ -struct wd_timer { - unsigned int resv1[4]; - unsigned int wdtwdsc; /* offset 0x010 */ - unsigned int wdtwdst; /* offset 0x014 */ - unsigned int wdtwisr; /* offset 0x018 */ - unsigned int wdtwier; /* offset 0x01C */ - unsigned int wdtwwer; /* offset 0x020 */ - unsigned int wdtwclr; /* offset 0x024 */ - unsigned int wdtwcrr; /* offset 0x028 */ - unsigned int wdtwldr; /* offset 0x02C */ - unsigned int wdtwtgr; /* offset 0x030 */ - unsigned int wdtwwps; /* offset 0x034 */ - unsigned int resv2[3]; - unsigned int wdtwdly; /* offset 0x044 */ - unsigned int wdtwspr; /* offset 0x048 */ - unsigned int resv3[1]; - unsigned int wdtwqeoi; /* offset 0x050 */ - unsigned int wdtwqstar; /* offset 0x054 */ - unsigned int wdtwqsta; /* offset 0x058 */ - unsigned int wdtwqens; /* offset 0x05C */ - unsigned int wdtwqenc; /* offset 0x060 */ - unsigned int resv4[39]; - unsigned int wdt_unfr; /* offset 0x100 */ -}; - /* Timer 32 bit registers */ struct gptimer { unsigned int tidr; /* offset 0x00 */ diff --git a/arch/arm/include/asm/arch-omap5/cpu.h b/arch/arm/include/asm/arch-omap5/cpu.h index 683d905333..26e7417459 100644 --- a/arch/arm/include/asm/arch-omap5/cpu.h +++ b/arch/arm/include/asm/arch-omap5/cpu.h @@ -18,6 +18,8 @@ #ifndef __KERNEL_STRICT_NAMES #ifndef __ASSEMBLY__ +#include <asm/ti-common/omap_wdt.h> + struct gptimer { u32 tidr; /* 0x00 r */ u8 res1[0xc]; @@ -44,6 +46,7 @@ struct gptimer { /* enable sys_clk NO-prescale /1 */ #define GPT_EN ((0x0 << 2) | (0x1 << 1) | (0x1 << 0)) +#define WDT_BASE (OMAP54XX_L4_WKUP_BASE + 0x14000) /* Watchdog */ #ifndef __KERNEL_STRICT_NAMES #ifndef __ASSEMBLY__ diff --git a/arch/arm/include/asm/ti-common/omap_wdt.h b/arch/arm/include/asm/ti-common/omap_wdt.h new file mode 100644 index 0000000000..b9f4c07822 --- /dev/null +++ b/arch/arm/include/asm/ti-common/omap_wdt.h @@ -0,0 +1,60 @@ +/* + * omap_wdt.h + * + * OMAP Watchdog header file + * + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __OMAP_WDT_H__ +#define __OMAP_WDT_H__ + +/* + * Watchdog: + * Using the prescaler, the OMAP watchdog could go for many + * months before firing. These limits work without scaling, + * with the 60 second default assumed by most tools and docs. + */ +#define TIMER_MARGIN_MAX (24 * 60 * 60) /* 1 day */ +#define TIMER_MARGIN_DEFAULT 60 /* 60 secs */ +#define TIMER_MARGIN_MIN 1 + +#define PTV 0 /* prescale */ +#define GET_WLDR_VAL(secs) (0xffffffff - ((secs) * (32768/(1<<PTV))) + 1) +#define WDT_WWPS_PEND_WCLR BIT(0) +#define WDT_WWPS_PEND_WLDR BIT(2) +#define WDT_WWPS_PEND_WTGR BIT(3) +#define WDT_WWPS_PEND_WSPR BIT(4) + +#define WDT_WCLR_PRE BIT(5) +#define WDT_WCLR_PTV_OFF 2 + +/* Watchdog timer registers */ +struct wd_timer { + unsigned int resv1[4]; + unsigned int wdtwdsc; /* offset 0x010 */ + unsigned int wdtwdst; /* offset 0x014 */ + unsigned int wdtwisr; /* offset 0x018 */ + unsigned int wdtwier; /* offset 0x01C */ + unsigned int wdtwwer; /* offset 0x020 */ + unsigned int wdtwclr; /* offset 0x024 */ + unsigned int wdtwcrr; /* offset 0x028 */ + unsigned int wdtwldr; /* offset 0x02C */ + unsigned int wdtwtgr; /* offset 0x030 */ + unsigned int wdtwwps; /* offset 0x034 */ + unsigned int resv2[3]; + unsigned int wdtwdly; /* offset 0x044 */ + unsigned int wdtwspr; /* offset 0x048 */ + unsigned int resv3[1]; + unsigned int wdtwqeoi; /* offset 0x050 */ + unsigned int wdtwqstar; /* offset 0x054 */ + unsigned int wdtwqsta; /* offset 0x058 */ + unsigned int wdtwqens; /* offset 0x05C */ + unsigned int wdtwqenc; /* offset 0x060 */ + unsigned int resv4[39]; + unsigned int wdt_unfr; /* offset 0x100 */ +}; + +#endif /* __OMAP_WDT_H__ */ diff --git a/arch/arm/mach-keystone/config.mk b/arch/arm/mach-keystone/config.mk index 9ae1e9ac91..db556ea0a8 100644 --- a/arch/arm/mach-keystone/config.mk +++ b/arch/arm/mach-keystone/config.mk @@ -5,9 +5,15 @@ # SPDX-License-Identifier: GPL-2.0+ # +include $(srctree)/arch/arm/mach-omap2/config_secure.mk + ifndef CONFIG_SPL_BUILD +ifeq ($(CONFIG_TI_SECURE_DEVICE),y) +ALL-y += u-boot_HS_MLO +else ALL-y += MLO endif +endif MKIMAGEFLAGS_u-boot-spl.gph = -A $(ARCH) -T gpimage -C none \ -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) -n SPL diff --git a/arch/arm/mach-keystone/mon.c b/arch/arm/mach-keystone/mon.c index 256f6300ed..81009848d0 100644 --- a/arch/arm/mach-keystone/mon.c +++ b/arch/arm/mach-keystone/mon.c @@ -10,6 +10,7 @@ #include <common.h> #include <command.h> #include <mach/mon.h> +#include <spl.h> asm(".arch_extension sec\n\t"); int mon_install(u32 addr, u32 dpsc, u32 freq) @@ -61,3 +62,75 @@ int mon_power_off(int core_id) : "cc", "r0", "r1", "memory"); return result; } + +#ifdef CONFIG_TI_SECURE_DEVICE +#define KS2_HS_SEC_HEADER_LEN 0x60 +#define KS2_HS_SEC_TAG_OFFSET 0x34 +#define KS2_AUTH_CMD 130 + +/** + * k2_hs_bm_auth() - Invokes security functions using a + * proprietary TI interface. This binary and source for + * this is available in the secure development package or + * SECDEV. For details on how to access this please refer + * doc/README.ti-secure + * + * @cmd: Secure monitor command + * @arg1: Argument for command + * + * returns non-zero value on success, zero on error + */ +static int k2_hs_bm_auth(int cmd, void *arg1) +{ + int result; + + asm volatile ( + "stmfd r13!, {r4-r12, lr}\n" + "mov r0, %1\n" + "mov r1, %2\n" + "smc #2\n" + "ldmfd r13!, {r4-r12, lr}\n" + : "=&r" (result) + : "r" (cmd), "r" (arg1) + : "cc", "r0", "r1", "memory"); + + return result; +} + +void board_fit_image_post_process(void **p_image, size_t *p_size) +{ + int result = 0; + void *image = *p_image; + + if (strncmp(image + KS2_HS_SEC_TAG_OFFSET, "KEYS", 4)) { + printf("No signature found in image!\n"); + hang(); + } + + result = k2_hs_bm_auth(KS2_AUTH_CMD, image); + if (result == 0) { + printf("Authentication failed!\n"); + hang(); + } + + /* + * Overwrite the image headers after authentication + * and decryption. Update size to reflect removal + * of header. + */ + memcpy(image, image + KS2_HS_SEC_HEADER_LEN, *p_size); + *p_size -= KS2_HS_SEC_HEADER_LEN; + + /* + * Output notification of successful authentication to re-assure the + * user that the secure code is being processed as expected. However + * suppress any such log output in case of building for SPL and booting + * via YMODEM. This is done to avoid disturbing the YMODEM serial + * protocol transactions. + */ + if (!(IS_ENABLED(CONFIG_SPL_BUILD) && + IS_ENABLED(CONFIG_SPL_YMODEM_SUPPORT) && + spl_boot_device() == BOOT_DEVICE_UART)) + printf("Authentication passed\n"); +} +#endif diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 24bc485195..d74b068abc 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -1,6 +1,6 @@ config TI_SECURE_DEVICE bool "HS Device Type Support" - depends on OMAP54XX || AM43XX || AM33XX + depends on OMAP54XX || AM43XX || AM33XX || ARCH_KEYSTONE help If a high secure (HS) device type is being used, this config must be set. This option impacts various aspects of the diff --git a/arch/arm/mach-omap2/clocks-common.c b/arch/arm/mach-omap2/clocks-common.c index 84f93e73f6..93c4c6fe33 100644 --- a/arch/arm/mach-omap2/clocks-common.c +++ b/arch/arm/mach-omap2/clocks-common.c @@ -828,27 +828,29 @@ void do_enable_clocks(u32 const *clk_domains, u32 i, max = 100; /* Put the clock domains in SW_WKUP mode */ - for (i = 0; (i < max) && clk_domains[i]; i++) { + for (i = 0; (i < max) && clk_domains && clk_domains[i]; i++) { enable_clock_domain(clk_domains[i], CD_CLKCTRL_CLKTRCTRL_SW_WKUP); } /* Clock modules that need to be put in HW_AUTO */ - for (i = 0; (i < max) && clk_modules_hw_auto[i]; i++) { + for (i = 0; (i < max) && clk_modules_hw_auto && + clk_modules_hw_auto[i]; i++) { enable_clock_module(clk_modules_hw_auto[i], MODULE_CLKCTRL_MODULEMODE_HW_AUTO, wait_for_enable); }; /* Clock modules that need to be put in SW_EXPLICIT_EN mode */ - for (i = 0; (i < max) && clk_modules_explicit_en[i]; i++) { + for (i = 0; (i < max) && clk_modules_explicit_en && + clk_modules_explicit_en[i]; i++) { enable_clock_module(clk_modules_explicit_en[i], MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN, wait_for_enable); }; /* Put the clock domains in HW_AUTO mode now */ - for (i = 0; (i < max) && clk_domains[i]; i++) { + for (i = 0; (i < max) && clk_domains && clk_domains[i]; i++) { enable_clock_domain(clk_domains[i], CD_CLKCTRL_CLKTRCTRL_HW_AUTO); } diff --git a/arch/arm/mach-omap2/config_secure.mk b/arch/arm/mach-omap2/config_secure.mk index 0c843338d7..0346cb93ab 100644 --- a/arch/arm/mach-omap2/config_secure.mk +++ b/arch/arm/mach-omap2/config_secure.mk @@ -77,6 +77,12 @@ u-boot-spl_HS_ISSW: $(obj)/u-boot-spl.bin FORCE u-boot-spl_HS_SPI_X-LOADER: $(obj)/u-boot-spl.bin FORCE $(call if_changed,mkomapsecimg) +# For supporting single stage boot on keystone, the image is a full u-boot +# file, not an SPL. This will work for all boot devices, other than SPI +# flash +u-boot_HS_MLO: $(obj)/u-boot.bin + $(call if_changed,mkomapsecimg) + # For supporting single stage XiP QSPI on AM43xx, the image is a full u-boot # file, not an SPL. In this case the mkomapsecimg command looks for a # u-boot-HS_* prefix |