static void configure_quadspi_as_needed(void) { // Start the lifetime counter microseconds_init(); if (qspi_need_configure()) { status_t qspiOtfadInitStatus = kStatus_QspiNotConfigured; // Try to configure QuadSPI module based on on qspi_config_block_pointer in BCA first, // If bootloader cannot get qspi config block from internal flash, try to configure QSPI // based on default place (start address of QuadSPI memory). uint32_t qspi_config_block_base = g_bootloaderContext.propertyInterface->store->configurationData.qspi_config_block_pointer; // Get the start address and flash size uint32_t flashStart; g_bootloaderContext.flashDriverInterface->flash_get_property(&g_bootloaderContext.flashState, kFLASH_PropertyPflashBlockBaseAddr, &flashStart); uint32_t flashSize; g_bootloaderContext.flashDriverInterface->flash_get_property(&g_bootloaderContext.flashState, kFLASH_PropertyPflashTotalSize, &flashSize); // Check if the pointer of qspi config block is valid. if ((qspi_config_block_base != 0xFFFFFFFF) && (qspi_config_block_base > flashStart) && (qspi_config_block_base <= (flashStart + flashSize - sizeof(qspi_config_t)))) { #if FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL if (!is_in_execute_only_region(qspi_config_block_base, sizeof(qspi_config_t))) { qspiOtfadInitStatus = quadspi_init((void *)qspi_config_block_base); } #else qspiOtfadInitStatus = quadspi_init((void *)qspi_config_block_base); #endif // FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL } if (qspiOtfadInitStatus == kStatus_QspiNotConfigured) { qspiOtfadInitStatus = quadspi_init(NULL); } update_qspi_otfad_init_status(qspiOtfadInitStatus); } // Shutdown the lifetime counter before configuring clock. lock_acquire(); microseconds_shutdown(); lock_release(); }
// See bl_shutdown_cleanup.h for documentation of this function. void shutdown_cleanup(shutdown_type_t shutdown) { #if !defined(BOOTLOADER_HOST) if (shutdown != kShutdownType_Reset) { // Clear (flush) the flash cache. flash_cache_clear(NULL); } if (shutdown != kShutdownType_Cleanup) { // Shutdown all peripherals because they could be active uint32_t i; for (i = 0; g_peripherals[i].typeMask != 0; i++) { if (g_peripherals[i].controlInterface->shutdown) { g_peripherals[i].controlInterface->shutdown(&g_peripherals[i]); } } } // If we are permanently exiting the bootloader, there are a few extra things to do. if (shutdown == kShutdownType_Shutdown) { // Turn off global interrupt lock_acquire(); // Shutdown microseconds driver. microseconds_shutdown(); #if defined(RCM_FM) // Disable force ROM. RCM_BWR_FM_FORCEROM(RCM, 0); // Clear status register (bits are w1c). RCM_BWR_MR_BOOTROM(RCM, 3); #endif // defined(RCM_FM) init_interrupts(); // Set the VTOR to default. SCB->VTOR = kDefaultVectorTableAddress; // Restore clock to default before leaving bootloader. configure_clocks(kClockOption_ExitBootloader); // De-initialize hardware such as disabling port clock gate deinit_hardware(); // Restore global interrupt. __enable_irq(); #if BL_FEATURE_BYPASS_WATCHDOG // De-initialize watchdog bootloader_watchdog_deinit(); #endif // BL_FEATURE_BYPASS_WATCHDOG } // Memory barriers for good measure. __ISB(); __DSB(); #endif }