1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright 2022-2024 HiSilicon Limited. 4 * Kunpeng hardware accelerator SEC module init. 5 */ 6 7 #include <initcall.h> 8 #include <io.h> 9 #include <malloc.h> 10 #include <sys/queue.h> 11 #include <trace.h> 12 #include <util.h> 13 14 #include "sec_main.h" 15 16 #define AM_CFG_SINGLE_PORT_MAX_TRANS 0x300014 17 #define SEC_CORE_INT_MASK 0x301000 18 #define SEC_CORE_INT_SOURCE 0x301010 19 #define SEC_RAS_CE_ENABLE 0x301050 20 #define SEC_RAS_FE_ENABLE 0x301054 21 #define SEC_RAS_NFE_ENABLE 0x301058 22 #define SEC_MEM_START_INIT 0x301100 23 #define SEC_MEM_INIT_DONE 0x301104 24 #define SEC_CONTROL_REG 0x301200 25 #define SEC_INTERFACE_USER_CTRL0 0x301220 26 #define SEC_INTERFACE_USER_CTRL1 0x301224 27 #define SEC_SAA_EN 0x301270 28 #define SEC_BD_ERR_CHK_EN0 0x301380 29 #define SEC_BD_ERR_CHK_EN1 0x301384 30 #define SEC_BD_ERR_CHK_EN2 0x301388 31 #define SEC_BD_ERR_CHK_EN3 0x30138c 32 #define SEC_DYNAMIC_GATE_V3 0x30121c 33 #define SEC_BD_ERR_CHK_EN2_V3 0x301508 34 #define SEC_CORE_AUTO_GATE_V3 0x30212c 35 #define SEC_INTERFACE_USER_CTRL0_V3 0x302220 36 #define SEC_INTERFACE_USER_CTRL1_V3 0x302224 37 #define SEC_SINGLE_PORT_MAX_TRANS 0x2060 38 #define SEC_ABNML_INT_DISABLE 0x0 39 #define SEC_RAS_CE_ENB_MASK 0x88 40 #define SEC_RAS_FE_ENB 0x0 41 #define SEC_RAS_NFE_ENB_MASK 0x177 42 #define SEC_CLK_GATE_ENABLE BIT(3) 43 #define SEC_DYNAMIC_GATE_EN 0x7bff 44 #define SEC_CORE_AUTO_GATE_EN GENMASK_32(3, 0) 45 #define SEC_TRNG_EN_MASK BIT(8) 46 #define SEC_SAA_ENABLE 0x17f 47 #define SEC_SAA_ENABLE_V3 0xf 48 #define SEC_BD_ERR_CHK0 0xefffffff 49 #define SEC_BD_ERR_CHK1 0x7ffff7fd 50 #define SEC_BD_ERR_CHK2 0xffff7fff 51 #define SEC_BD_ERR_CHK3 0xffffbfff 52 #define SEC_USER0_CFG 0x20200 53 #define SEC_USER0_SMMU_NORMAL (BIT(23) | BIT(15)) 54 #define SEC_USER1_CFG 0x12141214 55 #define SEC_USER1_SMMU_NORMAL (BIT(31) | BIT(23) | BIT(15) | BIT(7)) 56 #define SEC_USER0_CFG_V3 0x20200 57 #define SEC_USER1_CFG_V3 0x8c494 58 59 static SLIST_HEAD(, acc_device) sec_list = SLIST_HEAD_INITIALIZER(sec_list); 60 61 struct hisi_qp *sec_create_qp(uint8_t sq_type) 62 { 63 struct acc_device *sec_dev = NULL; 64 struct acc_device *cur_dev = NULL; 65 uint32_t free_qp_num = 0; 66 uint32_t max_qp_num = 0; 67 68 /* Find the SEC device with the most remaining qp numbers */ 69 SLIST_FOREACH(cur_dev, &sec_list, link) { 70 if (cur_dev->qm.fun_type == HISI_QM_HW_PF) 71 free_qp_num = HISI_QM_PF_Q_NUM - cur_dev->qm.qp_in_used; 72 else 73 free_qp_num = HISI_QM_VF_Q_NUM - cur_dev->qm.qp_in_used; 74 if (free_qp_num > max_qp_num) { 75 max_qp_num = free_qp_num; 76 sec_dev = cur_dev; 77 } 78 } 79 80 if (!sec_dev) { 81 EMSG("No available sec device"); 82 return NULL; 83 } 84 85 return hisi_qm_create_qp(&sec_dev->qm, sq_type); 86 } 87 88 static void sec_enable_clock_gate(struct hisi_qm *qm) 89 { 90 if (qm->version == HISI_QM_HW_V2) 91 return; 92 93 io_setbits32(qm->io_base + SEC_CONTROL_REG, SEC_CLK_GATE_ENABLE); 94 io_write32(qm->io_base + SEC_DYNAMIC_GATE_V3, SEC_DYNAMIC_GATE_EN); 95 io_write32(qm->io_base + SEC_CORE_AUTO_GATE_V3, SEC_CORE_AUTO_GATE_EN); 96 } 97 98 static enum hisi_drv_status sec_engine_init(struct acc_device *sec_dev) 99 { 100 struct hisi_qm *qm = &sec_dev->qm; 101 uint32_t val = 0; 102 103 if (qm->fun_type == HISI_QM_HW_VF) 104 return HISI_QM_DRVCRYPT_NO_ERR; 105 106 /* QM_HW_V2 version need to close clock gating */ 107 io_clrbits32(qm->io_base + SEC_CONTROL_REG, SEC_CLK_GATE_ENABLE); 108 109 hisi_qm_dev_init(qm); 110 111 io_write32(qm->io_base + SEC_MEM_START_INIT, 0x1); 112 if (IO_READ32_POLL_TIMEOUT(qm->io_base + SEC_MEM_INIT_DONE, val, 113 val & 0x1, POLL_PERIOD, POLL_TIMEOUT)) { 114 EMSG("Fail to init sec mem"); 115 return HISI_QM_DRVCRYPT_ETMOUT; 116 } 117 118 io_setbits32(qm->io_base + SEC_CONTROL_REG, sec_dev->endian); 119 120 if (qm->version == HISI_QM_HW_V2) { 121 /* SMMU bypass */ 122 io_write32(qm->io_base + SEC_INTERFACE_USER_CTRL0, 123 SEC_USER0_CFG); 124 io_write32(qm->io_base + SEC_INTERFACE_USER_CTRL1, 125 SEC_USER1_CFG); 126 io_write32(qm->io_base + AM_CFG_SINGLE_PORT_MAX_TRANS, 127 SEC_SINGLE_PORT_MAX_TRANS); 128 io_write32(qm->io_base + SEC_SAA_EN, SEC_SAA_ENABLE); 129 /* HW V2 enable SM4 extra mode, as CTR/ECB */ 130 io_write32(qm->io_base + SEC_BD_ERR_CHK_EN0, SEC_BD_ERR_CHK0); 131 /* Enable SM4 xts mode multiple iv */ 132 io_write32(qm->io_base + SEC_BD_ERR_CHK_EN1, SEC_BD_ERR_CHK1); 133 /* disable PBKDF2 len check */ 134 io_write32(qm->io_base + SEC_BD_ERR_CHK_EN2, SEC_BD_ERR_CHK2); 135 io_write32(qm->io_base + SEC_BD_ERR_CHK_EN3, SEC_BD_ERR_CHK3); 136 } else { 137 /* cmd_type is controlled by HAC subctrl, default normal */ 138 io_write32(qm->io_base + SEC_INTERFACE_USER_CTRL0_V3, 139 SEC_USER0_CFG_V3); 140 io_write32(qm->io_base + SEC_INTERFACE_USER_CTRL1_V3, 141 SEC_USER1_CFG_V3); 142 io_write32(qm->io_base + SEC_SAA_EN, SEC_SAA_ENABLE_V3); 143 /* disable PBKDF2 salt len check */ 144 io_write32(qm->io_base + SEC_BD_ERR_CHK_EN2_V3, 145 SEC_BD_ERR_CHK2); 146 } 147 io_write32(qm->io_base + SEC_RAS_CE_ENABLE, SEC_RAS_CE_ENB_MASK); 148 io_write32(qm->io_base + SEC_RAS_FE_ENABLE, SEC_RAS_FE_ENB); 149 io_write32(qm->io_base + SEC_RAS_NFE_ENABLE, SEC_RAS_NFE_ENB_MASK); 150 io_write32(qm->io_base + SEC_CORE_INT_MASK, SEC_ABNML_INT_DISABLE); 151 152 sec_enable_clock_gate(qm); 153 154 return HISI_QM_DRVCRYPT_NO_ERR; 155 } 156 157 static enum hisi_drv_status sec_dev_status_check(struct hisi_qm *qm) 158 { 159 uint32_t val = 0; 160 161 val = io_read32(qm->io_base + SEC_CORE_INT_SOURCE); 162 if (val & SEC_RAS_NFE_ENB_MASK) { 163 EMSG("SEC NFE RAS happened, need to reset"); 164 return HISI_QM_DRVCRYPT_HW_EACCESS; 165 } 166 167 val = io_read32(qm->io_base + HISI_QM_ABNML_INT_SRC); 168 if (val) { 169 if (val & HISI_QM_SEC_NFE_INT_MASK) 170 EMSG("QM NFE RAS happened, need to reset"); 171 172 if (val & HISI_QM_INVALID_DB) { 173 EMSG("QM invalid db happened, please check"); 174 io_write32(qm->io_base + HISI_QM_ABNML_INT_SRC, 175 HISI_QM_INVALID_DB); 176 } 177 178 return HISI_QM_DRVCRYPT_HW_EACCESS; 179 } 180 181 return HISI_QM_DRVCRYPT_NO_ERR; 182 } 183 184 static enum hisi_drv_status sec_qm_init(struct acc_device *sec_dev) 185 { 186 struct hisi_qm *qm = &sec_dev->qm; 187 188 qm->io_base = (vaddr_t)phys_to_virt_io(sec_dev->io_base, 189 sec_dev->io_size); 190 if (!qm->io_base) { 191 EMSG("Fail to get qm io_base"); 192 return HISI_QM_DRVCRYPT_EFAULT; 193 } 194 195 qm->fun_type = sec_dev->fun_type; 196 qm->vfs_num = sec_dev->vfs_num; 197 qm->sqe_size = SEC_SQE_SIZE; 198 qm->sqe_log2_size = SEC_SQE_LOG2_SIZE; 199 if (qm->fun_type == HISI_QM_HW_PF) { 200 hisi_qm_get_version(qm); 201 DMSG("SEC hardware version is %#"PRIx32, qm->version); 202 qm->qp_base = HISI_QM_PF_Q_BASE; 203 qm->qp_num = HISI_QM_PF_Q_NUM; 204 qm->dev_status_check = sec_dev_status_check; 205 } 206 207 return hisi_qm_init(qm); 208 } 209 210 static struct acc_device *sec_alloc(void) 211 { 212 struct acc_device *sec_dev = NULL; 213 214 sec_dev = calloc(1, sizeof(*sec_dev)); 215 if (!sec_dev) { 216 EMSG("Fail to alloc sec_dev"); 217 return NULL; 218 } 219 220 sec_dev->io_base = SEC_BAR; 221 sec_dev->io_size = SEC_SIZE; 222 sec_dev->fun_type = HISI_QM_HW_PF; 223 SLIST_INSERT_HEAD(&sec_list, sec_dev, link); 224 225 return sec_dev; 226 } 227 228 static void sec_free(struct acc_device *sec_dev) 229 { 230 SLIST_REMOVE_HEAD(&sec_list, link); 231 free(sec_dev); 232 } 233 234 static TEE_Result sec_probe(void) 235 { 236 enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR; 237 struct acc_device *sec_dev = NULL; 238 struct hisi_qm *qm = NULL; 239 240 DMSG("SEC driver init start"); 241 sec_dev = sec_alloc(); 242 if (!sec_dev) 243 return TEE_ERROR_OUT_OF_MEMORY; 244 245 qm = &sec_dev->qm; 246 ret = sec_qm_init(sec_dev); 247 if (ret) { 248 EMSG("Fail to init sec qm, ret=%d", ret); 249 goto err_with_pre_init; 250 } 251 252 ret = sec_engine_init(sec_dev); 253 if (ret) { 254 EMSG("fail to init engine, ret=%d", ret); 255 goto err_with_qm_init; 256 } 257 258 ret = hisi_qm_start(qm); 259 if (ret) { 260 EMSG("Fail to start qm, ret=%d", ret); 261 goto err_with_qm_init; 262 } 263 264 DMSG("SEC driver init done"); 265 return TEE_SUCCESS; 266 267 err_with_qm_init: 268 hisi_qm_uninit(qm); 269 err_with_pre_init: 270 sec_free(sec_dev); 271 272 return TEE_ERROR_BAD_STATE; 273 } 274 275 driver_init(sec_probe); 276