xref: /rk3399_ARM-atf/plat/intel/soc/common/socfpga_sip_svc.c (revision ec7d0055c955f60189d6a2063bdffa132b7ad0c0)
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 	return intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS);
104 }
105 
106 static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed)
107 {
108 	int i;
109 
110 	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
111 		if (fpga_config_buffers[i].block_number == current_block) {
112 			fpga_config_buffers[i].subblocks_sent--;
113 			if (fpga_config_buffers[i].subblocks_sent == 0
114 			&& fpga_config_buffers[i].size <=
115 			fpga_config_buffers[i].size_written) {
116 				fpga_config_buffers[i].write_requested = 0;
117 				current_block++;
118 				*buffer_addr_completed =
119 					fpga_config_buffers[i].addr;
120 				return 0;
121 			}
122 		}
123 	}
124 
125 	return -1;
126 }
127 
128 unsigned int address_in_ddr(uint32_t *addr)
129 {
130 	if (((unsigned long long)addr > DRAM_BASE) &&
131 		((unsigned long long)addr < DRAM_BASE + DRAM_SIZE))
132 		return 0;
133 
134 	return -1;
135 }
136 
137 int intel_fpga_config_completed_write(uint32_t *completed_addr,
138 					uint32_t *count)
139 {
140 	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
141 	*count = 0;
142 	int resp_len = 0;
143 	uint32_t resp[5];
144 	int all_completed = 1;
145 	int count_check = 0;
146 
147 	if (address_in_ddr(completed_addr) != 0 || address_in_ddr(count) != 0)
148 		return INTEL_SIP_SMC_STATUS_ERROR;
149 
150 	for (count_check = 0; count_check < 3; count_check++)
151 		if (address_in_ddr(&completed_addr[*count + count_check]) != 0)
152 			return INTEL_SIP_SMC_STATUS_ERROR;
153 
154 	resp_len = mailbox_read_response(0x4, resp);
155 
156 	while (resp_len >= 0 && *count < 3) {
157 		max_blocks++;
158 		if (mark_last_buffer_xfer_completed(
159 			&completed_addr[*count]) == 0)
160 			*count = *count + 1;
161 		else
162 			break;
163 		resp_len = mailbox_read_response(0x4, resp);
164 	}
165 
166 	if (*count <= 0) {
167 		if (resp_len != MBOX_NO_RESPONSE &&
168 			resp_len != MBOX_TIMEOUT && resp_len != 0) {
169 			return INTEL_SIP_SMC_STATUS_ERROR;
170 		}
171 
172 		*count = 0;
173 	}
174 
175 	intel_fpga_sdm_write_all();
176 
177 	if (*count > 0)
178 		status = INTEL_SIP_SMC_STATUS_OK;
179 	else if (*count == 0)
180 		status = INTEL_SIP_SMC_STATUS_BUSY;
181 
182 	for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
183 		if (fpga_config_buffers[i].write_requested != 0) {
184 			all_completed = 0;
185 			break;
186 		}
187 	}
188 
189 	if (all_completed == 1)
190 		return INTEL_SIP_SMC_STATUS_OK;
191 
192 	return status;
193 }
194 
195 int intel_fpga_config_start(uint32_t config_type)
196 {
197 	uint32_t response[3];
198 	int status = 0;
199 
200 	status = mailbox_send_cmd(2, MBOX_RECONFIG, 0, 0, 0,
201 			response);
202 
203 	if (status < 0)
204 		return status;
205 
206 	max_blocks = response[0];
207 	bytes_per_block = response[1];
208 
209 	for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
210 		fpga_config_buffers[i].size = 0;
211 		fpga_config_buffers[i].size_written = 0;
212 		fpga_config_buffers[i].addr = 0;
213 		fpga_config_buffers[i].write_requested = 0;
214 		fpga_config_buffers[i].block_number = 0;
215 		fpga_config_buffers[i].subblocks_sent = 0;
216 	}
217 
218 	blocks_submitted = 0;
219 	current_block = 0;
220 	current_buffer = 0;
221 
222 	return 0;
223 }
224 
225 
226 uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
227 {
228 	int i = 0;
229 	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
230 
231 	if (mem < DRAM_BASE || mem > DRAM_BASE + DRAM_SIZE)
232 		status = INTEL_SIP_SMC_STATUS_REJECTED;
233 
234 	if (mem + size > DRAM_BASE + DRAM_SIZE)
235 		status = INTEL_SIP_SMC_STATUS_REJECTED;
236 
237 	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
238 		if (!fpga_config_buffers[i].write_requested) {
239 			fpga_config_buffers[i].addr = mem;
240 			fpga_config_buffers[i].size = size;
241 			fpga_config_buffers[i].size_written = 0;
242 			fpga_config_buffers[i].write_requested = 1;
243 			fpga_config_buffers[i].block_number =
244 				blocks_submitted++;
245 			fpga_config_buffers[i].subblocks_sent = 0;
246 			break;
247 		}
248 	}
249 
250 
251 	if (i == FPGA_CONFIG_BUFFER_SIZE) {
252 		status = INTEL_SIP_SMC_STATUS_REJECTED;
253 		return status;
254 	} else if (i == FPGA_CONFIG_BUFFER_SIZE - 1) {
255 		status = INTEL_SIP_SMC_STATUS_BUSY;
256 	}
257 
258 	intel_fpga_sdm_write_all();
259 
260 	return status;
261 }
262 
263 /*
264  * This function is responsible for handling all SiP calls from the NS world
265  */
266 
267 uintptr_t sip_smc_handler(uint32_t smc_fid,
268 			 u_register_t x1,
269 			 u_register_t x2,
270 			 u_register_t x3,
271 			 u_register_t x4,
272 			 void *cookie,
273 			 void *handle,
274 			 u_register_t flags)
275 {
276 	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
277 	uint32_t completed_addr[3];
278 	uint32_t count = 0;
279 
280 	switch (smc_fid) {
281 	case SIP_SVC_UID:
282 		/* Return UID to the caller */
283 		SMC_UUID_RET(handle, intl_svc_uid);
284 		break;
285 	case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE:
286 		status = intel_mailbox_fpga_config_isdone();
287 		SMC_RET4(handle, status, 0, 0, 0);
288 		break;
289 	case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM:
290 		SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
291 			INTEL_SIP_SMC_FPGA_CONFIG_ADDR,
292 			INTEL_SIP_SMC_FPGA_CONFIG_SIZE -
293 				INTEL_SIP_SMC_FPGA_CONFIG_ADDR);
294 		break;
295 	case INTEL_SIP_SMC_FPGA_CONFIG_START:
296 		status = intel_fpga_config_start(x1);
297 		SMC_RET4(handle, status, 0, 0, 0);
298 		break;
299 	case INTEL_SIP_SMC_FPGA_CONFIG_WRITE:
300 		status = intel_fpga_config_write(x1, x2);
301 		SMC_RET4(handle, status, 0, 0, 0);
302 		break;
303 	case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE:
304 		status = intel_fpga_config_completed_write(completed_addr,
305 								&count);
306 		switch (count) {
307 		case 1:
308 			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
309 				completed_addr[0], 0, 0);
310 			break;
311 		case 2:
312 			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
313 				completed_addr[0],
314 				completed_addr[1], 0);
315 			break;
316 		case 3:
317 			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
318 				completed_addr[0],
319 				completed_addr[1],
320 				completed_addr[2]);
321 			break;
322 		case 0:
323 			SMC_RET4(handle, status, 0, 0, 0);
324 			break;
325 		default:
326 			SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR);
327 		}
328 		break;
329 
330 	default:
331 		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
332 			cookie, handle, flags);
333 	}
334 }
335 
336 DECLARE_RT_SVC(
337 	socfpga_sip_svc,
338 	OEN_SIP_START,
339 	OEN_SIP_END,
340 	SMC_TYPE_FAST,
341 	NULL,
342 	sip_smc_handler
343 );
344 
345 DECLARE_RT_SVC(
346 	socfpga_sip_svc_std,
347 	OEN_SIP_START,
348 	OEN_SIP_END,
349 	SMC_TYPE_YIELD,
350 	NULL,
351 	sip_smc_handler
352 );
353