]> git.sur5r.net Git - freertos/blob
e7453b51fc6cf025bc9047e3a3f79d349dc822b3
[freertos] /
1 /*******************************************************************************\r
2  * (c) Copyright 2012 Microsemi SoC Products Group.  All rights reserved.\r
3  *\r
4  * SmartFusion2 system services.\r
5  *\r
6  * SVN $Revision: 5615 $\r
7  * SVN $Date: 2013-04-05 14:48:10 +0100 (Fri, 05 Apr 2013) $\r
8  */\r
9 #include "mss_sys_services.h"\r
10 #include "mss_comblk.h"\r
11 #include "../../CMSIS/mss_assert.h"\r
12 #include <string.h>\r
13 \r
14 /*==============================================================================\r
15  *\r
16  */\r
17 /*\r
18  * Service request command opcodes:\r
19  */\r
20 #define DEVICE_CERTIFICATE_REQUEST_CMD      0u\r
21 #define SERIAL_NUMBER_REQUEST_CMD           1u\r
22 #define FLASH_FREEZE_REQUEST_CMD            2u\r
23 #define AES128_REQUEST_CMD                  3u\r
24 #define USERCODE_REQUEST_CMD                4u\r
25 #define DESIGNVER_REQUEST_CMD               5u\r
26 #define AES256_REQUEST_CMD                  6u\r
27 #define KEYTREE_REQUEST_CMD                 9u\r
28 #define SHA256_REQUEST_CMD                  10u\r
29 #define HMAC_REQUEST_CMD                    12u\r
30 #define PPUF_CHALLENGE_RESP_REQUEST_CMD     14u\r
31 #define ISP_PROGRAMMING_REQUEST_CMD         21u\r
32 #define DIGEST_CHECK_REQUEST_CMD            23u\r
33 #define NRBG_SELF_TEST_REQUEST_CMD          40u\r
34 #define NRBG_INSTANTIATE_REQUEST_CMD        41u\r
35 #define NRBG_GENERATE_REQUEST_CMD           42u\r
36 #define NRBG_RESEED_REQUEST_CMD             43u\r
37 #define NRBG_UNINSTANTIATE_REQUEST_CMD      44u\r
38 #define NRBG_RESET_REQUEST_CMD              45u\r
39 #define FLASHFREEZE_SHUTDOWN_CMD            224u\r
40 #define ZEROIZATION_REQUEST_CMD             240u\r
41 \r
42 #define POWER_ON_RESET_DIGEST_ERROR_CMD     241u\r
43 \r
44 /*\r
45  * System Services requests length:\r
46  */\r
47 #define FLASH_FREEZE_REQUEST_LENGTH         2u\r
48 \r
49 /*\r
50  * Service response lengths:\r
51  */\r
52 #define STANDARD_SERV_RESP_LENGTH           6u\r
53 \r
54 #define SERIAL_NUMBER_SERV_RESP_LENGTH      6u\r
55 #define USERCODE_SERV_RESP_LENGTH           6u\r
56 #define DESIGNVER_SERV_RESP_LENGTH          6u\r
57 #define DEVICE_CERT_SERV_RESP_LENGTH        6u\r
58 #define ISP_PROG_SERV_RESP_LENGTH           2u\r
59 #define NRBG_RESET_SERV_RESP_LENGTH         2u\r
60 #define NRBG_SELF_TEST_SERV_RESP_LENGTH     2u\r
61 #define NRBG_UNINST_SERV_RESP_LENGTH        3u\r
62 \r
63 #define DIGEST_CHECK_SERV_RESP_LENGTH       2u\r
64 #define FLASH_FREEZE_SERV_RESP_LENGTH       2u\r
65 \r
66 /*\r
67  * Non Deterministic Random Bit Generator defines:\r
68  */\r
69 #define INVALID_NRBG_HANDLE     0xFFu\r
70 \r
71 /*\r
72  * RTC_WAKEUP_CR system register bit masks:\r
73  */\r
74 #define RTC_WAKEUP_G4C_EN_MASK      0x00000004u\r
75 #define RTC_WAKEUP_FAB_EN_MASK      0x00000002u\r
76 \r
77 /*==============================================================================\r
78  * Local functions.\r
79  */\r
80 static void request_completion_handler(uint8_t * p_response, uint16_t response_size);\r
81 static void signal_request_start(void);\r
82 static uint16_t wait_for_request_completion(void);\r
83 static uint8_t execute_service\r
84 (\r
85     uint8_t cmd_opcode,\r
86     uint8_t * cmd_params_ptr,\r
87     uint8_t * response,\r
88     uint16_t response_length\r
89 );\r
90 \r
91 static void asynchronous_event_handler(uint8_t event_opcode);\r
92 \r
93 static void write_ptr_value_into_array\r
94 (\r
95     const uint8_t * pointer,\r
96     uint8_t target_array[],\r
97     uint32_t array_index\r
98 );\r
99 \r
100 /*==============================================================================\r
101  * Global variables\r
102  */\r
103 static volatile uint8_t g_request_in_progress = 0u;\r
104 static volatile uint16_t g_last_response_length = 0u;\r
105 static sys_serv_async_event_handler_t g_event_handler = 0;\r
106 \r
107 /*==============================================================================\r
108  *\r
109  */\r
110 void MSS_SYS_init(sys_serv_async_event_handler_t event_handler)\r
111 {\r
112     MSS_COMBLK_init(asynchronous_event_handler);\r
113     \r
114     g_event_handler = event_handler;\r
115     \r
116     g_request_in_progress = 0u;\r
117     g_last_response_length = 0u;\r
118 }\r
119 \r
120 /*==============================================================================\r
121  *\r
122  */\r
123 static void asynchronous_event_handler(uint8_t event_opcode)\r
124 {\r
125     if(g_event_handler != 0)\r
126     {\r
127     switch(event_opcode)\r
128         {\r
129             case FLASH_FREEZE_SHUTDOWN_OPCODE:\r
130             case FLASH_FREEZE_EXIT_OPCODE:\r
131                 g_event_handler(event_opcode);\r
132             break;\r
133             \r
134             default:\r
135                 /* Ignore all other events. */\r
136             break;\r
137         }\r
138     }\r
139 }\r
140 \r
141 /*==============================================================================\r
142  * See mss_sys_services.h for details.\r
143  */\r
144 uint8_t MSS_SYS_get_serial_number\r
145 (\r
146     uint8_t * p_serial_number\r
147 )\r
148 {\r
149     uint8_t response[SERIAL_NUMBER_SERV_RESP_LENGTH];\r
150     uint8_t status;\r
151     \r
152     status = execute_service(SERIAL_NUMBER_REQUEST_CMD,\r
153                              p_serial_number,\r
154                              response,\r
155                              SERIAL_NUMBER_SERV_RESP_LENGTH);\r
156     \r
157     return status;\r
158 }\r
159 \r
160 /*==============================================================================\r
161  * See mss_sys_services.h for details.\r
162  */\r
163 uint8_t MSS_SYS_get_user_code\r
164 (\r
165     uint8_t * p_user_code\r
166 )\r
167 {\r
168     uint8_t response[USERCODE_SERV_RESP_LENGTH];\r
169     uint8_t status;\r
170     \r
171     status = execute_service(USERCODE_REQUEST_CMD,\r
172                              p_user_code,\r
173                              response,\r
174                              USERCODE_SERV_RESP_LENGTH);\r
175     \r
176     return status;\r
177 }\r
178 \r
179 /*==============================================================================\r
180  * See mss_sys_services.h for details.\r
181  */\r
182 uint8_t MSS_SYS_get_design_version\r
183 (\r
184     uint8_t * p_design_version\r
185 )\r
186 {\r
187     uint8_t response[DESIGNVER_SERV_RESP_LENGTH];\r
188     uint8_t status;\r
189     \r
190     status = execute_service(DESIGNVER_REQUEST_CMD,\r
191                              p_design_version,\r
192                              response,\r
193                              DESIGNVER_SERV_RESP_LENGTH);\r
194     \r
195     return status;\r
196 }\r
197 \r
198 /*==============================================================================\r
199  * See mss_sys_services.h for details.\r
200  */\r
201 uint8_t MSS_SYS_get_device_certificate\r
202 (\r
203     uint8_t * p_device_certificate\r
204 )\r
205 {\r
206     uint8_t response[DEVICE_CERT_SERV_RESP_LENGTH];\r
207     uint8_t status;\r
208     \r
209     status = execute_service(DEVICE_CERTIFICATE_REQUEST_CMD,\r
210                              p_device_certificate,\r
211                              response,\r
212                              DEVICE_CERT_SERV_RESP_LENGTH);\r
213     \r
214     return status;\r
215 }\r
216 \r
217 /*==============================================================================\r
218  * See mss_sys_services.h for details.\r
219  */\r
220 uint8_t MSS_SYS_flash_freeze(uint8_t options)\r
221 {\r
222     uint8_t status;\r
223     uint16_t actual_response_length;\r
224     uint8_t flash_freeze_req[FLASH_FREEZE_REQUEST_LENGTH];\r
225     uint8_t response[FLASH_FREEZE_SERV_RESP_LENGTH];\r
226 \r
227     /*\r
228      * The Flash Freeze system service is not available on M2S050 rev A and rev B.\r
229      */\r
230     ASSERT(0x0000F802u != SYSREG->DEVICE_VERSION);\r
231     ASSERT(0x0001F802u != SYSREG->DEVICE_VERSION);\r
232     \r
233     /*\r
234      * Enable RTC wake-up interrupt to System Controller and FPGA fabric.\r
235      */\r
236     SYSREG->RTC_WAKEUP_CR |= (RTC_WAKEUP_G4C_EN_MASK | RTC_WAKEUP_FAB_EN_MASK);\r
237 \r
238     signal_request_start();\r
239 \r
240     flash_freeze_req[0] = FLASH_FREEZE_REQUEST_CMD;\r
241     flash_freeze_req[1] = options;\r
242 \r
243     MSS_COMBLK_send_cmd(flash_freeze_req,               /* p_cmd */\r
244                         FLASH_FREEZE_REQUEST_LENGTH,    /* cmd_size */\r
245                         0,                              /* p_data */\r
246                         0u,                             /* data_size */\r
247                         response,                       /* p_response */\r
248                         FLASH_FREEZE_SERV_RESP_LENGTH,  /* response_size */\r
249                         request_completion_handler);    /* completion_handler */\r
250 \r
251     actual_response_length = wait_for_request_completion();\r
252     \r
253     if((FLASH_FREEZE_SERV_RESP_LENGTH == actual_response_length) &&\r
254        (FLASH_FREEZE_REQUEST_CMD == response[0]))\r
255     {\r
256         status = response[1];\r
257     }\r
258     else\r
259     {\r
260         status = MSS_SYS_UNEXPECTED_ERROR;\r
261     }\r
262     \r
263     return status;\r
264 }\r
265 \r
266 /*==============================================================================\r
267  * See mss_sys_services.h for details.\r
268  */\r
269 #define AES128_KEY_LENGTH   16u\r
270 #define IV_LENGTH           16u\r
271 \r
272 #define AES256_KEY_LENGTH   32u\r
273 \r
274 #define HMAC_KEY_LENGTH     32u\r
275 \r
276 uint8_t MSS_SYS_128bit_aes\r
277 (\r
278     const uint8_t * key,\r
279     const uint8_t * iv,\r
280     uint16_t nb_blocks,\r
281     uint8_t mode,\r
282     uint8_t * dest_addr,\r
283     const uint8_t * src_addr)\r
284 {\r
285     uint8_t response[STANDARD_SERV_RESP_LENGTH];\r
286     uint8_t params[44];\r
287     uint8_t status;\r
288     \r
289     memcpy(&params[0], key, AES128_KEY_LENGTH);\r
290     memcpy(&params[16], iv, IV_LENGTH);\r
291     \r
292     params[32] = (uint8_t)nb_blocks;\r
293     params[33] = (uint8_t)(nb_blocks >> 8u);\r
294     params[34] = mode;\r
295     params[35] = 0u;\r
296 #if 1\r
297     write_ptr_value_into_array(dest_addr, params, 36u);\r
298     write_ptr_value_into_array(src_addr, params, 40u);\r
299 #else    \r
300     params[36] = (uint8_t)((uint32_t)dest_addr);\r
301     params[37] = (uint8_t)((uint32_t)dest_addr >> 8u);\r
302     params[38] = (uint8_t)((uint32_t)dest_addr >> 16u);\r
303     params[39] = (uint8_t)((uint32_t)dest_addr >> 24u);\r
304 \r
305     params[40] = (uint8_t)((uint32_t)src_addr);\r
306     params[41] = (uint8_t)((uint32_t)src_addr >> 8u);\r
307     params[42] = (uint8_t)((uint32_t)src_addr >> 16u);\r
308     params[43] = (uint8_t)((uint32_t)src_addr >> 24u);\r
309 #endif\r
310     status = execute_service(AES128_REQUEST_CMD,\r
311                              params,\r
312                              response,\r
313                              STANDARD_SERV_RESP_LENGTH);\r
314                              \r
315     return status;\r
316 }\r
317 \r
318 /*==============================================================================\r
319  * See mss_sys_services.h for details.\r
320  */\r
321 uint8_t MSS_SYS_256bit_aes\r
322\r
323     const uint8_t * key,\r
324     const uint8_t * iv,\r
325     uint16_t nb_blocks,\r
326     uint8_t mode,\r
327     uint8_t * dest_addr,\r
328     const uint8_t * src_addr\r
329 )\r
330 {\r
331     uint8_t response[STANDARD_SERV_RESP_LENGTH];\r
332     uint8_t params[60];\r
333     uint8_t status;\r
334     \r
335     memcpy(&params[0], key, AES256_KEY_LENGTH);\r
336     memcpy(&params[32], iv, IV_LENGTH);\r
337     \r
338     params[48] = (uint8_t)nb_blocks;\r
339     params[49] = (uint8_t)(nb_blocks >> 8u);\r
340     params[50] = mode;\r
341     params[51] = 0u;\r
342 #if 1\r
343     write_ptr_value_into_array(dest_addr, params, 52u);\r
344     write_ptr_value_into_array(src_addr, params, 56u);\r
345 #else    \r
346     params[52] = (uint8_t)((uint32_t)dest_addr);\r
347     params[53] = (uint8_t)((uint32_t)dest_addr >> 8u);\r
348     params[54] = (uint8_t)((uint32_t)dest_addr >> 16u);\r
349     params[55] = (uint8_t)((uint32_t)dest_addr >> 24u);\r
350 \r
351     params[56] = (uint8_t)((uint32_t)src_addr);\r
352     params[57] = (uint8_t)((uint32_t)src_addr >> 8u);\r
353     params[58] = (uint8_t)((uint32_t)src_addr >> 16u);\r
354     params[59] = (uint8_t)((uint32_t)src_addr >> 24u);\r
355 #endif\r
356     status = execute_service(AES256_REQUEST_CMD,\r
357                              params,\r
358                              response,\r
359                              STANDARD_SERV_RESP_LENGTH);\r
360                              \r
361     return status;\r
362 }\r
363 \r
364 /*==============================================================================\r
365  * See mss_sys_services.h for details.\r
366  */\r
367 uint8_t MSS_SYS_sha256\r
368 (\r
369     const uint8_t * p_data_in,\r
370     uint32_t length,\r
371     uint8_t * result\r
372 )\r
373 {\r
374     uint8_t response[STANDARD_SERV_RESP_LENGTH];\r
375     uint8_t params[12];\r
376     uint8_t status;\r
377     \r
378     params[0] = (uint8_t)((uint32_t)length);\r
379     params[1] = (uint8_t)((uint32_t)length >> 8u);\r
380     params[2] = (uint8_t)((uint32_t)length >> 16u);\r
381     params[3] = (uint8_t)((uint32_t)length >> 24u);\r
382     \r
383 #if 1\r
384     write_ptr_value_into_array(result, params, 4u);\r
385     write_ptr_value_into_array(p_data_in, params, 8u);\r
386 #else\r
387     params[4] = (uint8_t)((uint32_t)result);\r
388     params[5] = (uint8_t)((uint32_t)result >> 8u);\r
389     params[6] = (uint8_t)((uint32_t)result >> 16u);\r
390     params[7] = (uint8_t)((uint32_t)result >> 24u);\r
391 \r
392     params[8] = (uint8_t)((uint32_t)p_data_in);\r
393     params[9] = (uint8_t)((uint32_t)p_data_in >> 8u);\r
394     params[10] = (uint8_t)((uint32_t)p_data_in >> 16u);\r
395     params[11] = (uint8_t)((uint32_t)p_data_in >> 24u);\r
396 #endif\r
397     status = execute_service(SHA256_REQUEST_CMD,\r
398                              params,\r
399                              response,\r
400                              STANDARD_SERV_RESP_LENGTH);\r
401                              \r
402     return status;\r
403 }\r
404 \r
405 /*==============================================================================\r
406  * See mss_sys_services.h for details.\r
407  */\r
408 uint8_t MSS_SYS_hmac\r
409 (\r
410     const uint8_t * key,\r
411     const uint8_t * p_data_in,\r
412     uint32_t length,\r
413     uint8_t * p_result\r
414 )\r
415 {\r
416     uint8_t response[STANDARD_SERV_RESP_LENGTH];\r
417     uint8_t params[58];\r
418     uint8_t status;\r
419     \r
420     memcpy(&params[0], key, HMAC_KEY_LENGTH);\r
421     \r
422     params[32] = (uint8_t)((uint32_t)length);\r
423     params[33] = (uint8_t)((uint32_t)length >> 8u);\r
424     params[34] = (uint8_t)((uint32_t)length >> 16u);\r
425     params[35] = (uint8_t)((uint32_t)length >> 24u);\r
426 #if 1\r
427     write_ptr_value_into_array(p_data_in, params, 36u);\r
428     write_ptr_value_into_array(p_result, params, 40u);\r
429 #else    \r
430     params[36] = (uint8_t)((uint32_t)p_data_in);\r
431     params[37] = (uint8_t)((uint32_t)p_data_in >> 8u);\r
432     params[38] = (uint8_t)((uint32_t)p_data_in >> 16u);\r
433     params[39] = (uint8_t)((uint32_t)p_data_in >> 24u);\r
434 \r
435     params[40] = (uint8_t)((uint32_t)p_result);\r
436     params[41] = (uint8_t)((uint32_t)p_result >> 8u);\r
437     params[42] = (uint8_t)((uint32_t)p_result >> 16u);\r
438     params[43] = (uint8_t)((uint32_t)p_result >> 24u);\r
439 #endif\r
440     status = execute_service(HMAC_REQUEST_CMD,\r
441                              params,\r
442                              response,\r
443                              STANDARD_SERV_RESP_LENGTH);\r
444                              \r
445     return status;\r
446 }\r
447 \r
448 /*==============================================================================\r
449  * See mss_sys_services.h for details.\r
450  */\r
451 uint8_t MSS_SYS_nrbg_self_test(void)\r
452 {\r
453     uint8_t status;\r
454     uint16_t actual_response_length;\r
455     uint8_t self_test;\r
456     uint8_t response[NRBG_SELF_TEST_SERV_RESP_LENGTH];\r
457     \r
458     signal_request_start();\r
459     \r
460     self_test = NRBG_SELF_TEST_REQUEST_CMD;\r
461 \r
462     MSS_COMBLK_send_cmd(&self_test,                         /* p_cmd */\r
463                         sizeof(self_test),                  /* cmd_size */\r
464                         0,                                  /* p_data */\r
465                         0,                                  /* data_size */\r
466                         response,                           /* p_response */\r
467                         NRBG_SELF_TEST_SERV_RESP_LENGTH,    /* response_size */\r
468                         request_completion_handler);        /* completion_handler */\r
469     \r
470     actual_response_length = wait_for_request_completion();\r
471     \r
472     if((NRBG_SELF_TEST_SERV_RESP_LENGTH == actual_response_length) &&\r
473        (NRBG_SELF_TEST_REQUEST_CMD == response[0]))\r
474     {\r
475         status = response[1];\r
476     }\r
477     else\r
478     {\r
479         status = MSS_SYS_UNEXPECTED_ERROR;\r
480     }\r
481     \r
482     return status;\r
483 }\r
484 \r
485 /*==============================================================================\r
486  * See mss_sys_services.h for details.\r
487  */\r
488 uint8_t MSS_SYS_nrbg_instantiate\r
489 (\r
490     const uint8_t * personalization_str,\r
491     uint16_t personalization_str_length,\r
492     uint8_t * p_nrbg_handle\r
493 )\r
494 {\r
495     uint8_t response[STANDARD_SERV_RESP_LENGTH];\r
496     uint8_t intantiate_params[7];\r
497     uint8_t status;\r
498 #if 1\r
499     write_ptr_value_into_array(personalization_str, intantiate_params, 0u);\r
500 #else    \r
501     intantiate_params[0] = (uint8_t)((uint32_t)personalization_str);\r
502     intantiate_params[1] = (uint8_t)((uint32_t)personalization_str >> 8u);\r
503     intantiate_params[2] = (uint8_t)((uint32_t)personalization_str >> 16u);\r
504     intantiate_params[3] = (uint8_t)((uint32_t)personalization_str >> 24u);\r
505 #endif\r
506     intantiate_params[4] = (uint8_t)personalization_str_length;\r
507     intantiate_params[5] = (uint8_t)(personalization_str_length >> 8u);\r
508     intantiate_params[6] = INVALID_NRBG_HANDLE;\r
509     \r
510     status = execute_service(NRBG_INSTANTIATE_REQUEST_CMD,\r
511                              intantiate_params,\r
512                              response,\r
513                              STANDARD_SERV_RESP_LENGTH);\r
514                              \r
515     if(MSS_SYS_SUCCESS == status)\r
516     {\r
517         *p_nrbg_handle = intantiate_params[6];\r
518     }\r
519     \r
520     return status;\r
521 }\r
522 \r
523 /*==============================================================================\r
524  * See mss_sys_services.h for details.\r
525  */\r
526 uint8_t MSS_SYS_nrbg_generate\r
527 (\r
528     const uint8_t * p_requested_data,\r
529     const uint8_t * p_additional_input,\r
530     uint8_t requested_length,\r
531     uint8_t additional_input_length,\r
532     uint8_t pr_req,\r
533     uint8_t nrbg_handle\r
534 )\r
535 {\r
536     uint8_t response[STANDARD_SERV_RESP_LENGTH];\r
537     uint8_t generate_params[12];\r
538     uint8_t status;\r
539 #if 1\r
540     write_ptr_value_into_array(p_requested_data, generate_params, 0u);\r
541     write_ptr_value_into_array(p_additional_input, generate_params, 4u);\r
542 #else\r
543     generate_params[0] = (uint8_t)((uint32_t)p_requested_data);\r
544     generate_params[1] = (uint8_t)((uint32_t)p_requested_data >> 8u);\r
545     generate_params[2] = (uint8_t)((uint32_t)p_requested_data >> 16u);\r
546     generate_params[3] = (uint8_t)((uint32_t)p_requested_data >> 24u);\r
547     generate_params[4] = (uint8_t)((uint32_t)p_additional_input);\r
548     generate_params[5] = (uint8_t)((uint32_t)p_additional_input >> 8u);\r
549     generate_params[6] = (uint8_t)((uint32_t)p_additional_input >> 16u);\r
550     generate_params[7] = (uint8_t)((uint32_t)p_additional_input >> 24u);\r
551 #endif\r
552     generate_params[8] = requested_length;\r
553     generate_params[9] = additional_input_length;\r
554     generate_params[10] = pr_req;\r
555     generate_params[11] = nrbg_handle;\r
556     \r
557     status = execute_service(NRBG_GENERATE_REQUEST_CMD,\r
558                              generate_params,\r
559                              response,\r
560                              STANDARD_SERV_RESP_LENGTH);\r
561     \r
562     return status;\r
563 }\r
564 \r
565 /*==============================================================================\r
566  * See mss_sys_services.h for details.\r
567  */\r
568 uint8_t MSS_SYS_nrbg_reseed\r
569 (\r
570     const uint8_t * p_additional_input,\r
571     uint8_t additional_input_length,\r
572     uint8_t nrbg_handle\r
573 )\r
574 {\r
575     uint8_t response[STANDARD_SERV_RESP_LENGTH];\r
576     uint8_t params[6];\r
577     uint8_t status;\r
578 #if 1\r
579     write_ptr_value_into_array(p_additional_input, params, 0u);\r
580 #else\r
581     params[0] = (uint8_t)((uint32_t)p_additional_input);\r
582     params[1] = (uint8_t)((uint32_t)p_additional_input >> 8u);\r
583     params[2] = (uint8_t)((uint32_t)p_additional_input >> 16u);\r
584     params[3] = (uint8_t)((uint32_t)p_additional_input >> 24u);\r
585 #endif\r
586     params[4] = (uint8_t)additional_input_length;\r
587     params[5] = nrbg_handle;\r
588     \r
589     status = execute_service(NRBG_RESEED_REQUEST_CMD,\r
590                              params,\r
591                              response,\r
592                              STANDARD_SERV_RESP_LENGTH);\r
593     \r
594     return status;\r
595 }\r
596 \r
597 /*==============================================================================\r
598  * See mss_sys_services.h for details.\r
599  */\r
600 uint8_t MSS_SYS_nrbg_uninstantiate\r
601 (\r
602     uint8_t nrbg_handle\r
603 )\r
604 {\r
605     uint8_t status;\r
606     uint16_t actual_response_length;\r
607     uint8_t uninstantiate_req[2];\r
608     uint8_t response[NRBG_UNINST_SERV_RESP_LENGTH];\r
609     \r
610     signal_request_start();\r
611     \r
612     uninstantiate_req[0] = NRBG_UNINSTANTIATE_REQUEST_CMD;\r
613     uninstantiate_req[1] = nrbg_handle;\r
614 \r
615     MSS_COMBLK_send_cmd(uninstantiate_req,              /* p_cmd */\r
616                         sizeof(uninstantiate_req),      /* cmd_size */\r
617                         0,                              /* p_data */\r
618                         0,                              /* data_size */\r
619                         response,                       /* p_response */\r
620                         NRBG_UNINST_SERV_RESP_LENGTH,   /* response_size */\r
621                         request_completion_handler);    /* completion_handler */\r
622     \r
623     actual_response_length = wait_for_request_completion();\r
624     \r
625     if((NRBG_UNINST_SERV_RESP_LENGTH == actual_response_length) &&\r
626        (NRBG_UNINSTANTIATE_REQUEST_CMD == response[0]))\r
627     {\r
628         status = response[1];\r
629     }\r
630     else\r
631     {\r
632         status = MSS_SYS_UNEXPECTED_ERROR;\r
633     }\r
634     \r
635     return status;\r
636 }\r
637 \r
638 /*==============================================================================\r
639  * See mss_sys_services.h for details.\r
640  */\r
641 static uint8_t g_isp_response[ISP_PROG_SERV_RESP_LENGTH];\r
642 void (*g_isp_completion_handler)(uint32_t) = 0;\r
643 \r
644 static void isp_sys_completion_handler\r
645 (\r
646     uint8_t * p_response, \r
647     uint16_t length\r
648 )\r
649 {\r
650     if(g_isp_completion_handler != 0)\r
651     {\r
652         g_isp_completion_handler(p_response[1]);\r
653     }\r
654 }\r
655 \r
656 void MSS_SYS_start_isp\r
657 (\r
658     uint8_t mode,\r
659     uint32_t (*page_read_handler)(uint8_t const **),\r
660     void (*isp_completion_handler)(uint32_t)\r
661 )\r
662 {\r
663     uint8_t isp_prog_request[2];\r
664     \r
665     signal_request_start();\r
666     \r
667     isp_prog_request[0] = ISP_PROGRAMMING_REQUEST_CMD;\r
668     isp_prog_request[1] = mode;\r
669     \r
670     g_isp_completion_handler = isp_completion_handler;\r
671 \r
672     MSS_COMBLK_send_paged_cmd(isp_prog_request,                 /* p_cmd */\r
673                               sizeof(isp_prog_request),         /* cmd_size */\r
674                               g_isp_response,                   /* p_response */\r
675                               ISP_PROG_SERV_RESP_LENGTH, /* response_size */\r
676                               page_read_handler,                /* page_handler */\r
677                               isp_sys_completion_handler);      /* completion_handler */\r
678 }\r
679 \r
680 /*==============================================================================\r
681  * See mss_sys_services.h for details.\r
682  */\r
683 uint8_t MSS_SYS_check_digest\r
684 (\r
685     uint8_t options\r
686 )\r
687 {\r
688     uint8_t status;\r
689     uint16_t actual_response_length;\r
690     uint8_t digest_check_req[2];\r
691     uint8_t response[DIGEST_CHECK_SERV_RESP_LENGTH];\r
692     \r
693     signal_request_start();\r
694     \r
695     digest_check_req[0] = DIGEST_CHECK_REQUEST_CMD;\r
696     digest_check_req[1] = options;\r
697 \r
698     MSS_COMBLK_send_cmd(digest_check_req,               /* p_cmd */\r
699                         sizeof(digest_check_req),       /* cmd_size */\r
700                         0,                              /* p_data */\r
701                         0u,                             /* data_size */\r
702                         response,                       /* p_response */\r
703                         DIGEST_CHECK_SERV_RESP_LENGTH,  /* response_size */\r
704                         request_completion_handler);    /* completion_handler */\r
705     \r
706     actual_response_length = wait_for_request_completion();\r
707     \r
708     if((DIGEST_CHECK_SERV_RESP_LENGTH == actual_response_length) &&\r
709        (DIGEST_CHECK_REQUEST_CMD == response[0]))\r
710     {\r
711         status = response[1];\r
712     }\r
713     else\r
714     {\r
715         status = MSS_SYS_UNEXPECTED_ERROR;\r
716     }\r
717     \r
718     return status;\r
719 }\r
720 \r
721 /*==============================================================================\r
722  *\r
723  */\r
724 static uint8_t execute_service\r
725 (\r
726     uint8_t cmd_opcode,\r
727     uint8_t * cmd_params_ptr,\r
728     uint8_t * response,\r
729     uint16_t response_length\r
730 )\r
731 {\r
732     uint8_t status;\r
733     uint16_t actual_response_length;\r
734     \r
735     signal_request_start();\r
736     \r
737     MSS_COMBLK_send_cmd_with_ptr(cmd_opcode,                    /* cmd_opcode */\r
738                                  (uint32_t)cmd_params_ptr,      /* cmd_params_ptr */\r
739                                  response,                      /* p_response */\r
740                                  response_length,               /* response_size */\r
741                                  request_completion_handler);   /* completion_handler */\r
742     \r
743     actual_response_length = wait_for_request_completion();\r
744     \r
745     if((response_length == actual_response_length) && (cmd_opcode == response[0]))\r
746     {\r
747         status = response[1];\r
748     }\r
749     else\r
750     {\r
751         status = MSS_SYS_UNEXPECTED_ERROR;\r
752     }\r
753     \r
754     return status;\r
755 }\r
756 \r
757 /*==============================================================================\r
758  *\r
759  */\r
760 static void request_completion_handler\r
761 (\r
762     uint8_t * p_response,\r
763     uint16_t response_size\r
764 )\r
765 {\r
766     g_request_in_progress = 0u;\r
767     g_last_response_length = response_size;\r
768 }\r
769 \r
770 /*==============================================================================\r
771  *\r
772  */\r
773 static void signal_request_start(void)\r
774 {\r
775     /* Wait for current request to complete. */\r
776     while(g_request_in_progress)\r
777     {\r
778         ;\r
779     }\r
780     \r
781     g_request_in_progress = 1u;\r
782     g_last_response_length = 0u;\r
783 }\r
784 \r
785 /*==============================================================================\r
786  *\r
787  */\r
788 static uint16_t wait_for_request_completion(void)\r
789 {\r
790     while(g_request_in_progress)\r
791     {\r
792         ;\r
793     }\r
794     \r
795     return g_last_response_length;\r
796 }\r
797 \r
798 /*==============================================================================\r
799  *\r
800  */\r
801 static void write_ptr_value_into_array\r
802 (\r
803     const uint8_t * pointer,\r
804     uint8_t target_array[],\r
805     uint32_t array_index\r
806 )\r
807 {\r
808     target_array[array_index] = (uint8_t)((uint32_t)pointer);\r
809     target_array[array_index + 1] = (uint8_t)((uint32_t)pointer >> 8u);\r
810     target_array[array_index + 2] = (uint8_t)((uint32_t)pointer >> 16u);\r
811     target_array[array_index + 3] = (uint8_t)((uint32_t)pointer >> 24u);\r
812 }\r
813 \r