1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) 2022 Foundries.io Ltd 4 * Jorge Ramirez-Ortiz <jorge@foundries.io> 5 * 6 * Copyright (C) 2023 ProvenRun S.A.S 7 */ 8 9 #include <assert.h> 10 #include <io.h> 11 #include <kernel/panic.h> 12 #include <mm/core_mmu.h> 13 #include <string.h> 14 #include <tee/cache.h> 15 #include "drivers/versal_mbox.h" 16 17 18 #if defined(PLATFORM_FLAVOR_net) 19 #define IPI_REG_BASEADDR 0xEB300000 20 #define IPI_BUFFER_BASEADDR 0xEB3F0000 21 #else 22 #define IPI_REG_BASEADDR 0xFF300000 23 #define IPI_BUFFER_BASEADDR 0xFF3F0000 24 #endif 25 26 #define IPI_SIZE 0x10000 27 28 #define IPI_TRIG_OFFSET 0x00 29 #define IPI_OBR_OFFSET 0x04 30 #define IPI_ISR_OFFSET 0x10 31 #define IPI_IMR_OFFSET 0x14 32 #define IPI_IER_OFFSET 0x18 33 #define IPI_IDR_OFFSET 0x1C 34 35 #define IPI_PMC_TRIG_BIT BIT(1) 36 #define IPI0_TRIG_BIT BIT(2) 37 #define IPI1_TRIG_BIT BIT(3) 38 #define IPI2_TRIG_BIT BIT(4) 39 #define IPI3_TRIG_BIT BIT(5) 40 #define IPI4_TRIG_BIT BIT(6) 41 #define IPI5_TRIG_BIT BIT(7) 42 43 /* Interrupt Config Registers */ 44 #define IPI_PMC_REG_BASE (IPI_REG_BASEADDR + 0x20000) 45 #define IPI0_REG_BASE (IPI_REG_BASEADDR + 0x30000) 46 #define IPI1_REG_BASE (IPI_REG_BASEADDR + 0x40000) 47 #define IPI2_REG_BASE (IPI_REG_BASEADDR + 0x50000) 48 #define IPI3_REG_BASE (IPI_REG_BASEADDR + 0x60000) 49 #define IPI4_REG_BASE (IPI_REG_BASEADDR + 0x70000) 50 #define IPI5_REG_BASE (IPI_REG_BASEADDR + 0x80000) 51 52 /* Buffers */ 53 #define IPI_BUFFER_PMC_BASE (IPI_BUFFER_BASEADDR + 0x200) 54 #define IPI_BUFFER_APU_ID_0_BASE (IPI_BUFFER_BASEADDR + 0x400) 55 #define IPI_BUFFER_APU_ID_1_BASE (IPI_BUFFER_BASEADDR + 0x600) 56 #define IPI_BUFFER_APU_ID_2_BASE (IPI_BUFFER_BASEADDR + 0x800) 57 #define IPI_BUFFER_APU_ID_3_BASE (IPI_BUFFER_BASEADDR + 0xA00) 58 #define IPI_BUFFER_APU_ID_4_BASE (IPI_BUFFER_BASEADDR + 0xC00) 59 #define IPI_BUFFER_APU_ID_5_BASE (IPI_BUFFER_BASEADDR + 0xE00) 60 #define IPI_BUFFER_TARGET_PMC_OFFSET 0x40 61 #define IPI_BUFFER_TARGET_ID_0_OFFSET 0x80 62 #define IPI_BUFFER_TARGET_ID_1_OFFSET 0xC0 63 #define IPI_BUFFER_TARGET_ID_2_OFFSET 0x100 64 #define IPI_BUFFER_TARGET_ID_3_OFFSET 0x140 65 #define IPI_BUFFER_TARGET_ID_4_OFFSET 0x180 66 #define IPI_BUFFER_TARGET_ID_5_OFFSET 0x1C0 67 68 #define IPI_BUFFER_REQ_OFFSET 0x0 69 #define IPI_BUFFER_RESP_OFFSET 0x20 70 71 static const struct versal_ipi_cfg { 72 uint32_t ipi_bit_mask; 73 uint32_t ipi_reg_base; 74 uint32_t ipi_buf_base; 75 uint32_t ipi_remote_offset; 76 } versal_ipi_cfgs[] = { 77 /* PMC IPI */ 78 [VERSAL_IPI_ID_PMC] = { 79 .ipi_bit_mask = IPI_PMC_TRIG_BIT, 80 .ipi_reg_base = IPI_PMC_REG_BASE, 81 .ipi_buf_base = IPI_BUFFER_PMC_BASE, 82 .ipi_remote_offset = IPI_BUFFER_TARGET_PMC_OFFSET, 83 }, 84 85 /* IPI0 IPI */ 86 [VERSAL_IPI_ID_0] = { 87 .ipi_bit_mask = IPI0_TRIG_BIT, 88 .ipi_reg_base = IPI0_REG_BASE, 89 .ipi_buf_base = IPI_BUFFER_APU_ID_0_BASE, 90 .ipi_remote_offset = IPI_BUFFER_TARGET_ID_0_OFFSET, 91 }, 92 93 /* IPI1 IPI */ 94 [VERSAL_IPI_ID_1] = { 95 .ipi_bit_mask = IPI1_TRIG_BIT, 96 .ipi_reg_base = IPI1_REG_BASE, 97 .ipi_buf_base = IPI_BUFFER_APU_ID_1_BASE, 98 .ipi_remote_offset = IPI_BUFFER_TARGET_ID_1_OFFSET, 99 }, 100 101 /* IPI2 IPI */ 102 [VERSAL_IPI_ID_2] = { 103 .ipi_bit_mask = IPI2_TRIG_BIT, 104 .ipi_reg_base = IPI2_REG_BASE, 105 .ipi_buf_base = IPI_BUFFER_APU_ID_2_BASE, 106 .ipi_remote_offset = IPI_BUFFER_TARGET_ID_2_OFFSET, 107 }, 108 109 /* IPI3 IPI */ 110 [VERSAL_IPI_ID_3] = { 111 .ipi_bit_mask = IPI3_TRIG_BIT, 112 .ipi_reg_base = IPI3_REG_BASE, 113 .ipi_buf_base = IPI_BUFFER_APU_ID_3_BASE, 114 .ipi_remote_offset = IPI_BUFFER_TARGET_ID_3_OFFSET, 115 }, 116 117 /* IPI4 IPI */ 118 [VERSAL_IPI_ID_4] = { 119 .ipi_bit_mask = IPI4_TRIG_BIT, 120 .ipi_reg_base = IPI4_REG_BASE, 121 .ipi_buf_base = IPI_BUFFER_APU_ID_4_BASE, 122 .ipi_remote_offset = IPI_BUFFER_TARGET_ID_4_OFFSET, 123 }, 124 125 /* IPI5 IPI */ 126 [VERSAL_IPI_ID_5] = { 127 .ipi_bit_mask = IPI5_TRIG_BIT, 128 .ipi_reg_base = IPI5_REG_BASE, 129 .ipi_buf_base = IPI_BUFFER_APU_ID_5_BASE, 130 .ipi_remote_offset = IPI_BUFFER_TARGET_ID_5_OFFSET, 131 }, 132 }; 133 134 #define IPI_REG_BASE(idx) (versal_ipi_cfgs[idx].ipi_reg_base) 135 #define IPI_BIT_MASK(idx) (versal_ipi_cfgs[idx].ipi_bit_mask) 136 #define IPI_BUFFER_BASE(idx) (versal_ipi_cfgs[idx].ipi_buf_base) 137 #define IPI_REMOTE_OFFSET(idx) (versal_ipi_cfgs[idx].ipi_remote_offset) 138 139 static TEE_Result versal_mbox_write_req(struct versal_ipi *ipi, 140 struct versal_ipi_cmd *cmd) 141 { 142 size_t i = 0; 143 144 assert(ipi); 145 assert(cmd); 146 147 for (i = 0; i < VERSAL_MAX_IPI_BUF; i++) { 148 if (!cmd->ibuf[i].mem.buf) 149 continue; 150 151 if (!IS_ALIGNED((uintptr_t)cmd->ibuf[i].mem.buf, 152 CACHELINE_LEN)) { 153 EMSG("address not aligned: buffer %zu - %p", i, 154 cmd->ibuf[i].mem.buf); 155 return TEE_ERROR_GENERIC; 156 } 157 158 if (!IS_ALIGNED(cmd->ibuf[i].mem.alloc_len, CACHELINE_LEN)) { 159 EMSG("length not aligned: buffer %zu - %zu", 160 i, cmd->ibuf[i].mem.alloc_len); 161 return TEE_ERROR_GENERIC; 162 } 163 164 cache_operation(TEE_CACHEFLUSH, cmd->ibuf[i].mem.buf, 165 cmd->ibuf[i].mem.alloc_len); 166 } 167 168 memcpy(ipi->req, cmd->data, sizeof(cmd->data)); 169 170 /* Cache operation on the IPI buffer is safe */ 171 cache_operation(TEE_CACHEFLUSH, ipi->req, sizeof(cmd->data)); 172 173 return TEE_SUCCESS; 174 } 175 176 static TEE_Result versal_mbox_read_rsp(struct versal_ipi *ipi, 177 struct versal_ipi_cmd *cmd, 178 struct versal_ipi_cmd *rsp, 179 uint32_t *status) 180 { 181 size_t i = 0; 182 183 assert(ipi); 184 assert(cmd); 185 186 /* Cache operation on the IPI buffer is safe */ 187 cache_operation(TEE_CACHEINVALIDATE, ipi->rsp, sizeof(rsp->data)); 188 189 *status = *(uint32_t *)ipi->rsp; 190 191 if (*status) 192 return TEE_ERROR_GENERIC; 193 194 if (rsp) 195 memcpy(rsp->data, ipi->rsp, sizeof(rsp->data)); 196 197 for (i = 0; i < VERSAL_MAX_IPI_BUF; i++) { 198 if (!cmd->ibuf[i].mem.buf) 199 continue; 200 201 if (!IS_ALIGNED((uintptr_t)cmd->ibuf[i].mem.buf, 202 CACHELINE_LEN)) { 203 EMSG("address not aligned: buffer %zu - %p", 204 i, cmd->ibuf[i].mem.buf); 205 return TEE_ERROR_GENERIC; 206 } 207 208 if (!IS_ALIGNED(cmd->ibuf[i].mem.alloc_len, CACHELINE_LEN)) { 209 EMSG("length not aligned: buffer %zu - %zu", 210 i, cmd->ibuf[i].mem.alloc_len); 211 return TEE_ERROR_GENERIC; 212 } 213 214 cache_operation(TEE_CACHEINVALIDATE, 215 cmd->ibuf[i].mem.buf, 216 cmd->ibuf[i].mem.alloc_len); 217 } 218 219 return TEE_SUCCESS; 220 } 221 222 TEE_Result versal_mbox_open(uint32_t local, uint32_t remote, 223 struct versal_ipi *ipi) 224 { 225 assert(ipi); 226 227 ipi->regs = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, 228 IPI_REG_BASE(local), 229 IPI_SIZE); 230 231 ipi->req = core_mmu_add_mapping(MEM_AREA_IO_SEC, 232 IPI_BUFFER_BASE(local) + 233 IPI_REMOTE_OFFSET(remote) + 234 IPI_BUFFER_REQ_OFFSET, 235 sizeof(struct versal_ipi_cmd)); 236 237 ipi->rsp = core_mmu_add_mapping(MEM_AREA_IO_SEC, 238 IPI_BUFFER_BASE(local) + 239 IPI_REMOTE_OFFSET(remote) + 240 IPI_BUFFER_RESP_OFFSET, 241 sizeof(struct versal_ipi_cmd)); 242 243 ipi->lcl = local; 244 ipi->rmt = remote; 245 246 if (!ipi->regs || !ipi->req || !ipi->rsp) 247 panic(); 248 249 mutex_init(&ipi->lock); 250 251 io_write32(ipi->regs + IPI_IDR_OFFSET, IPI_BIT_MASK(remote)); 252 io_write32(ipi->regs + IPI_ISR_OFFSET, IPI_BIT_MASK(remote)); 253 254 return TEE_SUCCESS; 255 } 256 257 TEE_Result versal_mbox_close(struct versal_ipi *ipi) 258 { 259 assert(ipi); 260 261 io_write32(ipi->regs + IPI_IDR_OFFSET, 262 IPI_BIT_MASK(ipi->rmt)); 263 264 return TEE_SUCCESS; 265 } 266 267 TEE_Result versal_mbox_alloc(size_t len, const void *init, 268 struct versal_mbox_mem *mem) 269 { 270 mem->buf = memalign(CACHELINE_LEN, ROUNDUP(len, CACHELINE_LEN)); 271 if (!mem->buf) 272 return TEE_ERROR_OUT_OF_MEMORY; 273 274 memset(mem->buf, 0, ROUNDUP(len, CACHELINE_LEN)); 275 276 if (init) 277 memcpy(mem->buf, init, len); 278 279 mem->alloc_len = ROUNDUP(len, CACHELINE_LEN); 280 mem->len = len; 281 282 return TEE_SUCCESS; 283 } 284 285 void versal_mbox_free(struct versal_mbox_mem *mem) 286 { 287 assert(mem); 288 289 free(mem->buf); 290 mem->buf = NULL; 291 } 292 293 TEE_Result versal_mbox_notify(struct versal_ipi *ipi, 294 struct versal_ipi_cmd *cmd, 295 struct versal_ipi_cmd *rsp, uint32_t *err) 296 { 297 TEE_Result ret = TEE_SUCCESS; 298 uint32_t remote_status = 0; 299 300 mutex_lock(&ipi->lock); 301 302 ret = versal_mbox_write_req(ipi, cmd); 303 if (ret) { 304 EMSG("Can't write the request command"); 305 goto out; 306 } 307 308 /* Trigger interrupt to remote */ 309 io_write32(ipi->regs + IPI_TRIG_OFFSET, IPI_BIT_MASK(ipi->rmt)); 310 311 /* Wait for remote to acknowledge the interrupt */ 312 if (IO_READ32_POLL_TIMEOUT(ipi->regs + IPI_OBR_OFFSET, remote_status, 313 !(remote_status & IPI_BIT_MASK(ipi->rmt)), 1, 314 CFG_VERSAL_MBOX_TIMEOUT)) { 315 EMSG("Timeout waiting for remote response"); 316 ret = TEE_ERROR_GENERIC; 317 goto out; 318 } 319 320 ret = versal_mbox_read_rsp(ipi, cmd, rsp, &remote_status); 321 if (ret) 322 EMSG("Can't read the remote response"); 323 324 if (remote_status) { 325 if (err) 326 *err = remote_status; 327 328 ret = TEE_ERROR_GENERIC; 329 } 330 out: 331 mutex_unlock(&ipi->lock); 332 333 return ret; 334 } 335