1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. 4*91f16700Schasinglulu * 5*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 6*91f16700Schasinglulu */ 7*91f16700Schasinglulu 8*91f16700Schasinglulu #include <assert.h> 9*91f16700Schasinglulu #include <errno.h> 10*91f16700Schasinglulu #include <stdbool.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu #include <arch_helpers.h> 13*91f16700Schasinglulu #include <bpmp_ipc.h> 14*91f16700Schasinglulu #include <common/debug.h> 15*91f16700Schasinglulu #include <drivers/delay_timer.h> 16*91f16700Schasinglulu #include <lib/mmio.h> 17*91f16700Schasinglulu #include <lib/psci/psci.h> 18*91f16700Schasinglulu #include <se.h> 19*91f16700Schasinglulu #include <tegra_platform.h> 20*91f16700Schasinglulu 21*91f16700Schasinglulu #include "se_private.h" 22*91f16700Schasinglulu 23*91f16700Schasinglulu /******************************************************************************* 24*91f16700Schasinglulu * Constants and Macros 25*91f16700Schasinglulu ******************************************************************************/ 26*91f16700Schasinglulu #define ERR_STATUS_SW_CLEAR U(0xFFFFFFFF) 27*91f16700Schasinglulu #define INT_STATUS_SW_CLEAR U(0xFFFFFFFF) 28*91f16700Schasinglulu #define MAX_TIMEOUT_MS U(1000) /* Max. timeout of 1s */ 29*91f16700Schasinglulu #define NUM_SE_REGS_TO_SAVE U(4) 30*91f16700Schasinglulu 31*91f16700Schasinglulu #define BYTES_IN_WORD U(4) 32*91f16700Schasinglulu #define SHA256_MAX_HASH_RESULT U(7) 33*91f16700Schasinglulu #define SHA256_DST_SIZE U(32) 34*91f16700Schasinglulu #define SHA_FIRST_OP U(1) 35*91f16700Schasinglulu #define MAX_SHA_ENGINE_CHUNK_SIZE U(0xFFFFFF) 36*91f16700Schasinglulu #define SHA256_MSG_LENGTH_ONETIME U(0xFFFF) 37*91f16700Schasinglulu 38*91f16700Schasinglulu /******************************************************************************* 39*91f16700Schasinglulu * Data structure and global variables 40*91f16700Schasinglulu ******************************************************************************/ 41*91f16700Schasinglulu static uint32_t se_regs[NUM_SE_REGS_TO_SAVE]; 42*91f16700Schasinglulu 43*91f16700Schasinglulu /* 44*91f16700Schasinglulu * Check that SE operation has completed after kickoff. 45*91f16700Schasinglulu * 46*91f16700Schasinglulu * This function is invoked after an SE operation has been started, 47*91f16700Schasinglulu * and it checks the following conditions: 48*91f16700Schasinglulu * 49*91f16700Schasinglulu * 1. SE_STATUS = IDLE 50*91f16700Schasinglulu * 2. AHB bus data transfer is complete. 51*91f16700Schasinglulu * 3. SE_ERR_STATUS is clean. 52*91f16700Schasinglulu */ 53*91f16700Schasinglulu static bool tegra_se_is_operation_complete(void) 54*91f16700Schasinglulu { 55*91f16700Schasinglulu uint32_t val = 0, timeout = 0, sha_status, aes_status; 56*91f16700Schasinglulu int32_t ret = 0; 57*91f16700Schasinglulu bool se_is_busy, txn_has_errors, txn_successful; 58*91f16700Schasinglulu 59*91f16700Schasinglulu /* 60*91f16700Schasinglulu * Poll the status register to check if the operation 61*91f16700Schasinglulu * completed. 62*91f16700Schasinglulu */ 63*91f16700Schasinglulu do { 64*91f16700Schasinglulu val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS); 65*91f16700Schasinglulu se_is_busy = ((val & CTX_SAVE_AUTO_SE_BUSY) != 0U); 66*91f16700Schasinglulu 67*91f16700Schasinglulu /* sleep until SE finishes */ 68*91f16700Schasinglulu if (se_is_busy) { 69*91f16700Schasinglulu mdelay(1); 70*91f16700Schasinglulu timeout++; 71*91f16700Schasinglulu } 72*91f16700Schasinglulu 73*91f16700Schasinglulu } while (se_is_busy && (timeout < MAX_TIMEOUT_MS)); 74*91f16700Schasinglulu 75*91f16700Schasinglulu /* any transaction errors? */ 76*91f16700Schasinglulu txn_has_errors = (tegra_se_read_32(SHA_ERR_STATUS) != 0U) || 77*91f16700Schasinglulu (tegra_se_read_32(AES0_ERR_STATUS) != 0U); 78*91f16700Schasinglulu 79*91f16700Schasinglulu /* transaction successful? */ 80*91f16700Schasinglulu sha_status = tegra_se_read_32(SHA_INT_STATUS) & SHA_SE_OP_DONE; 81*91f16700Schasinglulu aes_status = tegra_se_read_32(AES0_INT_STATUS) & AES0_SE_OP_DONE; 82*91f16700Schasinglulu txn_successful = (sha_status == SHA_SE_OP_DONE) && 83*91f16700Schasinglulu (aes_status == AES0_SE_OP_DONE); 84*91f16700Schasinglulu 85*91f16700Schasinglulu if ((timeout == MAX_TIMEOUT_MS) || txn_has_errors || !txn_successful) { 86*91f16700Schasinglulu ERROR("%s: Atomic context save operation failed!\n", 87*91f16700Schasinglulu __func__); 88*91f16700Schasinglulu ret = -ECANCELED; 89*91f16700Schasinglulu } 90*91f16700Schasinglulu 91*91f16700Schasinglulu return (ret == 0); 92*91f16700Schasinglulu } 93*91f16700Schasinglulu 94*91f16700Schasinglulu /* 95*91f16700Schasinglulu * Wait for SE engine to be idle and clear any pending interrupts, before 96*91f16700Schasinglulu * starting the next SE operation. 97*91f16700Schasinglulu */ 98*91f16700Schasinglulu static bool tegra_se_is_ready(void) 99*91f16700Schasinglulu { 100*91f16700Schasinglulu int32_t ret = 0; 101*91f16700Schasinglulu uint32_t val = 0, timeout = 0; 102*91f16700Schasinglulu bool se_is_ready; 103*91f16700Schasinglulu 104*91f16700Schasinglulu /* Wait for previous operation to finish */ 105*91f16700Schasinglulu do { 106*91f16700Schasinglulu val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS); 107*91f16700Schasinglulu se_is_ready = (val == CTX_SAVE_AUTO_SE_READY); 108*91f16700Schasinglulu 109*91f16700Schasinglulu /* sleep until SE is ready */ 110*91f16700Schasinglulu if (!se_is_ready) { 111*91f16700Schasinglulu mdelay(1); 112*91f16700Schasinglulu timeout++; 113*91f16700Schasinglulu } 114*91f16700Schasinglulu 115*91f16700Schasinglulu } while (!se_is_ready && (timeout < MAX_TIMEOUT_MS)); 116*91f16700Schasinglulu 117*91f16700Schasinglulu if (timeout == MAX_TIMEOUT_MS) { 118*91f16700Schasinglulu ERROR("%s: SE is not ready!\n", __func__); 119*91f16700Schasinglulu ret = -ETIMEDOUT; 120*91f16700Schasinglulu } 121*91f16700Schasinglulu 122*91f16700Schasinglulu /* Clear any pending interrupts from previous operation */ 123*91f16700Schasinglulu tegra_se_write_32(AES0_INT_STATUS, INT_STATUS_SW_CLEAR); 124*91f16700Schasinglulu tegra_se_write_32(AES1_INT_STATUS, INT_STATUS_SW_CLEAR); 125*91f16700Schasinglulu tegra_se_write_32(RSA_INT_STATUS, INT_STATUS_SW_CLEAR); 126*91f16700Schasinglulu tegra_se_write_32(SHA_INT_STATUS, INT_STATUS_SW_CLEAR); 127*91f16700Schasinglulu 128*91f16700Schasinglulu /* Clear error status for each engine seen from current port */ 129*91f16700Schasinglulu tegra_se_write_32(AES0_ERR_STATUS, ERR_STATUS_SW_CLEAR); 130*91f16700Schasinglulu tegra_se_write_32(AES1_ERR_STATUS, ERR_STATUS_SW_CLEAR); 131*91f16700Schasinglulu tegra_se_write_32(RSA_ERR_STATUS, ERR_STATUS_SW_CLEAR); 132*91f16700Schasinglulu tegra_se_write_32(SHA_ERR_STATUS, ERR_STATUS_SW_CLEAR); 133*91f16700Schasinglulu 134*91f16700Schasinglulu return (ret == 0); 135*91f16700Schasinglulu } 136*91f16700Schasinglulu 137*91f16700Schasinglulu /* 138*91f16700Schasinglulu * During System Suspend, this handler triggers the hardware context 139*91f16700Schasinglulu * save operation. 140*91f16700Schasinglulu */ 141*91f16700Schasinglulu static int32_t tegra_se_save_context(void) 142*91f16700Schasinglulu { 143*91f16700Schasinglulu int32_t ret = -ECANCELED; 144*91f16700Schasinglulu 145*91f16700Schasinglulu /* 146*91f16700Schasinglulu * 1. Ensure all SE Driver including RNG1/PKA1 are shut down. 147*91f16700Schasinglulu * TSEC/R5s are powergated/idle. All tasks on SE1~SE4, RNG1, 148*91f16700Schasinglulu * PKA1 are wrapped up. SE0 is ready for use. 149*91f16700Schasinglulu * 2. Clear interrupt/error in SE0 status register. 150*91f16700Schasinglulu * 3. Scrub SE0 register to avoid false failure for illegal 151*91f16700Schasinglulu * configuration. Probably not needed, dependent on HW 152*91f16700Schasinglulu * implementation. 153*91f16700Schasinglulu * 4. Check SE is ready for HW CTX_SAVE by polling 154*91f16700Schasinglulu * SE_CTX_SAVE_AUTO_STATUS.SE_READY. 155*91f16700Schasinglulu * 156*91f16700Schasinglulu * Steps 1-4 are executed by tegra_se_is_ready(). 157*91f16700Schasinglulu * 158*91f16700Schasinglulu * 5. Issue context save command. 159*91f16700Schasinglulu * 6. Check SE is busy with CTX_SAVE, the command in step5 was not 160*91f16700Schasinglulu * dropped for ongoing traffic in any of SE port/engine. 161*91f16700Schasinglulu * 7. Poll SE register or wait for SE APB interrupt for task completion 162*91f16700Schasinglulu * a. Polling: Read SE_CTX_SAVE_AUTO_STATUS.BUSY till it reports IDLE 163*91f16700Schasinglulu * b. Interrupt: After receiving interrupt from SE APB, read 164*91f16700Schasinglulu * SE_CTX_SAVE_AUTO_STATUS.BUSY till it reports IDLE. 165*91f16700Schasinglulu * 8. Check AES0 and SHA ERR_STATUS to ensure no error case. 166*91f16700Schasinglulu * 9. Check AES0 and SHA INT_STATUS to ensure operation has successfully 167*91f16700Schasinglulu * completed. 168*91f16700Schasinglulu * 169*91f16700Schasinglulu * Steps 6-9 are executed by tegra_se_is_operation_complete(). 170*91f16700Schasinglulu */ 171*91f16700Schasinglulu if (tegra_se_is_ready()) { 172*91f16700Schasinglulu 173*91f16700Schasinglulu /* Issue context save command */ 174*91f16700Schasinglulu tegra_se_write_32(AES0_OPERATION, SE_OP_CTX_SAVE); 175*91f16700Schasinglulu 176*91f16700Schasinglulu /* Wait for operation to finish */ 177*91f16700Schasinglulu if (tegra_se_is_operation_complete()) { 178*91f16700Schasinglulu ret = 0; 179*91f16700Schasinglulu } 180*91f16700Schasinglulu } 181*91f16700Schasinglulu 182*91f16700Schasinglulu return ret; 183*91f16700Schasinglulu } 184*91f16700Schasinglulu 185*91f16700Schasinglulu /* 186*91f16700Schasinglulu * Check that SE operation has completed after kickoff 187*91f16700Schasinglulu * This function is invoked after an SE operation has been started, 188*91f16700Schasinglulu * and it checks the following conditions: 189*91f16700Schasinglulu * 1. SE0_INT_STATUS = SE0_OP_DONE 190*91f16700Schasinglulu * 2. SE0_STATUS = IDLE 191*91f16700Schasinglulu * 3. SE0_ERR_STATUS is clean. 192*91f16700Schasinglulu */ 193*91f16700Schasinglulu static int32_t tegra_se_sha256_hash_operation_complete(void) 194*91f16700Schasinglulu { 195*91f16700Schasinglulu uint32_t val = 0U; 196*91f16700Schasinglulu 197*91f16700Schasinglulu /* Poll the SE interrupt register to ensure H/W operation complete */ 198*91f16700Schasinglulu val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET); 199*91f16700Schasinglulu while (SE0_INT_OP_DONE(val) == SE0_INT_OP_DONE_CLEAR) { 200*91f16700Schasinglulu val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET); 201*91f16700Schasinglulu if (SE0_INT_OP_DONE(val) != SE0_INT_OP_DONE_CLEAR) { 202*91f16700Schasinglulu break; 203*91f16700Schasinglulu } 204*91f16700Schasinglulu } 205*91f16700Schasinglulu 206*91f16700Schasinglulu /* Poll the SE status idle to ensure H/W operation complete */ 207*91f16700Schasinglulu val = tegra_se_read_32(SE0_SHA_STATUS_0); 208*91f16700Schasinglulu while (val != SE0_SHA_STATUS_IDLE) { 209*91f16700Schasinglulu val = tegra_se_read_32(SE0_SHA_STATUS_0); 210*91f16700Schasinglulu if (val == SE0_SHA_STATUS_IDLE) { 211*91f16700Schasinglulu break; 212*91f16700Schasinglulu } 213*91f16700Schasinglulu } 214*91f16700Schasinglulu 215*91f16700Schasinglulu /* Ensure that no errors are thrown during operation */ 216*91f16700Schasinglulu val = tegra_se_read_32(SE0_ERR_STATUS_REG_OFFSET); 217*91f16700Schasinglulu if (val != 0U) { 218*91f16700Schasinglulu ERROR("%s: error during SE operation! 0x%x", __func__, 219*91f16700Schasinglulu val); 220*91f16700Schasinglulu return -ENOTSUP; 221*91f16700Schasinglulu } 222*91f16700Schasinglulu 223*91f16700Schasinglulu return 0; 224*91f16700Schasinglulu } 225*91f16700Schasinglulu 226*91f16700Schasinglulu /* 227*91f16700Schasinglulu * Security engine primitive normal operations 228*91f16700Schasinglulu */ 229*91f16700Schasinglulu static int32_t tegra_se_start_normal_operation(uint64_t src_addr, 230*91f16700Schasinglulu uint32_t nbytes, uint32_t last_buf, uint32_t src_len_inbytes) 231*91f16700Schasinglulu { 232*91f16700Schasinglulu uint32_t val = 0U; 233*91f16700Schasinglulu uint32_t src_in_lo; 234*91f16700Schasinglulu uint32_t src_in_msb; 235*91f16700Schasinglulu uint32_t src_in_hi; 236*91f16700Schasinglulu int32_t ret = 0; 237*91f16700Schasinglulu 238*91f16700Schasinglulu if ((src_addr == 0ULL) || (nbytes == 0U)) 239*91f16700Schasinglulu return -EINVAL; 240*91f16700Schasinglulu 241*91f16700Schasinglulu src_in_lo = (uint32_t)src_addr; 242*91f16700Schasinglulu src_in_msb = (uint32_t)((src_addr >> 32U) & 0xFFU); 243*91f16700Schasinglulu src_in_hi = ((src_in_msb << SE0_IN_HI_ADDR_HI_0_MSB_SHIFT) | 244*91f16700Schasinglulu (nbytes & MAX_SHA_ENGINE_CHUNK_SIZE)); 245*91f16700Schasinglulu 246*91f16700Schasinglulu /* set SRC_IN_ADDR_LO and SRC_IN_ADDR_HI*/ 247*91f16700Schasinglulu tegra_se_write_32(SE0_IN_ADDR, src_in_lo); 248*91f16700Schasinglulu tegra_se_write_32(SE0_IN_HI_ADDR_HI, src_in_hi); 249*91f16700Schasinglulu 250*91f16700Schasinglulu val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET); 251*91f16700Schasinglulu if (val > 0U) { 252*91f16700Schasinglulu tegra_se_write_32(SE0_INT_STATUS_REG_OFFSET, 0x0U); 253*91f16700Schasinglulu } 254*91f16700Schasinglulu 255*91f16700Schasinglulu /* Enable SHA interrupt for SE0 Operation */ 256*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_INT_ENABLE, 0x1aU); 257*91f16700Schasinglulu 258*91f16700Schasinglulu /* flush to DRAM for SE to use the updated contents */ 259*91f16700Schasinglulu flush_dcache_range(src_addr, src_len_inbytes); 260*91f16700Schasinglulu 261*91f16700Schasinglulu /* Start SHA256 operation */ 262*91f16700Schasinglulu if (last_buf == 1U) { 263*91f16700Schasinglulu tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START | 264*91f16700Schasinglulu SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD); 265*91f16700Schasinglulu } else { 266*91f16700Schasinglulu tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START); 267*91f16700Schasinglulu } 268*91f16700Schasinglulu 269*91f16700Schasinglulu return ret; 270*91f16700Schasinglulu } 271*91f16700Schasinglulu 272*91f16700Schasinglulu static int32_t tegra_se_calculate_sha256_hash(uint64_t src_addr, 273*91f16700Schasinglulu uint32_t src_len_inbyte) 274*91f16700Schasinglulu { 275*91f16700Schasinglulu uint32_t val, last_buf, i; 276*91f16700Schasinglulu int32_t ret = 0; 277*91f16700Schasinglulu uint32_t operations; 278*91f16700Schasinglulu uint64_t src_len_inbits; 279*91f16700Schasinglulu uint32_t len_bits_msb; 280*91f16700Schasinglulu uint32_t len_bits_lsb; 281*91f16700Schasinglulu uint32_t number_of_operations, max_bytes, bytes_left, remaining_bytes; 282*91f16700Schasinglulu 283*91f16700Schasinglulu if (src_len_inbyte > MAX_SHA_ENGINE_CHUNK_SIZE) { 284*91f16700Schasinglulu ERROR("SHA input chunk size too big: 0x%x\n", src_len_inbyte); 285*91f16700Schasinglulu return -EINVAL; 286*91f16700Schasinglulu } 287*91f16700Schasinglulu 288*91f16700Schasinglulu if (src_addr == 0ULL) { 289*91f16700Schasinglulu return -EINVAL; 290*91f16700Schasinglulu } 291*91f16700Schasinglulu 292*91f16700Schasinglulu /* number of bytes per operation */ 293*91f16700Schasinglulu max_bytes = (SHA256_HASH_SIZE_BYTES * SHA256_MSG_LENGTH_ONETIME); 294*91f16700Schasinglulu 295*91f16700Schasinglulu src_len_inbits = (uint32_t)(src_len_inbyte * 8U); 296*91f16700Schasinglulu len_bits_msb = (uint32_t)(src_len_inbits >> 32U); 297*91f16700Schasinglulu len_bits_lsb = (uint32_t)src_len_inbits; 298*91f16700Schasinglulu 299*91f16700Schasinglulu /* program SE0_CONFIG for SHA256 operation */ 300*91f16700Schasinglulu val = (uint32_t)(SE0_CONFIG_ENC_ALG_SHA | SE0_CONFIG_ENC_MODE_SHA256 | 301*91f16700Schasinglulu SE0_CONFIG_DEC_ALG_NOP | SE0_CONFIG_DST_HASHREG); 302*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_CONFIG, val); 303*91f16700Schasinglulu 304*91f16700Schasinglulu /* set SE0_SHA_MSG_LENGTH registers */ 305*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_MSG_LENGTH_0, len_bits_lsb); 306*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb); 307*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_MSG_LENGTH_1, len_bits_msb); 308*91f16700Schasinglulu 309*91f16700Schasinglulu /* zero out unused SE0_SHA_MSG_LENGTH and SE0_SHA_MSG_LEFT */ 310*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_MSG_LENGTH_2, 0U); 311*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_MSG_LENGTH_3, 0U); 312*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_MSG_LEFT_1, 0U); 313*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_MSG_LEFT_2, 0U); 314*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_MSG_LEFT_3, 0U); 315*91f16700Schasinglulu 316*91f16700Schasinglulu number_of_operations = (src_len_inbyte / max_bytes); 317*91f16700Schasinglulu remaining_bytes = (src_len_inbyte % max_bytes); 318*91f16700Schasinglulu if (remaining_bytes > 0U) { 319*91f16700Schasinglulu number_of_operations += 1U; 320*91f16700Schasinglulu } 321*91f16700Schasinglulu 322*91f16700Schasinglulu /* 323*91f16700Schasinglulu * 1. Operations == 1: program SE0_SHA_TASK register to initiate SHA256 324*91f16700Schasinglulu * hash generation by setting 325*91f16700Schasinglulu * 1(SE0_SHA_CONFIG_HW_INIT_HASH) to SE0_SHA_TASK 326*91f16700Schasinglulu * and start SHA256-normal operation. 327*91f16700Schasinglulu * 2. 1 < Operations < number_of_operations: program SE0_SHA_TASK to 328*91f16700Schasinglulu * 0(SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE) to load 329*91f16700Schasinglulu * intermediate SHA256 digest result from 330*91f16700Schasinglulu * HASH_RESULT register to continue SHA256 331*91f16700Schasinglulu * generation and start SHA256-normal operation. 332*91f16700Schasinglulu * 3. Operations == number_of_operations: continue with step 2 and set 333*91f16700Schasinglulu * max_bytes to bytes_left to process final 334*91f16700Schasinglulu * hash-result generation and start SHA256-normal 335*91f16700Schasinglulu * operation. 336*91f16700Schasinglulu */ 337*91f16700Schasinglulu bytes_left = src_len_inbyte; 338*91f16700Schasinglulu for (operations = 1U; operations <= number_of_operations; 339*91f16700Schasinglulu operations++) { 340*91f16700Schasinglulu if (operations == SHA_FIRST_OP) { 341*91f16700Schasinglulu val = SE0_SHA_CONFIG_HW_INIT_HASH; 342*91f16700Schasinglulu } else { 343*91f16700Schasinglulu /* Load intermediate SHA digest result to 344*91f16700Schasinglulu * SHA:HASH_RESULT(0..7) to continue the SHA 345*91f16700Schasinglulu * calculation and tell the SHA engine to use it. 346*91f16700Schasinglulu */ 347*91f16700Schasinglulu for (i = 0U; (i / BYTES_IN_WORD) <= 348*91f16700Schasinglulu SHA256_MAX_HASH_RESULT; i += BYTES_IN_WORD) { 349*91f16700Schasinglulu val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 + 350*91f16700Schasinglulu i); 351*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_HASH_RESULT_0 + i, 352*91f16700Schasinglulu val); 353*91f16700Schasinglulu } 354*91f16700Schasinglulu val = SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE; 355*91f16700Schasinglulu if (len_bits_lsb <= (max_bytes * 8U)) { 356*91f16700Schasinglulu len_bits_lsb = (remaining_bytes * 8U); 357*91f16700Schasinglulu } else { 358*91f16700Schasinglulu len_bits_lsb -= (max_bytes * 8U); 359*91f16700Schasinglulu } 360*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb); 361*91f16700Schasinglulu } 362*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_TASK_CONFIG, val); 363*91f16700Schasinglulu 364*91f16700Schasinglulu max_bytes = (SHA256_HASH_SIZE_BYTES * 365*91f16700Schasinglulu SHA256_MSG_LENGTH_ONETIME); 366*91f16700Schasinglulu if (bytes_left < max_bytes) { 367*91f16700Schasinglulu max_bytes = bytes_left; 368*91f16700Schasinglulu last_buf = 1U; 369*91f16700Schasinglulu } else { 370*91f16700Schasinglulu bytes_left = bytes_left - max_bytes; 371*91f16700Schasinglulu last_buf = 0U; 372*91f16700Schasinglulu } 373*91f16700Schasinglulu /* start operation */ 374*91f16700Schasinglulu ret = tegra_se_start_normal_operation(src_addr, max_bytes, 375*91f16700Schasinglulu last_buf, src_len_inbyte); 376*91f16700Schasinglulu if (ret != 0) { 377*91f16700Schasinglulu ERROR("Error during SE operation! 0x%x", ret); 378*91f16700Schasinglulu return -EINVAL; 379*91f16700Schasinglulu } 380*91f16700Schasinglulu } 381*91f16700Schasinglulu 382*91f16700Schasinglulu return ret; 383*91f16700Schasinglulu } 384*91f16700Schasinglulu 385*91f16700Schasinglulu static int32_t tegra_se_save_sha256_pmc_scratch(void) 386*91f16700Schasinglulu { 387*91f16700Schasinglulu uint32_t val = 0U, hash_offset = 0U, scratch_offset = 0U; 388*91f16700Schasinglulu int32_t ret; 389*91f16700Schasinglulu 390*91f16700Schasinglulu /* Check SE0 operation status */ 391*91f16700Schasinglulu ret = tegra_se_sha256_hash_operation_complete(); 392*91f16700Schasinglulu if (ret != 0) { 393*91f16700Schasinglulu ERROR("SE operation complete Failed! 0x%x", ret); 394*91f16700Schasinglulu return ret; 395*91f16700Schasinglulu } 396*91f16700Schasinglulu 397*91f16700Schasinglulu for (scratch_offset = SECURE_SCRATCH_TZDRAM_SHA256_HASH_START; 398*91f16700Schasinglulu scratch_offset <= SECURE_SCRATCH_TZDRAM_SHA256_HASH_END; 399*91f16700Schasinglulu scratch_offset += BYTES_IN_WORD) { 400*91f16700Schasinglulu val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 + hash_offset); 401*91f16700Schasinglulu mmio_write_32((uint32_t)(TEGRA_SCRATCH_BASE + scratch_offset), 402*91f16700Schasinglulu val); 403*91f16700Schasinglulu hash_offset += BYTES_IN_WORD; 404*91f16700Schasinglulu } 405*91f16700Schasinglulu return 0; 406*91f16700Schasinglulu } 407*91f16700Schasinglulu 408*91f16700Schasinglulu /* 409*91f16700Schasinglulu * Handler to generate SHA256 and save HASH-result to pmc-scratch register 410*91f16700Schasinglulu */ 411*91f16700Schasinglulu int32_t tegra_se_calculate_save_sha256(uint64_t src_addr, 412*91f16700Schasinglulu uint32_t src_len_inbyte) 413*91f16700Schasinglulu { 414*91f16700Schasinglulu uint32_t security; 415*91f16700Schasinglulu int32_t val = 0; 416*91f16700Schasinglulu 417*91f16700Schasinglulu /* Set SE_SOFT_SETTINGS=SE_SECURE to prevent NS process to change SE 418*91f16700Schasinglulu * registers. 419*91f16700Schasinglulu */ 420*91f16700Schasinglulu security = tegra_se_read_32(SE0_SECURITY); 421*91f16700Schasinglulu tegra_se_write_32(SE0_SECURITY, security | SE0_SECURITY_SE_SOFT_SETTING); 422*91f16700Schasinglulu 423*91f16700Schasinglulu /* Bootrom enable IN_ID bit in SE0_SHA_GSCID_0 register during SC7-exit, causing 424*91f16700Schasinglulu * SE0 ignores SE0 operation, and therefore failure of 2nd iteration of SC7 cycle. 425*91f16700Schasinglulu */ 426*91f16700Schasinglulu tegra_se_write_32(SE0_SHA_GSCID_0, 0x0U); 427*91f16700Schasinglulu 428*91f16700Schasinglulu /* Calculate SHA256 of BL31 */ 429*91f16700Schasinglulu val = tegra_se_calculate_sha256_hash(src_addr, src_len_inbyte); 430*91f16700Schasinglulu if (val != 0) { 431*91f16700Schasinglulu ERROR("%s: SHA256 generation failed\n", __func__); 432*91f16700Schasinglulu return val; 433*91f16700Schasinglulu } 434*91f16700Schasinglulu 435*91f16700Schasinglulu /* 436*91f16700Schasinglulu * Reset SE_SECURE to previous value. 437*91f16700Schasinglulu */ 438*91f16700Schasinglulu tegra_se_write_32(SE0_SECURITY, security); 439*91f16700Schasinglulu 440*91f16700Schasinglulu /* copy sha256_dst to PMC Scratch register */ 441*91f16700Schasinglulu val = tegra_se_save_sha256_pmc_scratch(); 442*91f16700Schasinglulu if (val != 0) { 443*91f16700Schasinglulu ERROR("%s: SE0 status Error.\n", __func__); 444*91f16700Schasinglulu } 445*91f16700Schasinglulu 446*91f16700Schasinglulu return val; 447*91f16700Schasinglulu } 448*91f16700Schasinglulu 449*91f16700Schasinglulu /* 450*91f16700Schasinglulu * Handler to power down the SE hardware blocks - SE, RNG1 and PKA1. This 451*91f16700Schasinglulu * needs to be called only during System Suspend. 452*91f16700Schasinglulu */ 453*91f16700Schasinglulu int32_t tegra_se_suspend(void) 454*91f16700Schasinglulu { 455*91f16700Schasinglulu int32_t ret = 0; 456*91f16700Schasinglulu 457*91f16700Schasinglulu /* initialise communication channel with BPMP */ 458*91f16700Schasinglulu assert(tegra_bpmp_ipc_init() == 0); 459*91f16700Schasinglulu 460*91f16700Schasinglulu /* Enable SE clock before SE context save */ 461*91f16700Schasinglulu ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE); 462*91f16700Schasinglulu assert(ret == 0); 463*91f16700Schasinglulu 464*91f16700Schasinglulu /* save SE registers */ 465*91f16700Schasinglulu se_regs[0] = mmio_read_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT); 466*91f16700Schasinglulu se_regs[1] = mmio_read_32(TEGRA_SE0_BASE + SE0_AES0_ENTROPY_SRC_AGE_CTRL); 467*91f16700Schasinglulu se_regs[2] = mmio_read_32(TEGRA_RNG1_BASE + RNG1_MUTEX_WATCHDOG_NS_LIMIT); 468*91f16700Schasinglulu se_regs[3] = mmio_read_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT); 469*91f16700Schasinglulu 470*91f16700Schasinglulu /* Save SE context. The BootROM restores it during System Resume */ 471*91f16700Schasinglulu ret = tegra_se_save_context(); 472*91f16700Schasinglulu if (ret != 0) { 473*91f16700Schasinglulu ERROR("%s: context save failed (%d)\n", __func__, ret); 474*91f16700Schasinglulu } 475*91f16700Schasinglulu 476*91f16700Schasinglulu /* Disable SE clock after SE context save */ 477*91f16700Schasinglulu ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE); 478*91f16700Schasinglulu assert(ret == 0); 479*91f16700Schasinglulu 480*91f16700Schasinglulu return ret; 481*91f16700Schasinglulu } 482*91f16700Schasinglulu 483*91f16700Schasinglulu /* 484*91f16700Schasinglulu * Handler to power up the SE hardware block(s) during System Resume. 485*91f16700Schasinglulu */ 486*91f16700Schasinglulu void tegra_se_resume(void) 487*91f16700Schasinglulu { 488*91f16700Schasinglulu int32_t ret = 0; 489*91f16700Schasinglulu 490*91f16700Schasinglulu /* initialise communication channel with BPMP */ 491*91f16700Schasinglulu assert(tegra_bpmp_ipc_init() == 0); 492*91f16700Schasinglulu 493*91f16700Schasinglulu /* Enable SE clock before SE context restore */ 494*91f16700Schasinglulu ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE); 495*91f16700Schasinglulu assert(ret == 0); 496*91f16700Schasinglulu 497*91f16700Schasinglulu /* 498*91f16700Schasinglulu * When TZ takes over after System Resume, TZ should first reconfigure 499*91f16700Schasinglulu * SE_MUTEX_WATCHDOG_NS_LIMIT, PKA1_MUTEX_WATCHDOG_NS_LIMIT, 500*91f16700Schasinglulu * RNG1_MUTEX_WATCHDOG_NS_LIMIT and SE_ENTROPY_SRC_AGE_CTRL before 501*91f16700Schasinglulu * other operations. 502*91f16700Schasinglulu */ 503*91f16700Schasinglulu mmio_write_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT, se_regs[0]); 504*91f16700Schasinglulu mmio_write_32(TEGRA_SE0_BASE + SE0_AES0_ENTROPY_SRC_AGE_CTRL, se_regs[1]); 505*91f16700Schasinglulu mmio_write_32(TEGRA_RNG1_BASE + RNG1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[2]); 506*91f16700Schasinglulu mmio_write_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[3]); 507*91f16700Schasinglulu 508*91f16700Schasinglulu /* Disable SE clock after SE context restore */ 509*91f16700Schasinglulu ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE); 510*91f16700Schasinglulu assert(ret == 0); 511*91f16700Schasinglulu } 512