1 /*
2 * Copyright 2024 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 */
8
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include "fsl_loader_utils.h"
13 #include "api_tree_root.h"
14 #include "fsl_power.h"
15 #ifndef __ZEPHYR__
16 #include "board.h"
17 #include "fsl_debug_console.h"
18 #else
19 #include "fsl_clock.h"
20 #endif
21
22 #ifdef MCUBOOT_APPLICATION
23 #include "mcuboot_app_support.h"
24 #endif
25
26 #include "mflash_drv.h"
27
28 #if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT)
29 #if defined(PSA_CRYPTO_DRIVER_THREAD_EN)
30 #include "mcux_psa_els_pkc_common_init.h"
31 #else
32 #include "els_pkc_mbedtls.h"
33 #endif /* defined(PSA_CRYPTO_DRIVER_THREAD_EN) */
34 #endif /* defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT) */
35
36 //! @addtogroup sbloader
37 //! @{
38
39 /*******************************************************************************
40 * Definitions
41 ******************************************************************************/
42 #if 0
43 #define SBLOADER_PRINTF(...) \
44 do \
45 { \
46 PLOG_DEBUG(__VA_ARGS__); \
47 } while (0)
48 #else
49 #define SBLOADER_PRINTF(...)
50 #endif
51
52 /*!
53 * @brief load cpu1/cpu2 firmware.
54 */
55 #define CIU_RST_SW2 (0x41240184U)
56 #define CIU_RST_SW2_CPU1_RST_MASK (0x40000000U)
57 #define CIU2_RST_SW3 (0x4424011cU)
58 #define CIU2_RST_SW3_CPU2_RST_MASK (0x00000010U)
59
60 #define IMU_SYNC_MAGIC_PATTERN (0xABCDEF89U)
61 #define CPU1_MAGIC_PATTERN_ADDR (0x41380000U)
62 #define CPU2_MAGIC_PATTERN_ADDR (0x443c0000U)
63
64 #define SOCCTRL_CHIP_INFO_REV_NUM_MASK (0xFU)
65
66
67 #define CLKCTL0_PSCCTL1_OTP_MASK (0x20000U)
68 #define RSTCTL0_PRSTCTL1_OTP_MASK (0x20000U)
69
70 #define STAGING_BUF_SZ 256u
71 typedef struct sb3_desc {
72 uint32_t fmt;
73 uint32_t sub_fmt;
74 uint32_t dst_addr;
75 uint32_t area_sz;
76 } sb3_load_desc_t;
77
78 /*******************************************************************************
79 * Prototype
80 ******************************************************************************/
81 static status_t ldr_DoHeader_v3(fsl_api_core_context_t *ctx);
82 static status_t ldr_DoDataRead(fsl_api_core_context_t *ctx);
83 static status_t ldr_DoBlock(fsl_api_core_context_t *ctx);
84 static status_t ldr_DoLoadCmd(fsl_api_core_context_t *ctx);
85 static status_t ldr_DoExecuteCmd(fsl_api_core_context_t *ctx);
86 static status_t ldr_ReadFromFlash(uint8_t * buf, uint32_t src_flash_offset, size_t read_sz);
87
88 static status_t load_service_monolithic(LOAD_Target_Type loadTarget, uint32_t sourceAddr);
89
90 /*******************************************************************************
91 * Variables
92 ******************************************************************************/
93 /*! @brief nboot library context. */
94 static fsl_api_core_context_t s_fsl_api_core_context = {0};
95 static fsl_ldr_Context_v3_t s_sbloader_context;
96 static uint8_t packetBuf[512] = {0};
97 static fsl_nboot_context_t g_nbootCtx = {0};
98 #ifdef CONFIG_FW_VDLLV2
99 static uint32_t vdll_image_base = 0;
100 #endif
101
102 static bootloader_tree_v0_t *g_bootloaderTree_v0;
103 static bootloader_tree_v1_t *g_bootloaderTree_v1;
104
105 /*******************************************************************************
106 * Codes
107 ******************************************************************************/
108 __attribute__((__noinline__))
sb3_Delay(uint32_t loop)109 static void sb3_Delay(uint32_t loop)
110 {
111 if (loop > 0U)
112 {
113 __ASM volatile(
114 "1: \n"
115 " SUBS %0, %0, #1 \n"
116 " CMP %0, #0 \n"
117 " BNE 1b \n"
118 :
119 : "r"(loop));
120 }
121 }
122
sb3_DelayUs(uint32_t us)123 static void sb3_DelayUs(uint32_t us)
124 {
125 uint32_t instNum;
126
127 instNum = ((SystemCoreClock + 999999UL) / 1000000UL) * us;
128 sb3_Delay((instNum + 2U) / 3U);
129 }
130
_ActiveApplicationRemapOffset(void)131 static uint32_t _ActiveApplicationRemapOffset(void)
132 {
133 return (MFLASH_FLEXSPI->HADDROFFSET);
134 }
135 ////////////////////////////////////////////////////////////////////////////
136 //! @brief power on device implementation
137 ////////////////////////////////////////////////////////////////////////////
power_on_device_impl(LOAD_Target_Type loadTarget)138 void power_on_device_impl(LOAD_Target_Type loadTarget)
139 {
140 uint8_t target_type = ((uint8_t)loadTarget & ~0x80);
141
142 if (LOAD_WIFI_FIRMWARE == target_type)
143 {
144 POWER_PowerOnWlan();
145 }
146 else if ((LOAD_BLE_FIRMWARE == target_type) || (LOAD_15D4_FIRMWARE == target_type))
147 {
148 POWER_PowerOnBle();
149 }
150 else
151 {
152 ; /* none to do */
153 }
154 // There's 2.6us gap from device Power-On till device sub-system power up.
155 // Do a time delay which >2.6us for device sub-system here.
156 sb3_DelayUs(5U);
157 }
158
159 ////////////////////////////////////////////////////////////////////////////
160 //! @brief power off device implementation
161 ////////////////////////////////////////////////////////////////////////////
power_off_device_impl(LOAD_Target_Type loadTarget)162 void power_off_device_impl(LOAD_Target_Type loadTarget)
163 {
164 uint8_t target_type = ((uint8_t)loadTarget & ~0x80);
165
166 if (LOAD_WIFI_FIRMWARE == target_type)
167 {
168 POWER_PowerOffWlan();
169 }
170 else if ((LOAD_BLE_FIRMWARE == target_type) || (LOAD_15D4_FIRMWARE == target_type))
171 {
172 POWER_PowerOffBle();
173 }
174 else
175 {
176 ; /* none to do */
177 }
178 sb3_DelayUs(5U);
179 }
180
181 ////////////////////////////////////////////////////////////////////////////
182 //! @brief reset device
183 ////////////////////////////////////////////////////////////////////////////
reset_device(LOAD_Target_Type loadTarget)184 void reset_device(LOAD_Target_Type loadTarget)
185 {
186 uint8_t target_type = ((uint8_t)loadTarget & ~0x80);
187 if (LOAD_WIFI_FIRMWARE == target_type)
188 {
189 *((uint32_t *)CIU_RST_SW2) = *((uint32_t *)CIU_RST_SW2) | CIU_RST_SW2_CPU1_RST_MASK;
190 }
191 else if ((LOAD_BLE_FIRMWARE == target_type) || (LOAD_15D4_FIRMWARE == target_type))
192 {
193 *((uint32_t *)CIU2_RST_SW3) = *((uint32_t *)CIU2_RST_SW3) | CIU2_RST_SW3_CPU2_RST_MASK;
194 }
195 else
196 {
197 ; /* none to do */
198 }
199 }
200
get_sbloader_v3_context(fsl_api_core_context_t * ctx)201 static fsl_ldr_Context_v3_t *get_sbloader_v3_context(fsl_api_core_context_t *ctx)
202 {
203 return ctx->sbloaderCtx;
204 }
205
206 ////////////////////////////////////////////////////////////////////////////
207 //! @brief get firmware version from otp
208 ////////////////////////////////////////////////////////////////////////////
nboot_hal_get_secure_firmware_version(uint32_t * fwVer,LOAD_Target_Type loadTarget)209 static fsl_nboot_status_t nboot_hal_get_secure_firmware_version(uint32_t *fwVer, LOAD_Target_Type loadTarget)
210 {
211 if (fwVer == NULL)
212 {
213 return kStatus_NBOOT_InvalidArgument;
214 }
215
216 uint32_t tmpVersion = 0u;
217 uint32_t trustedFwVersionFuses[4] = {0};
218 uint32_t fuseIdxStart;
219
220 uint8_t target_type = (uint8_t)loadTarget & ~0x80;
221 if (LOAD_WIFI_FIRMWARE == target_type)
222 {
223 fuseIdxStart = OTP_WIFI_FW_VER0_FUSE_IDX;
224 }
225 else if (LOAD_BLE_FIRMWARE == target_type)
226 {
227 fuseIdxStart = OTP_BLE_FW_VER0_FUSE_IDX;
228 }
229 else if (LOAD_15D4_FIRMWARE == target_type)
230 {
231 fuseIdxStart = OTP_15_4_FW_VER0_FUSE_IDX;
232 }
233 else
234 {
235 return kStatus_NBOOT_InvalidArgument;
236 }
237
238 for (uint32_t i = 0u; i < ARRAY_SIZE(trustedFwVersionFuses); i++)
239 {
240 status_t status = OCOTP_OtpFuseRead(fuseIdxStart, &trustedFwVersionFuses[i]);
241 if (status != kStatus_Success)
242 {
243 return kStatus_NBOOT_Fail;
244 }
245 ++fuseIdxStart;
246 }
247
248 for (uint32_t i = 0u; i < ARRAY_SIZE(trustedFwVersionFuses); i++)
249 {
250 // Only the low-half 16-bit is used for counter calculation
251 for (uint8_t j = 0U; j < 16U; j++)
252 {
253 if ((trustedFwVersionFuses[i] & (uint32_t)((uint32_t)(1U) << j)) != 0U)
254 {
255 ++tmpVersion;
256 }
257 }
258 }
259
260 *fwVer = tmpVersion;
261
262 return kStatus_NBOOT_Success;
263 }
264 ////////////////////////////////////////////////////////////////////////////
265 //! @brief fw download implementation
266 ////////////////////////////////////////////////////////////////////////////
sb3_fw_download_impl(LOAD_Target_Type loadTarget,uint32_t flag,uint32_t sourceAddr)267 status_t sb3_fw_download_impl(LOAD_Target_Type loadTarget, uint32_t flag, uint32_t sourceAddr)
268 {
269 volatile uint32_t *magic_pattern_addr = NULL;
270 status_t status = kStatus_Fail;
271 int wait_count = 200;
272 uint8_t target_type = ((uint8_t)loadTarget & ~0x80);
273
274 if ((g_bootloaderTree_v1 == NULL) && ((get_chip_revision() == 1U) || (get_chip_revision() == 2U)))
275 {
276 g_bootloaderTree_v1 = ((bootloader_tree_v1_t *)0x13030000);
277 }
278 else if (g_bootloaderTree_v0 == NULL)
279 {
280 g_bootloaderTree_v0 = ((bootloader_tree_v0_t *)0x13024100);
281 }
282 else
283 {
284 ; /* none to do */
285 }
286
287 if (LOAD_WIFI_FIRMWARE == target_type)
288 {
289 magic_pattern_addr = (volatile uint32_t *)CPU1_MAGIC_PATTERN_ADDR;
290 }
291 else if ((LOAD_BLE_FIRMWARE == target_type) || (LOAD_15D4_FIRMWARE == target_type))
292 {
293 magic_pattern_addr = (volatile uint32_t *)CPU2_MAGIC_PATTERN_ADDR;
294 }
295 #ifdef CONFIG_FW_VDLLV2
296 else if (LOAD_WIFI_VDLL_FIRMWARE == loadTarget)
297 {
298 status = load_service(loadTarget, sourceAddr);
299 return status;
300 }
301 #endif
302 else
303 {
304 return status;
305 }
306
307 // Check if fw already active, if active skip download fw
308 if (IMU_SYNC_MAGIC_PATTERN == *((volatile uint32_t *)magic_pattern_addr))
309 {
310 status = kStatus_Success;
311 return status;
312 }
313
314 if (loadTarget & 0x80)
315 {
316 status = load_service_monolithic(loadTarget, sourceAddr);
317 }
318 else
319 {
320 status = load_service(loadTarget, sourceAddr);
321 }
322
323 // Wait for fw activation for 1s. Return fail if wait_count is used up.
324 while (wait_count != 0)
325 {
326 if (IMU_SYNC_MAGIC_PATTERN != *((volatile uint32_t *)magic_pattern_addr))
327 {
328 /* 5 ms delay */
329 sb3_DelayUs(1000 * 5);
330 wait_count--;
331 if (wait_count == 0)
332 {
333 status = kStatus_Fail;
334 }
335 }
336 else
337 {
338 status = kStatus_Success;
339 break;
340 }
341 }
342
343 return status;
344 }
345
346 ////////////////////////////////////////////////////////////////////////////
347 //! @brief fw reset implementation
348 ////////////////////////////////////////////////////////////////////////////
sb3_fw_reset_impl(LOAD_Target_Type loadTarget,uint32_t flag,uint32_t sourceAddr)349 status_t sb3_fw_reset_impl(LOAD_Target_Type loadTarget, uint32_t flag, uint32_t sourceAddr)
350 {
351 status_t status = kStatus_Fail;
352
353 power_off_device_impl(loadTarget);
354
355 status = sb3_fw_download_impl(loadTarget, flag, sourceAddr);
356
357 return status;
358 }
359
360 ////////////////////////////////////////////////////////////////////////////
361 //! @brief load command processing
362 ////////////////////////////////////////////////////////////////////////////
ldr_DoLoadCmd(fsl_api_core_context_t * ctx)363 static status_t ldr_DoLoadCmd(fsl_api_core_context_t *ctx)
364 {
365 status_t status = kStatus_Fail;
366
367 fsl_ldr_Context_v3_t *context = get_sbloader_v3_context(ctx);
368
369 // check current data_block_position
370 if (context->data_block_position == context->block_data_size)
371 {
372 // we reached end of data section, need to get the next block
373 status = kStatus_Success;
374 }
375 else if (context->data_block_position + context->data_range_header.length <= context->block_data_size)
376 {
377 // the load data enough in data section (buffer)
378 (void)memcpy((uint8_t *)context->data_range_header.startAddress,
379 (uint8_t *)&context->data_block[context->data_block_position], context->data_range_header.length);
380 // this load command completed.
381 // this data range section process finiskStatus_FLASH_Successhed.
382 context->in_data_range = false;
383 context->data_range_handled = 0;
384 context->data_block_position += context->data_range_header.length + context->data_range_gap;
385 context->data_section_handled += context->data_range_header.length + context->data_range_gap;
386 status = kStatus_Success;
387 }
388 else
389 {
390 // we have partial data to load
391 (void)memcpy((uint8_t *)context->data_range_header.startAddress,
392 (uint8_t *)&context->data_block[context->data_block_position],
393 context->block_data_size - context->data_block_position);
394 context->data_range_handled = context->block_data_size - context->data_block_position;
395 context->data_range_header.startAddress += context->data_range_handled;
396 context->data_range_header.length -= context->data_range_handled;
397 context->data_block_position += context->data_range_handled;
398 context->data_section_handled += context->data_range_handled;
399 status = kStatus_Success;
400 }
401
402 return status;
403 }
404
405 ////////////////////////////////////////////////////////////////////////////
406 //! @brief Execute command processing
407 ////////////////////////////////////////////////////////////////////////////
ldr_DoExecuteCmd(fsl_api_core_context_t * ctx)408 static status_t ldr_DoExecuteCmd(fsl_api_core_context_t *ctx)
409 {
410 fsl_ldr_Context_v3_t *context = get_sbloader_v3_context(ctx);
411 // this data range section process finished.
412 context->in_data_range = false;
413 context->data_range_handled = 0;
414
415 // Actual jump is implemented in fsl_sbloader_finalize().
416 return (status_t)kStatusRomLdrPendingJumpCommand;
417 }
418
419 ////////////////////////////////////////////////////////////////////////////
420 //! @brief data block processing
421 ////////////////////////////////////////////////////////////////////////////
ldr_DoBlock(fsl_api_core_context_t * ctx)422 static status_t ldr_DoBlock(fsl_api_core_context_t *ctx)
423 {
424 fsl_ldr_Context_v3_t *context = get_sbloader_v3_context(ctx);
425
426 status_t status = kStatus_Fail;
427 // new data range with new data block
428 fsl_sb3_data_range_header_t *data_range_header;
429 fsl_sb3_section_header_t *data_section_header;
430
431 while (context->in_data_block)
432 {
433 // check if we are in a data section
434 if (context->in_data_section)
435 {
436 // in process of a data section
437 data_section_header = &context->data_section_header;
438 }
439 else
440 {
441 // new data section started
442 data_section_header = (fsl_sb3_section_header_t *)(void *)&context->data_block[context->data_block_position];
443
444 // save data range section header
445 (void)memcpy(&context->data_section_header, data_section_header, sizeof(fsl_sb3_section_header_t));
446
447 // branch to section types (only data range is currently supported)
448 switch (data_section_header->sectionType)
449 {
450 case ((uint32_t)kSectionNone):
451 status = kStatus_Success;
452 break;
453 case ((uint32_t)kSectionDataRange):
454 context->in_data_section = true;
455 context->data_section_handled = 0;
456 context->in_data_range = false;
457 context->data_range_handled = 0;
458 context->data_block_position += sizeof(fsl_sb3_section_header_t);
459 break;
460 case ((uint32_t)kSectionDiffUpdate):
461 case ((uint32_t)kSectionDDRConfig):
462 case ((uint32_t)kSectionRegister):
463 default:
464 // non-supported section type
465 SBLOADER_PRINTF("Bootloader: %s, invalid section type = %x", __func__,
466 data_section_header->sectionType);
467 status = kStatus_Fail;
468 break;
469 }
470 if (data_section_header->sectionType != (uint32_t)kSectionDataRange)
471 {
472 return status;
473 }
474 }
475
476 switch (data_section_header->sectionType)
477 {
478 case ((uint32_t)kSectionDataRange):
479 {
480 // check if we are in a data range
481 if (context->in_data_range)
482 {
483 // continue current data range process
484 data_range_header = &context->data_range_header;
485 }
486 else
487 {
488 // started a new data range
489 data_range_header =
490 (fsl_sb3_data_range_header_t *)(void *)&context->data_block[context->data_block_position];
491
492 // check command tag
493 if (data_range_header->tag != SB3_DATA_RANGE_HEADER_TAG)
494 {
495 // bad data range section
496 status = kStatus_Fail;
497 SBLOADER_PRINTF("Bootloader: %s, invalid data range header tag = %x", __func__,
498 data_range_header->tag);
499 return status;
500 }
501
502 // save data range section header
503 (void)memcpy(&context->data_range_header, data_range_header, sizeof(fsl_sb3_data_range_header_t));
504 context->in_data_range = true;
505 context->has_data_range_expansion = false;
506 context->data_range_handled = sizeof(fsl_sb3_data_range_header_t); // used anywhere?
507 context->data_block_position += sizeof(fsl_sb3_data_range_header_t);
508 context->data_section_handled += sizeof(fsl_sb3_data_range_header_t);
509
510 // 16 bytes alignmnent check and handling
511 context->data_range_gap = 0;
512
513 switch ((fsl_sb3_cmd_t)data_range_header->cmd)
514 {
515 case kSB3_CmdLoad:
516 context->data_range_gap =
517 (SB3_DATA_ALIGNMENT_SIZE_IN_BYTE - (data_range_header->length & 0xFU)) & 0xFU;
518 break;
519 default:
520 // Do nothing for the commands.
521 break;
522 }
523 }
524
525 switch (data_range_header->cmd)
526 {
527 case ((uint32_t)kSB3_CmdLoad):
528 if (!context->has_data_range_expansion)
529 {
530 SBLOADER_PRINTF("Bootloader: %s, Copy data range expansion", __func__);
531 // check current data_block_position
532 if (context->data_block_position == context->block_data_size)
533 {
534 // we reached end of data section, need to get the next block
535 return kStatus_Success;
536 }
537 else if ((context->data_block_position + sizeof(fsl_sb3_data_range_expansion_t)) <=
538 context->block_data_size)
539 {
540 // save data range section header expansion.
541 (void)memcpy(&context->data_range_expansion,
542 (fsl_sb3_data_range_expansion_t *)&context
543 ->data_block[context->data_block_position],
544 sizeof(fsl_sb3_data_range_expansion_t));
545 context->has_data_range_expansion = true;
546 context->data_block_position += sizeof(fsl_sb3_data_range_expansion_t);
547 context->data_section_handled += sizeof(fsl_sb3_data_range_expansion_t);
548 }
549 else
550 {
551 // Unaligned data range.
552 return kStatus_Fail;
553 }
554 }
555 else
556 {
557 SBLOADER_PRINTF("Bootloader: %s, Has data range expansion", __func__);
558 }
559 break;
560 default:
561 // Do nothing for the commands without header expansion.
562 break;
563 }
564
565 // branch to range commands
566 switch (data_range_header->cmd)
567 {
568 case ((uint32_t)kSB3_CmdLoad):
569 status = ldr_DoLoadCmd(ctx);
570 if (status != kStatus_Success)
571 {
572 return status;
573 }
574 break;
575 case ((uint32_t)kSB3_CmdExecute):
576 status = ldr_DoExecuteCmd(ctx);
577 break;
578 default:
579 // this data range section process finished.
580 context->in_data_range = false;
581 context->data_range_handled = 0;
582 break;
583 }
584 if (data_range_header->cmd == (uint32_t)kSB3_CmdExecute)
585 {
586 return status;
587 }
588
589 // check if we reach the end of this data section
590 if (context->data_section_handled == context->data_section_header.length)
591 {
592 // this data section completed
593 context->in_data_section = false;
594 }
595 else if (context->data_section_handled > context->data_section_header.length)
596 {
597 // bad data section
598 // return error
599 SBLOADER_PRINTF("Bootloader: %s, bad data section.", __func__);
600 status = kStatus_Fail;
601 return status;
602 }
603 else
604 {
605 ; /* none to do */
606 }
607
608 // check if we reach the end of this data block
609 if (context->data_block_position == context->block_data_size)
610 {
611 // This data block process finished.
612 context->block_buffer_position = 0;
613 context->in_data_block = false;
614 context->data_block_position = 0;
615 context->Action = (fsl_pLdrFnc_v3_t)ldr_DoDataRead;
616 SBLOADER_PRINTF("Bootloader: %s, data blobck process done.", __func__);
617 status = kStatus_Success;
618 }
619 else if (context->data_block_position > context->block_data_size)
620 {
621 // bad block position
622 // bad pointer
623 SBLOADER_PRINTF("Bootloader: %s, bad block position.", __func__);
624 status = kStatus_Fail;
625 return status;
626 }
627 else if (context->data_block_position + SB3_DATA_ALIGNMENT_SIZE_IN_BYTE > context->block_data_size)
628 {
629 // data is not 16 bytes aligned.
630 // return error
631 status = kStatus_Fail;
632 SBLOADER_PRINTF("Bootloader: %s, data not aligned.", __func__);
633 return status;
634 }
635 else
636 {
637 ; /* none to do */
638 }
639 }
640 break;
641 case ((uint32_t)kSectionDiffUpdate):
642 case ((uint32_t)kSectionDDRConfig):
643 case ((uint32_t)kSectionRegister):
644 default:
645 // non-supported section type
646 SBLOADER_PRINTF("Bootloader: %s, non-supported section type = %x", __func__,
647 data_section_header->sectionType);
648 status = kStatus_Fail;
649 context->in_data_block = false;
650 break;
651 }
652 }
653
654 return status;
655 }
656
657 ////////////////////////////////////////////////////////////////////////////
658 //! @brief data block decryption and handling
659 ////////////////////////////////////////////////////////////////////////////
ldr_DoDataRead(fsl_api_core_context_t * ctx)660 static status_t ldr_DoDataRead(fsl_api_core_context_t *ctx)
661 {
662 status_t status = kStatus_Fail;
663 fsl_nboot_status_t nbootResult = kStatus_NBOOT_Fail;
664
665 fsl_ldr_Context_v3_t *context = get_sbloader_v3_context(ctx);
666
667 // check block integrity
668 if (context->processedBlocks < ctx->nbootCtx->totalBlocks)
669 {
670 // call nboot lib to decrypt the data block
671 if ((get_chip_revision() == 1U) || (get_chip_revision() == 2U))
672 {
673 nbootResult = (fsl_nboot_status_t)g_bootloaderTree_v1->nbootDriver->nboot_sb3_load_block(
674 ctx->nbootCtx, (uint32_t *)&context->block_buffer[0]);
675 }
676 else
677 {
678 nbootResult = (fsl_nboot_status_t)g_bootloaderTree_v0->nbootDriver->nboot_sb3_load_block(
679 ctx->nbootCtx, (uint32_t *)&context->block_buffer[0]);
680 }
681 if (nbootResult == kStatus_NBOOT_Success)
682 {
683 context->block_buffer_position = 0;
684 #if defined(NBOOT_IGNORE_SB3_COMMANDS)
685 if (g_nboot_ctx.processData != NBOOT_IGNORE_SB3_COMMANDS)
686 #endif
687 {
688 context->in_data_block = true;
689 context->data_block = &context->block_buffer[context->data_block_offset];
690 context->data_block_position = 0;
691 context->processedBlocks++;
692 status = ldr_DoBlock(ctx);
693 }
694 #if defined(NBOOT_IGNORE_SB3_COMMANDS)
695 else
696 {
697 status = kStatus_Success;
698 }
699 #endif
700 }
701 else
702 {
703 SBLOADER_PRINTF("ROM API: %s, nboot_sb3_load_block is failed, status = %x", __func__, nbootResult);
704 status = kStatus_Fail;
705 }
706 }
707
708 return status;
709 }
710
711 ////////////////////////////////////////////////////////////////////////////
712 //! @brief header block handling
713 ////////////////////////////////////////////////////////////////////////////
ldr_DoHeader_v3(fsl_api_core_context_t * ctx)714 static status_t ldr_DoHeader_v3(fsl_api_core_context_t *ctx)
715 {
716 status_t status = kStatus_Success;
717 fsl_nboot_sb3_load_manifest_parms_t manifestParms;
718
719 fsl_ldr_Context_v3_t *context = get_sbloader_v3_context(ctx);
720
721 do
722 {
723 fsl_nboot_sb3_header_t *header = (fsl_nboot_sb3_header_t *)(void *)&context->block_buffer[0];
724 if (context->block_buffer_size == sizeof(fsl_nboot_sb3_header_t))
725 {
726 // Update the buffer size to the size of Block 0.
727 context->block_buffer_size = header->imageTotalLength;
728 SBLOADER_PRINTF("ROM API: %s, manifest size = %x, but buffer size =%x", __func__,
729 context->block_buffer_size, sizeof(context->block_buffer));
730 if (context->block_buffer_size > sizeof(context->block_buffer))
731 {
732 status = kStatus_Fail;
733 break;
734 }
735 // Resume the cleared buffer position.
736 context->block_buffer_position = sizeof(fsl_nboot_sb3_header_t);
737
738 status = kStatus_Success;
739 break;
740 }
741
742 if (context->block_buffer_size != header->imageTotalLength)
743 {
744 status = kStatus_Fail;
745 break;
746 }
747
748 (void)memset(&manifestParms, 0, sizeof(fsl_nboot_sb3_load_manifest_parms_t));
749
750 fsl_nboot_status_t nbootResult = nboot_hal_get_sb3_manifest_params(ctx->nbootCtx, &manifestParms);
751 if (nbootResult != kStatus_NBOOT_Success)
752 {
753 SBLOADER_PRINTF("ROM API: %s, nboot_hal_get_sb3_manifest_params is failed, status = %x", __func__,
754 nbootResult);
755 status = kStatus_Fail;
756 break;
757 }
758
759 // call nboot lib to verify the block header
760 if ((get_chip_revision() == 1U) || (get_chip_revision() == 2U))
761 {
762 nbootResult = (fsl_nboot_status_t)g_bootloaderTree_v1->nbootDriver->nboot_sb3_load_manifest(
763 ctx->nbootCtx, (uint32_t *)(void *)header, &manifestParms);
764 }
765 else
766 {
767 nbootResult = (fsl_nboot_status_t)g_bootloaderTree_v0->nbootDriver->nboot_sb3_load_manifest(
768 ctx->nbootCtx, (uint32_t *)(void *)header, &manifestParms);
769 }
770 if (nbootResult == kStatus_NBOOT_Success)
771 {
772 context->data_block_offset = (uint8_t)(sizeof(uint32_t) /* blockNumber*/ + header->certificateBlockOffset -
773 sizeof(fsl_nboot_sb3_header_t));
774 context->block_buffer_size = (uint32_t)context->data_block_offset + NBOOT_SB3_CHUNK_SIZE_IN_BYTES;
775 context->block_buffer_position = 0;
776 context->block_size = header->blockSize;
777 context->block_data_size = NBOOT_SB3_CHUNK_SIZE_IN_BYTES;
778 context->block_data_total = context->block_size * ctx->nbootCtx->totalBlocks;
779 context->in_data_section = false;
780 context->data_section_handled = 0;
781 context->processedBlocks = 0;
782 context->Action = (fsl_pLdrFnc_v3_t)ldr_DoDataRead;
783 status = kStatus_Success;
784 }
785 else
786 {
787 SBLOADER_PRINTF("ROM API: %s, nboot_sb3_load_manifest is failed, status = %x", __func__, nbootResult);
788 status = kStatus_Fail;
789 }
790 } while (false);
791
792 return status;
793 }
794
795 ////////////////////////////////////////////////////////////////////////////
796 //! @brief Initialize the loader state machine.
797 ////////////////////////////////////////////////////////////////////////////
fsl_sbloader_init(fsl_api_core_context_t * ctx)798 status_t fsl_sbloader_init(fsl_api_core_context_t *ctx)
799 {
800 status_t status = kStatus_InvalidArgument;
801
802 do
803 {
804 if (ctx == NULL)
805 {
806 break;
807 }
808
809 fsl_ldr_Context_v3_t *context = ctx->sbloaderCtx;
810
811 // Initialize the context
812 (void)memset(context, 0, sizeof(fsl_ldr_Context_v3_t));
813 context->block_buffer_size = sizeof(fsl_nboot_sb3_header_t);
814
815 // Process the first chunk of the image header
816 context->Action = (fsl_pLdrFnc_v3_t)ldr_DoHeader_v3;
817
818 // Initialize the allowed command set
819 context->commandSet = SBLOADER_V3_CMD_SET_ALL;
820
821 status = kStatus_Success;
822
823 } while (false);
824
825 return status;
826 }
827
828 ////////////////////////////////////////////////////////////////////////////
829 //! @brief Finalize the loader operations
830 ////////////////////////////////////////////////////////////////////////////
fsl_sbloader_finalize(fsl_api_core_context_t * ctx)831 status_t fsl_sbloader_finalize(fsl_api_core_context_t *ctx)
832 {
833 status_t status = kStatus_Fail;
834
835 fsl_ldr_Context_v3_t *context = get_sbloader_v3_context(ctx);
836
837 if (context->data_range_header.cmd == (uint32_t)kSB3_CmdExecute)
838 {
839 status = kStatus_Success;
840 }
841
842 return status;
843 }
844
845 ////////////////////////////////////////////////////////////////////////////
846 //! @brief Pump the loader state machine.///////////////////////////////////
fsl_sbloader_pump(fsl_api_core_context_t * ctx,uint8_t * data,uint32_t length)847 static status_t fsl_sbloader_pump(fsl_api_core_context_t *ctx, uint8_t *data, uint32_t length)
848 {
849 status_t status = kStatus_InvalidArgument;
850 do
851 {
852 fsl_ldr_Context_v3_t *context = ctx->sbloaderCtx;
853 uint32_t required = 0U;
854 uint32_t available = 0U;
855 uint32_t readPosition = 0U;
856
857 while (readPosition < length)
858 {
859 required = context->block_buffer_size - context->block_buffer_position;
860 available = length - readPosition;
861
862 // copy what we need to complete a full chunk into the chunk buffer
863 if ((required > 0U) && (available > 0U))
864 {
865 uint32_t toCopy = required > available ? available : required;
866 if ((context->block_buffer_position < context->block_buffer_size) &&
867 (context->block_buffer_position + toCopy <= context->block_buffer_size) &&
868 (readPosition + toCopy <= length))
869 {
870 if ((context->block_buffer_position + toCopy) >= sizeof(context->block_buffer))
871 {
872 // block buffer over-flow.
873 SBLOADER_PRINTF("ROM API: %s, block buffer is overflown", __func__);
874 status = kStatus_Fail;
875 break;
876 }
877 (void)memcpy(&context->block_buffer[context->block_buffer_position], &data[readPosition], toCopy);
878 required -= toCopy;
879 available -= toCopy;
880 readPosition += toCopy;
881 context->block_buffer_position += toCopy;
882 status = kStatus_Success;
883 }
884 else
885 {
886 status = kStatus_Fail;
887 break;
888 }
889 }
890
891 if (required == 0U)
892 {
893 // a full chunk was filled to process it
894 context->block_buffer_position = 0U;
895 status = (context->Action)(ctx);
896
897 if (status != kStatus_Success)
898 {
899 if (status != (status_t)kStatusRomLdrPendingJumpCommand)
900 {
901 SBLOADER_PRINTF("sbloader Action failed: 0x%08x", status);
902 }
903 break;
904 }
905 }
906 else if (available == 0U)
907 {
908 // otherwise we are just going to wait for more data
909 status = (status_t)kStatusRomLdrDataUnderrun;
910 break;
911 }
912 else
913 {
914 ; /* None to do */
915 }
916 }
917 } while (false);
918
919 return status;
920 }
921
922 ////////////////////////////////////////////////////////////////////////////
923 //! @brief Read flash area loading to RAM buffer.
924 // Direct read from flash is not allowed when remapping is active.
925 // buf : pointer to RAM buffer, its size must be sufficient to receive
926 // the required number of bytes.
927 // src_flash_offset: 'virtual' address in flash relative to start of flash storage.
928 // Actual 'physical' address results from the addition of the remap offset.
929 // read_sz : Number of bytes to be read.
930 ////////////////////////////////////////////////////////////////////////////
ldr_ReadFromFlash(uint8_t * buf,uint32_t src_flash_offset,size_t read_sz)931 static status_t ldr_ReadFromFlash(uint8_t * buf, uint32_t src_flash_offset, size_t read_sz)
932 {
933 status_t st;
934 static const uint32_t mflash_base = (1u << 27);
935 uint32_t remap_offset = _ActiveApplicationRemapOffset();
936 if (remap_offset == 0U)
937 {
938 memcpy(buf, (void*)src_flash_offset, read_sz);
939 st = kStatus_Success;
940 }
941 else
942 {
943 // similar to mflash_drv_log2phys
944 uint32_t phys_offset = (src_flash_offset + remap_offset) & ~mflash_base;
945 st = mflash_drv_read(phys_offset, (uint32_t *)buf, read_sz);
946 }
947 return st;
948 }
949
950 ////////////////////////////////////////////////////////////////////////////
951 //! @brief Read SB3 area descriptor.
952 // Direct read from flash is not allowed when remapping is active.
953 // hdr : pointer to RAM fsl_nboot_sb3_header_t structure.
954 // sourceAddr: 'virtual' address where SB3 header is expected.
955 ////////////////////////////////////////////////////////////////////////////
read_nboot_sb3_header(fsl_nboot_sb3_header_t * hdr,uint32_t sourceAddr)956 status_t read_nboot_sb3_header(fsl_nboot_sb3_header_t * hdr, uint32_t sourceAddr)
957 {
958 return ldr_ReadFromFlash((uint8_t*)hdr, sourceAddr, sizeof(fsl_nboot_sb3_header_t));
959 }
960
961 ////////////////////////////////////////////////////////////////////////////
962 //! @brief load service with format of sb3
963 // readOffset: image offset in flash
964 ////////////////////////////////////////////////////////////////////////////
loader_process_sb_file(uint32_t readOffset)965 status_t loader_process_sb_file(uint32_t readOffset)
966 {
967 status_t status = kStatus_Fail;
968 uint32_t packetLength = sizeof(packetBuf);
969 s_fsl_api_core_context.sbloaderCtx = &s_sbloader_context;
970 s_fsl_api_core_context.nbootCtx = &g_nbootCtx;
971 bool elsFlag = false;
972 uint32_t CSS_CTRL_context = 0;
973 #ifdef CONFIG_FW_VDLLV2
974 uint32_t counter;
975 #endif
976
977 do
978 {
979 (void)POWER_EnableGDetVSensors();
980 if (((CLKCTL0->PSCCTL0 & CLKCTL0_PSCCTL0_ELS_MASK) == 0U) ||
981 ((CLKCTL0->PSCCTL1 & CLKCTL0_PSCCTL1_ELS_APB_MASK) == 0U) ||
982 ((RSTCTL0->PRSTCTL0 & RSTCTL0_PRSTCTL0_ELS_MASK) != 0U))
983 {
984 elsFlag = true;
985 CLOCK_EnableClock(kCLOCK_Els);
986 CLOCK_EnableClock(kCLOCK_ElsApb);
987 RESET_PeripheralReset(kELS_RST_SHIFT_RSTn);
988 }
989
990 #if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT)
991 (void)mcux_els_mutex_lock();
992 #endif
993
994 if ((get_chip_revision() == 1U) || (get_chip_revision() == 2U))
995 {
996 status = (int32_t)g_bootloaderTree_v1->nbootDriver->nboot_context_init(s_fsl_api_core_context.nbootCtx);
997 }
998 else
999 {
1000 status = (int32_t)g_bootloaderTree_v0->nbootDriver->nboot_context_init(s_fsl_api_core_context.nbootCtx);
1001 }
1002 if (status != (status_t)kStatus_NBOOT_Success)
1003 {
1004 break;
1005 }
1006
1007 status = fsl_sbloader_init(&s_fsl_api_core_context);
1008 if (status != kStatus_Success)
1009 {
1010 break;
1011 }
1012
1013 // Pump the sbloader content and do sbloader handling until ROM see the jump command and jump to the image
1014 while (true)
1015 {
1016 memcpy(packetBuf, (void*)readOffset, packetLength);
1017
1018 if ((get_chip_revision() == 1U) || (get_chip_revision() == 2U))
1019 {
1020 status = fsl_sbloader_pump(&s_fsl_api_core_context, packetBuf, packetLength);
1021 }
1022 else
1023 {
1024 status = g_bootloaderTree_v0->iapApiDriver->fsl_sbloader_pump(&s_fsl_api_core_context, packetBuf,
1025 packetLength);
1026 }
1027
1028 // kStatusRomLdrDataUnderrun means need more data
1029 // kStatusRomLdrSectionOverrun means we reached the end of the sb file processing
1030 // either of these are OK
1031 if ((status == (status_t)kStatusRomLdrDataUnderrun) || (status == (status_t)kStatusRomLdrSectionOverrun))
1032 {
1033 status = kStatus_Success;
1034 }
1035 else if (status == (status_t)kStatusRomLdrPendingJumpCommand)
1036 {
1037 status = fsl_sbloader_finalize(&s_fsl_api_core_context);
1038 #ifdef CONFIG_FW_VDLLV2
1039 assert((readOffset & 0x3U) == 0U);
1040 for (counter = 0; counter < (packetLength + 7U) >> 2U; counter++)
1041 {
1042 if (*(uint32_t *)readOffset == TAG_SB_V3)
1043 {
1044 vdll_image_base = readOffset;
1045 break;
1046 }
1047 else
1048 {
1049 readOffset += 4U;
1050 }
1051 }
1052 #endif
1053 break;
1054 }
1055 else
1056 {
1057 ; /* No necessary actions. */
1058 }
1059
1060 if (status != kStatus_Success)
1061 {
1062 break;
1063 }
1064
1065 readOffset += packetLength;
1066 }
1067 } while (false);
1068
1069 if (get_chip_revision() == 0U)
1070 {
1071 CSS_CTRL_context = ELS->ELS_CTRL;
1072 }
1073
1074 if ((get_chip_revision() == 1U) || (get_chip_revision() == 2U))
1075 {
1076 (void)g_bootloaderTree_v1->nbootDriver->nboot_context_deinit(s_fsl_api_core_context.nbootCtx);
1077 }
1078 else
1079 {
1080 (void)g_bootloaderTree_v0->nbootDriver->nboot_context_deinit(s_fsl_api_core_context.nbootCtx);
1081 }
1082
1083 if (get_chip_revision() == 0U)
1084 {
1085 ELS->ELS_CTRL = (CSS_CTRL_context & 0xFFU);
1086 }
1087
1088 #if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT)
1089 (void)mcux_els_mutex_unlock();
1090 #endif
1091
1092 if (elsFlag == true)
1093 {
1094 RESET_SetPeripheralReset(kELS_RST_SHIFT_RSTn);
1095 CLOCK_DisableClock(kCLOCK_ElsApb);
1096 CLOCK_DisableClock(kCLOCK_Els);
1097 }
1098 POWER_DisableGDetVSensors();
1099
1100 return status;
1101 }
1102
1103 ////////////////////////////////////////////////////////////////////////////
1104 //! @brief load service with format of raw binary image
1105 // readOffset: image offset in flash
1106 ////////////////////////////////////////////////////////////////////////////
loader_process_raw_file(uint32_t readOffset)1107 static status_t loader_process_raw_file(uint32_t readOffset)
1108 {
1109 status_t status = kStatus_Fail;
1110 uint32_t *src_addr;
1111 uint32_t *dst_addr;
1112 uint32_t code_size;
1113 uint32_t *data_ptr = (uint32_t *)readOffset;
1114 uint32_t total_raw_size = 0;
1115
1116 #ifdef CONFIG_FW_VDLLV2
1117 if ((*data_ptr == LOADER_RAW_BINARY_FORMAT) && (*(data_ptr + 1) == LOADER_VDLL_RAW_BINARY_FORMAT))
1118 {
1119 src_addr = data_ptr + 4;
1120 dst_addr = (uint32_t *)*(data_ptr + 2);
1121 code_size = *(data_ptr + 3);
1122 (void)memcpy(dst_addr, src_addr, code_size);
1123 status = kStatus_Success;
1124 }
1125 else
1126 #endif
1127 {
1128 do
1129 {
1130 if (*data_ptr != LOADER_RAW_BINARY_FORMAT)
1131 {
1132 break;
1133 }
1134
1135 src_addr = data_ptr + 4;
1136 dst_addr = (uint32_t *)*(data_ptr + 2);
1137 code_size = *(data_ptr + 3);
1138 // Check for raw ending segment
1139 if (((uint32_t)src_addr == 0xffffffffU) || ((uint32_t)dst_addr == 0xffffffffU))
1140 {
1141 if (code_size == total_raw_size)
1142 {
1143 status = kStatus_Success;
1144 #ifdef CONFIG_FW_VDLLV2
1145 vdll_image_base = (uint32_t)(data_ptr + 4);
1146 #endif
1147 }
1148 break;
1149 }
1150
1151 (void)memcpy(dst_addr, src_addr, code_size);
1152 data_ptr += 4U + (code_size >> 2U);
1153 total_raw_size += code_size;
1154 } while (true);
1155 }
1156
1157 return status;
1158 }
1159
loader_process_raw_file_monolithic(uint32_t readOffset)1160 static status_t loader_process_raw_file_monolithic(uint32_t readOffset)
1161 {
1162 status_t status = kStatus_Fail;
1163 uint32_t *dst_addr;
1164 uint32_t code_size;
1165 uint32_t sz;
1166
1167
1168 uint32_t total_raw_size = 0U;
1169 uint8_t staging_buf[STAGING_BUF_SZ] = { 0u };
1170
1171 do {
1172 sb3_load_desc_t *p_desc = (sb3_load_desc_t*)&staging_buf[0];
1173 status_t flash_st;
1174 /* Firs read the SB3 area descriptor */
1175 flash_st = ldr_ReadFromFlash(&staging_buf[0], readOffset, sizeof(sb3_load_desc_t));
1176 if (flash_st != kStatus_Success)
1177 {
1178 break;
1179 }
1180 readOffset += sizeof(sb3_load_desc_t);
1181
1182 if (p_desc->fmt != LOADER_RAW_BINARY_FORMAT)
1183 {
1184 break;
1185 }
1186
1187 dst_addr = (uint32_t*)p_desc->dst_addr;
1188 code_size = p_desc->area_sz;
1189
1190 // Check for raw ending segment
1191 if (p_desc->dst_addr == 0xffffffffU)
1192 {
1193 if (code_size == total_raw_size)
1194 {
1195 status = kStatus_Success;
1196 #ifdef CONFIG_FW_VDLLV2
1197 vdll_image_base = readOffset;
1198 #endif
1199 }
1200 break;
1201 }
1202
1203 /* start of indirect memcpy to destination */
1204 sz = code_size;
1205 while (sz >= STAGING_BUF_SZ)
1206 {
1207 flash_st = ldr_ReadFromFlash(&staging_buf[0], readOffset, STAGING_BUF_SZ);
1208 if (flash_st != kStatus_Success)
1209 {
1210 break;
1211 }
1212 (void)memcpy(dst_addr, &staging_buf[0], STAGING_BUF_SZ);
1213 readOffset += STAGING_BUF_SZ;
1214 dst_addr += STAGING_BUF_SZ/4;
1215 sz -= STAGING_BUF_SZ;
1216 }
1217 if (flash_st != kStatus_Success)
1218 {
1219 break;
1220 }
1221 /* last chunk smaller than staging buffer */
1222 if (sz > 0U)
1223 {
1224 flash_st = ldr_ReadFromFlash(&staging_buf[0], readOffset, sz);
1225 if (flash_st != kStatus_Success)
1226 {
1227 break;
1228 }
1229 (void)memcpy(dst_addr, &staging_buf[0], sz);
1230 readOffset += sz;
1231 dst_addr += (sz+3U)/4U;
1232 }
1233 /* at this point are is fully consumed and copied to destination : */
1234 #ifdef CONFIG_FW_VDLLV2
1235 if ((p_desc->sub_fmt == LOADER_VDLL_RAW_BINARY_FORMAT))
1236 {
1237 status = kStatus_Success;
1238 break;
1239 }
1240 #endif
1241 total_raw_size += code_size;
1242
1243 } while (true);
1244
1245 return status;
1246 }
1247
1248 #ifndef __ZEPHYR__
__FlexSpiFlashInit(void)1249 static bool __FlexSpiFlashInit(void)
1250 {
1251 bool ret = false;
1252 if (((CLKCTL0->PSCCTL0 & CLKCTL0_PSCCTL0_FLEXSPI0_MASK) == 0U) ||
1253 ((RSTCTL0->PRSTCTL0 & RSTCTL0_PRSTCTL0_FLEXSPI0_MASK) != 0U))
1254 {
1255 CLOCK_EnableClock(kCLOCK_Flexspi);
1256 RESET_PeripheralReset(kFLEXSPI_RST_SHIFT_RSTn);
1257 BOARD_SetFlexspiClock(FLEXSPI, 2U, 2U);
1258 BOARD_InitFlash(FLEXSPI);
1259 ret = true;
1260 }
1261 return ret;
1262 }
1263
__FlexSpiFlashDeInit(void)1264 static void __FlexSpiFlashDeInit(void)
1265 {
1266 RESET_ClearPeripheralReset(kFLEXSPI_RST_SHIFT_RSTn);
1267 BOARD_DeinitFlash(FLEXSPI);
1268 CLOCK_AttachClk(kNONE_to_FLEXSPI_CLK);
1269 CLOCK_DisableClock(kCLOCK_Flexspi);
1270 RESET_SetPeripheralReset(kFLEXSPI_RST_SHIFT_RSTn);
1271 }
1272
1273 #endif
1274
__OtpInit(void)1275 static int __OtpInit(void)
1276 {
1277 int ret = 0; /* will stay 0 if nothing to do */
1278 if (((CLKCTL0->PSCCTL1 & CLKCTL0_PSCCTL1_OTP_MASK) == 0U) ||
1279 ((RSTCTL0->PRSTCTL1 & RSTCTL0_PRSTCTL1_OTP_MASK) != 0U))
1280 {
1281 status_t st;
1282 #ifdef USE_OCOTP_DRIVER_IN_LOAD_SERVICE
1283 st = OCOTP_OtpInit();
1284 #else
1285 if ((get_chip_revision() == 1U) || (get_chip_revision() == 2U))
1286 {
1287 st = g_bootloaderTree_v1->otpDriver->init(0U);
1288 }
1289 else
1290 {
1291 RESET_PeripheralReset(kOTP_RST_SHIFT_RSTn);
1292 st = g_bootloaderTree_v0->otpDriver->init(0U);
1293 }
1294 #endif
1295 if (st != kStatus_Success)
1296 {
1297 ret = -1;
1298 }
1299 else
1300 {
1301 ret = 1;
1302 }
1303 }
1304 return ret;
1305 }
1306
__OtpDeInit(void)1307 static int __OtpDeInit(void)
1308 {
1309 int ret = -1;
1310 #ifdef USE_OCOTP_DRIVER_IN_LOAD_SERVICE
1311 if (OCOTP_OtpDeinit() == kStatus_Success)
1312 {
1313 ret = 0;
1314 }
1315 #else
1316 if ((get_chip_revision() == 1U) || (get_chip_revision() == 2U))
1317 {
1318 if (g_bootloaderTree_v1->otpDriver->deinit() == kStatus_Success)
1319 {
1320 ret = 0;
1321 }
1322 }
1323 else
1324 {
1325 if (g_bootloaderTree_v0->otpDriver->deinit() == kStatus_Success)
1326 {
1327 ret = 0;
1328 }
1329 }
1330 #endif
1331 return ret;
1332 }
1333
1334
1335 ////////////////////////////////////////////////////////////////////////////
1336 //! @brief load service
1337 // loadTarget: LOAD_WIFI_FIRMWARE / LOAD_BLE_FIRMWARE / LOAD_15D4_FIRMWARE
1338 // sourceAddr: load firmware source address, if 0 load default address
1339 ////////////////////////////////////////////////////////////////////////////
load_service(LOAD_Target_Type loadTarget,uint32_t sourceAddr)1340 status_t load_service(LOAD_Target_Type loadTarget, uint32_t sourceAddr)
1341 {
1342 status_t status = kStatus_Fail;
1343 fsl_nboot_sb3_header_t *pt_a_ptr;
1344 fsl_nboot_sb3_header_t *pt_b_ptr;
1345 fsl_nboot_sb3_header_t *active_pt_ptr;
1346 uint32_t firmwareVersion = 0xFFFFFFFFU;
1347 int otp_status = 0;
1348 #ifndef __ZEPHYR__
1349 bool flexspiFlag = __FlexSpiFlashInit();
1350 #endif
1351
1352 if (LOAD_WIFI_FIRMWARE == loadTarget)
1353 {
1354 if (sourceAddr == 0U)
1355 {
1356 pt_a_ptr = (fsl_nboot_sb3_header_t *)WIFI_IMAGE_A_OFFSET;
1357 pt_b_ptr = (fsl_nboot_sb3_header_t *)WIFI_IMAGE_B_OFFSET;
1358 }
1359 else
1360 {
1361 pt_a_ptr = (fsl_nboot_sb3_header_t *)sourceAddr;
1362 pt_b_ptr = (fsl_nboot_sb3_header_t *)(sourceAddr + WIFI_IMAGE_SIZE_MAX);
1363 }
1364 }
1365 else if (LOAD_BLE_FIRMWARE == loadTarget)
1366 {
1367 if (sourceAddr == 0U)
1368 {
1369 pt_a_ptr = (fsl_nboot_sb3_header_t *)BLE_IMAGE_A_OFFSET;
1370 pt_b_ptr = (fsl_nboot_sb3_header_t *)BLE_IMAGE_B_OFFSET;
1371 }
1372 else
1373 {
1374 pt_a_ptr = (fsl_nboot_sb3_header_t *)sourceAddr;
1375 pt_b_ptr = (fsl_nboot_sb3_header_t *)(sourceAddr + BLE_IMAGE_SIZE_MAX);
1376 }
1377 }
1378 else if (LOAD_15D4_FIRMWARE == loadTarget)
1379 {
1380 if (sourceAddr == 0U)
1381 {
1382 pt_a_ptr = (fsl_nboot_sb3_header_t *)Z154_IMAGE_A_OFFSET;
1383 pt_b_ptr = (fsl_nboot_sb3_header_t *)Z154_IMAGE_B_OFFSET;
1384 }
1385 else
1386 {
1387 pt_a_ptr = (fsl_nboot_sb3_header_t *)sourceAddr;
1388 pt_b_ptr = (fsl_nboot_sb3_header_t *)(sourceAddr + Z154_IMAGE_SIZE_MAX);
1389 }
1390 }
1391 #ifdef CONFIG_FW_VDLLV2
1392 else if (LOAD_WIFI_VDLL_FIRMWARE == loadTarget)
1393 {
1394 assert(vdll_image_base != 0U);
1395 pt_a_ptr = (fsl_nboot_sb3_header_t *)(vdll_image_base + sourceAddr);
1396 pt_b_ptr = NULL;
1397 }
1398 #endif
1399 else
1400 {
1401 return kStatus_Fail;
1402 }
1403
1404 #ifdef MCUBOOT_APPLICATION
1405 {
1406 /* Skip MCUBoot header if present */
1407
1408 struct image_header *header;
1409
1410 header = (void *)pt_a_ptr;
1411 if (header->ih_magic == IMAGE_MAGIC)
1412 {
1413 pt_a_ptr = (void *)(((uint8_t *)pt_a_ptr) + header->ih_hdr_size);
1414 }
1415
1416 header = (void *)pt_b_ptr;
1417 if (header->ih_magic == IMAGE_MAGIC)
1418 {
1419 pt_b_ptr = (void *)(((uint8_t *)pt_b_ptr) + header->ih_hdr_size);
1420 }
1421 }
1422 #endif
1423
1424 otp_status = __OtpInit();
1425 if (otp_status < 0)
1426 {
1427 return kStatus_Fail;
1428 }
1429
1430 #ifdef CONFIG_FW_VDLLV2
1431 if (LOAD_WIFI_VDLL_FIRMWARE != loadTarget)
1432 #endif
1433 {
1434 if (nboot_hal_get_secure_firmware_version(&firmwareVersion, loadTarget) != kStatus_NBOOT_Success)
1435 {
1436 return kStatus_Fail;
1437 }
1438
1439 // imu init may be called before or after load_service(), not sure user will do in which sequence.
1440 // If imu init is before load_service(), it is not appropriate do Power-Off here, then comment out Power-Off.
1441 // power_off_device_impl(); // temporarily comment out for PDM Non-UPF version
1442
1443 power_on_device_impl(loadTarget);
1444 }
1445
1446 /* Check partition TAG and select active partition */
1447 if ((pt_a_ptr->magic != TAG_SB_V3) && (pt_b_ptr->magic != TAG_SB_V3))
1448 {
1449 active_pt_ptr = pt_a_ptr;
1450 status = loader_process_raw_file((uint32_t)active_pt_ptr);
1451 }
1452 else if ((pt_a_ptr->magic == TAG_SB_V3) && (pt_b_ptr->magic != TAG_SB_V3))
1453 {
1454 active_pt_ptr = pt_a_ptr;
1455 #ifdef CONFIG_FW_VDLLV2
1456 if (LOAD_WIFI_VDLL_FIRMWARE != loadTarget)
1457 {
1458 #endif
1459 if (active_pt_ptr->firmwareVersion < firmwareVersion)
1460 {
1461 return kStatus_Fail;
1462 }
1463 #ifdef CONFIG_FW_VDLLV2
1464 }
1465 #endif
1466 status = loader_process_sb_file((uint32_t)active_pt_ptr);
1467 }
1468 else if ((pt_a_ptr->magic != TAG_SB_V3) && (pt_b_ptr->magic == TAG_SB_V3))
1469 {
1470 active_pt_ptr = pt_b_ptr;
1471 if (active_pt_ptr->firmwareVersion < firmwareVersion)
1472 {
1473 return kStatus_Fail;
1474 }
1475 status = loader_process_sb_file((uint32_t)active_pt_ptr);
1476 }
1477 else
1478 {
1479 if (pt_a_ptr->firmwareVersion >= pt_b_ptr->firmwareVersion)
1480 {
1481 active_pt_ptr = pt_a_ptr;
1482 }
1483 else
1484 {
1485 active_pt_ptr = pt_b_ptr;
1486 }
1487
1488 if (active_pt_ptr->firmwareVersion < firmwareVersion)
1489 {
1490 return kStatus_Fail;
1491 }
1492 status = loader_process_sb_file((uint32_t)active_pt_ptr);
1493 }
1494
1495 if (otp_status != 0)
1496 {
1497 /* OTP init was done here */
1498 (void)__OtpDeInit();
1499 }
1500
1501 if (status == kStatus_Success)
1502 {
1503 reset_device(loadTarget);
1504 }
1505
1506 #ifndef __ZEPHYR__
1507 if (flexspiFlag)
1508 {
1509 __FlexSpiFlashDeInit();
1510 }
1511 #endif
1512 return status;
1513 }
1514
1515
load_service_monolithic(LOAD_Target_Type loadTarget,uint32_t sourceAddr)1516 static status_t load_service_monolithic(LOAD_Target_Type loadTarget, uint32_t sourceAddr)
1517 {
1518 status_t status = kStatus_Fail;
1519 uint32_t hdr_a = 0UL;
1520 fsl_nboot_sb3_header_t boot_hdr;
1521 fsl_nboot_sb3_header_t *pt_a_ptr = &boot_hdr;
1522 uint32_t firmwareVersion = 0xFFFFFFFFU;
1523 uint32_t sel_fw_ver;
1524 int otp_status = 0;
1525
1526 memset(&boot_hdr, 0xff, sizeof(fsl_nboot_sb3_header_t));
1527
1528 #ifndef __ZEPHYR__
1529 bool flexspiFlag = __FlexSpiFlashInit();
1530 #endif
1531 (void)mflash_drv_init();
1532 do {
1533 status_t ret = kStatus_Fail;
1534 if ((LOAD_WIFI_FW_MONOLITHIC != loadTarget) && (LOAD_BLE_FW_MONOLITHIC != loadTarget) && (LOAD_15D4_FW_MONOLITHIC != loadTarget))
1535 {
1536 break;
1537 }
1538 if (sourceAddr == 0UL)
1539 {
1540 break;
1541 }
1542 hdr_a = sourceAddr;
1543
1544 otp_status = __OtpInit();
1545 if (otp_status < 0)
1546 {
1547 break;
1548 }
1549
1550 if (nboot_hal_get_secure_firmware_version(&firmwareVersion, loadTarget) != kStatus_NBOOT_Success)
1551 {
1552 break;
1553 }
1554
1555 // imu init may be called before or after load_service(), not sure user will do in which sequence.
1556 // If imu init is before load_service(), it is not appropriate do Power-Off here, then comment out Power-Off.
1557 // power_off_device_impl(); // temporarily comment out for PDM Non-UPF version
1558
1559 power_on_device_impl(loadTarget);
1560
1561 ret = ldr_ReadFromFlash((uint8_t*)pt_a_ptr, hdr_a, sizeof(fsl_nboot_sb3_header_t ));
1562 if (ret != kStatus_Success)
1563 {
1564 break;
1565 }
1566 /* Check partition TAG and select active partition */
1567 if (pt_a_ptr->magic == TAG_SB_V3)
1568 {
1569 sel_fw_ver = pt_a_ptr->firmwareVersion;
1570
1571 if (sel_fw_ver < firmwareVersion)
1572 {
1573 break;
1574 }
1575 status = loader_process_sb_file(hdr_a);
1576 }
1577 else
1578 {
1579 status = loader_process_raw_file_monolithic(hdr_a);
1580 }
1581
1582 } while (false);
1583
1584 if (otp_status != 0)
1585 {
1586 /* OTP init was done here so undo it here */
1587 (void)__OtpDeInit();
1588 }
1589
1590 if (status == kStatus_Success)
1591 {
1592 reset_device(loadTarget);
1593 }
1594 #ifndef __ZEPHYR__
1595 if (flexspiFlag)
1596 {
1597 __FlexSpiFlashDeInit();
1598 }
1599 #endif
1600 return status;
1601 }
1602
1603 ////////////////////////////////////////////////////////////////////////////
1604 //! @brief get chip revision
1605 ////////////////////////////////////////////////////////////////////////////
get_chip_revision(void)1606 uint8_t get_chip_revision(void)
1607 {
1608 return (uint8_t)(SOCCTRL->CHIP_INFO & SOCCTRL_CHIP_INFO_REV_NUM_MASK);
1609 }
1610
1611 //! @}
1612 ////////////////////////////////////////////////////////////////////////////
1613 // EOF
1614 ////////////////////////////////////////////////////////////////////////////