1 /* 2 * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <common/debug.h> 9 #include <common/runtime_svc.h> 10 #include <tools_share/uuid.h> 11 12 #include "socfpga_mailbox.h" 13 #include "socfpga_sip_svc.h" 14 15 /* Number of SiP Calls implemented */ 16 #define SIP_NUM_CALLS 0x3 17 18 /* Total buffer the driver can hold */ 19 #define FPGA_CONFIG_BUFFER_SIZE 4 20 21 int current_block; 22 int current_buffer; 23 int current_id = 1; 24 int max_blocks; 25 uint32_t bytes_per_block; 26 uint32_t blocks_submitted; 27 uint32_t blocks_completed; 28 29 struct fpga_config_info { 30 uint32_t addr; 31 int size; 32 int size_written; 33 uint32_t write_requested; 34 int subblocks_sent; 35 int block_number; 36 }; 37 38 /* SiP Service UUID */ 39 DEFINE_SVC_UUID2(intl_svc_uid, 40 0xa85273b0, 0xe85a, 0x4862, 0xa6, 0x2a, 41 0xfa, 0x88, 0x88, 0x17, 0x68, 0x81); 42 43 uint64_t socfpga_sip_handler(uint32_t smc_fid, 44 uint64_t x1, 45 uint64_t x2, 46 uint64_t x3, 47 uint64_t x4, 48 void *cookie, 49 void *handle, 50 uint64_t flags) 51 { 52 ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); 53 SMC_RET1(handle, SMC_UNK); 54 } 55 56 struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE]; 57 58 static void intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) 59 { 60 uint32_t args[3]; 61 62 while (max_blocks > 0 && buffer->size > buffer->size_written) { 63 if (buffer->size - buffer->size_written <= 64 bytes_per_block) { 65 args[0] = (1<<8); 66 args[1] = buffer->addr + buffer->size_written; 67 args[2] = buffer->size - buffer->size_written; 68 buffer->size_written += 69 buffer->size - buffer->size_written; 70 buffer->subblocks_sent++; 71 mailbox_send_cmd_async(0x4, 72 MBOX_RECONFIG_DATA, 73 args, 3, 0); 74 current_buffer++; 75 current_buffer %= FPGA_CONFIG_BUFFER_SIZE; 76 } else { 77 args[0] = (1<<8); 78 args[1] = buffer->addr + buffer->size_written; 79 args[2] = bytes_per_block; 80 buffer->size_written += bytes_per_block; 81 mailbox_send_cmd_async(0x4, 82 MBOX_RECONFIG_DATA, 83 args, 3, 0); 84 buffer->subblocks_sent++; 85 } 86 max_blocks--; 87 } 88 } 89 90 static int intel_fpga_sdm_write_all(void) 91 { 92 int i; 93 94 for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) 95 intel_fpga_sdm_write_buffer( 96 &fpga_config_buffers[current_buffer]); 97 98 return 0; 99 } 100 101 uint32_t intel_mailbox_fpga_config_isdone(void) 102 { 103 uint32_t args[2]; 104 uint32_t response[6]; 105 int status; 106 107 status = mailbox_send_cmd(1, MBOX_RECONFIG_STATUS, args, 0, 0, 108 response); 109 110 if (status < 0) 111 return INTEL_SIP_SMC_STATUS_ERROR; 112 113 if (response[RECONFIG_STATUS_STATE] && 114 response[RECONFIG_STATUS_STATE] != MBOX_CFGSTAT_STATE_CONFIG) 115 return INTEL_SIP_SMC_STATUS_ERROR; 116 117 if (!(response[RECONFIG_STATUS_PIN_STATUS] & PIN_STATUS_NSTATUS)) 118 return INTEL_SIP_SMC_STATUS_ERROR; 119 120 if (response[RECONFIG_STATUS_SOFTFUNC_STATUS] & 121 SOFTFUNC_STATUS_SEU_ERROR) 122 return INTEL_SIP_SMC_STATUS_ERROR; 123 124 if ((response[RECONFIG_STATUS_SOFTFUNC_STATUS] & 125 SOFTFUNC_STATUS_CONF_DONE) && 126 (response[RECONFIG_STATUS_SOFTFUNC_STATUS] & 127 SOFTFUNC_STATUS_INIT_DONE)) 128 return INTEL_SIP_SMC_STATUS_OK; 129 130 return INTEL_SIP_SMC_STATUS_ERROR; 131 } 132 133 static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed) 134 { 135 int i; 136 137 for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { 138 if (fpga_config_buffers[i].block_number == current_block) { 139 fpga_config_buffers[i].subblocks_sent--; 140 if (fpga_config_buffers[i].subblocks_sent == 0 141 && fpga_config_buffers[i].size <= 142 fpga_config_buffers[i].size_written) { 143 fpga_config_buffers[i].write_requested = 0; 144 current_block++; 145 *buffer_addr_completed = 146 fpga_config_buffers[i].addr; 147 return 0; 148 } 149 } 150 } 151 152 return -1; 153 } 154 155 unsigned int address_in_ddr(uint32_t *addr) 156 { 157 if (((unsigned long long)addr > DRAM_BASE) && 158 ((unsigned long long)addr < DRAM_BASE + DRAM_SIZE)) 159 return 0; 160 161 return -1; 162 } 163 164 int intel_fpga_config_completed_write(uint32_t *completed_addr, 165 uint32_t *count) 166 { 167 uint32_t status = INTEL_SIP_SMC_STATUS_OK; 168 *count = 0; 169 int resp_len = 0; 170 uint32_t resp[5]; 171 int all_completed = 1; 172 int count_check = 0; 173 174 if (address_in_ddr(completed_addr) != 0 || address_in_ddr(count) != 0) 175 return INTEL_SIP_SMC_STATUS_ERROR; 176 177 for (count_check = 0; count_check < 3; count_check++) 178 if (address_in_ddr(&completed_addr[*count + count_check]) != 0) 179 return INTEL_SIP_SMC_STATUS_ERROR; 180 181 resp_len = mailbox_read_response(0x4, resp); 182 183 while (resp_len >= 0 && *count < 3) { 184 max_blocks++; 185 if (mark_last_buffer_xfer_completed( 186 &completed_addr[*count]) == 0) 187 *count = *count + 1; 188 else 189 break; 190 resp_len = mailbox_read_response(0x4, resp); 191 } 192 193 if (*count <= 0) { 194 if (resp_len != MBOX_NO_RESPONSE && 195 resp_len != MBOX_TIMEOUT && resp_len != 0) { 196 return INTEL_SIP_SMC_STATUS_ERROR; 197 } 198 199 *count = 0; 200 } 201 202 intel_fpga_sdm_write_all(); 203 204 if (*count > 0) 205 status = INTEL_SIP_SMC_STATUS_OK; 206 else if (*count == 0) 207 status = INTEL_SIP_SMC_STATUS_BUSY; 208 209 for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { 210 if (fpga_config_buffers[i].write_requested != 0) { 211 all_completed = 0; 212 break; 213 } 214 } 215 216 if (all_completed == 1) 217 return INTEL_SIP_SMC_STATUS_OK; 218 219 return status; 220 } 221 222 int intel_fpga_config_start(uint32_t config_type) 223 { 224 uint32_t response[3]; 225 int status = 0; 226 227 status = mailbox_send_cmd(2, MBOX_RECONFIG, 0, 0, 0, 228 response); 229 230 if (status < 0) 231 return status; 232 233 max_blocks = response[0]; 234 bytes_per_block = response[1]; 235 236 for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { 237 fpga_config_buffers[i].size = 0; 238 fpga_config_buffers[i].size_written = 0; 239 fpga_config_buffers[i].addr = 0; 240 fpga_config_buffers[i].write_requested = 0; 241 fpga_config_buffers[i].block_number = 0; 242 fpga_config_buffers[i].subblocks_sent = 0; 243 } 244 245 blocks_submitted = 0; 246 current_block = 0; 247 current_buffer = 0; 248 249 return 0; 250 } 251 252 253 uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size) 254 { 255 int i = 0; 256 uint32_t status = INTEL_SIP_SMC_STATUS_OK; 257 258 if (mem < DRAM_BASE || mem > DRAM_BASE + DRAM_SIZE) 259 status = INTEL_SIP_SMC_STATUS_REJECTED; 260 261 if (mem + size > DRAM_BASE + DRAM_SIZE) 262 status = INTEL_SIP_SMC_STATUS_REJECTED; 263 264 for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { 265 if (!fpga_config_buffers[i].write_requested) { 266 fpga_config_buffers[i].addr = mem; 267 fpga_config_buffers[i].size = size; 268 fpga_config_buffers[i].size_written = 0; 269 fpga_config_buffers[i].write_requested = 1; 270 fpga_config_buffers[i].block_number = 271 blocks_submitted++; 272 fpga_config_buffers[i].subblocks_sent = 0; 273 break; 274 } 275 } 276 277 278 if (i == FPGA_CONFIG_BUFFER_SIZE) { 279 status = INTEL_SIP_SMC_STATUS_REJECTED; 280 return status; 281 } else if (i == FPGA_CONFIG_BUFFER_SIZE - 1) { 282 status = INTEL_SIP_SMC_STATUS_BUSY; 283 } 284 285 intel_fpga_sdm_write_all(); 286 287 return status; 288 } 289 290 /* 291 * This function is responsible for handling all SiP calls from the NS world 292 */ 293 294 uintptr_t sip_smc_handler(uint32_t smc_fid, 295 u_register_t x1, 296 u_register_t x2, 297 u_register_t x3, 298 u_register_t x4, 299 void *cookie, 300 void *handle, 301 u_register_t flags) 302 { 303 uint32_t status = INTEL_SIP_SMC_STATUS_OK; 304 uint32_t completed_addr[3]; 305 uint32_t count = 0; 306 307 switch (smc_fid) { 308 case SIP_SVC_UID: 309 /* Return UID to the caller */ 310 SMC_UUID_RET(handle, intl_svc_uid); 311 break; 312 case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE: 313 status = intel_mailbox_fpga_config_isdone(); 314 SMC_RET4(handle, status, 0, 0, 0); 315 break; 316 case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM: 317 SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK, 318 INTEL_SIP_SMC_FPGA_CONFIG_ADDR, 319 INTEL_SIP_SMC_FPGA_CONFIG_SIZE - 320 INTEL_SIP_SMC_FPGA_CONFIG_ADDR); 321 break; 322 case INTEL_SIP_SMC_FPGA_CONFIG_START: 323 status = intel_fpga_config_start(x1); 324 SMC_RET4(handle, status, 0, 0, 0); 325 break; 326 case INTEL_SIP_SMC_FPGA_CONFIG_WRITE: 327 status = intel_fpga_config_write(x1, x2); 328 SMC_RET4(handle, status, 0, 0, 0); 329 break; 330 case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE: 331 status = intel_fpga_config_completed_write(completed_addr, 332 &count); 333 switch (count) { 334 case 1: 335 SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, 336 completed_addr[0], 0, 0); 337 break; 338 case 2: 339 SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, 340 completed_addr[0], 341 completed_addr[1], 0); 342 break; 343 case 3: 344 SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, 345 completed_addr[0], 346 completed_addr[1], 347 completed_addr[2]); 348 break; 349 case 0: 350 SMC_RET4(handle, status, 0, 0, 0); 351 break; 352 default: 353 SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR); 354 } 355 break; 356 357 default: 358 return socfpga_sip_handler(smc_fid, x1, x2, x3, x4, 359 cookie, handle, flags); 360 } 361 } 362 363 DECLARE_RT_SVC( 364 socfpga_sip_svc, 365 OEN_SIP_START, 366 OEN_SIP_END, 367 SMC_TYPE_FAST, 368 NULL, 369 sip_smc_handler 370 ); 371 372 DECLARE_RT_SVC( 373 socfpga_sip_svc_std, 374 OEN_SIP_START, 375 OEN_SIP_END, 376 SMC_TYPE_YIELD, 377 NULL, 378 sip_smc_handler 379 ); 380