692 lines
25 KiB
C
692 lines
25 KiB
C
/*
|
|
* Copyright 2018-2021 NXP
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*
|
|
*/
|
|
|
|
#include "fsl_iap.h"
|
|
#include "fsl_iap_ffr.h"
|
|
#include "fsl_iap_kbp.h"
|
|
#include "fsl_iap_skboot_authenticate.h"
|
|
#include "fsl_device_registers.h"
|
|
/*******************************************************************************
|
|
* Definitions
|
|
******************************************************************************/
|
|
/* Component ID definition, used by tools. */
|
|
#ifndef FSL_COMPONENT_ID
|
|
#define FSL_COMPONENT_ID "platform.drivers.iap1"
|
|
#endif
|
|
|
|
#if (defined(LPC5512_SERIES) || defined(LPC5514_SERIES) || defined(LPC55S14_SERIES) || defined(LPC5516_SERIES) || \
|
|
defined(LPC55S16_SERIES) || defined(LPC5524_SERIES) || defined(LPC5502_SERIES) || defined(LPC5504_SERIES) || \
|
|
defined(LPC5506_SERIES) || defined(LPC55S04_SERIES) || defined(LPC55S06_SERIES))
|
|
|
|
#define BOOTLOADER_API_TREE_POINTER ((bootloader_tree_t *)0x1301fe00U)
|
|
|
|
#elif (defined(LPC55S69_cm33_core0_SERIES) || defined(LPC55S69_cm33_core1_SERIES) || defined(LPC5526_SERIES) || \
|
|
defined(LPC55S26_SERIES) || defined(LPC5528_SERIES) || defined(LPC55S28_SERIES) || \
|
|
defined(LPC55S66_cm33_core0_SERIES) || defined(LPC55S66_cm33_core1_SERIES))
|
|
|
|
#define BOOTLOADER_API_TREE_POINTER ((bootloader_tree_t *)0x130010f0U)
|
|
|
|
#else
|
|
#error "No valid CPU defined!"
|
|
|
|
#endif
|
|
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
******************************************************************************/
|
|
static status_t get_cfpa_higher_version(flash_config_t *config);
|
|
|
|
/*!
|
|
* @name flash and ffr Structure
|
|
* @{
|
|
*/
|
|
|
|
typedef union functionCommandOption
|
|
{
|
|
uint32_t commandAddr;
|
|
status_t (*eraseCommand)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key);
|
|
status_t (*programCommand)(flash_config_t *config, uint32_t start, const uint8_t *src, uint32_t lengthInBytes);
|
|
status_t (*verifyProgramCommand)(flash_config_t *config,
|
|
uint32_t start,
|
|
uint32_t lengthInBytes,
|
|
const uint8_t *expectedData,
|
|
uint32_t *failedAddress,
|
|
uint32_t *failedData);
|
|
status_t (*flashReadCommand)(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes);
|
|
} function_command_option_t;
|
|
|
|
/*
|
|
*!@brief Structure of version property.
|
|
*
|
|
*!@ingroup bl_core
|
|
*/
|
|
typedef union StandardVersion
|
|
{
|
|
struct
|
|
{
|
|
uint32_t bugfix : 8; /*!< bugfix version [7:0] */
|
|
uint32_t minor : 8; /*!< minor version [15:8] */
|
|
uint32_t major : 8; /*!< major version [23:16] */
|
|
uint32_t name : 8; /*!< name [31:24] */
|
|
};
|
|
uint32_t version; /*!< combined version numbers. */
|
|
#if defined(__cplusplus)
|
|
StandardVersion() : version(0)
|
|
{
|
|
}
|
|
StandardVersion(uint32_t version) : version(version)
|
|
{
|
|
}
|
|
#endif
|
|
} standard_version_t;
|
|
|
|
/*! @brief Interface for the flash driver.*/
|
|
typedef struct version1FlashDriverInterface
|
|
{
|
|
standard_version_t version; /*!< flash driver API version number.*/
|
|
|
|
/*!< Flash driver.*/
|
|
status_t (*flash_init)(flash_config_t *config);
|
|
status_t (*flash_erase)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key);
|
|
status_t (*flash_program)(flash_config_t *config, uint32_t start, const uint8_t *src, uint32_t lengthInBytes);
|
|
status_t (*flash_verify_erase)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
|
|
status_t (*flash_verify_program)(flash_config_t *config,
|
|
uint32_t start,
|
|
uint32_t lengthInBytes,
|
|
const uint8_t *expectedData,
|
|
uint32_t *failedAddress,
|
|
uint32_t *failedData);
|
|
status_t (*flash_get_property)(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value);
|
|
uint32_t reserved[3]; /*! Reserved for future use */
|
|
/*!< Flash FFR driver*/
|
|
status_t (*ffr_init)(flash_config_t *config);
|
|
status_t (*ffr_lock_all)(flash_config_t *config);
|
|
status_t (*ffr_cust_factory_page_write)(flash_config_t *config, uint8_t *page_data, bool seal_part);
|
|
status_t (*ffr_get_uuid)(flash_config_t *config, uint8_t *uuid);
|
|
status_t (*ffr_get_customer_data)(flash_config_t *config, uint8_t *pData, uint32_t offset, uint32_t len);
|
|
status_t (*ffr_keystore_write)(flash_config_t *config, ffr_key_store_t *pKeyStore);
|
|
status_t (*ffr_keystore_get_ac)(flash_config_t *config, uint8_t *pActivationCode);
|
|
status_t (*ffr_keystore_get_kc)(flash_config_t *config, uint8_t *pKeyCode, ffr_key_type_t keyIndex);
|
|
status_t (*ffr_infield_page_write)(flash_config_t *config, uint8_t *page_data, uint32_t valid_len);
|
|
status_t (*ffr_get_customer_infield_data)(flash_config_t *config, uint8_t *pData, uint32_t offset, uint32_t len);
|
|
} version1_flash_driver_interface_t;
|
|
|
|
/*! @brief Interface for the flash driver.*/
|
|
typedef struct version0FlashDriverInterface
|
|
{
|
|
standard_version_t version; /*!< flash driver API version number.*/
|
|
|
|
/*!< Flash driver.*/
|
|
status_t (*flash_init)(flash_config_t *config);
|
|
status_t (*flash_erase)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key);
|
|
status_t (*flash_program)(flash_config_t *config, uint32_t start, const uint8_t *src, uint32_t lengthInBytes);
|
|
status_t (*flash_verify_erase)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
|
|
status_t (*flash_verify_program)(flash_config_t *config,
|
|
uint32_t start,
|
|
uint32_t lengthInBytes,
|
|
const uint8_t *expectedData,
|
|
uint32_t *failedAddress,
|
|
uint32_t *failedData);
|
|
status_t (*flash_get_property)(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value);
|
|
|
|
/*!< Flash FFR driver*/
|
|
status_t (*ffr_init)(flash_config_t *config);
|
|
status_t (*ffr_lock_all)(flash_config_t *config);
|
|
status_t (*ffr_cust_factory_page_write)(flash_config_t *config, uint8_t *page_data, bool seal_part);
|
|
status_t (*ffr_get_uuid)(flash_config_t *config, uint8_t *uuid);
|
|
status_t (*ffr_get_customer_data)(flash_config_t *config, uint8_t *pData, uint32_t offset, uint32_t len);
|
|
status_t (*ffr_keystore_write)(flash_config_t *config, ffr_key_store_t *pKeyStore);
|
|
status_t (*ffr_keystore_get_ac)(flash_config_t *config, uint8_t *pActivationCode);
|
|
status_t (*ffr_keystore_get_kc)(flash_config_t *config, uint8_t *pKeyCode, ffr_key_type_t keyIndex);
|
|
status_t (*ffr_infield_page_write)(flash_config_t *config, uint8_t *page_data, uint32_t valid_len);
|
|
status_t (*ffr_get_customer_infield_data)(flash_config_t *config, uint8_t *pData, uint32_t offset, uint32_t len);
|
|
} version0_flash_driver_interface_t;
|
|
|
|
typedef union flashDriverInterface
|
|
{
|
|
const version1_flash_driver_interface_t *version1FlashDriver;
|
|
const version0_flash_driver_interface_t *version0FlashDriver;
|
|
} flash_driver_interface_t;
|
|
|
|
/*! @}*/
|
|
|
|
/*!
|
|
* @name Bootloader API and image authentication Structure
|
|
* @{
|
|
*/
|
|
|
|
/*! @brief Interface for Bootloader API functions. */
|
|
typedef struct _kb_interface
|
|
{
|
|
/*!< Initialize the API. */
|
|
status_t (*kb_init_function)(kb_session_ref_t **session, const kb_options_t *options);
|
|
status_t (*kb_deinit_function)(kb_session_ref_t *session);
|
|
status_t (*kb_execute_function)(kb_session_ref_t *session, const uint8_t *data, uint32_t dataLength);
|
|
} kb_interface_t;
|
|
|
|
//! @brief Interface for image authentication API
|
|
typedef struct _skboot_authenticate_interface
|
|
{
|
|
skboot_status_t (*skboot_authenticate_function)(const uint8_t *imageStartAddr, secure_bool_t *isSignVerified);
|
|
void (*skboot_hashcrypt_irq_handler)(void);
|
|
} skboot_authenticate_interface_t;
|
|
/*! @}*/
|
|
|
|
/*!
|
|
* @brief Root of the bootloader API tree.
|
|
*
|
|
* An instance of this struct resides in read-only memory in the bootloader. It
|
|
* provides a user application access to APIs exported by the bootloader.
|
|
*
|
|
* @note The order of existing fields must not be changed.
|
|
*/
|
|
typedef struct BootloaderTree
|
|
{
|
|
void (*runBootloader)(void *arg); /*!< Function to start the bootloader executing. */
|
|
standard_version_t bootloader_version; /*!< Bootloader version number. */
|
|
const char *copyright; /*!< Copyright string. */
|
|
const uint32_t reserved0; /*!< Do NOT use. */
|
|
flash_driver_interface_t flashDriver;
|
|
const kb_interface_t *kbApi; /*!< Bootloader API. */
|
|
const uint32_t reserved1[4]; /*!< Do NOT use. */
|
|
const skboot_authenticate_interface_t *skbootAuthenticate; /*!< Image authentication API. */
|
|
} bootloader_tree_t;
|
|
|
|
/*******************************************************************************
|
|
* Prototype
|
|
******************************************************************************/
|
|
static uint32_t get_rom_api_version(void);
|
|
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
|
|
/*! Get pointer to flash driver API table in ROM. */
|
|
#define VERSION1_FLASH_API_TREE BOOTLOADER_API_TREE_POINTER->flashDriver.version1FlashDriver
|
|
#define VERSION0_FLASH_API_TREE BOOTLOADER_API_TREE_POINTER->flashDriver.version0FlashDriver
|
|
#define LPC55S69_REV0_FLASH_READ_ADDR (0x130043a3U)
|
|
#define LPC55S69_REV1_FLASH_READ_ADDR (0x13007539U)
|
|
#define LPC55S16_REV0_FLASH_READ_ADDR (0x1300ade5U)
|
|
|
|
/*******************************************************************************
|
|
* Code
|
|
******************************************************************************/
|
|
|
|
static uint32_t get_rom_api_version(void)
|
|
{
|
|
if (BOOTLOADER_API_TREE_POINTER->bootloader_version.major == 3u)
|
|
{
|
|
return 1u;
|
|
}
|
|
else
|
|
{
|
|
return 0u;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* @brief Initializes the global flash properties structure members.
|
|
*
|
|
* This function checks and initializes the Flash module for the other Flash APIs.
|
|
*/
|
|
status_t FLASH_Init(flash_config_t *config)
|
|
{
|
|
status_t status;
|
|
/* Initialize the clock to 96MHz */
|
|
config->modeConfig.sysFreqInMHz = (uint32_t)kSysToFlashFreq_defaultInMHz;
|
|
if (get_rom_api_version() == 1u)
|
|
{
|
|
status = VERSION1_FLASH_API_TREE->flash_init(config);
|
|
}
|
|
else
|
|
{
|
|
status = VERSION0_FLASH_API_TREE->flash_init(config);
|
|
}
|
|
|
|
if (config->PFlashTotalSize == 0xA0000U)
|
|
{
|
|
config->PFlashTotalSize -= 17U * config->PFlashPageSize;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/*!
|
|
* @brief Erases the flash sectors encompassed by parameters passed into function.
|
|
*
|
|
* This function erases the appropriate number of flash sectors based on the
|
|
* desired start address and length.
|
|
*/
|
|
status_t FLASH_Erase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key)
|
|
{
|
|
uint32_t core_frequency = CLOCK_GetFreq(kCLOCK_CoreSysClk);
|
|
|
|
/* Flash ERASE operations must be performed with a system clock below or equal to 100 MHz.*/
|
|
if (core_frequency > 100000000U)
|
|
{
|
|
return (status_t)kStatus_FLASH_EraseFrequencyError;
|
|
}
|
|
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
function_command_option_t runCmdFuncOption;
|
|
runCmdFuncOption.commandAddr = 0x1300413bU; /*!< get the flash erase api location adress in rom */
|
|
return runCmdFuncOption.eraseCommand(config, start, lengthInBytes, key);
|
|
}
|
|
else
|
|
{
|
|
return VERSION1_FLASH_API_TREE->flash_erase(config, start, lengthInBytes, key);
|
|
}
|
|
}
|
|
|
|
/*! See fsl_iap.h for documentation of this function. */
|
|
status_t FLASH_Program(flash_config_t *config, uint32_t start, const uint8_t *src, uint32_t lengthInBytes)
|
|
{
|
|
uint32_t core_frequency = CLOCK_GetFreq(kCLOCK_CoreSysClk);
|
|
|
|
/* Flash PROGRAM operations must be performed with a system clock below or equal to 100 MHz.*/
|
|
if (core_frequency > 100000000U)
|
|
{
|
|
return (status_t)kStatus_FLASH_ProgramFrequencyError;
|
|
}
|
|
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
function_command_option_t runCmdFuncOption;
|
|
runCmdFuncOption.commandAddr = 0x1300419dU; /*!< get the flash program api location adress in rom*/
|
|
return runCmdFuncOption.programCommand(config, start, src, lengthInBytes);
|
|
}
|
|
else
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
return VERSION1_FLASH_API_TREE->flash_program(config, start, src, lengthInBytes);
|
|
}
|
|
}
|
|
|
|
/*! See fsl_iap.h for documentation of this function. */
|
|
status_t FLASH_Read(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes)
|
|
{
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
/*!< get the flash read api location adress in rom*/
|
|
function_command_option_t runCmdFuncOption;
|
|
runCmdFuncOption.commandAddr = LPC55S69_REV0_FLASH_READ_ADDR;
|
|
return runCmdFuncOption.flashReadCommand(config, start, dest, lengthInBytes);
|
|
}
|
|
else
|
|
{
|
|
/*!< get the flash read api location adress in rom*/
|
|
function_command_option_t runCmdFuncOption;
|
|
if ((SYSCON->DIEID & SYSCON_DIEID_REV_ID_MASK) != 0u)
|
|
{
|
|
runCmdFuncOption.commandAddr = LPC55S69_REV1_FLASH_READ_ADDR;
|
|
}
|
|
else
|
|
{
|
|
runCmdFuncOption.commandAddr = LPC55S16_REV0_FLASH_READ_ADDR;
|
|
}
|
|
return runCmdFuncOption.flashReadCommand(config, start, dest, lengthInBytes);
|
|
}
|
|
}
|
|
|
|
/*! See fsl_iap.h for documentation of this function. */
|
|
status_t FLASH_VerifyErase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes)
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
return VERSION1_FLASH_API_TREE->flash_verify_erase(config, start, lengthInBytes);
|
|
}
|
|
|
|
/*!
|
|
* @brief Verifies programming of the desired flash area at a specified margin level.
|
|
*
|
|
* This function verifies the data programed in the flash memory using the
|
|
* Flash Program Check Command and compares it to the expected data for a given
|
|
* flash area as determined by the start address and length.
|
|
*/
|
|
status_t FLASH_VerifyProgram(flash_config_t *config,
|
|
uint32_t start,
|
|
uint32_t lengthInBytes,
|
|
const uint8_t *expectedData,
|
|
uint32_t *failedAddress,
|
|
uint32_t *failedData)
|
|
{
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
function_command_option_t runCmdFuncOption;
|
|
runCmdFuncOption.commandAddr = 0x1300427dU; /*!< get the flash verify program api location adress in rom*/
|
|
return runCmdFuncOption.verifyProgramCommand(config, start, lengthInBytes, expectedData, failedAddress,
|
|
failedData);
|
|
}
|
|
else
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
return VERSION1_FLASH_API_TREE->flash_verify_program(config, start, lengthInBytes, expectedData, failedAddress,
|
|
failedData);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* @brief Returns the desired flash property.
|
|
*/
|
|
status_t FLASH_GetProperty(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value)
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
return VERSION1_FLASH_API_TREE->flash_get_property(config, whichProperty, value);
|
|
}
|
|
/********************************************************************************
|
|
* fsl iap ffr CODE
|
|
*******************************************************************************/
|
|
|
|
static status_t get_cfpa_higher_version(flash_config_t *config)
|
|
{
|
|
uint32_t pageData[FLASH_FFR_MAX_PAGE_SIZE / sizeof(uint32_t)];
|
|
uint32_t versionPing = 0U;
|
|
uint32_t versionPong = 0U;
|
|
|
|
/* Get the CFPA ping page data and the corresponding version */
|
|
config->ffrConfig.cfpaPageOffset = 1U;
|
|
status_t status = FFR_GetCustomerInfieldData(config, (uint8_t *)pageData, 0U, FLASH_FFR_MAX_PAGE_SIZE);
|
|
if (status != (int32_t)kStatus_FLASH_Success)
|
|
{
|
|
return status;
|
|
}
|
|
versionPing = pageData[1];
|
|
|
|
/* Get the CFPA pong page data and the corresponding version */
|
|
config->ffrConfig.cfpaPageOffset = 2U;
|
|
status = FFR_GetCustomerInfieldData(config, (uint8_t *)pageData, 0U, FLASH_FFR_MAX_PAGE_SIZE);
|
|
if (status != (int32_t)kStatus_FLASH_Success)
|
|
{
|
|
return status;
|
|
}
|
|
versionPong = pageData[1];
|
|
|
|
/* Compare the CFPA ping version and pong version and set it correctly in flash_config structure */
|
|
if (versionPing > versionPong)
|
|
{
|
|
config->ffrConfig.cfpaPageVersion = versionPing;
|
|
config->ffrConfig.cfpaPageOffset = 1U;
|
|
}
|
|
else
|
|
{
|
|
config->ffrConfig.cfpaPageVersion = versionPong;
|
|
config->ffrConfig.cfpaPageOffset = 2U;
|
|
}
|
|
return (int32_t)kStatus_FLASH_Success;
|
|
}
|
|
|
|
/*!
|
|
* Initializes the global FFR properties structure members.
|
|
*/
|
|
status_t FFR_Init(flash_config_t *config)
|
|
{
|
|
status_t status;
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
assert(VERSION0_FLASH_API_TREE);
|
|
status = VERSION0_FLASH_API_TREE->ffr_init(config);
|
|
if (status != (status_t)kStatus_FLASH_Success)
|
|
{
|
|
return status;
|
|
}
|
|
return get_cfpa_higher_version(config);
|
|
}
|
|
else
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
status = VERSION1_FLASH_API_TREE->ffr_init(config);
|
|
if (status != (status_t)kStatus_FLASH_Success)
|
|
{
|
|
return status;
|
|
}
|
|
return get_cfpa_higher_version(config);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* Enable firewall for all flash banks.
|
|
*/
|
|
status_t FFR_Lock_All(flash_config_t *config)
|
|
{
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
assert(VERSION0_FLASH_API_TREE);
|
|
return VERSION0_FLASH_API_TREE->ffr_lock_all(config);
|
|
}
|
|
else
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
return VERSION1_FLASH_API_TREE->ffr_lock_all(config);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* APIs to access CMPA pages;
|
|
* This routine will erase "customer factory page" and program the page with passed data.
|
|
*/
|
|
status_t FFR_CustFactoryPageWrite(flash_config_t *config, uint8_t *page_data, bool seal_part)
|
|
{
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
assert(VERSION0_FLASH_API_TREE);
|
|
return VERSION0_FLASH_API_TREE->ffr_cust_factory_page_write(config, page_data, seal_part);
|
|
}
|
|
else
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
return VERSION1_FLASH_API_TREE->ffr_cust_factory_page_write(config, page_data, seal_part);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* See fsl_iap_ffr.h for documentation of this function.
|
|
*/
|
|
status_t FFR_GetUUID(flash_config_t *config, uint8_t *uuid)
|
|
{
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
assert(VERSION0_FLASH_API_TREE);
|
|
return VERSION0_FLASH_API_TREE->ffr_get_uuid(config, uuid);
|
|
}
|
|
else
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
return VERSION1_FLASH_API_TREE->ffr_get_uuid(config, uuid);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* APIs to access CMPA pages
|
|
* Read data stored in 'Customer Factory CFG Page'.
|
|
*/
|
|
status_t FFR_GetCustomerData(flash_config_t *config, uint8_t *pData, uint32_t offset, uint32_t len)
|
|
{
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
assert(VERSION0_FLASH_API_TREE);
|
|
return VERSION0_FLASH_API_TREE->ffr_get_customer_data(config, pData, offset, len);
|
|
}
|
|
else
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
return VERSION1_FLASH_API_TREE->ffr_get_customer_data(config, pData, offset, len);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* This routine writes the 3 pages allocated for Key store data,
|
|
* Used during manufacturing. Should write pages when 'customer factory page' is not in sealed state.
|
|
*/
|
|
status_t FFR_KeystoreWrite(flash_config_t *config, ffr_key_store_t *pKeyStore)
|
|
{
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
assert(VERSION0_FLASH_API_TREE);
|
|
return VERSION0_FLASH_API_TREE->ffr_keystore_write(config, pKeyStore);
|
|
}
|
|
else
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
return VERSION1_FLASH_API_TREE->ffr_keystore_write(config, pKeyStore);
|
|
}
|
|
}
|
|
|
|
/*! See fsl_iap_ffr.h for documentation of this function. */
|
|
status_t FFR_KeystoreGetAC(flash_config_t *config, uint8_t *pActivationCode)
|
|
{
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
assert(VERSION0_FLASH_API_TREE);
|
|
return VERSION0_FLASH_API_TREE->ffr_keystore_get_ac(config, pActivationCode);
|
|
}
|
|
else
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
return VERSION1_FLASH_API_TREE->ffr_keystore_get_ac(config, pActivationCode);
|
|
}
|
|
}
|
|
|
|
/*! See fsl_iap_ffr.h for documentation of this function. */
|
|
status_t FFR_KeystoreGetKC(flash_config_t *config, uint8_t *pKeyCode, ffr_key_type_t keyIndex)
|
|
{
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
assert(VERSION0_FLASH_API_TREE);
|
|
return VERSION0_FLASH_API_TREE->ffr_keystore_get_kc(config, pKeyCode, keyIndex);
|
|
}
|
|
else
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
return VERSION1_FLASH_API_TREE->ffr_keystore_get_kc(config, pKeyCode, keyIndex);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* APIs to access CFPA pages
|
|
* This routine will erase CFPA and program the CFPA page with passed data.
|
|
*/
|
|
status_t FFR_InfieldPageWrite(flash_config_t *config, uint8_t *page_data, uint32_t valid_len)
|
|
{
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
assert(VERSION0_FLASH_API_TREE);
|
|
return VERSION0_FLASH_API_TREE->ffr_infield_page_write(config, page_data, valid_len);
|
|
}
|
|
else
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
return VERSION1_FLASH_API_TREE->ffr_infield_page_write(config, page_data, valid_len);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* APIs to access CFPA pages
|
|
* Generic read function, used by customer to read data stored in 'Customer In-field Page'.
|
|
*/
|
|
status_t FFR_GetCustomerInfieldData(flash_config_t *config, uint8_t *pData, uint32_t offset, uint32_t len)
|
|
{
|
|
if (get_rom_api_version() == 0u)
|
|
{
|
|
assert(VERSION0_FLASH_API_TREE);
|
|
return VERSION0_FLASH_API_TREE->ffr_get_customer_infield_data(config, pData, offset, len);
|
|
}
|
|
else
|
|
{
|
|
assert(VERSION1_FLASH_API_TREE);
|
|
return VERSION1_FLASH_API_TREE->ffr_get_customer_infield_data(config, pData, offset, len);
|
|
}
|
|
}
|
|
|
|
/********************************************************************************
|
|
* Bootloader API
|
|
*******************************************************************************/
|
|
/*!
|
|
* @brief Initialize ROM API for a given operation.
|
|
*
|
|
* Inits the ROM API based on the options provided by the application in the second
|
|
* argument. Every call to rom_init() should be paired with a call to rom_deinit().
|
|
*/
|
|
status_t kb_init(kb_session_ref_t **session, const kb_options_t *options)
|
|
{
|
|
assert(BOOTLOADER_API_TREE_POINTER);
|
|
return BOOTLOADER_API_TREE_POINTER->kbApi->kb_init_function(session, options);
|
|
}
|
|
|
|
/*!
|
|
* @brief Cleans up the ROM API context.
|
|
*
|
|
* After this call, the @a context parameter can be reused for another operation
|
|
* by calling rom_init() again.
|
|
*/
|
|
status_t kb_deinit(kb_session_ref_t *session)
|
|
{
|
|
assert(BOOTLOADER_API_TREE_POINTER);
|
|
return BOOTLOADER_API_TREE_POINTER->kbApi->kb_deinit_function(session);
|
|
}
|
|
|
|
/*!
|
|
* Perform the operation configured during init.
|
|
*
|
|
* This application must call this API repeatedly, passing in sequential chunks of
|
|
* data from the boot image (SB file) that is to be processed. The ROM will perform
|
|
* the selected operation on this data and return. The application may call this
|
|
* function with as much or as little data as it wishes, which can be used to select
|
|
* the granularity of time given to the application in between executing the operation.
|
|
*
|
|
* @param context Current ROM context pointer.
|
|
* @param data Buffer of boot image data provided to the ROM by the application.
|
|
* @param dataLength Length in bytes of the data in the buffer provided to the ROM.
|
|
*
|
|
* @retval #kStatus_Success The operation has completed successfully.
|
|
* @retval #kStatus_Fail An error occurred while executing the operation.
|
|
* @retval #kStatus_RomApiNeedMoreData No error occurred, but the ROM needs more data to
|
|
* continue processing the boot image.
|
|
*/
|
|
status_t kb_execute(kb_session_ref_t *session, const uint8_t *data, uint32_t dataLength)
|
|
{
|
|
assert(BOOTLOADER_API_TREE_POINTER);
|
|
return BOOTLOADER_API_TREE_POINTER->kbApi->kb_execute_function(session, data, dataLength);
|
|
}
|
|
|
|
/********************************************************************************
|
|
* Image authentication API
|
|
*******************************************************************************/
|
|
|
|
/*!
|
|
* @brief Authenticate entry function with ARENA allocator init
|
|
*
|
|
* This is called by ROM boot or by ROM API g_skbootAuthenticateInterface
|
|
*/
|
|
skboot_status_t skboot_authenticate(const uint8_t *imageStartAddr, secure_bool_t *isSignVerified)
|
|
{
|
|
assert(BOOTLOADER_API_TREE_POINTER);
|
|
return BOOTLOADER_API_TREE_POINTER->skbootAuthenticate->skboot_authenticate_function(imageStartAddr,
|
|
isSignVerified);
|
|
}
|
|
|
|
/*!
|
|
* @brief Interface for image authentication API
|
|
*/
|
|
void HASH_IRQHandler(void)
|
|
{
|
|
assert(BOOTLOADER_API_TREE_POINTER);
|
|
BOOTLOADER_API_TREE_POINTER->skbootAuthenticate->skboot_hashcrypt_irq_handler();
|
|
}
|
|
|
|
/********************************************************************************
|
|
* runBootloader API
|
|
*******************************************************************************/
|
|
void BOOTLOADER_UserEntry(void *arg)
|
|
{
|
|
assert(BOOTLOADER_API_TREE_POINTER);
|
|
BOOTLOADER_API_TREE_POINTER->runBootloader(arg);
|
|
}
|
|
/********************************************************************************
|
|
* EOF
|
|
*******************************************************************************/
|