xref: /rk3399_ARM-atf/plat/intel/soc/common/socfpga_sip_svc.c (revision d25041bf1e1b2a59b723f07c697447415bd42d0a)
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