1 /*******************************************************************************
2 * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * PolarFire SoC Microprocessor Subsystem(MSS) System Services bare metal driver
7 * implementation.
8 */
9
10 #include "mpfs_hal/mss_hal.h"
11 #include "mss_sys_services_regs.h"
12 #include "mss_sys_services.h"
13
14
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18
19 /*******************************************************************************
20 * Null buffer constant definition
21 */
22 #define NULL_BUFFER (( uint8_t* ) 0)
23
24 /*-------------------------------------------------------------------------*//**
25 System service response offset
26 ============================
27 The following constants are used to specify the offset in the mailbox where
28 the service response is written by the system controller after service
29 execution.
30 */
31 #define MSS_SYS_COMMON_RET_OFFSET 0u
32 #define MSS_SYS_DIGITAL_SIG_RET_OFFSET 48u
33 #define MSS_SYS_SECURE_NVM_READ_RET_OFFSET 16u
34 #define MSS_SYS_PUF_EMULATION_RET_OFFSET 20u
35 #define MSS_SYS_DIGEST_CHECK_RET_OFFSET 4u
36 #define MSS_SYS_GENERATE_OTP_RET_OFFSET 20u
37
38 /*******************************************************************************
39 * Global variables declarations
40 */
41 volatile uint8_t g_message_received = 0u;
42 uint8_t g_service_mode = 0u;
43
44 uint8_t* gp_int_service_response;
45 uint16_t g_int_service_response_size;
46 uint16_t g_int_service_response_offset;
47
48 volatile uint8_t g_message_interrupt_counter = 0u;
49
50 /*******************************************************************************
51 * Callback handler function declaration
52 */
53 mss_sys_service_handler_t mss_sys_interrupt_handler;
54
55 /*******************************************************************************
56 * Local function declarations.
57 */
58 static uint16_t execute_ss_polling_mode
59 (
60 uint8_t cmd_opcode,
61 uint8_t* cmd_data,
62 uint16_t cmd_data_size,
63 uint8_t* p_response,
64 uint16_t response_size,
65 uint16_t mb_offset,
66 uint16_t response_offset
67 );
68
69 static uint16_t execute_ss_interrupt_mode
70 (
71 uint8_t cmd_opcode,
72 uint8_t* cmd_data,
73 uint16_t cmd_data_size,
74 uint8_t* p_response,
75 uint16_t response_size,
76 uint16_t mb_offset,
77 uint16_t response_offset
78 );
79
80 static uint16_t request_system_service
81 (
82 uint8_t cmd_opcode,
83 uint8_t* cmd_data,
84 uint16_t cmd_data_size,
85 uint8_t* p_response,
86 uint16_t response_size,
87 uint16_t mb_offset,
88 uint16_t response_offset
89 );
90
91 /*-----------------------------------------------------------------------------
92 Public Functions
93 -----------------------------------------------------------------------------*/
94
95 /***************************************************************************//**
96 * MSS_SYS_get_serial_number()
97 * See "mss_sysservices.h" for details of how to use this function.
98 */
99 void
MSS_SYS_select_service_mode(uint8_t sys_service_mode,mss_sys_service_handler_t mss_sys_service_interrupt_handler)100 MSS_SYS_select_service_mode
101 (
102 uint8_t sys_service_mode,
103 mss_sys_service_handler_t mss_sys_service_interrupt_handler
104 )
105 {
106 g_service_mode = sys_service_mode;
107 mss_sys_interrupt_handler = mss_sys_service_interrupt_handler;
108 }
109
110
111 /***************************************************************************//**
112 * MSS_SYS_get_serial_number()
113 * See "mss_sysservices.h" for details of how to use this function.
114 */
115 uint16_t
MSS_SYS_get_serial_number(uint8_t * p_serial_number,uint16_t mb_offset)116 MSS_SYS_get_serial_number
117 (
118 uint8_t * p_serial_number,
119 uint16_t mb_offset
120 )
121 {
122 uint16_t status = MSS_SYS_PARAM_ERR;
123
124 if (p_serial_number == NULL_BUFFER)
125 {
126 return status;
127 }
128
129 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
130 {
131 status = execute_ss_interrupt_mode(
132 (uint8_t)MSS_SYS_SERIAL_NUMBER_REQUEST_CMD,
133 NULL_BUFFER,
134 MSS_SYS_WITHOUT_CMD_DATA,
135 p_serial_number,
136 (uint16_t)MSS_SYS_SERIAL_NUMBER_RESP_LEN,
137 mb_offset,
138 MSS_SYS_COMMON_RET_OFFSET);
139 }
140 else
141 {
142 status = execute_ss_polling_mode(
143 (uint8_t)MSS_SYS_SERIAL_NUMBER_REQUEST_CMD,
144 NULL_BUFFER,
145 MSS_SYS_WITHOUT_CMD_DATA,
146 p_serial_number,
147 (uint16_t)MSS_SYS_SERIAL_NUMBER_RESP_LEN,
148 mb_offset,
149 MSS_SYS_COMMON_RET_OFFSET);
150 }
151
152 return status;
153 }
154
155 /***************************************************************************//**
156 * SYS_get_user_code()
157 * See "mss_sysservices.h" for details of how to use this function.
158 */
159 uint16_t
MSS_SYS_get_user_code(uint8_t * p_user_code,uint16_t mb_offset)160 MSS_SYS_get_user_code
161 (
162 uint8_t * p_user_code,
163 uint16_t mb_offset
164 )
165 {
166 uint16_t status = MSS_SYS_PARAM_ERR;
167
168 if (p_user_code == NULL_BUFFER)
169 {
170 return status;
171 }
172
173 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
174 {
175 status = execute_ss_interrupt_mode(
176 (uint8_t)MSS_SYS_USERCODE_REQUEST_CMD,
177 NULL_BUFFER,
178 MSS_SYS_WITHOUT_CMD_DATA,
179 p_user_code,
180 (uint16_t)MSS_SYS_USERCODE_RESP_LEN,
181 mb_offset,
182 MSS_SYS_COMMON_RET_OFFSET);
183 }
184 else
185 {
186 status = execute_ss_polling_mode(
187 (uint8_t)MSS_SYS_USERCODE_REQUEST_CMD,
188 NULL_BUFFER,
189 MSS_SYS_WITHOUT_CMD_DATA,
190 p_user_code,
191 (uint16_t)MSS_SYS_USERCODE_RESP_LEN,
192 mb_offset,
193 MSS_SYS_COMMON_RET_OFFSET);
194 }
195
196 return status;
197 }
198
199 /***************************************************************************//**
200 * SYS_get_design_info()
201 * See "mss_sysservices.h" for details of how to use this function.
202 */
203 uint16_t
MSS_SYS_get_design_info(uint8_t * p_design_info,uint16_t mb_offset)204 MSS_SYS_get_design_info
205 (
206 uint8_t * p_design_info,
207 uint16_t mb_offset
208 )
209 {
210 uint16_t status = MSS_SYS_PARAM_ERR;
211
212 if (p_design_info == NULL_BUFFER)
213 {
214 return status;
215 }
216
217 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
218 {
219 status = execute_ss_interrupt_mode(
220 (uint8_t)MSS_SYS_DESIGN_INFO_REQUEST_CMD,
221 NULL_BUFFER,
222 MSS_SYS_WITHOUT_CMD_DATA,
223 p_design_info,
224 (uint16_t)MSS_SYS_DESIGN_INFO_RESP_LEN,
225 mb_offset,
226 MSS_SYS_COMMON_RET_OFFSET);
227 }
228 else
229 {
230 status = execute_ss_polling_mode(
231 (uint8_t)MSS_SYS_DESIGN_INFO_REQUEST_CMD,
232 NULL_BUFFER,
233 MSS_SYS_WITHOUT_CMD_DATA,
234 p_design_info,
235 (uint16_t)MSS_SYS_DESIGN_INFO_RESP_LEN,
236 mb_offset,
237 MSS_SYS_COMMON_RET_OFFSET);
238 }
239
240 return status;
241 }
242
243 /***************************************************************************//**
244 * SYS_get_device_certificate()
245 * See "mss_sysservices.h" for details of how to use this function.
246 */
247 uint16_t
MSS_SYS_get_device_certificate(uint8_t * p_device_certificate,uint16_t mb_offset)248 MSS_SYS_get_device_certificate
249 (
250 uint8_t * p_device_certificate,
251 uint16_t mb_offset
252 )
253 {
254 uint16_t status = MSS_SYS_PARAM_ERR;
255
256 if (p_device_certificate == NULL_BUFFER)
257 {
258 return status;
259 }
260
261 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
262 {
263 status = execute_ss_interrupt_mode(
264 (uint8_t)MSS_SYS_DEVICE_CERTIFICATE_REQUEST_CMD,
265 NULL_BUFFER,
266 MSS_SYS_WITHOUT_CMD_DATA,
267 p_device_certificate,
268 (uint16_t)MSS_SYS_DEVICE_CERTIFICATE_RESP_LEN,
269 mb_offset,
270 MSS_SYS_COMMON_RET_OFFSET);
271 }
272 else
273 {
274 status = execute_ss_polling_mode(
275 (uint8_t)MSS_SYS_DEVICE_CERTIFICATE_REQUEST_CMD,
276 NULL_BUFFER,
277 MSS_SYS_WITHOUT_CMD_DATA,
278 p_device_certificate,
279 (uint16_t)MSS_SYS_DEVICE_CERTIFICATE_RESP_LEN,
280 mb_offset,
281 MSS_SYS_COMMON_RET_OFFSET);
282 }
283
284 return status;
285 }
286
287 /***************************************************************************//**
288 * SYS_read_digest()
289 * See "mss_sysservices.h" for details of how to use this function.
290 */
291 uint16_t
MSS_SYS_read_digest(uint8_t * p_digest,uint16_t mb_offset)292 MSS_SYS_read_digest
293 (
294 uint8_t * p_digest,
295 uint16_t mb_offset
296 )
297 {
298 uint16_t status = MSS_SYS_PARAM_ERR;
299
300 if (p_digest == NULL_BUFFER)
301 {
302 return status;
303 }
304
305 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
306 {
307 status = execute_ss_interrupt_mode(
308 (uint8_t)MSS_SYS_READ_DIGEST_REQUEST_CMD,
309 NULL_BUFFER,
310 MSS_SYS_WITHOUT_CMD_DATA,
311 p_digest,
312 (uint16_t)MSS_SYS_READ_DIGEST_RESP_LEN,
313 mb_offset,
314 MSS_SYS_COMMON_RET_OFFSET);
315 }
316 else
317 {
318 status = execute_ss_polling_mode(
319 (uint8_t)MSS_SYS_READ_DIGEST_REQUEST_CMD,
320 NULL_BUFFER,
321 MSS_SYS_WITHOUT_CMD_DATA,
322 p_digest,
323 (uint16_t)MSS_SYS_READ_DIGEST_RESP_LEN,
324 mb_offset,
325 MSS_SYS_COMMON_RET_OFFSET);
326 }
327
328 return status;
329 }
330
331 /***************************************************************************//**
332 * SYS_query_security()
333 * See "mss_sysservices.h" for details of how to use this function.
334 */
335 uint16_t
MSS_SYS_query_security(uint8_t * p_security_locks,uint16_t mb_offset)336 MSS_SYS_query_security
337 (
338 uint8_t * p_security_locks,
339 uint16_t mb_offset
340 )
341 {
342 uint16_t status = MSS_SYS_PARAM_ERR;
343 uint8_t idx=0;
344 uint8_t buf[36] = {0};
345
346 if (p_security_locks == NULL_BUFFER)
347 {
348 return status;
349 }
350
351 /* Actual QUERY_SECURITY_RESP_LEN is 9 but CoreSysService_PF IP needs number
352 * of words instead of number of bytes to be written to or read from
353 * MailBox */
354 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
355 {
356 status = execute_ss_interrupt_mode(
357 (uint8_t)MSS_SYS_QUERY_SECURITY_REQUEST_CMD,
358 NULL_BUFFER,
359 MSS_SYS_WITHOUT_CMD_DATA,
360 buf,
361 (uint16_t)(MSS_SYS_QUERY_SECURITY_RESP_LEN + 3u),
362 mb_offset,
363 MSS_SYS_COMMON_RET_OFFSET);
364 }
365 else
366 {
367 status = execute_ss_polling_mode(
368 (uint8_t)MSS_SYS_QUERY_SECURITY_REQUEST_CMD,
369 NULL_BUFFER,
370 MSS_SYS_WITHOUT_CMD_DATA,
371 buf,
372 (uint16_t)(MSS_SYS_QUERY_SECURITY_RESP_LEN + 3u),
373 mb_offset,
374 MSS_SYS_COMMON_RET_OFFSET);
375 }
376
377 for (idx = 0u; idx < MSS_SYS_QUERY_SECURITY_RESP_LEN; idx++)
378 {
379 *(p_security_locks + idx) = buf[idx];
380 }
381
382 return status;
383 }
384
385 /***************************************************************************//**
386 * SYS_read_debug_info()
387 * See "mss_sysservices.h" for details of how to use this function.
388 */
389 uint16_t
MSS_SYS_read_debug_info(uint8_t * p_debug_info,uint16_t mb_offset)390 MSS_SYS_read_debug_info
391 (
392 uint8_t * p_debug_info,
393 uint16_t mb_offset
394 )
395 {
396
397 uint16_t status = MSS_SYS_PARAM_ERR;
398
399 if (p_debug_info == NULL_BUFFER)
400 {
401 return status;
402 }
403
404 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
405 {
406 status = execute_ss_interrupt_mode(
407 (uint8_t)MSS_SYS_READ_DEBUG_INFO_REQUEST_CMD,
408 NULL_BUFFER,
409 MSS_SYS_WITHOUT_CMD_DATA,
410 p_debug_info,
411 (uint16_t)MSS_SYS_READ_DEBUG_INFO_RESP_LEN,
412 mb_offset,
413 MSS_SYS_COMMON_RET_OFFSET);
414 }
415 else
416 {
417 status = execute_ss_polling_mode(
418 (uint8_t)MSS_SYS_READ_DEBUG_INFO_REQUEST_CMD,
419 NULL_BUFFER,
420 MSS_SYS_WITHOUT_CMD_DATA,
421 p_debug_info,
422 (uint16_t)MSS_SYS_READ_DEBUG_INFO_RESP_LEN,
423 mb_offset,
424 MSS_SYS_COMMON_RET_OFFSET);
425 }
426
427 return status;
428 }
429
430 /**************************************************************************//**
431 * SYS_read_envm_param()
432 * See "mss_sysservices.h" for details of how to use this function.
433 */
434
435 uint16_t
MSS_SYS_read_envm_parameter(uint8_t * p_envm_param,uint16_t mb_offset)436 MSS_SYS_read_envm_parameter
437 (
438 uint8_t * p_envm_param,
439 uint16_t mb_offset
440 )
441 {
442 uint16_t status = MSS_SYS_PARAM_ERR;
443
444 if (p_envm_param == NULL_BUFFER)
445 {
446 return status;
447 }
448
449 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
450 {
451 status = execute_ss_interrupt_mode(
452 (uint8_t)MSS_SYS_READ_ENVM_PARAM_REQUEST_CMD,
453 NULL_BUFFER,
454 MSS_SYS_WITHOUT_CMD_DATA,
455 p_envm_param,
456 (uint16_t)MSS_SYS_READ_ENVM_PARAM_RESP_LEN,
457 mb_offset,
458 MSS_SYS_COMMON_RET_OFFSET);
459 }
460 else
461 {
462 status = execute_ss_polling_mode(
463 (uint8_t)MSS_SYS_READ_ENVM_PARAM_REQUEST_CMD,
464 NULL_BUFFER,
465 MSS_SYS_WITHOUT_CMD_DATA,
466 p_envm_param,
467 (uint16_t)MSS_SYS_READ_ENVM_PARAM_RESP_LEN,
468 mb_offset,
469 MSS_SYS_COMMON_RET_OFFSET);
470 }
471
472 return status;
473 }
474
475 /***************************************************************************//**
476 * SYS_puf_emulation_service()
477 * See "mss_sysservices.h" for details of how to use this function.
478 */
479 uint16_t
MSS_SYS_puf_emulation_service(uint8_t * p_challenge,uint8_t op_type,uint8_t * p_response,uint16_t mb_offset)480 MSS_SYS_puf_emulation_service
481 (
482 uint8_t * p_challenge,
483 uint8_t op_type,
484 uint8_t* p_response,
485 uint16_t mb_offset
486 )
487 {
488 uint16_t status = MSS_SYS_PARAM_ERR;
489 uint8_t mb_format[20] = {0x00};
490 uint8_t index = 0u;
491
492 if((p_response == NULL_BUFFER) || (p_challenge == NULL_BUFFER))
493 {
494 return status;
495 }
496
497 /* Frame the data required for mailbox */
498 mb_format[index] = op_type;
499
500 for (index = 4u; index < 20u; index++)
501 {
502 mb_format[index] = p_challenge[index - 4u];
503 }
504
505 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
506 {
507 status = execute_ss_interrupt_mode(
508 (uint8_t)MSS_SYS_PUF_EMULATION_SERVICE_REQUEST_CMD,
509 mb_format,
510 (uint16_t)MSS_SYS_PUF_EMULATION_SERVICE_CMD_LEN,
511 p_response,
512 (uint16_t)MSS_SYS_PUF_EMULATION_SERVICE_RESP_LEN,
513 mb_offset,
514 (uint16_t)MSS_SYS_PUF_EMULATION_RET_OFFSET);
515 }
516 else
517 {
518 status = execute_ss_polling_mode(
519 (uint8_t)MSS_SYS_PUF_EMULATION_SERVICE_REQUEST_CMD,
520 mb_format,
521 (uint16_t)MSS_SYS_PUF_EMULATION_SERVICE_CMD_LEN,
522 p_response,
523 (uint16_t)MSS_SYS_PUF_EMULATION_SERVICE_RESP_LEN,
524 mb_offset,
525 (uint16_t)MSS_SYS_PUF_EMULATION_RET_OFFSET);
526 }
527
528 return status;
529 }
530
531 /***************************************************************************//**
532 * SYS_digital_signature_service()
533 * See "mss_sysservices.h" for details of how to use this function.
534 */
535 uint16_t
MSS_SYS_digital_signature_service(uint8_t * p_hash,uint8_t format,uint8_t * p_response,uint16_t mb_offset)536 MSS_SYS_digital_signature_service
537 (
538 uint8_t* p_hash,
539 uint8_t format,
540 uint8_t* p_response,
541 uint16_t mb_offset
542 )
543 {
544 uint16_t status = MSS_SYS_PARAM_ERR;
545
546 if((p_hash == NULL_BUFFER) || (p_response == NULL_BUFFER))
547 {
548 return status;
549 }
550
551 if (format == MSS_SYS_DIGITAL_SIGNATURE_RAW_FORMAT_REQUEST_CMD)
552 {
553 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
554 {
555 status = execute_ss_interrupt_mode
556 ((uint8_t)MSS_SYS_DIGITAL_SIGNATURE_RAW_FORMAT_REQUEST_CMD,
557 p_hash,
558 (uint16_t)MSS_SYS_DIGITAL_SIGNATURE_HASH_DATA_LEN,
559 p_response,
560 (uint16_t)MSS_SYS_DIGITAL_SIGNATURE_RAW_FORMAT_RESP_SIZE,
561 mb_offset,
562 (uint16_t)MSS_SYS_DIGITAL_SIG_RET_OFFSET);
563 }
564 else
565 {
566 status = execute_ss_polling_mode
567 ((uint8_t)MSS_SYS_DIGITAL_SIGNATURE_RAW_FORMAT_REQUEST_CMD,
568 p_hash,
569 (uint16_t)MSS_SYS_DIGITAL_SIGNATURE_HASH_DATA_LEN,
570 p_response,
571 (uint16_t)MSS_SYS_DIGITAL_SIGNATURE_RAW_FORMAT_RESP_SIZE,
572 mb_offset,
573 (uint16_t)MSS_SYS_DIGITAL_SIG_RET_OFFSET);
574 }
575 }
576
577 else
578 {
579 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
580 {
581 status = execute_ss_interrupt_mode
582 ((uint8_t)MSS_SYS_DIGITAL_SIGNATURE_DER_FORMAT_REQUEST_CMD,
583 p_hash,
584 (uint16_t)MSS_SYS_DIGITAL_SIGNATURE_HASH_DATA_LEN,
585 p_response,
586 (uint16_t)MSS_SYS_DIGITAL_SIGNATURE_DER_FORMAT_RESP_SIZE,
587 mb_offset,
588 (uint16_t)MSS_SYS_DIGITAL_SIG_RET_OFFSET);
589 }
590 else
591 {
592 status = execute_ss_polling_mode
593 ((uint8_t)MSS_SYS_DIGITAL_SIGNATURE_DER_FORMAT_REQUEST_CMD,
594 p_hash,
595 (uint16_t)MSS_SYS_DIGITAL_SIGNATURE_HASH_DATA_LEN,
596 p_response,
597 (uint16_t)MSS_SYS_DIGITAL_SIGNATURE_DER_FORMAT_RESP_SIZE,
598 mb_offset,
599 (uint16_t)MSS_SYS_DIGITAL_SIG_RET_OFFSET);
600 }
601 }
602
603 return status;
604 }
605
606 /***************************************************************************//**
607 * SYS_secure_nvm_write()
608 * See "mss_sysservices.h" for details of how to use this function.
609 */
610 uint16_t
MSS_SYS_secure_nvm_write(uint8_t format,uint8_t snvm_module,uint8_t * p_data,uint8_t * p_user_key,uint16_t mb_offset)611 MSS_SYS_secure_nvm_write
612 (
613 uint8_t format,
614 uint8_t snvm_module,
615 uint8_t* p_data,
616 uint8_t* p_user_key,
617 uint16_t mb_offset
618 )
619 {
620 uint8_t frame[256] = {0x00};
621 uint8_t* p_frame = &frame[0];
622 uint16_t index = 0;
623 uint16_t status = MSS_SYS_PARAM_ERR;
624
625 ASSERT(!(NULL_BUFFER == p_data));
626 ASSERT(!(NULL_BUFFER == p_user_key));
627 ASSERT(!(snvm_module >= 221u));
628
629 if((p_data == NULL_BUFFER) || (p_user_key == NULL_BUFFER)
630 || (snvm_module >= 221))
631 {
632 return status;
633 }
634
635 if ((format != MSS_SYS_SNVM_NON_AUTHEN_TEXT_REQUEST_CMD)
636 || (format != MSS_SYS_SNVM_AUTHEN_TEXT_REQUEST_CMD)
637 || (format != MSS_SYS_SNVM_AUTHEN_CIPHERTEXT_REQUEST_CMD))
638 {
639 return status;
640 }
641
642 *p_frame = snvm_module; /* SNVMADDR - SNVM module */
643 p_frame += 4; /* Next 3 bytes RESERVED - For alignment */
644
645 /* Copy user key and send the command/data to mailbox. */
646 if ((format == MSS_SYS_SNVM_AUTHEN_TEXT_REQUEST_CMD) ||
647 (format == MSS_SYS_SNVM_AUTHEN_CIPHERTEXT_REQUEST_CMD))
648 {
649 /* Copy user data */
650 for (index = 0u; index < (MSS_SYS_AUTHENTICATED_TEXT_DATA_LEN
651 - MSS_SYS_USER_SECRET_KEY_LEN - 4u); index++)
652 {
653 *p_frame = p_data[index];
654 p_frame++;
655 }
656
657 /* Copy user key */
658 for (index = 0u; index < MSS_SYS_USER_SECRET_KEY_LEN; index++)
659 {
660 *p_frame = p_user_key[index];
661 p_frame++;
662 }
663
664 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
665 {
666 status = execute_ss_interrupt_mode(
667 format,
668 &frame[0],
669 (uint16_t)MSS_SYS_AUTHENTICATED_TEXT_DATA_LEN,
670 NULL_BUFFER,
671 MSS_SYS_NO_RESPONSE_LEN,
672 mb_offset,
673 MSS_SYS_COMMON_RET_OFFSET);
674 }
675 else
676 {
677 status = execute_ss_polling_mode(
678 format,
679 &frame[0],
680 (uint16_t)MSS_SYS_AUTHENTICATED_TEXT_DATA_LEN,
681 NULL_BUFFER,
682 MSS_SYS_NO_RESPONSE_LEN,
683 mb_offset,
684 MSS_SYS_COMMON_RET_OFFSET);
685 }
686 }
687 else
688 {
689 /* Copy user data */
690 for (index = 0u; index < (MSS_SYS_NON_AUTHENTICATED_TEXT_DATA_LEN - 4u);
691 index++)
692 {
693 *(p_frame+index) = p_data[index];
694 }
695
696 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
697 {
698 status = execute_ss_interrupt_mode(
699 format,
700 &frame[0],
701 (uint16_t)MSS_SYS_NON_AUTHENTICATED_TEXT_DATA_LEN,
702 NULL_BUFFER,
703 MSS_SYS_NO_RESPONSE_LEN,
704 mb_offset,
705 MSS_SYS_COMMON_RET_OFFSET);
706 }
707 else
708 {
709 status = execute_ss_polling_mode(
710 format,
711 &frame[0],
712 (uint16_t)MSS_SYS_NON_AUTHENTICATED_TEXT_DATA_LEN,
713 NULL_BUFFER,
714 MSS_SYS_NO_RESPONSE_LEN,
715 mb_offset,
716 MSS_SYS_COMMON_RET_OFFSET);
717 }
718 }
719
720 return status;
721 }
722
723 /***************************************************************************//**
724 * SYS_secure_nvm_read()
725 * See "mss_sysservices.h" for details of how to use this function.
726 */
727 uint16_t
MSS_SYS_secure_nvm_read(uint8_t snvm_module,uint8_t * p_user_key,uint8_t * p_admin,uint8_t * p_data,uint16_t data_len,uint16_t mb_offset)728 MSS_SYS_secure_nvm_read
729 (
730 uint8_t snvm_module,
731 uint8_t* p_user_key,
732 uint8_t* p_admin,
733 uint8_t* p_data,
734 uint16_t data_len,
735 uint16_t mb_offset
736 )
737 {
738 /* Frame the message. */
739 uint8_t frame[16] = {0x00u};
740 uint8_t* p_frame = &frame[0];
741 uint16_t index = 0u;
742 uint16_t status = MSS_SYS_PARAM_ERR;
743 uint8_t response[256] = {0x00};
744
745 ASSERT(!(NULL_BUFFER == p_data));
746 ASSERT(!(NULL_BUFFER == p_admin));
747 ASSERT(!(snvm_module > 221u));
748
749 ASSERT((data_len == 236u) || (data_len == 252u));
750
751 if((p_data == NULL_BUFFER) || (snvm_module >= 221) ||
752 (p_admin == NULL_BUFFER))
753 {
754 return status;
755 }
756
757
758 *p_frame = snvm_module; /* SNVMADDR - SNVM module */
759 p_frame += 4u; /* RESERVED - For alignment */
760
761 /* Copy user key */
762 if (236u == data_len)
763 {
764 for (index = 0u; index < 12u; index++)
765 {
766 ASSERT(p_user_key != NULL_BUFFER);
767 *p_frame = p_user_key[index];
768 p_frame++;
769 }
770 }
771 else
772 {
773 p_frame += 12u;
774 }
775
776 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
777 {
778 status = execute_ss_interrupt_mode(
779 (uint8_t)MSS_SYS_SNVM_READ_REQUEST_CMD,
780 &frame[0],
781 (uint16_t)MSS_SYS_SECURE_NVM_READ_DATA_LEN,
782 response,
783 (data_len + 4u),
784 mb_offset,
785 (uint16_t)MSS_SYS_SECURE_NVM_READ_RET_OFFSET);
786 }
787 else
788 {
789 status = execute_ss_polling_mode(
790 (uint8_t)MSS_SYS_SNVM_READ_REQUEST_CMD,
791 &frame[0],
792 (uint16_t)MSS_SYS_SECURE_NVM_READ_DATA_LEN,
793 response,
794 (data_len + 4u),
795 mb_offset,
796 (uint16_t)MSS_SYS_SECURE_NVM_READ_RET_OFFSET);
797 }
798
799 if (MSS_SYS_SUCCESS == status)
800 {
801 for (index = 0u; index < 4u; index++)
802 {
803 *(p_admin+index) = (uint32_t)response[index];
804 }
805
806 /* Copy data into user buffer. */
807 for (index = 4u; index < (data_len + 4u); index++)
808 {
809 *(p_data + (index - 4u)) = response[index];
810 }
811 }
812 else
813 {
814 ;
815 }
816
817 return status;
818 }
819
820 /***************************************************************************//**
821 * SYS_nonce_service()
822 * See "mss_sysservices.h" for details of how to use this function.
823 */
824 uint16_t
MSS_SYS_nonce_service(uint8_t * p_nonce,uint16_t mb_offset)825 MSS_SYS_nonce_service
826 (
827 uint8_t * p_nonce,
828 uint16_t mb_offset
829 )
830 {
831 uint16_t status = MSS_SYS_PARAM_ERR;
832
833 if (p_nonce == NULL_BUFFER)
834 {
835 return status;
836 }
837
838 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
839 {
840 status = execute_ss_interrupt_mode(
841 (uint8_t)MSS_SYS_NONCE_SERVICE_REQUEST_CMD,
842 NULL_BUFFER,
843 MSS_SYS_WITHOUT_CMD_DATA,
844 p_nonce,
845 (uint16_t)MSS_SYS_NONCE_SERVICE_RESP_LEN,
846 mb_offset,
847 MSS_SYS_COMMON_RET_OFFSET);
848 }
849 else
850 {
851 status = execute_ss_polling_mode(
852 (uint8_t)MSS_SYS_NONCE_SERVICE_REQUEST_CMD,
853 NULL_BUFFER,
854 MSS_SYS_WITHOUT_CMD_DATA,
855 p_nonce,
856 (uint16_t)MSS_SYS_NONCE_SERVICE_RESP_LEN,
857 mb_offset,
858 MSS_SYS_COMMON_RET_OFFSET);
859 }
860
861 return status;
862 }
863
864 /***************************************************************************//**
865 * MSS_SYS_authenticate_bitstream()
866 * See "mss_sysservices.h" for details of how to use this function.
867 */
868 uint16_t
MSS_SYS_authenticate_bitstream(uint32_t spi_flash_address,uint16_t mb_offset)869 MSS_SYS_authenticate_bitstream
870 (
871 uint32_t spi_flash_address,
872 uint16_t mb_offset
873 )
874 {
875 uint16_t status = MSS_SYS_PARAM_ERR;
876 uint32_t l_spi_flash_address = spi_flash_address;
877
878 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
879 {
880 status = execute_ss_interrupt_mode(
881 (uint8_t)MSS_SYS_BITSTREAM_AUTHENTICATE_CMD,
882 (uint8_t* )&l_spi_flash_address,
883 (uint16_t)MSS_SYS_BITSTREAM_AUTHENTICATE_DATA_LEN,
884 NULL_BUFFER,
885 MSS_SYS_NO_RESPONSE_LEN,
886 mb_offset,
887 MSS_SYS_COMMON_RET_OFFSET);
888 }
889 else
890 {
891 status = execute_ss_polling_mode(
892 (uint8_t)MSS_SYS_BITSTREAM_AUTHENTICATE_CMD,
893 (uint8_t* )&l_spi_flash_address,
894 (uint16_t)MSS_SYS_BITSTREAM_AUTHENTICATE_DATA_LEN,
895 NULL_BUFFER,
896 MSS_SYS_NO_RESPONSE_LEN,
897 mb_offset,
898 MSS_SYS_COMMON_RET_OFFSET);
899 }
900
901 return status;
902 }
903
904 /***************************************************************************//**
905 * MSS_SYS_authenticate_iap_image()
906 * See "mss_sysservices.h" for details of how to use this function.
907 */
908 uint16_t
MSS_SYS_authenticate_iap_image(uint32_t spi_idx)909 MSS_SYS_authenticate_iap_image
910 (
911 uint32_t spi_idx
912 )
913 {
914 uint16_t status = MSS_SYS_PARAM_ERR;
915
916 ASSERT(!(spi_idx == 1u));
917
918 if (spi_idx == 1u)
919 {
920 return status;
921 }
922
923 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
924 {
925 status = execute_ss_interrupt_mode(
926 (uint8_t)MSS_SYS_IAP_BITSTREAM_AUTHENTICATE_CMD,
927 NULL_BUFFER,
928 MSS_SYS_WITHOUT_CMD_DATA,
929 NULL_BUFFER,
930 MSS_SYS_NO_RESPONSE_LEN,
931 (uint16_t)spi_idx,
932 MSS_SYS_COMMON_RET_OFFSET);
933 }
934 else
935 {
936 status = execute_ss_polling_mode(
937 (uint8_t)MSS_SYS_IAP_BITSTREAM_AUTHENTICATE_CMD,
938 NULL_BUFFER,
939 MSS_SYS_WITHOUT_CMD_DATA,
940 NULL_BUFFER,
941 MSS_SYS_NO_RESPONSE_LEN,
942 (uint16_t)spi_idx,
943 MSS_SYS_COMMON_RET_OFFSET);
944 }
945
946 return status;
947 }
948
949 /***************************************************************************//**
950 * MSS_SYS_digest_check()
951 * See "mss_sysservices.h" for details of how to use this function.
952 */
953 uint16_t
MSS_SYS_digest_check(uint32_t options,uint8_t * digesterr,uint16_t mb_offset)954 MSS_SYS_digest_check
955 (
956 uint32_t options,
957 uint8_t* digesterr,
958 uint16_t mb_offset
959 )
960 {
961 uint16_t status = MSS_SYS_PARAM_ERR;
962 uint32_t l_options = options;
963
964 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
965 {
966 status = execute_ss_interrupt_mode(
967 (uint8_t)MSS_SYS_DIGEST_CHECK_CMD,
968 (uint8_t* )&l_options,
969 (uint16_t)MSS_SYS_DIGEST_CHECK_DATA_LEN,
970 digesterr,
971 (uint16_t)MSS_SYS_DIGEST_CHECK_SERVICE_RESP_LEN,
972 mb_offset,
973 MSS_SYS_DIGEST_CHECK_RET_OFFSET);
974 }
975 else
976 {
977 status = execute_ss_polling_mode(
978 (uint8_t)MSS_SYS_DIGEST_CHECK_CMD,
979 (uint8_t* )&l_options,
980 (uint16_t)MSS_SYS_DIGEST_CHECK_DATA_LEN,
981 digesterr,
982 (uint16_t)MSS_SYS_DIGEST_CHECK_SERVICE_RESP_LEN,
983 mb_offset,
984 MSS_SYS_DIGEST_CHECK_RET_OFFSET);
985 }
986
987 return status;
988 }
989
990 /***************************************************************************//**
991 * MSS_SYS_execute_iap()
992 * See "mss_sysservices.h" for details of how to use this function.
993 */
994 uint16_t
MSS_SYS_execute_iap(uint8_t iap_cmd,uint32_t spiaddr)995 MSS_SYS_execute_iap
996 (
997 uint8_t iap_cmd,
998 uint32_t spiaddr
999 )
1000 {
1001 uint16_t status = MSS_SYS_PARAM_ERR;
1002 uint32_t l_spiaddr = spiaddr;
1003
1004 if ((MSS_SYS_IAP_PROGRAM_BY_SPIIDX_CMD == iap_cmd)
1005 || (MSS_SYS_IAP_VERIFY_BY_SPIIDX_CMD == iap_cmd))
1006 {
1007 return status;
1008 }
1009
1010 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1011 {
1012 status = execute_ss_interrupt_mode(
1013 (uint8_t)iap_cmd,
1014 (uint8_t*)&l_spiaddr,
1015 MSS_SYS_IAP_SERVICE_DATA_LEN,
1016 NULL_BUFFER,
1017 MSS_SYS_NO_RESPONSE_LEN,
1018 (uint16_t)spiaddr,
1019 MSS_SYS_COMMON_RET_OFFSET);
1020 }
1021 else
1022 {
1023 status = execute_ss_polling_mode(
1024 (uint8_t)iap_cmd,
1025 (uint8_t*)&l_spiaddr,
1026 MSS_SYS_IAP_SERVICE_DATA_LEN,
1027 NULL_BUFFER,
1028 MSS_SYS_NO_RESPONSE_LEN,
1029 (uint16_t)spiaddr,
1030 MSS_SYS_COMMON_RET_OFFSET);
1031 }
1032
1033 return status;
1034 }
1035
1036 /***************************************************************************//**
1037 * MSS_SYS_spi_copy()
1038 * See "mss_sysservices.h" for details of how to use this function.
1039 */
1040 uint16_t
MSS_SYS_spi_copy(uint64_t mss_dest_addr,uint32_t mss_spi_flash,uint32_t n_bytes,uint8_t options,uint16_t mb_offset)1041 MSS_SYS_spi_copy
1042 (
1043 uint64_t mss_dest_addr,
1044 uint32_t mss_spi_flash,
1045 uint32_t n_bytes,
1046 uint8_t options,
1047 uint16_t mb_offset
1048 )
1049 {
1050 uint16_t status = MSS_SYS_PARAM_ERR;
1051 uint8_t mb_format[17];
1052
1053 if ((options < 1U) || (options > 3U))
1054 {
1055 return MSS_SYS_PARAM_ERR;
1056 }
1057
1058 *(uint64_t *)mb_format = mss_dest_addr;
1059 *(uint32_t *)(mb_format + 8u) = mss_spi_flash;
1060 *(uint32_t *)(mb_format + 12u) = n_bytes;
1061 mb_format[16] = options;
1062
1063
1064 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1065 {
1066 status = execute_ss_interrupt_mode(
1067 (uint8_t)MSS_SYS_SPI_COPY_CMD,
1068 mb_format,
1069 (uint16_t)MSS_SYS_SPI_COPY_MAILBOX_DATA_LEN,
1070 NULL_BUFFER,
1071 MSS_SYS_NO_RESPONSE_LEN,
1072 mb_offset,
1073 MSS_SYS_COMMON_RET_OFFSET);
1074 }
1075 else
1076 {
1077 status = execute_ss_polling_mode(
1078 (uint8_t)MSS_SYS_SPI_COPY_CMD,
1079 mb_format,
1080 (uint16_t)MSS_SYS_SPI_COPY_MAILBOX_DATA_LEN,
1081 NULL_BUFFER,
1082 MSS_SYS_NO_RESPONSE_LEN,
1083 mb_offset,
1084 MSS_SYS_COMMON_RET_OFFSET);
1085 }
1086
1087 return status;
1088 }
1089
1090 /***************************************************************************//**
1091 * MSS_SYS_debug_read_probe()
1092 * See "mss_sysservices.h" for details of how to use this function.
1093 */
1094 uint16_t
MSS_SYS_debug_read_probe(uint8_t ipseg_addr,uint8_t iprow_addr,uint8_t * prdata,uint16_t mb_offset,uint8_t resp_offset)1095 MSS_SYS_debug_read_probe
1096 (
1097 uint8_t ipseg_addr,
1098 uint8_t iprow_addr,
1099 uint8_t *prdata,
1100 uint16_t mb_offset,
1101 uint8_t resp_offset
1102 )
1103 {
1104 uint16_t status = MSS_SYS_PARAM_ERR;
1105 uint8_t mb_format[2];
1106 uint16_t service_data = 0u;
1107 uint8_t l_resp_offset = resp_offset;
1108
1109 if (prdata == NULL_BUFFER)
1110 {
1111 return status;
1112 }
1113
1114 service_data = iprow_addr;
1115 service_data = service_data << 6u;
1116
1117 service_data = service_data + ipseg_addr;
1118
1119 *(uint16_t*)mb_format = service_data;
1120
1121 l_resp_offset = (4u + (4u * l_resp_offset));
1122
1123 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1124 {
1125 status = execute_ss_interrupt_mode(
1126 (uint8_t)MSS_SYS_PROBE_READ_DEBUG_CMD,
1127 mb_format,
1128 (uint16_t)MSS_SYS_PROBE_READ_SERVICE_DATA_LEN,
1129 prdata,
1130 (uint16_t)MSS_SYS_PROBE_READ_SERVICE_RESP_LEN,
1131 mb_offset,
1132 (uint16_t)l_resp_offset);
1133 }
1134 else
1135 {
1136 status = execute_ss_polling_mode(
1137 (uint8_t)MSS_SYS_PROBE_READ_DEBUG_CMD,
1138 mb_format,
1139 (uint16_t)MSS_SYS_PROBE_READ_SERVICE_DATA_LEN,
1140 prdata,
1141 (uint16_t)MSS_SYS_PROBE_READ_SERVICE_RESP_LEN,
1142 mb_offset,
1143 (uint16_t)l_resp_offset);
1144 }
1145
1146 return status;
1147 }
1148
1149 /***************************************************************************//**
1150 * MSS_SYS_debug_write_probe()
1151 * See "mss_sysservices.h" for details of how to use this function.
1152 */
1153 uint16_t
MSS_SYS_debug_write_probe(uint8_t prb_addr,uint8_t ipseg_addr,uint8_t iprow_addr,uint32_t pwmask,uint32_t pwdata,uint16_t mb_offset)1154 MSS_SYS_debug_write_probe
1155 (
1156 uint8_t prb_addr,
1157 uint8_t ipseg_addr,
1158 uint8_t iprow_addr,
1159 uint32_t pwmask,
1160 uint32_t pwdata,
1161 uint16_t mb_offset
1162 )
1163 {
1164 uint16_t status = MSS_SYS_PARAM_ERR;
1165 uint8_t mb_format[12] = {0};
1166
1167 /* Local variable to store the combination of iprow_addr, ipseg_addr and
1168 * prb_addr */
1169 uint32_t service_data = 0u;
1170
1171 uint16_t ip_addr = iprow_addr;
1172 ip_addr = ip_addr << 6u;
1173 ip_addr += ipseg_addr;/* ip_addr is ipseg_addr + iprow_addr */
1174
1175 service_data = ip_addr;
1176 service_data = service_data << 16; /* 2 bytes space for prb_addr */
1177 service_data += prb_addr;
1178
1179 *(uint32_t *)mb_format = service_data;
1180 *(uint32_t *)(mb_format + 4u) = pwmask;
1181 *(uint32_t *)(mb_format + 8u) = pwdata;
1182
1183 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1184 {
1185 status = execute_ss_interrupt_mode(
1186 (uint8_t)MSS_SYS_PROBE_WRITE_DEBUG_CMD,
1187 mb_format,
1188 (uint16_t)MSS_SYS_PROBE_WRITE_SERVICE_DATA_LEN,
1189 NULL_BUFFER,
1190 MSS_SYS_NO_RESPONSE_LEN,
1191 mb_offset,
1192 MSS_SYS_COMMON_RET_OFFSET);
1193 }
1194 else
1195 {
1196 status = execute_ss_polling_mode(
1197 (uint8_t)MSS_SYS_PROBE_WRITE_DEBUG_CMD,
1198 mb_format,
1199 (uint16_t)MSS_SYS_PROBE_WRITE_SERVICE_DATA_LEN,
1200 NULL_BUFFER,
1201 MSS_SYS_NO_RESPONSE_LEN,
1202 mb_offset,
1203 MSS_SYS_COMMON_RET_OFFSET);
1204 }
1205
1206 return status;
1207 }
1208
1209 /***************************************************************************//**
1210 * MSS_SYS_debug_live_probe()
1211 * See "mss_sysservices.h" for details of how to use this function.
1212 */
1213 uint16_t
MSS_SYS_debug_live_probe(uint8_t x_addr,uint8_t y_addr,uint8_t ipseg_addr,uint8_t iprow_addr,uint8_t clear,uint8_t ioen,uint16_t mb_offset,uint8_t service_cmd)1214 MSS_SYS_debug_live_probe
1215 (
1216 uint8_t x_addr,
1217 uint8_t y_addr,
1218 uint8_t ipseg_addr,
1219 uint8_t iprow_addr,
1220 uint8_t clear,
1221 uint8_t ioen,
1222 uint16_t mb_offset,
1223 uint8_t service_cmd
1224 )
1225 {
1226 uint16_t status = MSS_SYS_PARAM_ERR;
1227 uint8_t mb_format[6] = {0};
1228 uint32_t service_data = 0u;
1229
1230 uint16_t channel_addr = 0u;
1231 uint16_t probe_addr = 0u;
1232
1233 channel_addr = y_addr;
1234 channel_addr = (channel_addr << 5u) + x_addr;
1235
1236 probe_addr = iprow_addr;
1237 probe_addr = (probe_addr << 6u) + ipseg_addr;
1238
1239 service_data = probe_addr;
1240 service_data = (service_data << 16u) + channel_addr;
1241
1242 *(uint32_t*)mb_format = service_data;
1243 mb_format[4] = clear & 0x01u;
1244 mb_format[5] = ioen & 0x01u;
1245
1246 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1247 {
1248 status = execute_ss_interrupt_mode(
1249 service_cmd,
1250 mb_format,
1251 (uint16_t)MSS_SYS_LIVE_PROBE_DEBUG_SERVICE_DATA_LEN,
1252 NULL_BUFFER,
1253 MSS_SYS_NO_RESPONSE_LEN,
1254 mb_offset,
1255 MSS_SYS_COMMON_RET_OFFSET);
1256 }
1257 else
1258 {
1259 status = execute_ss_polling_mode(
1260 service_cmd,
1261 mb_format,
1262 (uint16_t)MSS_SYS_LIVE_PROBE_DEBUG_SERVICE_DATA_LEN,
1263 NULL_BUFFER,
1264 MSS_SYS_NO_RESPONSE_LEN,
1265 mb_offset,
1266 MSS_SYS_COMMON_RET_OFFSET);
1267 }
1268
1269 return status;
1270 }
1271
1272 /***************************************************************************//**
1273 * MSS_SYS_debug_select_mem()
1274 * See "mss_sysservices.h" for details of how to use this function.
1275 */
1276 uint16_t
MSS_SYS_debug_select_mem(uint8_t ipblk_addr,uint8_t ipseg_addr,uint8_t iprow_addr,uint8_t memtype,uint8_t memlock_mode,uint16_t timeout,uint16_t mb_offset)1277 MSS_SYS_debug_select_mem
1278 (
1279 uint8_t ipblk_addr,
1280 uint8_t ipseg_addr,
1281 uint8_t iprow_addr,
1282 uint8_t memtype,
1283 uint8_t memlock_mode,
1284 uint16_t timeout,
1285 uint16_t mb_offset
1286 )
1287 {
1288 uint16_t status = MSS_SYS_PARAM_ERR;
1289 uint8_t mb_format[6] = {0};
1290 uint16_t service_data = 0u;
1291
1292 if ((memlock_mode >= 4u) || (timeout > 8193u))
1293 {
1294 return status;
1295 }
1296
1297 service_data = ipblk_addr;
1298
1299 uint16_t temp = iprow_addr;
1300 temp = ((temp << 6u) + ipseg_addr);
1301 service_data = ((temp << 3u) + service_data);
1302
1303 *(uint16_t *)mb_format = service_data;
1304 mb_format[2] = memtype;
1305 mb_format[3] = memlock_mode;
1306 *(uint16_t*)(mb_format + 4u) = timeout;
1307
1308 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1309 {
1310 status = execute_ss_interrupt_mode(
1311 (uint8_t)MSS_SYS_MEM_SELECT_DEBUG_CMD,
1312 mb_format,
1313 (uint16_t)MSS_SYS_MEM_SELECT_DATA_LEN,
1314 NULL_BUFFER,
1315 MSS_SYS_NO_RESPONSE_LEN,
1316 mb_offset,
1317 MSS_SYS_COMMON_RET_OFFSET);
1318 }
1319 else
1320 {
1321 status = execute_ss_polling_mode(
1322 (uint8_t)MSS_SYS_MEM_SELECT_DEBUG_CMD,
1323 mb_format,
1324 (uint16_t)MSS_SYS_MEM_SELECT_DATA_LEN,
1325 NULL_BUFFER,
1326 MSS_SYS_NO_RESPONSE_LEN,
1327 mb_offset,
1328 MSS_SYS_COMMON_RET_OFFSET);
1329 }
1330
1331 return status;
1332 }
1333
1334 /***************************************************************************//**
1335 * MSS_SYS_debug_read_mem()
1336 * See "mss_sysservices.h" for details of how to use this function.
1337 */
1338 uint16_t
MSS_SYS_debug_read_mem(uint16_t mem_addr,uint16_t n_words,uint64_t mss_addr,uint16_t mb_offset)1339 MSS_SYS_debug_read_mem
1340 (
1341 uint16_t mem_addr,
1342 uint16_t n_words,
1343 uint64_t mss_addr,
1344 uint16_t mb_offset
1345 )
1346 {
1347 uint16_t status = MSS_SYS_PARAM_ERR;
1348 uint8_t mb_format[12] = {0};
1349
1350 *(uint16_t*)(mb_format) = mem_addr;
1351 *(uint16_t*)(mb_format + 2u) = n_words;
1352
1353 for (uint8_t index = 4u; index < 12u; index++)
1354 {
1355 mb_format[index] = (mss_addr >> (8u * (index - 4u)));
1356 }
1357
1358 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1359 {
1360 status = execute_ss_interrupt_mode(
1361 (uint8_t)MSS_SYS_MEM_READ_DEBUG_CMD,
1362 mb_format,
1363 (uint16_t)MSS_SYS_MEM_READ_WRITE_DATA_LEN,
1364 NULL_BUFFER,
1365 MSS_SYS_NO_RESPONSE_LEN,
1366 mb_offset,
1367 MSS_SYS_COMMON_RET_OFFSET);
1368 }
1369 else
1370 {
1371 status = execute_ss_polling_mode(
1372 (uint8_t)MSS_SYS_MEM_READ_DEBUG_CMD,
1373 mb_format,
1374 (uint16_t)MSS_SYS_MEM_READ_WRITE_DATA_LEN,
1375 NULL_BUFFER,
1376 MSS_SYS_NO_RESPONSE_LEN,
1377 mb_offset,
1378 MSS_SYS_COMMON_RET_OFFSET);
1379 }
1380
1381 return status;
1382 }
1383
1384
1385 /***************************************************************************//**
1386 * MSS_SYS_debug_write_mem()
1387 * See "mss_sysservices.h" for details of how to use this function.
1388 */
1389 uint16_t
MSS_SYS_debug_write_mem(uint16_t mem_addr,uint16_t n_words,uint64_t mss_addr,uint16_t mb_offset)1390 MSS_SYS_debug_write_mem
1391 (
1392 uint16_t mem_addr,
1393 uint16_t n_words,
1394 uint64_t mss_addr,
1395 uint16_t mb_offset
1396 )
1397 {
1398 uint16_t status = MSS_SYS_PARAM_ERR;
1399 uint8_t mb_format[12] = {0};
1400
1401 *(uint16_t*)(mb_format) = mem_addr;
1402 *(uint16_t*)(mb_format + 2u) = n_words;
1403
1404 for (uint8_t index = 4u; index < 12u; index++)
1405 {
1406 mb_format[index] = (mss_addr >> (8u * (index - 4u)));
1407 }
1408
1409 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1410 {
1411 status = execute_ss_interrupt_mode(
1412 (uint8_t)MSS_SYS_MEM_WRITE_DEBUG_CMD,
1413 mb_format,
1414 (uint16_t)MSS_SYS_MEM_READ_WRITE_DATA_LEN,
1415 NULL_BUFFER,
1416 MSS_SYS_NO_RESPONSE_LEN,
1417 mb_offset,
1418 MSS_SYS_COMMON_RET_OFFSET);
1419 }
1420 else
1421 {
1422 status = execute_ss_polling_mode(
1423 (uint8_t)MSS_SYS_MEM_WRITE_DEBUG_CMD,
1424 mb_format,
1425 (uint16_t)MSS_SYS_MEM_READ_WRITE_DATA_LEN,
1426 NULL_BUFFER,
1427 MSS_SYS_NO_RESPONSE_LEN,
1428 mb_offset,
1429 MSS_SYS_COMMON_RET_OFFSET);
1430 }
1431
1432 return status;
1433 }
1434
1435 /***************************************************************************//**
1436 * MSS_SYS_debug_read_apb()
1437 * See "mss_sysservices.h" for details of how to use this function.
1438 */
1439 uint16_t
MSS_SYS_debug_read_apb(uint32_t apb_addr,uint8_t apb_wsize,uint16_t max_bytes,uint64_t mss_addr,uint16_t mb_offset)1440 MSS_SYS_debug_read_apb
1441 (
1442 uint32_t apb_addr,
1443 uint8_t apb_wsize,
1444 uint16_t max_bytes,
1445 uint64_t mss_addr,
1446 uint16_t mb_offset
1447 )
1448 {
1449 uint16_t status = MSS_SYS_PARAM_ERR;
1450 uint8_t mb_format[24] = {0};
1451 *(uint32_t *)mb_format = apb_addr;
1452
1453 mb_format[4] = apb_wsize;
1454 *(uint16_t *)(mb_format + 8u) = max_bytes;
1455
1456 for (uint8_t index = 12u; index < 20u; index++)
1457 {
1458 mb_format[index] = (mss_addr >> (8u * (index - 12u)));
1459 }
1460
1461 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1462 {
1463 status = execute_ss_interrupt_mode(
1464 (uint8_t)MSS_SYS_APB_READ_DEBUG_CMD,
1465 mb_format,
1466 (uint16_t)MSS_SYS_APB_SERVICE_DATA_LEN,
1467 NULL_BUFFER,
1468 MSS_SYS_NO_RESPONSE_LEN,
1469 mb_offset,
1470 MSS_SYS_COMMON_RET_OFFSET);
1471 }
1472 else
1473 {
1474 status = execute_ss_polling_mode(
1475 (uint8_t)MSS_SYS_APB_READ_DEBUG_CMD,
1476 mb_format,
1477 (uint16_t)MSS_SYS_APB_SERVICE_DATA_LEN,
1478 NULL_BUFFER,
1479 MSS_SYS_NO_RESPONSE_LEN,
1480 mb_offset,
1481 MSS_SYS_COMMON_RET_OFFSET);
1482 }
1483
1484 return status;
1485 }
1486
1487 /***************************************************************************//**
1488 * MSS_SYS_debug_write_apb()
1489 * See "mss_sysservices.h" for details of how to use this function.
1490 */
1491 uint16_t
MSS_SYS_debug_write_apb(uint32_t apb_addr,uint8_t apb_wsize,uint16_t max_bytes,uint64_t mss_addr,uint16_t mb_offset)1492 MSS_SYS_debug_write_apb
1493 (
1494 uint32_t apb_addr,
1495 uint8_t apb_wsize,
1496 uint16_t max_bytes,
1497 uint64_t mss_addr,
1498 uint16_t mb_offset
1499 )
1500 {
1501 uint16_t status = MSS_SYS_PARAM_ERR;
1502 uint8_t mb_format[20] = {0};
1503
1504 *(uint32_t *)mb_format = apb_addr;
1505 mb_format[4] = apb_wsize;
1506 *(uint16_t *)(mb_format + 8u) = max_bytes;
1507
1508 for (uint8_t index = 12u; index < 20u; index++)
1509 {
1510 mb_format[index] = (mss_addr >> (8u * (index - 12u)));
1511 }
1512
1513 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1514 {
1515 status = execute_ss_interrupt_mode(
1516 (uint8_t)MSS_SYS_APB_WRITE_DEBUG_CMD,
1517 mb_format,
1518 (uint16_t)MSS_SYS_APB_SERVICE_DATA_LEN,
1519 NULL_BUFFER,
1520 MSS_SYS_NO_RESPONSE_LEN,
1521 mb_offset,
1522 MSS_SYS_COMMON_RET_OFFSET);
1523 }
1524 else
1525 {
1526 status = execute_ss_polling_mode(
1527 (uint8_t)MSS_SYS_APB_WRITE_DEBUG_CMD,
1528 mb_format,
1529 (uint16_t)MSS_SYS_APB_SERVICE_DATA_LEN,
1530 NULL_BUFFER,
1531 MSS_SYS_NO_RESPONSE_LEN,
1532 mb_offset,
1533 MSS_SYS_COMMON_RET_OFFSET);
1534 }
1535
1536 return status;
1537 }
1538
1539 /***************************************************************************//**
1540 * MSS_SYS_debug_fabric_snapshot()
1541 * See "mss_sysservices.h" for details of how to use this function.
1542 */
1543 uint16_t
MSS_SYS_debug_fabric_snapshot(uint32_t port_addr,uint8_t apb_fast_write,uint16_t mb_offset)1544 MSS_SYS_debug_fabric_snapshot
1545 (
1546 uint32_t port_addr,
1547 uint8_t apb_fast_write,
1548 uint16_t mb_offset
1549 )
1550 {
1551 uint16_t status = MSS_SYS_PARAM_ERR;
1552 uint8_t mb_format[5]={0};
1553
1554 *(uint32_t *)mb_format = port_addr;
1555 mb_format[4] = apb_fast_write;
1556
1557 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1558 {
1559 status = execute_ss_interrupt_mode(
1560 (uint8_t)MSS_SYS_DEBUG_SNAPSHOT_CMD,
1561 mb_format,
1562 (uint16_t)MSS_SYS_DEBUG_SNAPSHOT_DATA_LEN,
1563 NULL_BUFFER,
1564 MSS_SYS_NO_RESPONSE_LEN,
1565 mb_offset,
1566 MSS_SYS_COMMON_RET_OFFSET);
1567 }
1568 else
1569 {
1570 status = execute_ss_polling_mode(
1571 (uint8_t)MSS_SYS_DEBUG_SNAPSHOT_CMD,
1572 mb_format,
1573 (uint16_t)MSS_SYS_DEBUG_SNAPSHOT_DATA_LEN,
1574 NULL_BUFFER,
1575 MSS_SYS_NO_RESPONSE_LEN,
1576 mb_offset,
1577 MSS_SYS_COMMON_RET_OFFSET);
1578 }
1579
1580 return status;
1581 }
1582
1583 /***************************************************************************//**
1584 * MSS_SYS_otp_generate()
1585 * See "mss_sysservices.h" for details of how to use this function.
1586 */
1587 uint16_t
MSS_SYS_otp_generate(uint8_t keymode,uint8_t * n_user,uint8_t * n_fpga,uint16_t mb_offset,uint16_t resp_offset)1588 MSS_SYS_otp_generate
1589 (
1590 uint8_t keymode,
1591 uint8_t* n_user,
1592 uint8_t* n_fpga,
1593 uint16_t mb_offset,
1594 uint16_t resp_offset
1595 )
1596 {
1597 uint16_t status = MSS_SYS_PARAM_ERR;
1598 uint8_t mb_format[20] = {0};
1599 uint8_t index = 0u;
1600
1601 if ((n_user = NULL_BUFFER) || (n_fpga == NULL_BUFFER))
1602 {
1603 return status;
1604 }
1605
1606 mb_format[index] = keymode;
1607
1608 for (index = 0u; index < 16u; index++ )
1609 {
1610 mb_format[index + 4u] = *(n_user + index);
1611 }
1612
1613 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1614 {
1615 status = execute_ss_interrupt_mode(
1616 (uint8_t)MSS_SYS_GENERATE_OTP_CMD,
1617 mb_format,
1618 (uint16_t)MSS_SYS_GENERATE_OTP_DATA_LEN,
1619 n_fpga,
1620 (uint16_t)MSS_SYS_GENERATE_OTP_RESP_LEN,
1621 mb_offset,
1622 resp_offset);
1623 }
1624 else
1625 {
1626 status = execute_ss_polling_mode(
1627 (uint8_t)MSS_SYS_GENERATE_OTP_CMD,
1628 mb_format,
1629 (uint16_t)MSS_SYS_GENERATE_OTP_DATA_LEN,
1630 n_fpga,
1631 (uint16_t)MSS_SYS_GENERATE_OTP_RESP_LEN,
1632 mb_offset,
1633 resp_offset);
1634 }
1635
1636 return status;
1637 }
1638
1639 /***************************************************************************//**
1640 * MSS_SYS_otp_match()
1641 * See "mss_sysservices.h" for details of how to use this function.
1642 */
MSS_SYS_otp_match(uint8_t * user_id,uint8_t * validator,uint8_t * otp,uint16_t mb_offset,uint16_t resp_offset)1643 uint16_t MSS_SYS_otp_match
1644 (
1645 uint8_t * user_id,
1646 uint8_t * validator,
1647 uint8_t * otp,
1648 uint16_t mb_offset,
1649 uint16_t resp_offset
1650 )
1651 {
1652 uint16_t status = MSS_SYS_PARAM_ERR;
1653 uint8_t mb_format[80] = {0};
1654 uint8_t index = 0u;
1655
1656 if ((user_id == NULL_BUFFER) || (validator == NULL_BUFFER))
1657 {
1658 return status;
1659 }
1660
1661 for (index = 0u; index < 80u; index++)
1662 {
1663 if (index < 16u)
1664 {
1665 mb_format[index] = user_id[index];
1666 }
1667 if ((index > 15u) && (index < 48u))
1668 {
1669 mb_format[index] = validator[index - 16u];
1670 }
1671 if (index > 47u)
1672 {
1673 mb_format[index] = otp[index - 48u];
1674 }
1675 }
1676
1677 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1678 {
1679 status = execute_ss_interrupt_mode(
1680 (uint8_t)MSS_SYS_MATCH_OTP_CMD,
1681 mb_format,
1682 (uint16_t)MSS_SYS_MATCH_OTP_DATA_LEN,
1683 NULL_BUFFER,
1684 MSS_SYS_NO_RESPONSE_LEN,
1685 mb_offset,
1686 resp_offset);
1687 }
1688 else
1689 {
1690 status = execute_ss_polling_mode(
1691 (uint8_t)MSS_SYS_MATCH_OTP_CMD,
1692 mb_format,
1693 (uint16_t)MSS_SYS_MATCH_OTP_DATA_LEN,
1694 NULL_BUFFER,
1695 MSS_SYS_NO_RESPONSE_LEN,
1696 mb_offset,
1697 resp_offset);
1698 }
1699
1700 return status;
1701 }
1702
1703 /***************************************************************************//**
1704 * MSS_SYS_unlock_debug_passcode()
1705 * See "mss_sysservices.h" for details of how to use this function.
1706 */
1707 uint16_t
MSS_SYS_unlock_debug_passcode(uint8_t * cmd_data,uint16_t mb_offset,uint16_t resp_offset)1708 MSS_SYS_unlock_debug_passcode
1709 (
1710 uint8_t* cmd_data,
1711 uint16_t mb_offset,
1712 uint16_t resp_offset
1713 )
1714 {
1715 uint16_t status = MSS_SYS_PARAM_ERR;
1716 uint8_t mb_format[32] = {0};
1717 uint8_t index = 0u;
1718
1719 if (cmd_data == NULL_BUFFER)
1720 {
1721 return status;
1722 }
1723
1724 for (index = 0u; index < 32u; index++)
1725 {
1726 mb_format[index] = cmd_data[index];
1727 }
1728
1729 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1730 {
1731 status = execute_ss_interrupt_mode(
1732 (uint8_t)MSS_SYS_UNLOCK_DEBUG_PASSCODE,
1733 cmd_data,
1734 (uint16_t)MSS_SYS_UNLOCK_DEBUG_PASSCODE_DATA_LEN,
1735 NULL_BUFFER,
1736 MSS_SYS_NO_RESPONSE_LEN,
1737 mb_offset,
1738 resp_offset);
1739 }
1740 else
1741 {
1742 status = execute_ss_polling_mode(
1743 (uint8_t)MSS_SYS_UNLOCK_DEBUG_PASSCODE,
1744 cmd_data,
1745 (uint16_t)MSS_SYS_UNLOCK_DEBUG_PASSCODE_DATA_LEN,
1746 NULL_BUFFER,
1747 MSS_SYS_NO_RESPONSE_LEN,
1748 mb_offset,
1749 resp_offset);
1750 }
1751
1752 return status;
1753 }
1754
1755 /***************************************************************************//**
1756 * MSS_SYS_one_way_passcode()
1757 * See "mss_sysservices.h" for details of how to use this function.
1758 */
1759 uint16_t
MSS_SYS_one_way_passcode(uint8_t * msg_id,uint8_t * validator,uint8_t keymode,uint8_t * dsn,uint8_t * hash,uint8_t * plaintext_passcode,uint8_t * hwm,uint16_t mb_offset,uint16_t resp_offset)1760 MSS_SYS_one_way_passcode
1761 (
1762 uint8_t* msg_id,
1763 uint8_t* validator,
1764 uint8_t keymode,
1765 uint8_t* dsn,
1766 uint8_t* hash,
1767 uint8_t* plaintext_passcode,
1768 uint8_t* hwm,
1769 uint16_t mb_offset,
1770 uint16_t resp_offset
1771 )
1772 {
1773 uint16_t status = MSS_SYS_PARAM_ERR;
1774 uint8_t mb_format[480] = {0};
1775 uint16_t index = 0;
1776 for (index = 0u; index < 480u; index++)
1777 {
1778 if ( index < 16u)
1779 {
1780 mb_format[index] = msg_id[index];
1781 }
1782 if ((index > 15u) && (index < 48u))
1783 {
1784 mb_format[index] = validator[index - 16];
1785 }
1786 if ( index == 51u)
1787 {
1788 mb_format[index] = keymode;
1789 }
1790 if ((index > 67u) && (index < 84u))
1791 {
1792 mb_format[index] = dsn[index - 68];
1793 }
1794 if ((index > 351u) && (index < 384u))
1795 {
1796 mb_format[index] = hash[index - 352];
1797 }
1798 if ((index > 383u) && (index < 416u))
1799 {
1800 mb_format[index] = plaintext_passcode[index - 384];
1801 }
1802 if ((index > 415u) && (index < 432u))
1803 {
1804 mb_format[index] = hwm[index];
1805 }
1806 }
1807
1808 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1809 {
1810 status = execute_ss_interrupt_mode(
1811 (uint8_t)MSS_SYS_ONE_WAY_PASSCODE_CMD,
1812 mb_format,
1813 (uint16_t)MSS_SYS_ONE_WAY_PASSCODE_DATA_LEN,
1814 NULL_BUFFER,
1815 MSS_SYS_NO_RESPONSE_LEN,
1816 mb_offset,
1817 resp_offset);
1818 }
1819 else
1820 {
1821 status = execute_ss_polling_mode(
1822 (uint8_t)MSS_SYS_ONE_WAY_PASSCODE_CMD,
1823 mb_format,
1824 (uint16_t)MSS_SYS_ONE_WAY_PASSCODE_DATA_LEN,
1825 NULL_BUFFER,
1826 MSS_SYS_NO_RESPONSE_LEN,
1827 mb_offset,
1828 resp_offset);
1829 }
1830
1831 return status;
1832 }
1833
1834 /***************************************************************************//**
1835 * MSS_SYS_debug_terminate()
1836 * See "mss_sysservices.h" for details of how to use this function.
1837 */
1838 uint16_t
MSS_SYS_debug_terminate(uint16_t mb_offset,uint16_t resp_offset)1839 MSS_SYS_debug_terminate
1840 (
1841 uint16_t mb_offset,
1842 uint16_t resp_offset
1843 )
1844 {
1845 uint16_t status = MSS_SYS_PARAM_ERR;
1846
1847 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1848 {
1849 status = execute_ss_interrupt_mode(
1850 (uint8_t)MSS_SYS_TERMINATE_DEBUG_CMD,
1851 NULL_BUFFER,
1852 MSS_SYS_WITHOUT_CMD_DATA,
1853 NULL_BUFFER,
1854 MSS_SYS_NO_RESPONSE_LEN,
1855 mb_offset,
1856 resp_offset);
1857 }
1858 else
1859 {
1860 status = execute_ss_polling_mode(
1861 (uint8_t)MSS_SYS_TERMINATE_DEBUG_CMD,
1862 NULL_BUFFER,
1863 MSS_SYS_WITHOUT_CMD_DATA,
1864 NULL_BUFFER,
1865 MSS_SYS_NO_RESPONSE_LEN,
1866 mb_offset,
1867 resp_offset);
1868 }
1869
1870 return status;
1871 }
1872
1873 /***************************************************************************//**
1874 * MSS_SYS_read_response()
1875 * See "mss_sysservices.h" for details of how to use this function.
1876 */
MSS_SYS_read_response(void)1877 uint16_t MSS_SYS_read_response
1878 (
1879 void
1880 )
1881 {
1882 uint16_t response_limit = 0u;
1883 uint32_t idx;
1884 uint16_t status = MSS_SYS_PARAM_ERR;
1885
1886 if (g_message_interrupt_counter > 0u)
1887 {
1888 g_message_interrupt_counter = 0u;
1889
1890 if (g_int_service_response_size > 0u)
1891 {
1892 response_limit = g_int_service_response_size +
1893 g_int_service_response_offset;
1894
1895 for (idx = g_int_service_response_offset; idx < response_limit; idx++)
1896 {
1897 gp_int_service_response[idx - g_int_service_response_offset] =
1898 *((uint8_t *)MSS_SCBMAILBOX + idx);
1899 }
1900 }
1901
1902 /* Read the status returned by System Controller*/
1903 status = ((MSS_SCBCTRL->SERVICES_SR & SCBCTRL_SERVICESSR_STATUS_MASK) >>
1904 SCBCTRL_SERVICESSR_STATUS);
1905 }
1906
1907 return status;
1908 }
1909
1910 /***************************************************************************//**
1911 Internal functions.
1912 */
1913
1914 /*
1915 * This function requests the system service to the system controller. It will
1916 * first write the Mailbox input data to the mailbox from the cmd_data if
1917 * required for that service.
1918 *
1919 */
request_system_service(uint8_t cmd_opcode,uint8_t * cmd_data,uint16_t cmd_data_size,uint8_t * p_response,uint16_t response_size,uint16_t mb_offset,uint16_t response_offset)1920 static uint16_t request_system_service
1921 (
1922 uint8_t cmd_opcode,
1923 uint8_t* cmd_data,
1924 uint16_t cmd_data_size,
1925 uint8_t* p_response,
1926 uint16_t response_size,
1927 uint16_t mb_offset,
1928 uint16_t response_offset
1929
1930 )
1931 {
1932 uint32_t idx;
1933 uint16_t ss_command = 0u;
1934 uint32_t* word_buf ;
1935 uint8_t* byte_buf ;
1936 uint8_t byte_off;
1937 uint8_t byte_index;
1938 uint32_t * mailbox_reg;
1939 uint32_t mailbox_val = 0u;
1940
1941 if (MSS_SCBCTRL->SERVICES_SR & SCBCTRL_SERVICESSR_BUSY_MASK)
1942 {
1943 /* System controller is busy with executing service */
1944 return MSS_SYS_BUSY;
1945 }
1946
1947 /* Code for MSS_SYS_PARAM_ERR is not implemented with this version of
1948 driver. */
1949
1950 *MSS_SCBMESSAGE_INT = 0x0u; /* clear message_int reg */
1951
1952 if (g_service_mode == MSS_SYS_SERVICE_INTERRUPT_MODE)
1953 {
1954 gp_int_service_response = (uint8_t*)p_response;
1955 g_int_service_response_offset = response_offset;
1956 g_int_service_response_size = response_size;
1957 }
1958
1959 if (cmd_data_size > 0u)
1960 {
1961 word_buf = (uint32_t*)cmd_data;
1962
1963 /* Write the user data into mail box. */
1964 for (idx = 0u; idx < (cmd_data_size / 4u); idx++)
1965 {
1966 *(MSS_SCBMAILBOX + idx) = word_buf[idx];
1967 }
1968
1969 if ((cmd_data_size % 4u) > 0u)
1970 {
1971 byte_off = (((cmd_data_size / 4u) * 4u));
1972 byte_buf = (uint8_t*)(cmd_data + byte_off);
1973
1974 mailbox_reg = (MSS_SCBMAILBOX + idx);
1975 mailbox_val = *mailbox_reg;
1976
1977 for (byte_index = 0u; byte_index < (cmd_data_size % 4u);
1978 byte_index++)
1979 {
1980 mailbox_val &= ~(0xffu << (byte_index * 8u));
1981 mailbox_val |= (byte_buf[byte_index] << (byte_index * 8u));
1982 }
1983 *mailbox_reg = mailbox_val;
1984 }
1985 }
1986
1987 /* Form the SS command: bit 0to6 is the opcode, bit 7to15 is the Mailbox
1988 * offset For some services this field has another meaning.
1989 * (e.g. for IAP bit-stream auth. it means spi_idx) */
1990 ss_command = ((mb_offset << 7u) | (cmd_opcode & 0x7Fu));
1991
1992 /* Interrupt based implementation of services */
1993 if (MSS_SYS_SERVICE_INTERRUPT_MODE == g_service_mode)
1994 {
1995 MSS_SCBCTRL->SERVICES_CR = (((ss_command << SCBCTRL_SERVICESCR_COMMAND)
1996 & SCBCTRL_SERVICESCR_COMMAND_MASK) |
1997 SCBCTRL_SERVICESCR_REQ_MASK |
1998 SCBCTRL_SERVICESSR_NOTIFY_MASK);
1999 }
2000 else
2001 {
2002 MSS_SCBCTRL->SERVICES_CR = (((ss_command << SCBCTRL_SERVICESCR_COMMAND)
2003 & SCBCTRL_SERVICESCR_COMMAND_MASK) |
2004 SCBCTRL_SERVICESCR_REQ_MASK);
2005
2006 }
2007
2008 /* Service requested successfully */
2009 return MSS_SYS_SUCCESS;
2010 }
2011
2012 /* This function executes the SS command in interrupt mode. If Mailbox input data
2013 * is required by the service, the call to request_system_service() function will
2014 * first load it from cmd_data into the Mailbox. The response of the service is
2015 * not read by this function as it depends on message interrupt. Application
2016 * will have to read the response of service by calling MSS_SYS_read_response(),
2017 * only after interrupt occurs. */
execute_ss_interrupt_mode(uint8_t cmd_opcode,uint8_t * cmd_data,uint16_t cmd_data_size,uint8_t * p_response,uint16_t response_size,uint16_t mb_offset,uint16_t response_offset)2018 static uint16_t execute_ss_interrupt_mode
2019 (
2020 uint8_t cmd_opcode,
2021 uint8_t* cmd_data,
2022 uint16_t cmd_data_size,
2023 uint8_t* p_response,
2024 uint16_t response_size,
2025 uint16_t mb_offset,
2026 uint16_t response_offset
2027 )
2028 {
2029
2030 uint16_t status;
2031 status = request_system_service(cmd_opcode, cmd_data, cmd_data_size,
2032 p_response, response_size, mb_offset,
2033 response_offset);
2034
2035 return status;
2036 }
2037
2038 /* This function executes the SS command in polling mode. If Mailbox input data
2039 * is required by the it will first load it from cmd_data into the Mailbox.
2040 * After requesting the service it will poll the request and busy bit. If the
2041 * service requires the response data to be read from mailbox, it will read the
2042 * mailbox contents and store it in p_response buffer.
2043 */
execute_ss_polling_mode(uint8_t cmd_opcode,uint8_t * cmd_data,uint16_t cmd_data_size,uint8_t * p_response,uint16_t response_size,uint16_t mb_offset,uint16_t response_offset)2044 static uint16_t execute_ss_polling_mode
2045 (
2046 uint8_t cmd_opcode,
2047 uint8_t* cmd_data,
2048 uint16_t cmd_data_size,
2049 uint8_t* p_response,
2050 uint16_t response_size,
2051 uint16_t mb_offset,
2052 uint16_t response_offset
2053 )
2054 {
2055 uint32_t idx;
2056 uint16_t status = 0u;
2057 uint16_t response_limit = 0u;
2058 uint8_t* response_buf;
2059
2060 status = request_system_service(cmd_opcode, cmd_data, cmd_data_size,
2061 p_response,response_size, mb_offset,
2062 response_offset);
2063
2064 if (status == MSS_SYS_SUCCESS)
2065 {
2066 /* REQ bit will remain set till the system controller starts
2067 * processing command. Since DRI is slow interface, we are waiting
2068 * here to make sure System controller has started processing
2069 * command*/
2070 while (SCBCTRL_SERVICESCR_REQ_MASK == (MSS_SCBCTRL->SERVICES_CR &
2071 SCBCTRL_SERVICESCR_REQ_MASK))
2072 {
2073 ;
2074 }
2075
2076 /* Once system controller starts processing command The busy bit will
2077 * go 1. Make sure that service is complete i.e. BUSY bit is gone 0 */
2078 while (SCBCTRL_SERVICESSR_BUSY_MASK == (MSS_SCBCTRL->SERVICES_SR &
2079 SCBCTRL_SERVICESSR_BUSY_MASK))
2080 {
2081 ;
2082 }
2083
2084 if (response_size > 0u)
2085 {
2086 response_limit = response_size + response_offset;
2087 response_buf = (uint8_t*)p_response;
2088
2089 for (idx = response_offset; idx < response_limit; idx++)
2090 {
2091 response_buf[idx - response_offset] =
2092 *((uint8_t *)MSS_SCBMAILBOX + idx);
2093 }
2094 }
2095
2096 /* Read the status returned by System Controller */
2097 status = ((MSS_SCBCTRL->SERVICES_SR & SCBCTRL_SERVICESSR_STATUS_MASK) >>
2098 SCBCTRL_SERVICESSR_STATUS);
2099 }
2100 else
2101 {
2102 status = MSS_SYS_BUSY;
2103 }
2104
2105 return status;
2106 }
2107
2108 /***************************************************************************//**
2109 * Interrupt service routine triggered by message interrupt.
2110 * This routine will call handler function which will read the service response
2111 * in interrupt mode of operation.
2112 */
2113 uint8_t
g5c_message_plic_IRQHandler(void)2114 g5c_message_plic_IRQHandler
2115 (
2116 void
2117 )
2118 {
2119 g_message_interrupt_counter++;
2120
2121 volatile uint32_t reg = *MSS_SCBMESSAGE; /* read message reg. */
2122 reg = *MSS_SCBMESSAGE_INT;
2123 *MSS_SCBMESSAGE_INT = 0x0u; /* clear message_int reg */
2124 reg = *MSS_SCBMESSAGE_INT;
2125
2126 mss_sys_interrupt_handler();
2127
2128 return 0;
2129 }
2130
2131 #ifdef __cplusplus
2132 }
2133 #endif
2134