1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Texas Instruments K3 SA2UL Driver 4 * 5 * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/ 6 * Andrew Davis <afd@ti.com> 7 */ 8 9 #include <drivers/ti_sci.h> 10 #include <initcall.h> 11 #include <io.h> 12 #include <keep.h> 13 #include <kernel/interrupt.h> 14 #include <kernel/misc.h> 15 #include <kernel/spinlock.h> 16 #include <mm/core_memprot.h> 17 #include <mm/core_mmu.h> 18 #include <platform_config.h> 19 #include <rng_support.h> 20 21 #include "sa2ul.h" 22 23 #define SA2UL_ES 0x0008 24 #define SA2UL_ES_TRNG BIT(3) 25 #define SA2UL_EEC 0x1000 26 #define SA2UL_EEC_TRNG BIT(3) 27 28 #define FW_ENABLE_REGION 0x0a 29 #define FW_BACKGROUND_REGION BIT(8) 30 #define FW_BIG_ARM_PRIVID 0x01 31 #define FW_TIFS_PRIVID 0xca 32 #define FW_WILDCARD_PRIVID 0xc3 33 #define FW_SECURE_ONLY GENMASK_32(7, 0) 34 #define FW_NON_SECURE GENMASK_32(15, 0) 35 36 register_phys_mem_pgdir(MEM_AREA_IO_SEC, SA2UL_BASE, SA2UL_REG_SIZE); 37 38 static TEE_Result sa2ul_init(void) 39 { 40 vaddr_t sa2ul = (vaddr_t)phys_to_virt(SA2UL_BASE, MEM_AREA_IO_SEC, 41 RNG_REG_SIZE); 42 uint16_t fwl_id = SA2UL_TI_SCI_FW_ID; 43 uint16_t sa2ul_region = SA2UL_TI_SCI_FW_RGN_ID; 44 uint16_t rng_region = RNG_TI_SCI_FW_RGN_ID; 45 uint8_t owner_index = OPTEE_HOST_ID; 46 uint8_t owner_privid = 0; 47 uint16_t owner_permission_bits = 0; 48 uint32_t control = 0; 49 uint32_t permissions[FWL_MAX_PRIVID_SLOTS] = { }; 50 uint32_t num_perm = 0; 51 uint64_t start_address = 0; 52 uint64_t end_address = 0; 53 uint32_t val = 0; 54 TEE_Result result = TEE_SUCCESS; 55 int ret = 0; 56 57 if (SA2UL_TI_SCI_DEV_ID != -1) { 58 /* Power on the SA2UL device */ 59 ret = ti_sci_device_get(SA2UL_TI_SCI_DEV_ID); 60 if (ret) { 61 EMSG("Failed to get SA2UL device"); 62 return TEE_ERROR_GENERIC; 63 } 64 } 65 66 IMSG("Activated SA2UL device"); 67 68 /* Try to claim the SA2UL firewall for ourselves */ 69 ret = ti_sci_change_fwl_owner(fwl_id, sa2ul_region, owner_index, 70 &owner_privid, &owner_permission_bits); 71 if (ret) { 72 /* 73 * This is not fatal, it just means we are on an HS device 74 * where the DMSC already owns the SA2UL. On GP we need 75 * to do additional setup for access permissions below. 76 */ 77 DMSG("Could not change SA2UL firewall owner"); 78 } else { 79 IMSG("Fixing SA2UL firewall owner for GP device"); 80 81 /* Get current SA2UL firewall configuration */ 82 ret = ti_sci_get_fwl_region(fwl_id, sa2ul_region, 1, 83 &control, permissions, 84 &start_address, &end_address); 85 if (ret) { 86 EMSG("Could not get firewall region information"); 87 return TEE_ERROR_GENERIC; 88 } 89 90 /* Modify SA2UL firewall to allow all others access*/ 91 control = FW_BACKGROUND_REGION | FW_ENABLE_REGION; 92 permissions[0] = (FW_WILDCARD_PRIVID << 16) | FW_NON_SECURE; 93 ret = ti_sci_set_fwl_region(fwl_id, sa2ul_region, 1, 94 control, permissions, 95 0x0, UINT32_MAX); 96 if (ret) { 97 EMSG("Could not set firewall region information"); 98 return TEE_ERROR_GENERIC; 99 } 100 } 101 102 /* Claim the TRNG firewall for ourselves */ 103 ret = ti_sci_change_fwl_owner(fwl_id, rng_region, owner_index, 104 &owner_privid, &owner_permission_bits); 105 if (ret) { 106 EMSG("Could not change TRNG firewall owner"); 107 return TEE_ERROR_GENERIC; 108 } 109 110 /* Get current TRNG firewall configuration */ 111 ret = ti_sci_get_fwl_region(fwl_id, rng_region, 1, 112 &control, permissions, 113 &start_address, &end_address); 114 if (ret) { 115 EMSG("Could not get firewall region information"); 116 return TEE_ERROR_GENERIC; 117 } 118 119 /* Modify TRNG firewall to block all others access */ 120 control = FW_ENABLE_REGION; 121 start_address = RNG_BASE; 122 end_address = RNG_BASE + RNG_REG_SIZE - 1; 123 permissions[num_perm++] = (FW_BIG_ARM_PRIVID << 16) | FW_SECURE_ONLY; 124 #if defined(PLATFORM_FLAVOR_am62x) 125 permissions[num_perm++] = (FW_TIFS_PRIVID << 16) | FW_NON_SECURE; 126 #endif 127 ret = ti_sci_set_fwl_region(fwl_id, rng_region, num_perm, 128 control, permissions, 129 start_address, end_address); 130 if (ret) { 131 EMSG("Could not set firewall region information"); 132 return TEE_ERROR_GENERIC; 133 } 134 135 IMSG("Enabled firewalls for SA2UL TRNG device"); 136 137 /* Enable RNG engine in SA2UL if not already enabled */ 138 val = io_read32(sa2ul + SA2UL_ES); 139 if (!(val & SA2UL_ES_TRNG)) { 140 IMSG("Enabling SA2UL TRNG engine"); 141 io_setbits32(sa2ul + SA2UL_EEC, SA2UL_EEC_TRNG); 142 } 143 144 /* Initialize the RNG Module */ 145 result = sa2ul_rng_init(); 146 if (result != TEE_SUCCESS) 147 return result; 148 149 IMSG("SA2UL Drivers initialized"); 150 151 return TEE_SUCCESS; 152 } 153 driver_init(sa2ul_init); 154