TBB: add Trusted Watchdog support on ARM platforms
authorJuan Castillo <juan.castillo@arm.com>
Tue, 6 Oct 2015 13:01:35 +0000 (14:01 +0100)
committerJuan Castillo <juan.castillo@arm.com>
Wed, 2 Dec 2015 13:54:35 +0000 (13:54 +0000)
This patch adds watchdog support on ARM platforms (FVP and Juno).
A secure instance of SP805 is used as Trusted Watchdog. It is
entirely managed in BL1, being enabled in the early platform setup
hook and disabled in the exit hook. By default, the watchdog is
enabled in every build (even when TBB is disabled).

A new ARM platform specific build option `ARM_DISABLE_TRUSTED_WDOG`
has been introduced to allow the user to disable the watchdog at
build time. This feature may be used for testing or debugging
purposes.

Specific error handlers for Juno and FVP are also provided in this
patch. These handlers will be called after an image load or
authentication error. On FVP, the Table of Contents (ToC) in the FIP
is erased. On Juno, the corresponding error code is stored in the
V2M Non-Volatile flags register. In both cases, the CPU spins until
a watchdog reset is generated after 256 seconds (as specified in
the TBBR document).

Change-Id: I9ca11dcb0fe15af5dbc5407ab3cf05add962f4b4

12 files changed:
docs/user-guide.md
include/plat/arm/board/common/v2m_def.h
include/plat/arm/common/arm_def.h
plat/arm/board/common/board_common.mk
plat/arm/board/common/board_css_common.c
plat/arm/board/fvp/aarch64/fvp_common.c
plat/arm/board/fvp/fvp_err.c [new file with mode: 0644]
plat/arm/board/fvp/platform.mk
plat/arm/board/juno/juno_err.c [new file with mode: 0644]
plat/arm/board/juno/platform.mk
plat/arm/common/arm_bl1_setup.c
plat/arm/common/arm_common.mk

index 25f884efb95eaa766bd92b2eb4ddb73efee2ab5e..9f9d0a5a5ce4a572d93e6d9d02102c1ae7abc927 100644 (file)
@@ -428,6 +428,14 @@ map is explained in the [Firmware Design].
     in which case the platform is configured to expect NULL in the State-ID
     field of power-state parameter.
 
+*   `ARM_DISABLE_TRUSTED_WDOG`: boolean option to disable the Trusted Watchdog.
+    By default, ARM platforms use a watchdog to trigger a system reset in case
+    an error is encountered during the boot process (for example, when an image
+    could not be loaded or authenticated). The watchdog is enabled in the early
+    platform setup hook at BL1 and disabled in the BL1 prepare exit hook. The
+    Trusted Watchdog may be disabled at build time for testing or development
+    purposes.
+
 #### ARM CSS platform specific build options
 
 *   `CSS_DETECT_PRE_1_7_0_SCP`: Boolean flag to detect SCP version
index 7a4ef5add1e9b499b7140b542cb50f6fd43267d5..7ed0af6c4a92c3a5cc62a3c87ac1e870d1785364 100644 (file)
@@ -38,6 +38,9 @@
 #define V2M_SYS_ID                     0x0
 #define V2M_SYS_SWITCH                 0x4
 #define V2M_SYS_LED                    0x8
+#define V2M_SYS_NVFLAGS                        0x38
+#define V2M_SYS_NVFLAGSSET             0x38
+#define V2M_SYS_NVFLAGSCLR             0x3c
 #define V2M_SYS_CFGDATA                        0xa0
 #define V2M_SYS_CFGCTRL                        0xa4
 #define V2M_SYS_CFGSTATUS              0xa8
 #define V2M_SP804_TIMER0_BASE          0x1C110000
 #define V2M_SP804_TIMER1_BASE          0x1C120000
 
-#define V2M_MAP_FLASH0                 MAP_REGION_FLAT(V2M_FLASH0_BASE,\
+#define V2M_MAP_FLASH0_RW              MAP_REGION_FLAT(V2M_FLASH0_BASE,\
+                                               V2M_FLASH0_SIZE,        \
+                                               MT_DEVICE | MT_RW | MT_SECURE)
+
+#define V2M_MAP_FLASH0_RO              MAP_REGION_FLAT(V2M_FLASH0_BASE,\
                                                V2M_FLASH0_SIZE,        \
                                                MT_MEMORY | MT_RO | MT_SECURE)
 
index 452c38564d6ec5257f7a77b76d4a8be93ca0035a..4726d5e532f7c2abb24de336f68fffae98976359 100644 (file)
 
 #define ARM_CONSOLE_BAUDRATE           115200
 
+/* Trusted Watchdog constants */
+#define ARM_SP805_TWDG_BASE            0x2a490000
+#define ARM_SP805_TWDG_CLK_HZ          32768
+/* The TBBR document specifies a watchdog timeout of 256 seconds. SP805
+ * asserts reset after two consecutive countdowns (2 x 128 = 256 sec) */
+#define ARM_TWDG_TIMEOUT_SEC           128
+#define ARM_TWDG_LOAD_VAL              (ARM_SP805_TWDG_CLK_HZ *        \
+                                        ARM_TWDG_TIMEOUT_SEC)
+
 /******************************************************************************
  * Required platform porting definitions common to all ARM standard platforms
  *****************************************************************************/
index bec49ed2782645ac470788e6027bb07792c8764a..9e0c84843c5c57b28a2748a1b67186ae924a47ec 100644 (file)
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-PLAT_INCLUDES          +=      -Iinclude/plat/arm/board/common/
+PLAT_INCLUDES          +=      -Iinclude/plat/arm/board/common/                        \
+                               -Iinclude/plat/arm/board/common/drivers
 
 PLAT_BL_COMMON_SOURCES +=      drivers/arm/pl011/pl011_console.S                       \
                                plat/arm/board/common/aarch64/board_arm_helpers.S
 
-#BL1_SOURCES           +=
+BL1_SOURCES            +=      plat/arm/board/common/drivers/norflash/norflash.c
 
-#BL2_SOURCES           +=
+BL2_SOURCES            +=      plat/arm/board/common/drivers/norflash/norflash.c
 
 #BL31_SOURCES          +=
 
index 3bb3dd6fd41a14e8460f4b88a73fb0a38f980401..7bf0273d14a082901e4b73b316733d218a59aacb 100644 (file)
@@ -38,7 +38,7 @@
 #if IMAGE_BL1
 const mmap_region_t plat_arm_mmap[] = {
        ARM_MAP_SHARED_RAM,
-       V2M_MAP_FLASH0,
+       V2M_MAP_FLASH0_RO,
        V2M_MAP_IOFPGA,
        CSS_MAP_DEVICE,
        SOC_CSS_MAP_DEVICE,
@@ -48,7 +48,7 @@ const mmap_region_t plat_arm_mmap[] = {
 #if IMAGE_BL2
 const mmap_region_t plat_arm_mmap[] = {
        ARM_MAP_SHARED_RAM,
-       V2M_MAP_FLASH0,
+       V2M_MAP_FLASH0_RO,
        V2M_MAP_IOFPGA,
        CSS_MAP_DEVICE,
        SOC_CSS_MAP_DEVICE,
index 58b646a45c827e447938368b3a6a3f448c33d85f..8771e5b4fb62ab4e20b6df560284b064e9488894 100644 (file)
@@ -68,7 +68,7 @@ arm_config_t arm_config;
 #if IMAGE_BL1
 const mmap_region_t plat_arm_mmap[] = {
        ARM_MAP_SHARED_RAM,
-       V2M_MAP_FLASH0,
+       V2M_MAP_FLASH0_RW,
        V2M_MAP_IOFPGA,
        MAP_DEVICE0,
        MAP_DEVICE1,
@@ -79,7 +79,7 @@ const mmap_region_t plat_arm_mmap[] = {
 #if IMAGE_BL2
 const mmap_region_t plat_arm_mmap[] = {
        ARM_MAP_SHARED_RAM,
-       V2M_MAP_FLASH0,
+       V2M_MAP_FLASH0_RW,
        V2M_MAP_IOFPGA,
        MAP_DEVICE0,
        MAP_DEVICE1,
diff --git a/plat/arm/board/fvp/fvp_err.c b/plat/arm/board/fvp/fvp_err.c
new file mode 100644 (file)
index 0000000..7867e49
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <board_arm_def.h>
+#include <debug.h>
+#include <errno.h>
+#include <norflash.h>
+#include <stdint.h>
+
+/*
+ * FVP error handler
+ */
+void plat_error_handler(int err)
+{
+       int ret;
+
+       switch (err) {
+       case -ENOENT:
+       case -EAUTH:
+               /* Image load or authentication error. Erase the ToC */
+               INFO("Erasing FIP ToC from flash...\n");
+               nor_unlock(PLAT_ARM_FIP_BASE);
+               ret = nor_word_program(PLAT_ARM_FIP_BASE, 0);
+               if (ret) {
+                       ERROR("Cannot erase ToC\n");
+               } else {
+                       INFO("Done\n");
+               }
+               break;
+       default:
+               /* Unexpected error */
+               break;
+       }
+
+       /* Loop until the watchdog resets the system */
+       for (;;)
+               ;
+}
index 51b718ee13accfbe9fcad3a144af61ff83346a6c..c46d3b71194735cb5b9278cb9ba5d92381d25082 100644 (file)
@@ -41,6 +41,7 @@ BL1_SOURCES           +=      drivers/io/io_semihosting.c                     \
                                lib/semihosting/aarch64/semihosting_call.S      \
                                plat/arm/board/fvp/aarch64/fvp_helpers.S        \
                                plat/arm/board/fvp/fvp_bl1_setup.c              \
+                               plat/arm/board/fvp/fvp_err.c                    \
                                plat/arm/board/fvp/fvp_io_storage.c
 
 BL2_SOURCES            +=      drivers/arm/sp804/sp804_delay_timer.c           \
@@ -49,6 +50,7 @@ BL2_SOURCES           +=      drivers/arm/sp804/sp804_delay_timer.c           \
                                lib/semihosting/semihosting.c                   \
                                lib/semihosting/aarch64/semihosting_call.S      \
                                plat/arm/board/fvp/fvp_bl2_setup.c              \
+                               plat/arm/board/fvp/fvp_err.c                    \
                                plat/arm/board/fvp/fvp_io_storage.c             \
                                plat/arm/board/fvp/fvp_security.c
 
diff --git a/plat/arm/board/juno/juno_err.c b/plat/arm/board/juno/juno_err.c
new file mode 100644 (file)
index 0000000..497cc7f
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <v2m_def.h>
+
+#define V2M_SYS_NVFLAGS_ADDR           (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGS)
+
+/*
+ * Juno error handler
+ */
+void plat_error_handler(int err)
+{
+       uint32_t *flags_ptr = (uint32_t *)V2M_SYS_NVFLAGS_ADDR;
+
+       /* Propagate the err code in the NV-flags register */
+       *flags_ptr = err;
+
+       /* Loop until the watchdog resets the system */
+       for (;;)
+               ;
+}
index b711f3d5df1e8535fe3463bd77ae0e82853fb90e..127dcbea86622caa224e98eeb9238372d5f984ee 100644 (file)
@@ -34,9 +34,11 @@ PLAT_BL_COMMON_SOURCES       :=      plat/arm/board/juno/aarch64/juno_helpers.S
 
 BL1_SOURCES            +=      lib/cpus/aarch64/cortex_a53.S           \
                                lib/cpus/aarch64/cortex_a57.S           \
-                               lib/cpus/aarch64/cortex_a72.S
+                               lib/cpus/aarch64/cortex_a72.S           \
+                               plat/arm/board/juno/juno_err.c
 
 BL2_SOURCES            +=      plat/arm/board/juno/juno_security.c     \
+                               plat/arm/board/juno/juno_err.c
 
 BL31_SOURCES           +=      lib/cpus/aarch64/cortex_a53.S           \
                                lib/cpus/aarch64/cortex_a57.S           \
index 887223cf4f8bc396c97e3d6834c8848c1419efc6..79c7d94409c9c430b2b26bea72981a2b241534ad 100644 (file)
@@ -35,6 +35,7 @@
 #include <console.h>
 #include <platform_def.h>
 #include <plat_arm.h>
+#include <sp805.h>
 #include "../../../bl1/bl1_private.h"
 
 
@@ -74,6 +75,11 @@ void arm_bl1_early_platform_setup(void)
 {
        const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
 
+#if !ARM_DISABLE_TRUSTED_WDOG
+       /* Enable watchdog */
+       sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+#endif
+
        /* Initialize the console to provide early debug support */
        console_init(PLAT_ARM_BOOT_UART_BASE, PLAT_ARM_BOOT_UART_CLK_IN_HZ,
                        ARM_CONSOLE_BAUDRATE);
@@ -147,6 +153,11 @@ void bl1_platform_setup(void)
 
 void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
 {
+#if !ARM_DISABLE_TRUSTED_WDOG
+       /* Disable watchdog before leaving BL1 */
+       sp805_stop(ARM_SP805_TWDG_BASE);
+#endif
+
 #ifdef EL3_PAYLOAD_BASE
        /*
         * Program the EL3 payload's entry point address into the CPUs mailbox
index 7b23527598397c932ddc2778295eb80963a6d2d5..1290cef3cc45f83311e3653692817e85abccc56a 100644 (file)
@@ -63,6 +63,15 @@ endif
 $(eval $(call assert_boolean,ARM_RECOM_STATE_ID_ENC))
 $(eval $(call add_define,ARM_RECOM_STATE_ID_ENC))
 
+# Process ARM_DISABLE_TRUSTED_WDOG flag
+# By default, Trusted Watchdog is always enabled unless SPIN_ON_BL1_EXIT is set
+ARM_DISABLE_TRUSTED_WDOG       :=      0
+ifeq (${SPIN_ON_BL1_EXIT}, 1)
+ARM_DISABLE_TRUSTED_WDOG       :=      1
+endif
+$(eval $(call assert_boolean,ARM_DISABLE_TRUSTED_WDOG))
+$(eval $(call add_define,ARM_DISABLE_TRUSTED_WDOG))
+
 PLAT_INCLUDES          +=      -Iinclude/common/tbbr                           \
                                -Iinclude/plat/arm/common                       \
                                -Iinclude/plat/arm/common/aarch64
@@ -75,6 +84,7 @@ PLAT_BL_COMMON_SOURCES        +=      lib/aarch64/xlat_tables.c                       \
 
 BL1_SOURCES            +=      drivers/arm/cci/cci.c                           \
                                drivers/arm/ccn/ccn.c                           \
+                               drivers/arm/sp805/sp805.c                       \
                                drivers/io/io_fip.c                             \
                                drivers/io/io_memmap.c                          \
                                drivers/io/io_storage.c                         \