]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
Tegra210: SE: add context save support
authorHarvey Hsieh <hhsieh@nvidia.com>
Tue, 10 Apr 2018 10:16:51 +0000 (18:16 +0800)
committerVarun Wadekar <vwadekar@nvidia.com>
Mon, 9 Mar 2020 22:25:15 +0000 (15:25 -0700)
Tegra210B01 SoCs support atomic context save for the two SE
hardware engines. Tegra210 SoCs have support for only one SE
engine and support a software based save/restore mechanism
instead.

This patch updates the SE driver to make this change.

Change-Id: Ia5e5ed75d0fe011f17809684bbc2ed2338925946
Signed-off-by: Harvey Hsieh <hhsieh@nvidia.com>
plat/nvidia/tegra/include/t210/tegra_def.h
plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
plat/nvidia/tegra/soc/t210/plat_setup.c

index 4a39aa1fb1ebaf5364a2aa1880fe4a72adcc2d2f..e8bce5e05519cf4822c481472e2e84ba07c5a1a8 100644 (file)
 #define  SE_CLK_ENB_BIT                        (U(1) << 31)
 #define TEGRA_CLK_OUT_ENB_W            U(0x364)
 #define  ENTROPY_RESET_BIT             (U(1) << 21)
+#define TEGRA_CLK_RST_CTL_CLK_SRC_SE   U(0x42C)
+#define  SE_CLK_SRC_MASK               (U(7) << 29)
+#define  SE_CLK_SRC_CLK_M              (U(6) << 29)
 #define TEGRA_RST_DEV_SET_V            U(0x430)
 #define  SE_RESET_BIT                  (U(1) << 31)
 #define  HDA_RESET_BIT                 (U(1) << 29)
index 352107d2ceccf2fa5cc3429ef610a21d86bd2098..c44b0fc46521dbe6a25112765c8e7f55df284afc 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION.  All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,6 +15,9 @@
  * PMC registers
  */
 
+/* SC7 context save scratch register for T210 */
+#define PMC_SCRATCH43_REG_OFFSET               U(0x22C)
+
 /* Secure scratch registers */
 #define PMC_SECURE_SCRATCH4_OFFSET             0xC0U
 #define PMC_SECURE_SCRATCH5_OFFSET             0xC4U
                ((x) & ((0x1U) << SE_TZRAM_OP_REQ_SHIFT))
 
 /* SE Interrupt */
+#define SE_INT_ENABLE_REG_OFFSET               U(0xC)
 #define SE_INT_STATUS_REG_OFFSET               0x10U
 #define SE_INT_OP_DONE_SHIFT                   4
 #define SE_INT_OP_DONE_CLEAR   \
index d5e04912686ea08ccc162472b9fbadbec2399c85..635018dbc0f0d2edef8dca0678a7e5960659d970 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION.  All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,8 +20,8 @@
  * Constants and Macros
  ******************************************************************************/
 
-#define TIMEOUT_100MS  100U    // Timeout in 100ms
-#define RNG_AES_KEY_INDEX   1
+#define TIMEOUT_100MS          100U    /* Timeout in 100ms */
+#define RNG_AES_KEY_INDEX      1
 
 /*******************************************************************************
  * Data structure and global variables
  * #--------------------------------#
  */
 
-/* Known pattern data */
-static const uint32_t se_ctx_known_pattern_data[SE_CTX_KNOWN_PATTERN_SIZE_WORDS] = {
+/* Known pattern data for T210 */
+static const uint8_t se_ctx_known_pattern_data[SE_CTX_KNOWN_PATTERN_SIZE] = {
        /* 128 bit AES block */
-       0x0C0D0E0F,
-       0x08090A0B,
-       0x04050607,
-       0x00010203,
-};
+       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+       };
 
 /* SE input and output linked list buffers */
 static tegra_se_io_lst_t se1_src_ll_buf;
@@ -85,6 +83,9 @@ static tegra_se_io_lst_t se1_dst_ll_buf;
 static tegra_se_io_lst_t se2_src_ll_buf;
 static tegra_se_io_lst_t se2_dst_ll_buf;
 
+/* SE1 context buffer, 132 blocks */
+static __aligned(64) uint8_t se1_ctx_buf[SE_CTX_DRBG_BUFER_SIZE];
+
 /* SE1 security engine device handle */
 static tegra_se_dev_t se_dev_1 = {
        .se_num = 1,
@@ -97,10 +98,10 @@ static tegra_se_dev_t se_dev_1 = {
        /* Setup DST buffers for SE operations */
        .dst_ll_buf = &se1_dst_ll_buf,
        /* Setup context save destination */
-       .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE),
+       .ctx_save_buf = (uint32_t *)&se1_ctx_buf
 };
 
-/* SE2 security engine device handle */
+/* SE2 security engine device handle (T210B01 only) */
 static tegra_se_dev_t se_dev_2 = {
        .se_num = 2,
        /* Setup base address for se */
@@ -112,7 +113,7 @@ static tegra_se_dev_t se_dev_2 = {
        /* Setup DST buffers for SE operations */
        .dst_ll_buf = &se2_dst_ll_buf,
        /* Setup context save destination */
-       .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE + 0x1000),
+       .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE + 0x1000)
 };
 
 static bool ecid_valid;
@@ -201,18 +202,6 @@ static int32_t tegra_se_operation_complete(const tegra_se_dev_t *se_dev)
        return ret;
 }
 
-/*
- * Returns true if the SE engine is configured to perform SE context save in
- * hardware.
- */
-static inline bool tegra_se_atomic_save_enabled(const tegra_se_dev_t *se_dev)
-{
-       uint32_t val;
-
-       val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET);
-       return (SE_CTX_SAVE_AUTO_ENABLE(val) == SE_CTX_SAVE_AUTO_EN);
-}
-
 /*
  * Wait for SE engine to be idle and clear pending interrupts before
  * starting the next SE operation.
@@ -223,6 +212,9 @@ static int32_t tegra_se_operation_prepare(const tegra_se_dev_t *se_dev)
        uint32_t val = 0;
        uint32_t timeout;
 
+       /* disable SE interrupt to prevent interrupt issued by SE operation */
+       tegra_se_write_32(se_dev, SE_INT_ENABLE_REG_OFFSET, 0U);
+
        /* Wait for previous operation to finish */
        val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
        for (timeout = 0; (val != 0U) && (timeout < TIMEOUT_100MS); timeout++) {
@@ -629,19 +621,19 @@ static int tegra_se_lp_rsakeytable_context_save(tegra_se_dev_t *se_dev)
 {
        uint32_t val = 0;
        int ret = 0;
-       /* First the modulus and then the exponent must be
+       /* For T210, First the modulus and then exponent must be
         * encrypted and saved. This is repeated for SLOT 0
         * and SLOT 1. Hence the order:
-        * SLOT 0 exponent : RSA_KEY_INDEX : 0
         * SLOT 0 modulus : RSA_KEY_INDEX : 1
-        * SLOT 1 exponent : RSA_KEY_INDEX : 2
+        * SLOT 0 exponent : RSA_KEY_INDEX : 0
         * SLOT 1 modulus : RSA_KEY_INDEX : 3
+        * SLOT 1 exponent : RSA_KEY_INDEX : 2
         */
        const unsigned int key_index_mod[TEGRA_SE_RSA_KEYSLOT_COUNT][2] = {
                /* RSA key slot 0 */
-               {SE_RSA_KEY_INDEX_SLOT0_EXP, SE_RSA_KEY_INDEX_SLOT0_MOD},
+               {SE_RSA_KEY_INDEX_SLOT0_MOD, SE_RSA_KEY_INDEX_SLOT0_EXP},
                /* RSA key slot 1 */
-               {SE_RSA_KEY_INDEX_SLOT1_EXP, SE_RSA_KEY_INDEX_SLOT1_MOD},
+               {SE_RSA_KEY_INDEX_SLOT1_MOD, SE_RSA_KEY_INDEX_SLOT1_EXP},
        };
 
        se_dev->dst_ll_buf->last_buff_num = 0;
@@ -876,8 +868,8 @@ static int tegra_se_context_save_sw(tegra_se_dev_t *se_dev)
 
        /* Write lp context buffer address into PMC scratch register */
        if (se_dev->se_num == 1) {
-               /* SE context address */
-               mmio_write_32((uint64_t)TEGRA_PMC_BASE + PMC_SECURE_SCRATCH117_OFFSET,
+               /* SE context address, support T210 only */
+               mmio_write_32((uint64_t)TEGRA_PMC_BASE + PMC_SCRATCH43_REG_OFFSET,
                                ((uint64_t)(se_dev->ctx_save_buf)));
        } else if (se_dev->se_num == 2) {
                /* SE2 & PKA1 context address */
@@ -909,7 +901,10 @@ void tegra_se_init(void)
 
        /* Generate random SRK to initialize DRBG */
        tegra_se_generate_srk(&se_dev_1);
-       tegra_se_generate_srk(&se_dev_2);
+
+       if (tegra_chipid_is_t210_b01()) {
+               tegra_se_generate_srk(&se_dev_2);
+       }
 
        /* determine if ECID is valid */
        val = mmio_read_32(TEGRA_FUSE_BASE + FUSE_JTAG_SECUREID_VALID);
@@ -932,6 +927,18 @@ static void tegra_se_enable_clocks(void)
        val &= ~ENTROPY_RESET_BIT;
        mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W, val);
 
+       if (!tegra_chipid_is_t210_b01()) {
+
+               /*
+                * T210 SE clock source is turned off in kernel, to simplify
+                * SE clock source setting, we switch SE clock source to
+                * CLK_M, SE_CLK_DIVISOR = 0. T210 B01 SE clock source is
+                * always on, so don't need this setting.
+                */
+               mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_RST_CTL_CLK_SRC_SE,
+                             SE_CLK_SRC_CLK_M);
+       }
+
        /* Enable SE clock */
        val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V);
        val |= SE_CLK_ENB_BIT;
@@ -975,43 +982,25 @@ int32_t tegra_se_suspend(void)
 
        tegra_se_enable_clocks();
 
-       if (tegra_se_atomic_save_enabled(&se_dev_2) &&
-                       tegra_se_atomic_save_enabled(&se_dev_1)) {
-               /* Atomic context save se2 and pka1 */
+       if (tegra_chipid_is_t210_b01()) {
+               /* It is T210 B01, Atomic context save se2 and pka1 */
                INFO("%s: SE2/PKA1 atomic context save\n", __func__);
-               if (ret == 0) {
-                       ret = tegra_se_context_save_atomic(&se_dev_2);
-               }
-
-               /* Atomic context save se */
-               if (ret == 0) {
-                       INFO("%s: SE1 atomic context save\n", __func__);
-                       ret = tegra_se_context_save_atomic(&se_dev_1);
+               ret = tegra_se_context_save_atomic(&se_dev_2);
+               if (ret != 0) {
+                       ERROR("%s: SE2 ctx save failed (%d)\n", __func__, ret);
                }
 
-               if (ret == 0) {
-                       INFO("%s: SE atomic context save done\n", __func__);
-               }
-       } else if (!tegra_se_atomic_save_enabled(&se_dev_2) &&
-                       !tegra_se_atomic_save_enabled(&se_dev_1)) {
-               /* SW context save se2 and pka1 */
-               INFO("%s: SE2/PKA1 legacy(SW) context save\n", __func__);
-               if (ret == 0) {
-                       ret = tegra_se_context_save_sw(&se_dev_2);
-               }
-
-               /* SW context save se */
-               if (ret == 0) {
-                       INFO("%s: SE1 legacy(SW) context save\n", __func__);
-                       ret = tegra_se_context_save_sw(&se_dev_1);
-               }
-
-               if (ret == 0) {
-                       INFO("%s: SE SW context save done\n", __func__);
+               ret = tegra_se_context_save_atomic(&se_dev_1);
+               if (ret != 0) {
+                       ERROR("%s: SE1 ctx save failed (%d)\n", __func__, ret);
                }
        } else {
-               ERROR("%s: One SE set for atomic CTX save, the other is not\n",
-                        __func__);
+               /* It is T210, SW context save se */
+               INFO("%s: SE1 legacy(SW) context save\n", __func__);
+               ret = tegra_se_context_save_sw(&se_dev_1);
+               if (ret != 0) {
+                       ERROR("%s: SE1 ctx save failed (%d)\n", __func__, ret);
+               }
        }
 
        tegra_se_disable_clocks();
@@ -1080,5 +1069,8 @@ static void tegra_se_warm_boot_resume(const tegra_se_dev_t *se_dev)
 void tegra_se_resume(void)
 {
        tegra_se_warm_boot_resume(&se_dev_1);
-       tegra_se_warm_boot_resume(&se_dev_2);
+
+       if (tegra_chipid_is_t210_b01()) {
+               tegra_se_warm_boot_resume(&se_dev_2);
+       }
 }
index 832b8d647f5b623af75600ca6ec7b1a5378e1434..f29e624eae4a4f4056d21710e91f9e5cecaabe29 100644 (file)
@@ -210,12 +210,9 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
                assert((stateid_afflvl1 == PLAT_MAX_OFF_STATE) ||
                        (stateid_afflvl1 == PSTATE_ID_SOC_POWERDN));
 
-               if (tegra_chipid_is_t210_b01()) {
-
-                       /* Suspend se/se2 and pka1 */
-                       if (tegra_se_suspend() != 0) {
-                               ret = PSCI_E_INTERN_FAIL;
-                       }
+               /* Suspend se/se2 and pka1 for T210 B01 and se for T210 */
+               if (tegra_se_suspend() != 0) {
+                       ret = PSCI_E_INTERN_FAIL;
                }
 
        } else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) {
index 7afbe0d9a4616c0cbaba192e88c504704df27e20..933e925ec4c8e0769d9c08586c0a0330364b4cb7 100644 (file)
@@ -174,9 +174,7 @@ void plat_early_platform_setup(void)
        }
 
        /* Initialize security engine driver */
-       if (tegra_chipid_is_t210_b01()) {
-               tegra_se_init();
-       }
+       tegra_se_init();
 }
 
 /* Secure IRQs for Tegra186 */