1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) 2022 Foundries.io Ltd 4 * Jorge Ramirez-Ortiz <jorge@foundries.io> 5 */ 6 7 #include <initcall.h> 8 #include <kernel/delay.h> 9 #include <kernel/panic.h> 10 #include <mm/core_mmu.h> 11 #include <string.h> 12 #include <tee/cache.h> 13 #include "drivers/versal_mbox.h" 14 15 #define PM_SIP_SVC 0xc2000000 16 17 /* IPI targets */ 18 #define IPI_ID_PMC 1 19 #define IPI_ID_0 2 20 #define IPI_ID_RPU0 3 21 #define IPI_ID_RPU1 4 22 #define IPI_ID_3 5 23 #define IPI_ID_4 6 24 #define IPI_ID_5 7 25 26 /* Buffers */ 27 #define IPI_BUFFER_BASEADDR 0xFF3F0000 28 #define IPI_BUFFER_APU_ID_0_BASE (IPI_BUFFER_BASEADDR + 0x400) 29 #define IPI_BUFFER_APU_ID_3_BASE (IPI_BUFFER_BASEADDR + 0xA00) 30 #define IPI_BUFFER_APU_ID_4_BASE (IPI_BUFFER_BASEADDR + 0xC00) 31 #define IPI_BUFFER_APU_ID_5_BASE (IPI_BUFFER_BASEADDR + 0xE00) 32 #define IPI_BUFFER_PMC_BASE (IPI_BUFFER_BASEADDR + 0x200) 33 #define IPI_BUFFER_TARGET_APU_OFFSET 0x80 34 #define IPI_BUFFER_TARGET_PMC_OFFSET 0x40 35 #define IPI_BUFFER_REQ_OFFSET 0x0 36 #define IPI_BUFFER_RESP_OFFSET 0x20 37 38 #define IPI_BUFFER_LOCAL_OFFSET IPI_BUFFER_TARGET_APU_OFFSET 39 #define IPI_BUFFER_REMOTE_OFFSET IPI_BUFFER_TARGET_PMC_OFFSET 40 41 #define IPI_BLOCK 1 42 #define IPI_NON_BLOCK 0 43 44 /* Mailbox api */ 45 enum versal_ipi_api_id { 46 IPI_MAILBOX_OPEN = 0x1000, 47 IPI_MAILBOX_RELEASE, 48 IPI_MAILBOX_STATUS_ENQUIRY, 49 IPI_MAILBOX_NOTIFY, 50 IPI_MAILBOX_ACK, 51 IPI_MAILBOX_ENABLE_IRQ, 52 IPI_MAILBOX_DISABLE_IRQ 53 }; 54 55 static struct versal_ipi { 56 uint32_t lcl; 57 const uint32_t rmt; 58 paddr_t buf; 59 /* Exclusive access to the IPI shared buffer */ 60 struct mutex lock; 61 void *rsp; 62 void *req; 63 } ipi = { 64 .buf = IPI_BUFFER_APU_ID_3_BASE, 65 .rmt = IPI_ID_PMC, 66 .lcl = IPI_ID_3, 67 }; 68 69 static const char *const nvm_id[] = { 70 [0] = "API_FEATURES", 71 [1] = "BBRAM_WRITE_AES_KEY", 72 [2] = "BBRAM_ZEROIZE", 73 [3] = "BBRAM_WRITE_USER_DATA", 74 [4] = "BBRAM_READ_USER_DATA", 75 [5] = "BBRAM_LOCK_WRITE_USER_DATA", 76 [6] = "EFUSE_WRITE", 77 [7] = "EFUSE_WRITE_PUF", 78 [8] = "EFUSE_PUF_USER_FUSE_WRITE", 79 [9] = "EFUSE_READ_IV", 80 [10] = "EFUSE_READ_REVOCATION_ID", 81 [11] = "EFUSE_READ_OFFCHIP_REVOCATION_ID", 82 [12] = "EFUSE_READ_USER_FUSES", 83 [13] = "EFUSE_READ_MISC_CTRL", 84 [14] = "EFUSE_READ_SEC_CTRL", 85 [15] = "EFUSE_READ_SEC_MISC1", 86 [16] = "EFUSE_READ_BOOT_ENV_CTRL", 87 [17] = "EFUSE_READ_PUF_SEC_CTRL", 88 [18] = "EFUSE_READ_PPK_HASH", 89 [19] = "EFUSE_READ_DEC_EFUSE_ONLY", 90 [20] = "EFUSE_READ_DNA", 91 [21] = "EFUSE_READ_PUF_USER_FUSES", 92 [22] = "EFUSE_READ_PUF", 93 [23] = "EFUSE_INVALID", 94 }; 95 96 static const char *const crypto_id[] = { 97 [0] = "FEATURES", 98 [1] = "RSA_SIGN_VERIFY", 99 [2] = "RSA_PUBLIC_ENCRYPT", 100 [3] = "RSA_PRIVATE_DECRYPT", 101 [4] = "RSA_KAT", 102 [32] = "SHA3_UPDATE", 103 [33] = "SHA3_KAT", 104 [64] = "ELLIPTIC_GENERATE_PUBLIC_KEY", 105 [65] = "ELLIPTIC_GENERATE_SIGN", 106 [66] = "ELLIPTIC_VALIDATE_PUBLIC_KEY", 107 [67] = "ELLIPTIC_VERIFY_SIGN", 108 [68] = "ELLIPTIC_KAT", 109 [96] = "AES_INIT", 110 [97] = "AES_OP_INIT", 111 [98] = "AES_UPDATE_AAD", 112 [99] = "AES_ENCRYPT_UPDATE", 113 [100] = "AES_ENCRYPT_FINAL", 114 [101] = "AES_DECRYPT_UPDATE", 115 [102] = "AES_DECRYPT_FINAL", 116 [103] = "AES_KEY_ZERO", 117 [104] = "AES_WRITE_KEY", 118 [105] = "AES_LOCK_USER_KEY", 119 [106] = "AES_KEK_DECRYPT", 120 [107] = "AES_SET_DPA_CM", 121 [108] = "AES_DECRYPT_KAT", 122 [109] = "AES_DECRYPT_CM_KAT", 123 [110] = "MAX", 124 }; 125 126 static const char *const puf_id[] = { 127 [0] = "PUF_API_FEATURES", 128 [1] = "PUF_REGISTRATION", 129 [2] = "PUF_REGENERATION", 130 [3] = "PUF_CLEAR_PUF_ID", 131 }; 132 133 static const char *const module[] = { 134 [5] = "CRYPTO", 135 [7] = "FPGA", 136 [11] = "NVM", 137 [12] = "PUF", 138 }; 139 140 static const char *const fpga_id[] = { 141 [1] = "LOAD", 142 }; 143 144 static void versal_mbox_call_trace(uint32_t call) 145 { 146 uint32_t mid = call >> 8 & 0xff; 147 uint32_t api = call & 0xff; 148 const char *val = NULL; 149 150 switch (mid) { 151 case 5: 152 if (api < ARRAY_SIZE(crypto_id)) 153 val = crypto_id[api]; 154 155 break; 156 case 7: 157 if (api < ARRAY_SIZE(fpga_id)) 158 val = fpga_id[api]; 159 160 break; 161 case 11: 162 if (api < ARRAY_SIZE(nvm_id)) 163 val = nvm_id[api]; 164 165 break; 166 case 12: 167 if (api < ARRAY_SIZE(puf_id)) 168 val = puf_id[api]; 169 170 break; 171 default: 172 break; 173 } 174 175 IMSG("--- mbox: service: %s\t call: %s", module[mid], 176 val ? val : "Invalid"); 177 }; 178 179 static TEE_Result mbox_call(enum versal_ipi_api_id id, uint32_t blocking_call) 180 { 181 struct thread_smc_args args = { 182 .a0 = PM_SIP_SVC | id, 183 .a1 = reg_pair_to_64(0, ipi.lcl), 184 .a2 = reg_pair_to_64(0, ipi.rmt), 185 .a3 = reg_pair_to_64(0, blocking_call), 186 }; 187 188 thread_smccc(&args); 189 190 /* Give the PLM time to access the console */ 191 if (IS_ENABLED(CFG_VERSAL_TRACE_PLM)) 192 mdelay(500); 193 194 if (args.a0) 195 return TEE_ERROR_GENERIC; 196 197 return TEE_SUCCESS; 198 } 199 200 static TEE_Result versal_mbox_write_req(struct versal_ipi_cmd *cmd) 201 { 202 size_t i = 0; 203 204 for (i = 0; i < VERSAL_MAX_IPI_BUF; i++) { 205 if (!cmd->ibuf[i].mem.buf) 206 continue; 207 208 if (!IS_ALIGNED((uintptr_t)cmd->ibuf[i].mem.buf, 209 CACHELINE_LEN)) { 210 EMSG("address not aligned: buffer %zu - %p", i, 211 cmd->ibuf[i].mem.buf); 212 return TEE_ERROR_GENERIC; 213 } 214 215 if (!IS_ALIGNED(cmd->ibuf[i].mem.alloc_len, CACHELINE_LEN)) { 216 EMSG("length not aligned: buffer %zu - %zu", 217 i, cmd->ibuf[i].mem.alloc_len); 218 return TEE_ERROR_GENERIC; 219 } 220 221 cache_operation(TEE_CACHEFLUSH, cmd->ibuf[i].mem.buf, 222 cmd->ibuf[i].mem.alloc_len); 223 } 224 225 memcpy(ipi.req, cmd->data, sizeof(cmd->data)); 226 227 /* Cache operation on the IPI buffer is safe */ 228 cache_operation(TEE_CACHEFLUSH, ipi.req, sizeof(cmd->data)); 229 230 return TEE_SUCCESS; 231 } 232 233 static TEE_Result versal_mbox_read_rsp(struct versal_ipi_cmd *cmd, 234 struct versal_ipi_cmd *rsp, 235 uint32_t *status) 236 { 237 size_t i = 0; 238 239 /* Cache operation on the IPI buffer is safe */ 240 cache_operation(TEE_CACHEINVALIDATE, ipi.rsp, sizeof(rsp->data)); 241 242 *status = *(uint32_t *)ipi.rsp; 243 244 if (*status) 245 return TEE_ERROR_GENERIC; 246 247 if (rsp) 248 memcpy(rsp->data, ipi.rsp, sizeof(rsp->data)); 249 250 for (i = 0; i < VERSAL_MAX_IPI_BUF; i++) { 251 if (!cmd->ibuf[i].mem.buf) 252 continue; 253 254 if (!IS_ALIGNED((uintptr_t)cmd->ibuf[i].mem.buf, 255 CACHELINE_LEN)) { 256 EMSG("address not aligned: buffer %zu - %p", 257 i, cmd->ibuf[i].mem.buf); 258 return TEE_ERROR_GENERIC; 259 } 260 261 if (!IS_ALIGNED(cmd->ibuf[i].mem.alloc_len, CACHELINE_LEN)) { 262 EMSG("length not aligned: buffer %zu - %zu", 263 i, cmd->ibuf[i].mem.alloc_len); 264 return TEE_ERROR_GENERIC; 265 } 266 267 cache_operation(TEE_CACHEINVALIDATE, 268 cmd->ibuf[i].mem.buf, 269 cmd->ibuf[i].mem.alloc_len); 270 } 271 272 return TEE_SUCCESS; 273 } 274 275 TEE_Result versal_mbox_alloc(size_t len, const void *init, 276 struct versal_mbox_mem *mem) 277 { 278 mem->buf = memalign(CACHELINE_LEN, ROUNDUP(len, CACHELINE_LEN)); 279 if (!mem->buf) 280 panic(); 281 282 memset(mem->buf, 0, ROUNDUP(len, CACHELINE_LEN)); 283 284 if (init) 285 memcpy(mem->buf, init, len); 286 287 mem->alloc_len = ROUNDUP(len, CACHELINE_LEN); 288 mem->len = len; 289 290 return TEE_SUCCESS; 291 } 292 293 TEE_Result versal_mbox_notify(struct versal_ipi_cmd *cmd, 294 struct versal_ipi_cmd *rsp, uint32_t *err) 295 { 296 TEE_Result ret = TEE_SUCCESS; 297 uint32_t remote_status = 0; 298 299 mutex_lock(&ipi.lock); 300 301 ret = versal_mbox_write_req(cmd); 302 if (ret) { 303 EMSG("Can't write the request command"); 304 goto out; 305 } 306 307 if (IS_ENABLED(CFG_VERSAL_TRACE_MBOX)) 308 versal_mbox_call_trace(cmd->data[0]); 309 310 ret = mbox_call(IPI_MAILBOX_NOTIFY, IPI_BLOCK); 311 if (ret) { 312 EMSG("IPI error"); 313 goto out; 314 } 315 316 ret = versal_mbox_read_rsp(cmd, rsp, &remote_status); 317 if (ret) 318 EMSG("Can't read the remote response"); 319 320 if (remote_status) { 321 if (err) 322 *err = remote_status; 323 /* 324 * Check the remote code (FSBL repository) in xplmi_status.h 325 * and the relevant service error (ie, xsecure_error.h) for 326 * detailed information. 327 */ 328 DMSG("PLM: plm status = 0x%" PRIx32 ", lib_status = 0x%" PRIx32, 329 (remote_status & 0xFFFF0000) >> 16, 330 (remote_status & 0x0000FFFF)); 331 332 ret = TEE_ERROR_GENERIC; 333 } 334 out: 335 mutex_unlock(&ipi.lock); 336 337 return ret; 338 } 339 340 static TEE_Result versal_mbox_init(void) 341 { 342 switch (CFG_VERSAL_MBOX_IPI_ID) { 343 case 0: 344 ipi.buf = IPI_BUFFER_APU_ID_0_BASE; 345 ipi.lcl = IPI_ID_0; 346 break; 347 case 3: 348 break; 349 case 4: 350 ipi.buf = IPI_BUFFER_APU_ID_4_BASE; 351 ipi.lcl = IPI_ID_4; 352 break; 353 case 5: 354 ipi.buf = IPI_BUFFER_APU_ID_5_BASE; 355 ipi.lcl = IPI_ID_5; 356 break; 357 default: 358 EMSG("Invalid IPI requested"); 359 return TEE_ERROR_GENERIC; 360 } 361 362 ipi.req = core_mmu_add_mapping(MEM_AREA_RAM_SEC, 363 ipi.buf + IPI_BUFFER_REMOTE_OFFSET + 364 IPI_BUFFER_REQ_OFFSET, 365 sizeof(struct versal_ipi_cmd)); 366 367 ipi.rsp = core_mmu_add_mapping(MEM_AREA_RAM_SEC, 368 ipi.buf + IPI_BUFFER_REMOTE_OFFSET + 369 IPI_BUFFER_RESP_OFFSET, 370 sizeof(struct versal_ipi_cmd)); 371 if (!ipi.req || !ipi.rsp) 372 panic(); 373 374 mutex_init(&ipi.lock); 375 376 return mbox_call(IPI_MAILBOX_OPEN, IPI_BLOCK); 377 } 378 early_init(versal_mbox_init); 379