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