Imported more library files
Not compiling currently
This commit is contained in:
168
Libs/platform/bootloader/api/application_properties.h
Normal file
168
Libs/platform/bootloader/api/application_properties.h
Normal file
@@ -0,0 +1,168 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Representation of Application Properties
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc. Your use of this
|
||||
* software is governed by the terms of Silicon Labs Master Software License
|
||||
* Agreement (MSLA) available at
|
||||
* www.silabs.com/about-us/legal/master-software-license-agreement. This
|
||||
* software is distributed to you in Source Code format and is governed by the
|
||||
* sections of the MSLA applicable to Source Code.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef APPLICATION_PROPERTIES_H
|
||||
#define APPLICATION_PROPERTIES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup Interface
|
||||
* @{
|
||||
* @addtogroup ApplicationProperties Application Properties
|
||||
* @brief Properties of the application that can be accessed by the bootloader
|
||||
* @details
|
||||
* Applications must contain an @ref ApplicationProperties_t struct declaring
|
||||
* the application version and capabilities, and so on. The metadata contained
|
||||
* in this struct will be extracted from the application by the Simplicity
|
||||
* Commander tool and placed in the GBL upgrade file. If this struct is not
|
||||
* in the application image, it will be added to the GBL file by the
|
||||
* Simplicity Commander.
|
||||
*
|
||||
* The struct is also used to declare whether the application image is signed
|
||||
* and what type of signature is used. If no @ref ApplicationProperties_t
|
||||
* struct is present, the bootloader will assume that the application image
|
||||
* is signed using @ref APPLICATION_SIGNATURE_ECDSA_P256.
|
||||
*
|
||||
* To ensure that the bootloader can easily locate the ApplicationProperties_t
|
||||
* struct, if not already done by the linker, Simplicity Commander will modify
|
||||
* word 13 of the application to insert a pointer to the
|
||||
* ApplicationProperties_t struct.
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/// Magic value declaring the existence of an ApplicationProperties_t struct
|
||||
#define APPLICATION_PROPERTIES_MAGIC { \
|
||||
0x13, 0xb7, 0x79, 0xfa, \
|
||||
0xc9, 0x25, 0xdd, 0xb7, \
|
||||
0xad, 0xf3, 0xcf, 0xe0, \
|
||||
0xf1, 0xb6, 0x14, 0xb8 \
|
||||
}
|
||||
|
||||
/// Byte-reversed version of ::APPLICATION_PROPERTIES_MAGIC
|
||||
#define APPLICATION_PROPERTIES_REVERSED { \
|
||||
0xb8, 0x14, 0xb6, 0xf1, \
|
||||
0xe0, 0xcf, 0xf3, 0xad, \
|
||||
0xb7, 0xdd, 0x25, 0xc9, \
|
||||
0xfa, 0x79, 0xb7, 0x13 \
|
||||
}
|
||||
|
||||
/// Major version number of the AppliationProperties_t struct
|
||||
#define APPLICATION_PROPERTIES_VERSION_MAJOR (1UL)
|
||||
/// Minor version number of the AppliationProperties_t struct
|
||||
#define APPLICATION_PROPERTIES_VERSION_MINOR (2UL)
|
||||
/// Version number of the ApplicationCertificate_t struct
|
||||
#define APPLICATION_CERTIFICATE_VERSION (1UL)
|
||||
/// The application is not signed
|
||||
#define APPLICATION_SIGNATURE_NONE (0UL)
|
||||
/// @brief The SHA-256 digest of the application is signed using ECDSA with the
|
||||
/// NIST P-256 curve.
|
||||
#define APPLICATION_SIGNATURE_ECDSA_P256 (1UL << 0UL)
|
||||
/// @brief The application is not signed, but has a CRC-32 checksum
|
||||
#define APPLICATION_SIGNATURE_CRC32 (1UL << 1UL)
|
||||
|
||||
/// The application contains a Zigbee wireless stack
|
||||
#define APPLICATION_TYPE_ZIGBEE (1UL << 0UL)
|
||||
/// The application contains a Thread wireless stack
|
||||
#define APPLICATION_TYPE_THREAD (1UL << 1UL)
|
||||
/// The application contains a Flex wireless stack
|
||||
#define APPLICATION_TYPE_FLEX (1UL << 2UL)
|
||||
/// The application contains a Bluetooth wireless stack
|
||||
#define APPLICATION_TYPE_BLUETOOTH (1UL << 3UL)
|
||||
/// The application is an MCU application
|
||||
#define APPLICATION_TYPE_MCU (1UL << 4UL)
|
||||
/// The application contains a Bluetooth application
|
||||
#define APPLICATION_TYPE_BLUETOOTH_APP (1UL << 5UL)
|
||||
/// The application contains a bootloader
|
||||
#define APPLICATION_TYPE_BOOTLOADER (1UL << 6UL)
|
||||
/// The application contains a Zwave wireless stack
|
||||
#define APPLICATION_TYPE_ZWAVE (1UL << 7UL)
|
||||
|
||||
/// Application Data
|
||||
typedef struct ApplicationData {
|
||||
/// @brief Bitfield representing type of application, e.g.,
|
||||
/// @ref APPLICATION_TYPE_ZIGBEE
|
||||
uint32_t type;
|
||||
/// Version number for this application
|
||||
uint32_t version;
|
||||
/// Capabilities of this application
|
||||
uint32_t capabilities;
|
||||
/// Unique ID (UUID or GUID) for the product this application is built for
|
||||
uint8_t productId[16];
|
||||
} ApplicationData_t;
|
||||
|
||||
/// Application Certificate
|
||||
typedef struct ApplicationCertificate {
|
||||
/// Version of the certificate structure
|
||||
uint8_t structVersion;
|
||||
/// Reserved flags
|
||||
uint8_t flags[3];
|
||||
/// Public key
|
||||
uint8_t key[64];
|
||||
/// The version number of this certificate
|
||||
uint32_t version;
|
||||
/// Signature of the certificate
|
||||
uint8_t signature[64];
|
||||
} ApplicationCertificate_t;
|
||||
|
||||
/// Application Properties struct
|
||||
typedef struct {
|
||||
/// @brief Magic value indicating this is an ApplicationProperties_t struct.
|
||||
/// Must equal @ref APPLICATION_PROPERTIES_MAGIC
|
||||
uint8_t magic[16];
|
||||
/// Version number of this struct
|
||||
uint32_t structVersion;
|
||||
/// Type of signature this application is signed with
|
||||
uint32_t signatureType;
|
||||
/// Location of the signature. Typically points to the end of the application
|
||||
uint32_t signatureLocation;
|
||||
/// Information about the application
|
||||
ApplicationData_t app;
|
||||
/// Pointer to information about the certificate
|
||||
ApplicationCertificate_t *cert;
|
||||
/// Pointer to Long Token Data Section
|
||||
uint8_t *longTokenSectionAddress;
|
||||
/// Parser Decryption Key
|
||||
const uint8_t decryptKey[16];
|
||||
} ApplicationProperties_t;
|
||||
|
||||
/** @} (end addtogroup ApplicationProperties) */
|
||||
/** @} (end addtogroup Interface) */
|
||||
|
||||
/// Application Properties major version shift value
|
||||
#define APPLICATION_PROPERTIES_VERSION_MAJOR_SHIFT (0U)
|
||||
/// Application Properties minor version shift value
|
||||
#define APPLICATION_PROPERTIES_VERSION_MINOR_SHIFT (8U)
|
||||
|
||||
/// Application Properties major version mask
|
||||
#define APPLICATION_PROPERTIES_VERSION_MAJOR_MASK (0x000000FFU)
|
||||
/// Application Properties minor version mask
|
||||
#define APPLICATION_PROPERTIES_VERSION_MINOR_MASK (0xFFFFFF00U)
|
||||
|
||||
/// Version number of the AppliationProperties_t struct
|
||||
#define APPLICATION_PROPERTIES_VERSION ((APPLICATION_PROPERTIES_VERSION_MINOR \
|
||||
<< APPLICATION_PROPERTIES_VERSION_MINOR_SHIFT) \
|
||||
| (APPLICATION_PROPERTIES_VERSION_MAJOR \
|
||||
<< APPLICATION_PROPERTIES_VERSION_MAJOR_SHIFT))
|
||||
|
||||
#if (APPLICATION_PROPERTIES_VERSION_MAJOR \
|
||||
> (APPLICATION_PROPERTIES_VERSION_MAJOR_MASK >> APPLICATION_PROPERTIES_VERSION_MAJOR_SHIFT))
|
||||
|| (APPLICATION_PROPERTIES_VERSION_MINOR \
|
||||
> (APPLICATION_PROPERTIES_VERSION_MINOR_MASK >> APPLICATION_PROPERTIES_VERSION_MINOR_SHIFT))
|
||||
#error "Invalid application properties version"
|
||||
#endif
|
||||
|
||||
#endif // APPLICATION_PROPERTIES_H
|
||||
382
Libs/platform/bootloader/api/btl_errorcode.h
Normal file
382
Libs/platform/bootloader/api/btl_errorcode.h
Normal file
@@ -0,0 +1,382 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Error codes used and exposed by the bootloader.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc. Your use of this
|
||||
* software is governed by the terms of Silicon Labs Master Software License
|
||||
* Agreement (MSLA) available at
|
||||
* www.silabs.com/about-us/legal/master-software-license-agreement. This
|
||||
* software is distributed to you in Source Code format and is governed by the
|
||||
* sections of the MSLA applicable to Source Code.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTL_ERRORCODE_H
|
||||
#define BTL_ERRORCODE_H
|
||||
|
||||
/**
|
||||
* @addtogroup ErrorCodes Error Codes
|
||||
* @brief Bootloader error codes
|
||||
* @details
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// No error, operation OK
|
||||
#define BOOTLOADER_OK 0L
|
||||
|
||||
/**
|
||||
* @addtogroup ErrorBases Error Code Base Values
|
||||
* @brief Bootloader error code base values, per logical function
|
||||
* @details
|
||||
* @{
|
||||
*/
|
||||
/// Initialization errors
|
||||
#define BOOTLOADER_ERROR_INIT_BASE 0x0100L
|
||||
/// Image verification errors
|
||||
#define BOOTLOADER_ERROR_PARSE_BASE 0x0200L
|
||||
/// Storage errors
|
||||
#define BOOTLOADER_ERROR_STORAGE_BASE 0x0400L
|
||||
/// Bootload errors
|
||||
#define BOOTLOADER_ERROR_BOOTLOAD_BASE 0x0500L
|
||||
/// Security errors
|
||||
#define BOOTLOADER_ERROR_SECURITY_BASE 0x0600L
|
||||
/// Communication component errors
|
||||
#define BOOTLOADER_ERROR_COMMUNICATION_BASE 0x0700L
|
||||
/// XMODEM parser errors
|
||||
#define BOOTLOADER_ERROR_XMODEM_BASE 0x0900L
|
||||
/// Image file parser errors
|
||||
#define BOOTLOADER_ERROR_PARSER_BASE 0x1000L
|
||||
/// SPI Peripheral driver errors
|
||||
#define BOOTLOADER_ERROR_SPI_PERIPHERAL_BASE 0x1100L
|
||||
/// UART driver errors
|
||||
#define BOOTLOADER_ERROR_UART_BASE 0x1200L
|
||||
/// Compression errors
|
||||
#define BOOTLOADER_ERROR_COMPRESSION_BASE 0x1300L
|
||||
|
||||
/** @} addtogroup ErrorBases */
|
||||
|
||||
/**
|
||||
* @addtogroup InitError Initialization Error Codes
|
||||
* @brief Bootloader error codes returned by initialization code.
|
||||
* @details
|
||||
* Offset from @ref BOOTLOADER_ERROR_INIT_BASE
|
||||
* @{
|
||||
*/
|
||||
/// Storage initialization error
|
||||
#define BOOTLOADER_ERROR_INIT_STORAGE \
|
||||
(BOOTLOADER_ERROR_INIT_BASE | 0x01L)
|
||||
/// Bootloader table invalid
|
||||
#define BOOTLOADER_ERROR_INIT_TABLE \
|
||||
(BOOTLOADER_ERROR_INIT_BASE | 0x02L)
|
||||
/// Bootloader SFDP not supported
|
||||
#define BOOTLOADER_ERROR_INIT_SFDP \
|
||||
(BOOTLOADER_ERROR_INIT_BASE | 0x03L)
|
||||
|
||||
/** @} addtogroup InitError */
|
||||
|
||||
/**
|
||||
* @addtogroup ParseErrpr Parse Error Codes
|
||||
* @brief Bootloader error codes returned by image parsing.
|
||||
* @details
|
||||
* Offset from @ref BOOTLOADER_ERROR_PARSE_BASE
|
||||
* @{
|
||||
*/
|
||||
/// Parse not complete, continue calling the
|
||||
/// parsing function
|
||||
#define BOOTLOADER_ERROR_PARSE_CONTINUE (BOOTLOADER_ERROR_PARSE_BASE | 0x01L)
|
||||
/// Verification failed
|
||||
#define BOOTLOADER_ERROR_PARSE_FAILED (BOOTLOADER_ERROR_PARSE_BASE | 0x02L)
|
||||
/// Verification successfully completed. Image is valid.
|
||||
#define BOOTLOADER_ERROR_PARSE_SUCCESS (BOOTLOADER_ERROR_PARSE_BASE | 0x03L)
|
||||
/// Bootloader has no storage, and cannot parse images.
|
||||
#define BOOTLOADER_ERROR_PARSE_STORAGE (BOOTLOADER_ERROR_PARSE_BASE | 0x04L)
|
||||
/// Parse context incompatible with parse function
|
||||
#define BOOTLOADER_ERROR_PARSE_CONTEXT (BOOTLOADER_ERROR_PARSE_BASE | 0x05L)
|
||||
|
||||
/** @} addtogroup VerificationError */
|
||||
|
||||
/**
|
||||
* @addtogroup StorageError Storage Driver Error Codes
|
||||
* @brief Bootloader error codes returned by a storage driver.
|
||||
* @details
|
||||
* Offset from @ref BOOTLOADER_ERROR_STORAGE_BASE
|
||||
* @{
|
||||
*/
|
||||
/// Invalid slot
|
||||
#define BOOTLOADER_ERROR_STORAGE_INVALID_SLOT \
|
||||
(BOOTLOADER_ERROR_STORAGE_BASE | 0x01L)
|
||||
/// Invalid address. Address not aligned/out of range
|
||||
#define BOOTLOADER_ERROR_STORAGE_INVALID_ADDRESS \
|
||||
(BOOTLOADER_ERROR_STORAGE_BASE | 0x02L)
|
||||
/// The storage area needs to be erased before it can be used
|
||||
#define BOOTLOADER_ERROR_STORAGE_NEEDS_ERASE \
|
||||
(BOOTLOADER_ERROR_STORAGE_BASE | 0x03L)
|
||||
/// The address or length needs to be aligned
|
||||
#define BOOTLOADER_ERROR_STORAGE_NEEDS_ALIGN \
|
||||
(BOOTLOADER_ERROR_STORAGE_BASE | 0x04L)
|
||||
/// An error occured during bootload from storage
|
||||
#define BOOTLOADER_ERROR_STORAGE_BOOTLOAD \
|
||||
(BOOTLOADER_ERROR_STORAGE_BASE | 0x05L)
|
||||
/// There is no image in this storage slot
|
||||
#define BOOTLOADER_ERROR_STORAGE_NO_IMAGE \
|
||||
(BOOTLOADER_ERROR_STORAGE_BASE | 0x06L)
|
||||
/// Continue calling function
|
||||
#define BOOTLOADER_ERROR_STORAGE_CONTINUE \
|
||||
(BOOTLOADER_ERROR_STORAGE_BASE | 0x07L)
|
||||
/// Generic storage error
|
||||
#define BOOTLOADER_ERROR_STORAGE_GENERIC \
|
||||
(BOOTLOADER_ERROR_STORAGE_BASE | 0x08L)
|
||||
|
||||
/** @} addtogroup StorageError */
|
||||
|
||||
/**
|
||||
* @addtogroup BootloadError Bootloading Error Codes
|
||||
* @brief Bootloader error codes returned by the bootloading process.
|
||||
* @details
|
||||
* Offset from @ref BOOTLOADER_ERROR_BOOTLOAD_BASE
|
||||
* @{
|
||||
*/
|
||||
/// No images marked for bootload
|
||||
#define BOOTLOADER_ERROR_BOOTLOAD_LIST_EMPTY \
|
||||
(BOOTLOADER_ERROR_BOOTLOAD_BASE | 0x01L)
|
||||
/// List of images marked for bootload is full
|
||||
#define BOOTLOADER_ERROR_BOOTLOAD_LIST_FULL \
|
||||
(BOOTLOADER_ERROR_BOOTLOAD_BASE | 0x02L)
|
||||
/// Image already marked for bootload
|
||||
#define BOOTLOADER_ERROR_BOOTLOAD_LIST_ENTRY_EXISTS \
|
||||
(BOOTLOADER_ERROR_BOOTLOAD_BASE | 0x03L)
|
||||
/// Bootload list overflowed, requested length too large
|
||||
#define BOOTLOADER_ERROR_BOOTLOAD_LIST_OVERFLOW \
|
||||
(BOOTLOADER_ERROR_BOOTLOAD_BASE | 0x04L)
|
||||
/// No bootload list found at the base of storage
|
||||
#define BOOTLOADER_ERROR_BOOTLOAD_LIST_NO_LIST \
|
||||
(BOOTLOADER_ERROR_BOOTLOAD_BASE | 0x05L)
|
||||
/// Bootload list found but with invalid CRC
|
||||
#define BOOTLOADER_ERROR_BOOTLOAD_LIST_INVALID \
|
||||
(BOOTLOADER_ERROR_BOOTLOAD_BASE | 0x06L)
|
||||
|
||||
/** @} addtogroup BootloadError */
|
||||
|
||||
/**
|
||||
* @addtogroup SecurityError Security Error Codes
|
||||
* @brief Bootloader error codes returned by security algorithms.
|
||||
* @details
|
||||
* Offset from @ref BOOTLOADER_ERROR_SECURITY_BASE
|
||||
* @{
|
||||
*/
|
||||
/// Invalid input parameter to security algorithm
|
||||
#define BOOTLOADER_ERROR_SECURITY_INVALID_PARAM \
|
||||
(BOOTLOADER_ERROR_SECURITY_BASE | 0x01L)
|
||||
/// Input parameter to security algorithm is out of range
|
||||
#define BOOTLOADER_ERROR_SECURITY_PARAM_OUT_RANGE \
|
||||
(BOOTLOADER_ERROR_SECURITY_BASE | 0x02L)
|
||||
/// Invalid option for security algorithm
|
||||
#define BOOTLOADER_ERROR_SECURITY_INVALID_OPTION \
|
||||
(BOOTLOADER_ERROR_SECURITY_BASE | 0x03L)
|
||||
/// Authentication did not check out
|
||||
#define BOOTLOADER_ERROR_SECURITY_REJECTED \
|
||||
(BOOTLOADER_ERROR_SECURITY_BASE | 0x04L)
|
||||
|
||||
/** @} addtogroup SecurityError */
|
||||
|
||||
/**
|
||||
* @addtogroup CommunicationError Communication Component Error Codes
|
||||
* @brief Bootloader error codes returned by communication components.
|
||||
* @details
|
||||
* Offset from @ref BOOTLOADER_ERROR_COMMUNICATION_BASE
|
||||
* @{
|
||||
*/
|
||||
/// Invalid input parameter to security algorithm
|
||||
/// Could not initialize hardware resources for communication protocol
|
||||
#define BOOTLOADER_ERROR_COMMUNICATION_INIT \
|
||||
(BOOTLOADER_ERROR_COMMUNICATION_BASE | 0x01L)
|
||||
/// @brief Could not start communication with host (timeout, sync error,
|
||||
/// version mismatch, ...)
|
||||
#define BOOTLOADER_ERROR_COMMUNICATION_START \
|
||||
(BOOTLOADER_ERROR_COMMUNICATION_BASE | 0x02L)
|
||||
/// Host closed communication, no image received
|
||||
#define BOOTLOADER_ERROR_COMMUNICATION_DONE \
|
||||
(BOOTLOADER_ERROR_COMMUNICATION_BASE | 0x03L)
|
||||
/// Unrecoverable error in host-bootloader communication
|
||||
#define BOOTLOADER_ERROR_COMMUNICATION_ERROR \
|
||||
(BOOTLOADER_ERROR_COMMUNICATION_BASE | 0x04L)
|
||||
/// Host closed communication, no valid image received
|
||||
#define BOOTLOADER_ERROR_COMMUNICATION_IMAGE_ERROR \
|
||||
(BOOTLOADER_ERROR_COMMUNICATION_BASE | 0x05L)
|
||||
/// Communication aborted, no response from host
|
||||
#define BOOTLOADER_ERROR_COMMUNICATION_TIMEOUT \
|
||||
(BOOTLOADER_ERROR_COMMUNICATION_BASE | 0x06L)
|
||||
|
||||
/** @} addtogroup CommunicationError */
|
||||
|
||||
/**
|
||||
* @addtogroup XmodemError XMODEM Error Codes
|
||||
* @brief Bootloader error codes returned by the XMODEM parser.
|
||||
* @details
|
||||
* Offset from @ref BOOTLOADER_ERROR_XMODEM_BASE
|
||||
* @{
|
||||
*/
|
||||
/// Could not verify lower CRC byte
|
||||
#define BOOTLOADER_ERROR_XMODEM_CRCL \
|
||||
(BOOTLOADER_ERROR_XMODEM_BASE | 0x01L)
|
||||
/// Could not verify upper CRC byte
|
||||
#define BOOTLOADER_ERROR_XMODEM_CRCH \
|
||||
(BOOTLOADER_ERROR_XMODEM_BASE | 0x02L)
|
||||
/// No start of header found
|
||||
#define BOOTLOADER_ERROR_XMODEM_NO_SOH \
|
||||
(BOOTLOADER_ERROR_XMODEM_BASE | 0x03L)
|
||||
/// Packet number doesn't match its inverse
|
||||
#define BOOTLOADER_ERROR_XMODEM_PKTNUM \
|
||||
(BOOTLOADER_ERROR_XMODEM_BASE | 0x04L)
|
||||
/// Packet number error (unexpected sequence)
|
||||
#define BOOTLOADER_ERROR_XMODEM_PKTSEQ \
|
||||
(BOOTLOADER_ERROR_XMODEM_BASE | 0x05L)
|
||||
/// Packet number error (duplicate)
|
||||
#define BOOTLOADER_ERROR_XMODEM_PKTDUP \
|
||||
(BOOTLOADER_ERROR_XMODEM_BASE | 0x06L)
|
||||
/// Transfer is done (Technically not an error)
|
||||
#define BOOTLOADER_ERROR_XMODEM_DONE \
|
||||
(BOOTLOADER_ERROR_XMODEM_BASE | 0x07L)
|
||||
/// Transfer is canceled
|
||||
#define BOOTLOADER_ERROR_XMODEM_CANCEL \
|
||||
(BOOTLOADER_ERROR_XMODEM_BASE | 0x08L)
|
||||
|
||||
/** @} addtogroup XmodemError */
|
||||
|
||||
/**
|
||||
* @addtogroup ParserError Image Parser Error Codes
|
||||
* @brief Bootloader error codes returned by the image file parser.
|
||||
* @details
|
||||
* Offset from @ref BOOTLOADER_ERROR_PARSER_BASE
|
||||
* @{
|
||||
*/
|
||||
/// Encountered unexpected data/option
|
||||
#define BOOTLOADER_ERROR_PARSER_UNEXPECTED \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x01L)
|
||||
/// Ran out of internal buffer space.
|
||||
/// Please increase internal buffer size to match biggest header
|
||||
#define BOOTLOADER_ERROR_PARSER_BUFFER \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x02L)
|
||||
/// Internal state: done parsing the current input buffer
|
||||
#define BOOTLOADER_ERROR_PARSER_PARSED \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x03L)
|
||||
/// Invalid encryption key or no key not present
|
||||
#define BOOTLOADER_ERROR_PARSER_KEYERROR \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x04L)
|
||||
/// Invalid checksum
|
||||
#define BOOTLOADER_ERROR_PARSER_CRC \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x05L)
|
||||
/// Invalid signature
|
||||
#define BOOTLOADER_ERROR_PARSER_SIGNATURE \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x06L)
|
||||
/// Image parsing is already done (or has previously errored out)
|
||||
#define BOOTLOADER_ERROR_PARSER_EOF \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x07L)
|
||||
/// Unknown data type in image file
|
||||
#define BOOTLOADER_ERROR_PARSER_UNKNOWN_TAG \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x08L)
|
||||
/// Image file version doesn't match with parser
|
||||
#define BOOTLOADER_ERROR_PARSER_VERSION \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x09L)
|
||||
/// Image file type doesn't match with parser
|
||||
#define BOOTLOADER_ERROR_PARSER_FILETYPE \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x0AL)
|
||||
/// Initialization failed
|
||||
#define BOOTLOADER_ERROR_PARSER_INIT \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x0BL)
|
||||
/// Upgrade file was rejected
|
||||
#define BOOTLOADER_ERROR_PARSER_REJECTED \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x0CL)
|
||||
/// Upgrade file overlaps with the upgrade location
|
||||
#define BOOTLOADER_ERROR_PARSER_OVERLAP \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x0DL)
|
||||
/// A GBL tag occurred in an order forbidden by the GBL format spec
|
||||
#define BOOTLOADER_ERROR_PARSER_INVALID_TAG_ORDER \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x0EL)
|
||||
/// OOB write in the storage slot while parsing the GBL file
|
||||
#define BOOTLOADER_ERROR_PARSER_OOB_WRITE \
|
||||
(BOOTLOADER_ERROR_PARSER_BASE | 0x0FL)
|
||||
|
||||
/** @} addtogroup ParserError */
|
||||
|
||||
/**
|
||||
* @addtogroup SpiPeripheralError SPI Peripheral Driver Error Codes
|
||||
* @brief Bootloader error codes returned by the SPI Peripheral driver.
|
||||
* @details
|
||||
* Offset from @ref BOOTLOADER_ERROR_SPI_PERIPHERAL_BASE
|
||||
* @{
|
||||
*/
|
||||
/// Operation not allowed because hardware has not been initialized
|
||||
#define BOOTLOADER_ERROR_SPI_PERIPHERAL_UNINIT \
|
||||
(BOOTLOADER_ERROR_SPI_PERIPHERAL_BASE | 0x01)
|
||||
/// Hardware fail during initialization
|
||||
#define BOOTLOADER_ERROR_SPI_PERIPHERAL_INIT \
|
||||
(BOOTLOADER_ERROR_SPI_PERIPHERAL_BASE | 0x02)
|
||||
/// Invalid argument
|
||||
#define BOOTLOADER_ERROR_SPI_PERIPHERAL_ARGUMENT \
|
||||
(BOOTLOADER_ERROR_SPI_PERIPHERAL_BASE | 0x03)
|
||||
/// Timeout
|
||||
#define BOOTLOADER_ERROR_SPI_PERIPHERAL_TIMEOUT \
|
||||
(BOOTLOADER_ERROR_SPI_PERIPHERAL_BASE | 0x04)
|
||||
/// Buffer overflow condition
|
||||
#define BOOTLOADER_ERROR_SPI_PERIPHERAL_OVERFLOW \
|
||||
(BOOTLOADER_ERROR_SPI_PERIPHERAL_BASE | 0x05)
|
||||
/// Busy condition
|
||||
#define BOOTLOADER_ERROR_SPI_PERIPHERAL_BUSY \
|
||||
(BOOTLOADER_ERROR_SPI_PERIPHERAL_BASE | 0x06)
|
||||
|
||||
/** @} addtogroup SpiPeripheralError */
|
||||
|
||||
/**
|
||||
* @addtogroup UartError UART Driver Error Codes
|
||||
* @brief Bootloader error codes returned by the UART driver.
|
||||
* @details
|
||||
* Offset from @ref BOOTLOADER_ERROR_UART_BASE
|
||||
* @{
|
||||
*/
|
||||
/// Operation not allowed because hardware has not been initialized
|
||||
#define BOOTLOADER_ERROR_UART_UNINIT (BOOTLOADER_ERROR_UART_BASE | 0x01)
|
||||
/// Hardware fail during initialization
|
||||
#define BOOTLOADER_ERROR_UART_INIT (BOOTLOADER_ERROR_UART_BASE | 0x02)
|
||||
/// Invalid argument
|
||||
#define BOOTLOADER_ERROR_UART_ARGUMENT (BOOTLOADER_ERROR_UART_BASE | 0x03)
|
||||
/// Operation timed out
|
||||
#define BOOTLOADER_ERROR_UART_TIMEOUT (BOOTLOADER_ERROR_UART_BASE | 0x04)
|
||||
/// Buffer overflow condition
|
||||
#define BOOTLOADER_ERROR_UART_OVERFLOW (BOOTLOADER_ERROR_UART_BASE | 0x05)
|
||||
/// Busy condition
|
||||
#define BOOTLOADER_ERROR_UART_BUSY (BOOTLOADER_ERROR_UART_BASE | 0x06)
|
||||
|
||||
/** @} addtogroup UartError */
|
||||
|
||||
/**
|
||||
* @addtogroup CompressionError Compression Error Codes
|
||||
* @brief Bootloader error codes returned by the decompressor
|
||||
* @details
|
||||
* Offset from @ref BOOTLOADER_ERROR_COMPRESSION_BASE
|
||||
* @{
|
||||
*/
|
||||
/// Could not initialize decompressor
|
||||
#define BOOTLOADER_ERROR_COMPRESSION_INIT \
|
||||
(BOOTLOADER_ERROR_COMPRESSION_BASE | 0x01)
|
||||
/// Invalid decompressor state -- possible invalid input
|
||||
#define BOOTLOADER_ERROR_COMPRESSION_STATE \
|
||||
(BOOTLOADER_ERROR_COMPRESSION_BASE | 0x02)
|
||||
/// Data error
|
||||
#define BOOTLOADER_ERROR_COMPRESSION_DATA \
|
||||
(BOOTLOADER_ERROR_COMPRESSION_BASE | 0x03)
|
||||
/// Data length error
|
||||
#define BOOTLOADER_ERROR_COMPRESSION_DATALEN \
|
||||
(BOOTLOADER_ERROR_COMPRESSION_BASE | 0x04)
|
||||
/// Memory error
|
||||
#define BOOTLOADER_ERROR_COMPRESSION_MEM \
|
||||
(BOOTLOADER_ERROR_COMPRESSION_BASE | 0x05)
|
||||
|
||||
/** @} addtogroup CompressionError */
|
||||
|
||||
/** @} addtogroup ErrorCodes */
|
||||
|
||||
#endif // BTL_ERRORCODE_H
|
||||
944
Libs/platform/bootloader/api/btl_interface.c
Normal file
944
Libs/platform/bootloader/api/btl_interface.c
Normal file
@@ -0,0 +1,944 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Application interface to the bootloader.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc. Your use of this
|
||||
* software is governed by the terms of Silicon Labs Master Software License
|
||||
* Agreement (MSLA) available at
|
||||
* www.silabs.com/about-us/legal/master-software-license-agreement. This
|
||||
* software is distributed to you in Source Code format and is governed by the
|
||||
* sections of the MSLA applicable to Source Code.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "btl_interface.h"
|
||||
#include "em_core.h"
|
||||
#include "btl_interface_cfg.h"
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif
|
||||
|
||||
#if defined(SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
extern uint32_t __ResetReasonStart__;
|
||||
#elif defined(__ICCARM__)
|
||||
#pragma section = "BOOTLOADER_RESET_REASON"
|
||||
#endif
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Configurations
|
||||
|
||||
#if ((!defined(BOOTLOADER_DISABLE_NVM3_FAULT_HANDLING) \
|
||||
|| (defined(BOOTLOADER_DISABLE_NVM3_FAULT_HANDLING) \
|
||||
&& (BOOTLOADER_DISABLE_NVM3_FAULT_HANDLING == 0))) && defined(SL_CATALOG_NVM3_PRESENT))
|
||||
#define BOOTLOADER_ENABLE_NVM3_FAULT_HANDLING
|
||||
#endif // BOOTLOADER_DISABLE_NVM3_FAULT_HANDLING && SL_CATALOG_NVM3_PRESENT
|
||||
|
||||
#if !defined(BOOTLOADER_MANUAL_OVERRIDE_SECURITY_STATE) \
|
||||
|| (defined(BOOTLOADER_MANUAL_OVERRIDE_SECURITY_STATE) \
|
||||
&& (BOOTLOADER_MANUAL_OVERRIDE_SECURITY_STATE == 0))
|
||||
#define BOOTLOADER_ENABLE_USART_AUTO_DETECTION
|
||||
#endif // BOOTLOADER_MANUAL_OVERRIDE_SECURITY_STATE
|
||||
|
||||
#if (defined(BOOTLOADER_DISABLE_OLD_BOOTLOADER_MITIGATION) \
|
||||
&& (BOOTLOADER_DISABLE_OLD_BOOTLOADER_MITIGATION == 1))
|
||||
#define BOOTLOADER_DISABLE_MULTI_TIERED_FALLBACK
|
||||
#undef BOOTLOADER_ENABLE_NVM3_FAULT_HANDLING
|
||||
#undef BOOTLOADER_ENABLE_USART_AUTO_DETECTION
|
||||
#endif // BOOTLOADER_DISABLE_OLD_BOOTLOADER_MITIGATION
|
||||
|
||||
#if defined(SL_TRUSTZONE_SECURE)
|
||||
#undef BOOTLOADER_ENABLE_NVM3_FAULT_HANDLING
|
||||
#endif // SL_TRUSTZONE_SECURE
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Configuration spesifics
|
||||
|
||||
#if defined(BOOTLOADER_ENABLE_NVM3_FAULT_HANDLING)
|
||||
// Allocated range of NVM3 IDs for bootloader usage */
|
||||
#define BL_NVM3_RESERVED_ID (0x87100UL)
|
||||
|
||||
#include <string.h>
|
||||
#include "nvm3_default.h"
|
||||
|
||||
static bool blPPUSATDnStateCacheSet = false;
|
||||
static uint32_t blPPUSATDnStateCache[2] = { 0 };
|
||||
#endif // BOOTLOADER_ENABLE_NVM3_FAULT_HANDLING
|
||||
|
||||
#if defined(BOOTLOADER_ENABLE_USART_AUTO_DETECTION)
|
||||
static void preConfigureUsartPPUSATD(void);
|
||||
static void storeUsartInUse(void);
|
||||
static int32_t usartNumberSpi = -1;
|
||||
#endif // BOOTLOADER_ENABLE_USART_AUTO_DETECTION
|
||||
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Static variables
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
#if !defined(BOOTLOADER_TEST_UNPRIVILEGED_ACCESS)
|
||||
static CORE_DECLARE_IRQ_STATE;
|
||||
#endif
|
||||
static Bootloader_PPUSATDnCLKENnState_t blPPUSATDnCLKENnState = { 0 };
|
||||
|
||||
typedef enum {
|
||||
IDLE, SAVE, TIERED
|
||||
} ppusatdConfigurationState_t;
|
||||
|
||||
static ppusatdConfigurationState_t bootloader_ppusatdConfigstate = IDLE;
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Enums
|
||||
|
||||
typedef enum {
|
||||
RESET, INITIALIZED, DEINITIALIZED
|
||||
} initState_t;
|
||||
|
||||
static initState_t bootloader_InitState = RESET;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Test helpers
|
||||
|
||||
#if defined(BOOTLOADER_TEST_UNPRIVILEGED_ACCESS)
|
||||
extern bool enabled;
|
||||
extern void enterUnprivilegedMode(bool);
|
||||
extern void exitUnprivilegedMode(void);
|
||||
#endif // BOOTLOADER_TEST_UNPRIVILEGED_ACCESS
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Functions
|
||||
|
||||
void bootloader_getInfo(BootloaderInformation_t *info)
|
||||
{
|
||||
#if defined(BOOTLOADER_HAS_FIRST_STAGE)
|
||||
if (!bootloader_pointerToFirstStageValid(firstBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable)) {
|
||||
// No bootloader is present (first stage or main stage invalid)
|
||||
info->type = NO_BOOTLOADER;
|
||||
info->capabilities = 0;
|
||||
} else if ((firstBootloaderTable->header.type == BOOTLOADER_MAGIC_FIRST_STAGE)
|
||||
&& (mainBootloaderTable->header.type == BOOTLOADER_MAGIC_MAIN)) {
|
||||
info->type = SL_BOOTLOADER;
|
||||
info->version = mainBootloaderTable->header.version;
|
||||
info->capabilities = mainBootloaderTable->capabilities;
|
||||
} else {
|
||||
info->type = NO_BOOTLOADER;
|
||||
info->capabilities = 0;
|
||||
}
|
||||
#else
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
// No bootloader is present (first stage or main stage invalid)
|
||||
info->type = NO_BOOTLOADER;
|
||||
info->capabilities = 0;
|
||||
} else if (mainBootloaderTable->header.type == BOOTLOADER_MAGIC_MAIN) {
|
||||
info->type = SL_BOOTLOADER;
|
||||
info->version = mainBootloaderTable->header.version;
|
||||
info->capabilities = mainBootloaderTable->capabilities;
|
||||
} else {
|
||||
info->type = NO_BOOTLOADER;
|
||||
info->capabilities = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t bootloader_init(void)
|
||||
{
|
||||
int32_t retVal;
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
return BOOTLOADER_ERROR_INIT_TABLE;
|
||||
}
|
||||
if (mainBootloaderTable->header.type != BOOTLOADER_MAGIC_MAIN) {
|
||||
return BOOTLOADER_ERROR_INIT_TABLE;
|
||||
}
|
||||
|
||||
if (bootloader_InitState == RESET || bootloader_InitState == DEINITIALIZED) {
|
||||
#if defined(SL_TRUSTZONE_SECURE)
|
||||
if (bootloader_InitState == RESET) {
|
||||
// Enable SMU bus clock at the start-up of the TZ secure application
|
||||
// to make it possible to configure the SMU peripheral. Since the CMU address
|
||||
// is known. Otherwise, delegate the SMU bus clock enablement to the NS application.
|
||||
#if defined(_CMU_CLKEN1_SMU_MASK)
|
||||
CMU->CLKEN1_SET = CMU_CLKEN1_SMU;
|
||||
#endif // _CMU_CLKEN1_SMU_MASK
|
||||
}
|
||||
#endif // SL_TRUSTZONE_SECURE
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif
|
||||
|
||||
#if defined(BOOTLOADER_ENABLE_NVM3_FAULT_HANDLING)
|
||||
NVIC_ClearPendingIRQ(SMU_SECURE_IRQn);
|
||||
SMU->IF_CLR = SMU_IEN_PPUSEC;
|
||||
NVIC_EnableIRQ(SMU_SECURE_IRQn);
|
||||
SMU->IEN_SET = SMU_IEN_PPUSEC;
|
||||
#endif
|
||||
retVal = mainBootloaderTable->init();
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif
|
||||
|
||||
if (retVal == BOOTLOADER_OK) {
|
||||
bootloader_InitState = INITIALIZED;
|
||||
}
|
||||
} else {
|
||||
retVal = BOOTLOADER_OK;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_deinit(void)
|
||||
{
|
||||
int32_t retVal;
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
return BOOTLOADER_ERROR_INIT_TABLE;
|
||||
}
|
||||
if (mainBootloaderTable->header.type != BOOTLOADER_MAGIC_MAIN) {
|
||||
return BOOTLOADER_ERROR_INIT_TABLE;
|
||||
}
|
||||
|
||||
if (bootloader_InitState == INITIALIZED) {
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
#if defined(BOOTLOADER_ENABLE_NVM3_FAULT_HANDLING)
|
||||
SMU->IF_CLR = SMU_IEN_PPUSEC;
|
||||
SMU->IEN_CLR = SMU_IEN_PPUSEC;
|
||||
NVIC_ClearPendingIRQ(SMU_SECURE_IRQn);
|
||||
NVIC_DisableIRQ(SMU_SECURE_IRQn);
|
||||
#endif
|
||||
|
||||
retVal = mainBootloaderTable->deinit();
|
||||
if (retVal == BOOTLOADER_OK) {
|
||||
bootloader_InitState = DEINITIALIZED;
|
||||
}
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
} else {
|
||||
retVal = BOOTLOADER_OK;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
BootloaderResetCause_t bootloader_getResetReason(void)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
uint32_t resetReasonBase = (uint32_t)&__ResetReasonStart__;
|
||||
#elif defined(__ICCARM__)
|
||||
void *resetReasonBase = __section_begin("BOOTLOADER_RESET_REASON");
|
||||
#endif
|
||||
|
||||
volatile BootloaderResetCause_t *resetCause = (BootloaderResetCause_t *)(resetReasonBase);
|
||||
return *resetCause;
|
||||
}
|
||||
|
||||
void bootloader_rebootAndInstall(void)
|
||||
{
|
||||
// Set reset reason to bootloader entry
|
||||
#if defined(__GNUC__)
|
||||
uint32_t resetReasonBase = (uint32_t)&__ResetReasonStart__;
|
||||
#elif defined(__ICCARM__)
|
||||
void *resetReasonBase = __section_begin("BOOTLOADER_RESET_REASON");
|
||||
#endif
|
||||
BootloaderResetCause_t *resetCause = (BootloaderResetCause_t *) (resetReasonBase);
|
||||
resetCause->reason = BOOTLOADER_RESET_REASON_BOOTLOAD;
|
||||
resetCause->signature = BOOTLOADER_RESET_SIGNATURE_VALID;
|
||||
#if defined(RMU_PRESENT)
|
||||
// Clear resetcause
|
||||
RMU->CMD = RMU_CMD_RCCLR;
|
||||
// Trigger a software system reset
|
||||
RMU->CTRL = (RMU->CTRL & ~_RMU_CTRL_SYSRMODE_MASK) | RMU_CTRL_SYSRMODE_FULL;
|
||||
#endif
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
int32_t bootloader_initParser(BootloaderParserContext_t *context,
|
||||
size_t contextSize)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
return BOOTLOADER_ERROR_PARSE_FAILED;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
int32_t retVal = mainBootloaderTable->initParser(context, contextSize);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_parseBuffer(BootloaderParserContext_t *context,
|
||||
BootloaderParserCallbacks_t *callbacks,
|
||||
uint8_t data[],
|
||||
size_t numBytes)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
return BOOTLOADER_ERROR_PARSE_FAILED;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
int32_t retVal = mainBootloaderTable->parseBuffer(context, callbacks, data, numBytes);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_parseImageInfo(BootloaderParserContext_t *context,
|
||||
uint8_t data[],
|
||||
size_t numBytes,
|
||||
ApplicationData_t *appInfo,
|
||||
uint32_t *bootloaderVersion)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
return BOOTLOADER_ERROR_PARSE_FAILED;
|
||||
}
|
||||
|
||||
BootloaderInformation_t info = { .type = SL_BOOTLOADER, .version = 0U, .capabilities = 0U };
|
||||
bootloader_getInfo(&info);
|
||||
|
||||
uint32_t blMajorVersion = ((info.version & BOOTLOADER_VERSION_MAJOR_MASK)
|
||||
>> BOOTLOADER_VERSION_MAJOR_SHIFT);
|
||||
uint32_t blMinorVersion = ((info.version & BOOTLOADER_VERSION_MINOR_MASK)
|
||||
>> BOOTLOADER_VERSION_MINOR_SHIFT);
|
||||
|
||||
if ((blMajorVersion < 1UL) || (blMajorVersion == 1UL && blMinorVersion < 11UL)) {
|
||||
return BOOTLOADER_ERROR_PARSE_FAILED;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
int32_t retVal = mainBootloaderTable->parseImageInfo(context, data, numBytes, appInfo, bootloaderVersion);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
uint32_t bootloader_parserContextSize(void)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
BootloaderInformation_t info = { .type = SL_BOOTLOADER, .version = 0U, .capabilities = 0U };
|
||||
bootloader_getInfo(&info);
|
||||
|
||||
uint32_t blMajorVersion = ((info.version & BOOTLOADER_VERSION_MAJOR_MASK)
|
||||
>> BOOTLOADER_VERSION_MAJOR_SHIFT);
|
||||
uint32_t blMinorVersion = ((info.version & BOOTLOADER_VERSION_MINOR_MASK)
|
||||
>> BOOTLOADER_VERSION_MINOR_SHIFT);
|
||||
|
||||
if (blMajorVersion < 1UL) {
|
||||
return 384UL;
|
||||
}
|
||||
|
||||
if (blMajorVersion == 1UL && blMinorVersion < 11UL) {
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
if (blMinorVersion == 10UL) {
|
||||
return 524UL;
|
||||
} else {
|
||||
return 384UL;
|
||||
}
|
||||
#else
|
||||
return 384UL;
|
||||
#endif
|
||||
}
|
||||
|
||||
return (uint32_t)mainBootloaderTable->parserContextSize();
|
||||
}
|
||||
|
||||
bool bootloader_verifyApplication(uint32_t startAddress)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
bool retVal = mainBootloaderTable->verifyApplication(startAddress);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool bootloader_secureBootEnforced(void)
|
||||
{
|
||||
BootloaderInformation_t info = { .type = SL_BOOTLOADER, .version = 0U, .capabilities = 0U };
|
||||
bootloader_getInfo(&info);
|
||||
|
||||
if (info.capabilities & BOOTLOADER_CAPABILITY_ENFORCE_SECURE_BOOT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bootloader_getUpgradeLocation(uint32_t *location)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BootloaderInformation_t info = { .type = SL_BOOTLOADER, .version = 0U, .capabilities = 0U };
|
||||
bootloader_getInfo(&info);
|
||||
|
||||
uint32_t blMajorVersion = ((info.version & BOOTLOADER_VERSION_MAJOR_MASK)
|
||||
>> BOOTLOADER_VERSION_MAJOR_SHIFT);
|
||||
uint32_t blMinorVersion = ((info.version & BOOTLOADER_VERSION_MINOR_MASK)
|
||||
>> BOOTLOADER_VERSION_MINOR_SHIFT);
|
||||
|
||||
if (blMajorVersion > 2UL || (blMajorVersion == 2UL && blMinorVersion >= 1UL)) {
|
||||
*location = mainBootloaderTable->getUpgradeLocation();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
|
||||
uint32_t bootloader_remainingApplicationUpgrades(void)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
BootloaderInformation_t info = { .type = SL_BOOTLOADER, .version = 0U, .capabilities = 0U };
|
||||
bootloader_getInfo(&info);
|
||||
|
||||
uint32_t blMajorVersion = ((info.version & BOOTLOADER_VERSION_MAJOR_MASK)
|
||||
>> BOOTLOADER_VERSION_MAJOR_SHIFT);
|
||||
uint32_t blMinorVersion = ((info.version & BOOTLOADER_VERSION_MINOR_MASK)
|
||||
>> BOOTLOADER_VERSION_MINOR_SHIFT);
|
||||
|
||||
if ((blMajorVersion < 1UL) || (blMajorVersion == 1UL && blMinorVersion < 11UL)) {
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
return (uint32_t)mainBootloaderTable->remainingApplicationUpgrades();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
bool bootloader_getCertificateVersion(uint32_t *version)
|
||||
{
|
||||
// Access word 13 to read sl_app_properties of the bootloader.
|
||||
ApplicationProperties_t *blProperties =
|
||||
(ApplicationProperties_t *)(*(uint32_t *)(BTL_MAIN_STAGE_BASE + 52UL));
|
||||
|
||||
if (!bootloader_pointerValid(blProperties)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compatibility check of the application properties struct.
|
||||
if (((blProperties->structVersion & APPLICATION_PROPERTIES_VERSION_MAJOR_MASK)
|
||||
>> APPLICATION_PROPERTIES_VERSION_MAJOR_SHIFT) < 1UL) {
|
||||
return false;
|
||||
}
|
||||
if (((blProperties->structVersion & APPLICATION_PROPERTIES_VERSION_MINOR_MASK)
|
||||
>> APPLICATION_PROPERTIES_VERSION_MINOR_SHIFT) < 1UL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (blProperties->cert == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*version = blProperties->cert->version;
|
||||
return true;
|
||||
}
|
||||
#endif // _SILICON_LABS_32B_SERIES_2
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
|
||||
void bootloader_getPeripheralList(uint32_t *ppusatd0, uint32_t *ppusatd1, uint32_t *ppusatd2)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
BootloaderInformation_t info = { .type = SL_BOOTLOADER, .version = 0U, .capabilities = 0U };
|
||||
bootloader_getInfo(&info);
|
||||
|
||||
if (info.capabilities & BOOTLOADER_CAPABILITY_PERIPHERAL_LIST) {
|
||||
mainBootloaderTable->getPeripheralList(ppusatd0, ppusatd1, ppusatd2);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void bootloader_getPeripheralList(uint32_t *ppusatd0, uint32_t *ppusatd1)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
BootloaderInformation_t info = { .type = SL_BOOTLOADER, .version = 0U, .capabilities = 0U };
|
||||
bootloader_getInfo(&info);
|
||||
|
||||
if (info.capabilities & BOOTLOADER_CAPABILITY_PERIPHERAL_LIST) {
|
||||
mainBootloaderTable->getPeripheralList(ppusatd0, ppusatd1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void bootloader_ppusatdnSaveReconfigureState(Bootloader_PPUSATDnCLKENnState_t *ctx)
|
||||
{
|
||||
if (bootloader_ppusatdConfigstate != IDLE) {
|
||||
// This function is called from a bootloader callback function
|
||||
bootloader_ppusatdConfigstate = TIERED;
|
||||
return;
|
||||
}
|
||||
uint32_t ppusatd0 = 0u;
|
||||
uint32_t ppusatd1 = 0u;
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
|
||||
uint32_t ppusatd2 = 0u;
|
||||
#endif
|
||||
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
bootloader_ppusatdConfigstate = SAVE;
|
||||
|
||||
// Enter ATOMIC section. The ATOMIC section is exited when
|
||||
// the restore function is called.
|
||||
#if !defined(BOOTLOADER_TEST_UNPRIVILEGED_ACCESS)
|
||||
CORE_ENTER_ATOMIC();
|
||||
#endif
|
||||
|
||||
sli_bootloader_preHook();
|
||||
|
||||
#if defined(BOOTLOADER_ENABLE_NVM3_FAULT_HANDLING)
|
||||
// Read the stored PPUSATD state from NVM3
|
||||
if (!blPPUSATDnStateCacheSet) {
|
||||
Ecode_t status;
|
||||
status = nvm3_initDefault();
|
||||
if (status == ECODE_NVM3_OK) {
|
||||
nvm3_ObjectKey_t object_id = BL_NVM3_RESERVED_ID;
|
||||
status = nvm3_readData(nvm3_defaultHandle,
|
||||
object_id,
|
||||
blPPUSATDnStateCache,
|
||||
sizeof(blPPUSATDnStateCache));
|
||||
if (status == ECODE_NVM3_OK) {
|
||||
blPPUSATDnStateCacheSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // BOOTLOADER_ENABLE_NVM3_FAULT_HANDLING
|
||||
|
||||
// Store the CLKENn states
|
||||
#if defined(_CMU_CLKEN0_MASK)
|
||||
ctx->CLKEN0 = CMU->CLKEN0;
|
||||
ctx->CLKEN1 = CMU->CLKEN1;
|
||||
#endif
|
||||
|
||||
#if defined(_CMU_CLKEN1_SMU_MASK)
|
||||
CMU->CLKEN1_SET = CMU_CLKEN1_SMU;
|
||||
#endif // _CMU_CLKEN1_SMU_MASK
|
||||
ctx->SMU_STATUS = SMU->STATUS;
|
||||
|
||||
// Unlock SMU before re-configuration
|
||||
SMU->LOCK = SMU_LOCK_SMULOCKKEY_UNLOCK;
|
||||
|
||||
// Store the PPUSATDn states
|
||||
ctx->PPUSATD0 = SMU->PPUSATD0;
|
||||
ctx->PPUSATD1 = SMU->PPUSATD1;
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
|
||||
ctx->PPUSATD2 = SMU->PPUSATD2;
|
||||
#endif
|
||||
ctx->BMPUSATD0 = SMU->BMPUSATD0;
|
||||
|
||||
#if defined(SMU_NS_CFGNS_BASE)
|
||||
// Store the PPUPATDn states
|
||||
ctx->PPUPATD0 = SMU->PPUPATD0;
|
||||
ctx->PPUPATD1 = SMU->PPUPATD1;
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
|
||||
ctx->PPUPATD2 = SMU->PPUPATD2;
|
||||
#endif
|
||||
SMU->PPUPATD0 = SMU_NS_CFGNS->PPUNSPATD0;
|
||||
SMU->PPUPATD1 = SMU_NS_CFGNS->PPUNSPATD1;
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
|
||||
SMU->PPUPATD2 = SMU_NS_CFGNS->PPUNSPATD2;
|
||||
#endif
|
||||
#endif // SMU_NS_CFGNS_BASE
|
||||
|
||||
#if defined(CMU_CLKEN0_LDMA)
|
||||
CMU->CLKEN0_SET = CMU_CLKEN0_LDMA;
|
||||
#endif // CMU_CLKEN0_LDMA
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
CMU->CLKEN1_SET = CMU_CLKEN1_CRYPTOACC;
|
||||
#endif
|
||||
|
||||
// Wait for any active transition of other busmasters to finish
|
||||
if (SMU->PPUSATD0 & SMU_PPUSATD0_LDMA) {
|
||||
while (LDMA_S->STATUS & LDMA_STATUS_ANYBUSY) ;
|
||||
} else {
|
||||
while (LDMA_NS->STATUS & LDMA_STATUS_ANYBUSY) ;
|
||||
}
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
if (SMU->PPUSATD1 & SMU_PPUSATD1_CRYPTOACC) {
|
||||
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_230)
|
||||
while (CRYPTOACC_S->DMACTRL_STATUS & (CRYPTOACC_DMACTRL_STATUS_FETCH_BUSY | CRYPTOACC_DMACTRL_STATUS_PUSH_BUSY | CRYPTOACC_DMACTRL_STATUS_SOFT_RST_BUSY)) ;
|
||||
#else
|
||||
while (CRYPTOACC_S->STATUS & (CRYPTOACC_STATUS_FETCHERBSY | CRYPTOACC_STATUS_PUSHERBSY | CRYPTOACC_STATUS_SOFTRSTBSY)) ;
|
||||
#endif
|
||||
} else {
|
||||
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_230)
|
||||
while (CRYPTOACC_NS->DMACTRL_STATUS & (CRYPTOACC_DMACTRL_STATUS_FETCH_BUSY | CRYPTOACC_DMACTRL_STATUS_PUSH_BUSY | CRYPTOACC_DMACTRL_STATUS_SOFT_RST_BUSY)) ;
|
||||
#else
|
||||
while (CRYPTOACC_NS->STATUS & (CRYPTOACC_STATUS_FETCHERBSY | CRYPTOACC_STATUS_PUSHERBSY | CRYPTOACC_STATUS_SOFTRSTBSY)) ;
|
||||
#endif
|
||||
}
|
||||
#endif // CRYPTOACC_PRESENT
|
||||
|
||||
// Configure the peripheral secure access state before calling into the bootloader.
|
||||
#if !defined(BOOTLOADER_DISABLE_MULTI_TIERED_FALLBACK)
|
||||
#if defined(BOOTLOADER_ENABLE_USART_AUTO_DETECTION)
|
||||
// If we do not know which USART is used by the bootloader,
|
||||
// and the bootloader is not initialized,
|
||||
// Configure PPUSATDn bits for all the USART not in use.
|
||||
preConfigureUsartPPUSATD();
|
||||
#else
|
||||
SMU->PPUSATD0_SET = BOOTLOADER_PPUSATD0_MASK;
|
||||
SMU->PPUSATD1_SET = BOOTLOADER_PPUSATD1_MASK;
|
||||
#endif // BOOTLOADER_ENABLE_USART_AUTO_DETECTION
|
||||
|
||||
SMU->PPUSATD0_SET = SMU_PPUSATD0_CMU;
|
||||
SMU->PPUSATD0_SET = SMU_PPUSATD0_MSC;
|
||||
if (bootloader_getAllocatedDMAChannel() != -1
|
||||
&& bootloader_getAllocatedDMAChannel() != BOOTLOADER_ERROR_INIT_STORAGE) {
|
||||
SMU->PPUSATD0_SET = SMU_PPUSATD0_LDMA;
|
||||
SMU->PPUSATD0_SET = SMU_PPUSATD0_LDMAXBAR;
|
||||
SMU->BMPUSATD0_SET = SMU_BMPUSATD0_LDMA;
|
||||
}
|
||||
|
||||
SMU->PPUSATD0_SET = SMU_PPUSATD0_HFRCO0;
|
||||
#if !defined(_SILICON_LABS_32B_SERIES_2_CONFIG_5) && !defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6) \
|
||||
&& !defined(_SILICON_LABS_32B_SERIES_2_CONFIG_8) && !defined(_SILICON_LABS_32B_SERIES_2_CONFIG_9)
|
||||
SMU->PPUSATD0_SET = SMU_PPUSATD0_GPIO;
|
||||
#endif
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
|
||||
SMU->PPUSATD1_SET = SMU_PPUSATD1_GPCRC;
|
||||
#else
|
||||
SMU->PPUSATD0_SET = SMU_PPUSATD0_GPCRC;
|
||||
#endif
|
||||
#if defined(SMU_PPUSATD1_CRYPTOACC)
|
||||
SMU->PPUSATD1_SET = SMU_PPUSATD1_CRYPTOACC;
|
||||
#endif // SMU_PPUSATD1_CRYPTOACC
|
||||
#if defined(SMU_PPUSATD1_SEMAILBOX)
|
||||
SMU->PPUSATD1_SET = SMU_PPUSATD1_SEMAILBOX;
|
||||
#elif defined(SMU_PPUSATD2_SEMAILBOX)
|
||||
SMU->PPUSATD2_SET = SMU_PPUSATD2_SEMAILBOX;
|
||||
#endif // SMU_PPUSATD1_SEMAILBOX
|
||||
#elif defined(SL_TRUSTZONE_SECURE)
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_5)
|
||||
SMU->BMPUSATD0_SET = SMU_BMPUSATD0_LDMA0;
|
||||
SMU->BMPUSATD0_SET = SMU_BMPUSATD0_LDMA1;
|
||||
#else
|
||||
SMU->BMPUSATD0_SET = SMU_BMPUSATD0_LDMA;
|
||||
#endif
|
||||
#endif // BOOTLOADER_DISABLE_MULTI_TIERED_FALLBACK
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
|
||||
bootloader_getPeripheralList(&ppusatd0, &ppusatd1, &ppusatd2);
|
||||
SMU->PPUSATD0_SET = ppusatd0;
|
||||
SMU->PPUSATD1_SET = ppusatd1;
|
||||
SMU->PPUSATD2_SET = ppusatd2;
|
||||
#else
|
||||
bootloader_getPeripheralList(&ppusatd0, &ppusatd1);
|
||||
SMU->PPUSATD0_SET = ppusatd0;
|
||||
SMU->PPUSATD1_SET = ppusatd1;
|
||||
#endif
|
||||
|
||||
#if defined(BOOTLOADER_ENABLE_NVM3_FAULT_HANDLING)
|
||||
// Update the peripheral secure access state of
|
||||
// the "unknown" peripheral that triggered a fault earlier
|
||||
if (blPPUSATDnStateCacheSet == true) {
|
||||
SMU->PPUSATD0_SET = blPPUSATDnStateCache[0];
|
||||
SMU->PPUSATD1_SET = blPPUSATDnStateCache[1];
|
||||
}
|
||||
#endif // BOOTLOADER_ENABLE_NVM3_FAULT_HANDLING
|
||||
#if defined(BOOTLOADER_TEST_UNPRIVILEGED_ACCESS)
|
||||
enterUnprivilegedMode(enabled);
|
||||
#endif
|
||||
}
|
||||
|
||||
void bootloader_ppusatdnRestoreState(Bootloader_PPUSATDnCLKENnState_t *ctx)
|
||||
{
|
||||
#if defined(BOOTLOADER_TEST_UNPRIVILEGED_ACCESS)
|
||||
exitUnprivilegedMode();
|
||||
#endif
|
||||
|
||||
if (bootloader_ppusatdConfigstate != SAVE) {
|
||||
// This function is called from a bootloader callback function
|
||||
bootloader_ppusatdConfigstate = SAVE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait for any active transition of other busmasters to finish
|
||||
if (bootloader_getAllocatedDMAChannel() != -1
|
||||
&& bootloader_getAllocatedDMAChannel() != BOOTLOADER_ERROR_INIT_STORAGE) {
|
||||
#if defined(CMU_CLKEN0_LDMA)
|
||||
CMU_S->CLKEN0_SET = CMU_CLKEN0_LDMA;
|
||||
#endif // CMU_CLKEN0_LDMA
|
||||
while (LDMA_S->STATUS & LDMA_STATUS_ANYBUSY) ;
|
||||
}
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
if (SMU->PPUSATD0 & SMU_PPUSATD0_CMU) {
|
||||
CMU_S->CLKEN1_SET = CMU_CLKEN1_CRYPTOACC;
|
||||
} else {
|
||||
CMU_NS->CLKEN1_SET = CMU_CLKEN1_CRYPTOACC;
|
||||
}
|
||||
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_230)
|
||||
while (CRYPTOACC_S->DMACTRL_STATUS & (CRYPTOACC_DMACTRL_STATUS_FETCH_BUSY | CRYPTOACC_DMACTRL_STATUS_PUSH_BUSY | CRYPTOACC_DMACTRL_STATUS_SOFT_RST_BUSY)) ;
|
||||
#else
|
||||
while (CRYPTOACC_S->STATUS & (CRYPTOACC_STATUS_FETCHERBSY | CRYPTOACC_STATUS_PUSHERBSY | CRYPTOACC_STATUS_SOFTRSTBSY)) ;
|
||||
#endif
|
||||
#endif // CRYPTOACC_PRESENT
|
||||
|
||||
SMU->PPUSATD0 = ctx->PPUSATD0;
|
||||
SMU->PPUSATD1 = ctx->PPUSATD1;
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
|
||||
SMU->PPUSATD2 = ctx->PPUSATD2;
|
||||
#endif
|
||||
SMU->BMPUSATD0 = ctx->BMPUSATD0;
|
||||
#if defined(SMU_NS_CFGNS_BASE)
|
||||
SMU->PPUPATD0 = ctx->PPUPATD0;
|
||||
SMU->PPUPATD1 = ctx->PPUPATD1;
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
|
||||
SMU->PPUPATD2 = ctx->PPUPATD2;
|
||||
#endif
|
||||
#endif // SMU_NS_CFGNS_BASE
|
||||
if (ctx->SMU_STATUS & SMU_STATUS_SMULOCK) {
|
||||
SMU->LOCK = 0u;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_ENABLE_USART_AUTO_DETECTION)
|
||||
storeUsartInUse();
|
||||
#endif // BOOTLOADER_ENABLE_USART_AUTO_DETECTION
|
||||
|
||||
// Restore the CLKENn states
|
||||
#if defined(_CMU_CLKEN0_MASK)
|
||||
CMU->CLKEN0 = ctx->CLKEN0;
|
||||
CMU->CLKEN1 = ctx->CLKEN1;
|
||||
#endif
|
||||
|
||||
sli_bootloader_postHook();
|
||||
|
||||
#if !defined(BOOTLOADER_TEST_UNPRIVILEGED_ACCESS)
|
||||
CORE_EXIT_ATOMIC();
|
||||
#endif
|
||||
|
||||
// Update the state after the critical section has been
|
||||
// exited to ensure that the SMU interrupt gets fired,
|
||||
// before the state change happens.
|
||||
bootloader_ppusatdConfigstate = IDLE;
|
||||
}
|
||||
|
||||
__attribute__ ((weak)) void sli_bootloader_preHook(void)
|
||||
{
|
||||
}
|
||||
|
||||
__attribute__ ((weak)) void sli_bootloader_postHook(void)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_ENABLE_USART_AUTO_DETECTION)
|
||||
static void preConfigureUsartPPUSATD(void)
|
||||
{
|
||||
if (usartNumberSpi != -1) {
|
||||
#if defined(SMU_PPUSATD1_USART0)
|
||||
SMU->PPUSATD1_SET = (SMU_PPUSATD1_USART0 << usartNumberSpi);
|
||||
#else
|
||||
SMU->PPUSATD0_SET = (SMU_PPUSATD0_USART0 << usartNumberSpi);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (bootloader_InitState != RESET) {
|
||||
// The USART taken by the bootloader
|
||||
// is still unknown, do nothing.
|
||||
return;
|
||||
}
|
||||
#if defined(USART0_BASE)
|
||||
#if defined(CMU_CLKEN0_USART0)
|
||||
CMU->CLKEN0_SET = CMU_CLKEN0_USART0;
|
||||
#endif // CMU_CLKEN0_USART0
|
||||
#if defined(SL_TRUSTZONE_SECURE)
|
||||
if (USART0_NS->EN == _USART_EN_RESETVALUE) {
|
||||
#else
|
||||
if (USART0->EN == _USART_EN_RESETVALUE) {
|
||||
#endif // SL_TRUSTZONE_SECURE
|
||||
#if defined(SMU_PPUSATD1_USART0)
|
||||
SMU->PPUSATD1_SET = SMU_PPUSATD1_USART0;
|
||||
#else
|
||||
SMU->PPUSATD0_SET = SMU_PPUSATD0_USART0;
|
||||
#endif
|
||||
}
|
||||
#endif // USART0_BASE
|
||||
|
||||
#if defined(USART1_BASE)
|
||||
#if defined(CMU_CLKEN0_USART1)
|
||||
CMU->CLKEN0_SET = CMU_CLKEN0_USART1;
|
||||
#elif defined(CMU_CLKEN2_USART1)
|
||||
CMU->CLKEN2_SET = CMU_CLKEN2_USART1;
|
||||
#endif
|
||||
#if defined(SL_TRUSTZONE_SECURE)
|
||||
if (USART1_NS->EN == _USART_EN_RESETVALUE) {
|
||||
#else
|
||||
if (USART1->EN == _USART_EN_RESETVALUE) {
|
||||
#endif // SL_TRUSTZONE_SECURE
|
||||
#if defined(SMU_PPUSATD1_USART1)
|
||||
SMU->PPUSATD1_SET = SMU_PPUSATD1_USART1;
|
||||
#else
|
||||
SMU->PPUSATD0_SET = SMU_PPUSATD0_USART1;
|
||||
#endif
|
||||
}
|
||||
#endif // USART1_BASE
|
||||
|
||||
#if defined(USART2_BASE)
|
||||
#if defined(CMU_CLKEN0_USART2)
|
||||
CMU->CLKEN0_SET = CMU_CLKEN0_USART2;
|
||||
#elif defined(CMU_CLKEN2_USART2)
|
||||
CMU->CLKEN2_SET = CMU_CLKEN2_USART2;
|
||||
#endif
|
||||
#if defined(SL_TRUSTZONE_SECURE)
|
||||
if (USART2_NS->EN == _USART_EN_RESETVALUE) {
|
||||
#else
|
||||
if (USART2->EN == _USART_EN_RESETVALUE) {
|
||||
#endif // SL_TRUSTZONE_SECURE
|
||||
#if defined(SMU_PPUSATD1_USART2)
|
||||
SMU->PPUSATD1_SET = SMU_PPUSATD1_USART2;
|
||||
#else
|
||||
SMU->PPUSATD0_SET = SMU_PPUSATD0_USART2;
|
||||
#endif
|
||||
}
|
||||
#endif // USART2_BASE
|
||||
}
|
||||
|
||||
static void storeUsartInUse(void)
|
||||
{
|
||||
if ((usartNumberSpi != -1) || (bootloader_InitState != RESET)) {
|
||||
return;
|
||||
}
|
||||
#if defined(USART0_BASE)
|
||||
#if defined(SL_TRUSTZONE_SECURE)
|
||||
if (USART0_NS->EN & USART_EN_EN) {
|
||||
#else
|
||||
if (USART0->EN & USART_EN_EN) {
|
||||
#endif // SL_TRUSTZONE_SECURE
|
||||
usartNumberSpi = 0;
|
||||
}
|
||||
#endif // USART0_BASE
|
||||
|
||||
#if defined(USART1_BASE)
|
||||
#if defined(SL_TRUSTZONE_SECURE)
|
||||
if (USART1_NS->EN & USART_EN_EN) {
|
||||
#else
|
||||
if (USART1->EN & USART_EN_EN) {
|
||||
#endif // SL_TRUSTZONE_SECURE
|
||||
usartNumberSpi = 1;
|
||||
}
|
||||
#endif // USART1_BASE
|
||||
|
||||
#if defined(USART2_BASE)
|
||||
#if defined(SL_TRUSTZONE_SECURE)
|
||||
if (USART2_NS->EN & USART_EN_EN) {
|
||||
#else
|
||||
if (USART2->EN & USART_EN_EN) {
|
||||
#endif // SL_TRUSTZONE_SECURE
|
||||
usartNumberSpi = 2;
|
||||
}
|
||||
#endif // USART2_BASE
|
||||
}
|
||||
#endif // BOOTLOADER_ENABLE_USART_AUTO_DETECTION
|
||||
|
||||
#if defined(BOOTLOADER_ENABLE_NVM3_FAULT_HANDLING)
|
||||
void SMU_SECURE_IRQHandler(void)
|
||||
{
|
||||
#if !defined(BOOTLOADER_TEST_FAULT_HANDLING)
|
||||
if (bootloader_ppusatdConfigstate == IDLE) {
|
||||
// If none of the bootloader interface operations are active,
|
||||
// the fault is not caused by the bootloader. Just park in the while loop.
|
||||
while (true) ;
|
||||
}
|
||||
#endif // BOOTLOADER_TEST_FAULT_HANDLING
|
||||
|
||||
Ecode_t status;
|
||||
uint32_t PPUSATDn_state[2] = { 0 };
|
||||
nvm3_ObjectKey_t object_id = BL_NVM3_RESERVED_ID;
|
||||
|
||||
// First read the pre-existing configuration
|
||||
status = nvm3_readData(nvm3_defaultHandle, object_id, PPUSATDn_state, sizeof(PPUSATDn_state));
|
||||
if (status == ECODE_NVM3_OK) {
|
||||
if (SMU->PPUFS > 31) {
|
||||
PPUSATDn_state[1] |= 1 << (SMU->PPUFS - 32);
|
||||
} else {
|
||||
PPUSATDn_state[0] |= 1 << SMU->PPUFS;
|
||||
}
|
||||
// Nothing to do to recover if this fails, just continue and perform a reset.
|
||||
(void)nvm3_writeData(nvm3_defaultHandle, object_id, PPUSATDn_state, sizeof(PPUSATDn_state));
|
||||
} else if (status == ECODE_NVM3_ERR_KEY_NOT_FOUND) {
|
||||
if (SMU->PPUFS > 31) {
|
||||
PPUSATDn_state[1] = 1 << (SMU->PPUFS - 32);
|
||||
} else {
|
||||
PPUSATDn_state[0] = 1 << SMU->PPUFS;
|
||||
}
|
||||
(void)nvm3_writeData(nvm3_defaultHandle, object_id, PPUSATDn_state, sizeof(PPUSATDn_state));
|
||||
} else {
|
||||
// Do nothing. If NVM3 read fails for an unknown reason,
|
||||
// perform a reset to recover from the failure state.
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
uint32_t resetReasonBase = (uint32_t)&__ResetReasonStart__;
|
||||
#elif defined(__ICCARM__)
|
||||
void *resetReasonBase = __section_begin("BOOTLOADER_RESET_REASON");
|
||||
#endif
|
||||
BootloaderResetCause_t *resetCause = (BootloaderResetCause_t *) (resetReasonBase);
|
||||
resetCause->reason = BOOTLOADER_RESET_REASON_FAULT;
|
||||
resetCause->signature = BOOTLOADER_RESET_SIGNATURE_VALID;
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#endif // BOOTLOADER_ENABLE_NVM3_FAULT_HANDLING
|
||||
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
773
Libs/platform/bootloader/api/btl_interface.h
Normal file
773
Libs/platform/bootloader/api/btl_interface.h
Normal file
@@ -0,0 +1,773 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Application interface to the bootloader.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc. Your use of this
|
||||
* software is governed by the terms of Silicon Labs Master Software License
|
||||
* Agreement (MSLA) available at
|
||||
* www.silabs.com/about-us/legal/master-software-license-agreement. This
|
||||
* software is distributed to you in Source Code format and is governed by the
|
||||
* sections of the MSLA applicable to Source Code.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTL_INTERFACE_H
|
||||
#define BTL_INTERFACE_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "btl_errorcode.h"
|
||||
#include "btl_reset_info.h"
|
||||
#include "application_properties.h"
|
||||
|
||||
// Include component-specific interfaces
|
||||
#include "btl_interface_parser.h"
|
||||
#include "btl_interface_storage.h"
|
||||
|
||||
// Get flash page size
|
||||
#include "em_device.h"
|
||||
|
||||
#if defined(SL_TRUSTZONE_NONSECURE)
|
||||
#include "sli_tz_ns_interface.h"
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif
|
||||
/***************************************************************************//**
|
||||
* @addtogroup Interface Application Interface
|
||||
* @brief Application interface to the bootloader
|
||||
* @details
|
||||
* The application interface consists of functions that can be included
|
||||
* in the customer application that and will communicate with the
|
||||
* bootloader through the @ref MainBootloaderTable_t. This table
|
||||
* contains function pointers to the bootloader. The 10th word of the
|
||||
* bootloader contains a pointer to this struct, allowing any application to
|
||||
* easily locate it.
|
||||
* To access the bootloader table, use wrapper functions. Avoid
|
||||
* accessing the bootloader table directly.
|
||||
*
|
||||
* @{
|
||||
* @addtogroup CommonInterface Common Application Interface
|
||||
* @brief Generic application interface available on all versions of the
|
||||
* bootloader, regardless of the available components.
|
||||
* @note These Bootloader APIs are not reentrant and should be wrapped in critical section
|
||||
* where needed.
|
||||
* @details
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/// Bare boot table. Can be mapped on top of vector table to access contents.
|
||||
typedef struct {
|
||||
/// Pointer to top of stack
|
||||
uint32_t *stackTop;
|
||||
/// Pointer to reset vector
|
||||
void (*resetVector)(void);
|
||||
/// Reserved pointers to fault handlers
|
||||
uint32_t reserved0[5];
|
||||
/// Reserved pointers to RESERVED fields
|
||||
uint32_t reserved1[3];
|
||||
/// Pointer to bootloader table
|
||||
void *table;
|
||||
/// Reserved pointers to SVC and DebugMon interrupts
|
||||
uint32_t reserved2[2];
|
||||
/// Pointer to application signature
|
||||
void *signature;
|
||||
} BareBootTable_t;
|
||||
|
||||
// --------------------------------
|
||||
// Bootloader defines
|
||||
|
||||
/// Bootloader version major version shift value
|
||||
#define BOOTLOADER_VERSION_MAJOR_SHIFT (24U)
|
||||
/// Bootloader version minor version shift value
|
||||
#define BOOTLOADER_VERSION_MINOR_SHIFT (16U)
|
||||
/// Bootloader version major version mask
|
||||
#define BOOTLOADER_VERSION_MAJOR_MASK (0xFF000000U)
|
||||
/// Bootloader version minor version mask
|
||||
#define BOOTLOADER_VERSION_MINOR_MASK (0x00FF0000U)
|
||||
|
||||
/// Bootloader interface APIs are trust zone aware
|
||||
#if defined(BOOTLOADER_SECURE)
|
||||
#define BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_2) && !defined(BOOTLOADER_APPLOADER)
|
||||
// The bootloader with AppLoader as the communication interface will not
|
||||
// re-configure the SMU since it is using the NS peripherals by default.
|
||||
#define BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
#endif
|
||||
|
||||
// --------------------------------
|
||||
// Bootloader information typedefs
|
||||
|
||||
/// Type of bootloader
|
||||
typedef enum {
|
||||
/// No bootloader present.
|
||||
NO_BOOTLOADER = 0,
|
||||
/// Bootloader is a Silicon Labs bootloader.
|
||||
SL_BOOTLOADER = 1
|
||||
} BootloaderType_t;
|
||||
|
||||
/// Information about the current bootloader
|
||||
typedef struct {
|
||||
/// The type of bootloader.
|
||||
BootloaderType_t type;
|
||||
/// Version number of the bootloader
|
||||
uint32_t version;
|
||||
/// Capability mask for the bootloader.
|
||||
uint32_t capabilities;
|
||||
} BootloaderInformation_t;
|
||||
|
||||
/// Common header for bootloader tables
|
||||
typedef struct {
|
||||
/// Type of image
|
||||
uint32_t type;
|
||||
/// Version number of the bootloader/application table
|
||||
uint32_t layout;
|
||||
/// Version number of the image
|
||||
uint32_t version;
|
||||
} BootloaderHeader_t;
|
||||
|
||||
/// Address table for the First Stage Bootloader
|
||||
typedef struct {
|
||||
/// Header of the First Stage Bootloader table
|
||||
BootloaderHeader_t header;
|
||||
/// Start address of the Main Bootloader
|
||||
BareBootTable_t *mainBootloader;
|
||||
/// Location of the Main Bootloader upgrade image
|
||||
BareBootTable_t *upgradeLocation;
|
||||
} FirstBootloaderTable_t;
|
||||
|
||||
/// Address table for the Main Bootloader
|
||||
typedef struct {
|
||||
/// Header of the Main Bootloader table
|
||||
BootloaderHeader_t header;
|
||||
/// Size of the Main Bootloader
|
||||
uint32_t size;
|
||||
/// Start address of the application
|
||||
BareBootTable_t *startOfAppSpace;
|
||||
/// End address of the allocated application space
|
||||
uint32_t *endOfAppSpace;
|
||||
/// Capabilities of the bootloader
|
||||
uint32_t capabilities;
|
||||
// ------------------------------
|
||||
/// Initialize bootloader for use from application
|
||||
int32_t (*init)(void);
|
||||
/// Deinitialize bootloader after use from application
|
||||
int32_t (*deinit)(void);
|
||||
// ------------------------------
|
||||
/// Verify application
|
||||
bool (*verifyApplication)(uint32_t startAddress);
|
||||
// ------------------------------
|
||||
/// Initialize parser
|
||||
int32_t (*initParser)(BootloaderParserContext_t *context, size_t contextSize);
|
||||
/// Parse a buffer
|
||||
int32_t (*parseBuffer)(BootloaderParserContext_t *context,
|
||||
const BootloaderParserCallbacks_t *callbacks,
|
||||
uint8_t data[],
|
||||
size_t numBytes);
|
||||
// ------------------------------
|
||||
/// Function table for storage component
|
||||
const BootloaderStorageFunctions_t *storage;
|
||||
// ------------------------------
|
||||
/// Parse a buffer and get application and bootloader upgrade metadata from the buffer.
|
||||
int32_t (*parseImageInfo)(BootloaderParserContext_t *context,
|
||||
uint8_t data[],
|
||||
size_t numBytes,
|
||||
ApplicationData_t *appInfo,
|
||||
uint32_t *bootloaderVersion);
|
||||
// ------------------------------
|
||||
/// Size of context buffer used by bootloader image parser to store parser state
|
||||
uint32_t (*parserContextSize)(void);
|
||||
// ------------------------------
|
||||
/// Remaining number of application upgrades
|
||||
uint32_t (*remainingApplicationUpgrades)(void);
|
||||
// ------------------------------
|
||||
/// Get the list of the peripheral that is used by the bootloader
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
|
||||
void (*getPeripheralList)(uint32_t *ppusatd0, uint32_t *ppusatd1, uint32_t *ppusatd2);
|
||||
#else
|
||||
void (*getPeripheralList)(uint32_t *ppusatd0, uint32_t *ppusatd1);
|
||||
#endif
|
||||
// ------------------------------
|
||||
/// Get base address of bootloader upgrade image
|
||||
uint32_t (*getUpgradeLocation)(void);
|
||||
} MainBootloaderTable_t;
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
/// Struct that represents the state of the PPUSATDn, PPUPATDn and CLKENn registers
|
||||
typedef struct {
|
||||
uint32_t PPUSATD0;
|
||||
uint32_t PPUSATD1;
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
|
||||
uint32_t PPUSATD2;
|
||||
#endif
|
||||
uint32_t BMPUSATD0;
|
||||
#if defined(SMU_NS_CFGNS_BASE)
|
||||
uint32_t PPUPATD0;
|
||||
uint32_t PPUPATD1;
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
|
||||
uint32_t PPUPATD2;
|
||||
#endif
|
||||
#endif
|
||||
#if defined(_CMU_CLKEN0_MASK)
|
||||
uint32_t CLKEN0;
|
||||
uint32_t CLKEN1;
|
||||
#endif
|
||||
uint32_t SMU_STATUS;
|
||||
} Bootloader_PPUSATDnCLKENnState_t;
|
||||
|
||||
/// Struct containing function arguments
|
||||
typedef struct Bootloader_inOutVec {
|
||||
void *base; /// the start address of the memory buffer
|
||||
size_t len; /// the size in bytes
|
||||
} Bootloader_inOutVec_t;
|
||||
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
// --------------------------------
|
||||
// Bootloader capabilities
|
||||
|
||||
/// Bootloader enforces signed application upgrade images
|
||||
#define BOOTLOADER_CAPABILITY_ENFORCE_UPGRADE_SIGNATURE (1 << 0)
|
||||
/// Bootloader enforces encrypted application upgrade images
|
||||
#define BOOTLOADER_CAPABILITY_ENFORCE_UPGRADE_ENCRYPTION (1 << 1)
|
||||
/// @brief Bootloader enforces signature verification of the application image
|
||||
/// before every boot
|
||||
#define BOOTLOADER_CAPABILITY_ENFORCE_SECURE_BOOT (1 << 2)
|
||||
|
||||
/// Bootloader has the capability of being upgraded
|
||||
#define BOOTLOADER_CAPABILITY_BOOTLOADER_UPGRADE (1 << 4)
|
||||
|
||||
/// Bootloader has the capability of parsing GBL files
|
||||
#define BOOTLOADER_CAPABILITY_GBL (1 << 5)
|
||||
/// Bootloader has the capability of parsing signed GBL files
|
||||
#define BOOTLOADER_CAPABILITY_GBL_SIGNATURE (1 << 6)
|
||||
/// Bootloader has the capability of parsing encrypted GBL files
|
||||
#define BOOTLOADER_CAPABILITY_GBL_ENCRYPTION (1 << 7)
|
||||
/// @brief Bootloader enforces signature verification of the application image
|
||||
/// before every boot using certificate
|
||||
#define BOOTLOADER_CAPABILITY_ENFORCE_CERTIFICATE_SECURE_BOOT (1 << 8)
|
||||
/// Bootloader has the capability of application rollback protection
|
||||
#define BOOTLOADER_CAPABILITY_ROLLBACK_PROTECTION (1 << 9)
|
||||
/// Bootloader has the capability to check the peripherals in use
|
||||
#define BOOTLOADER_CAPABILITY_PERIPHERAL_LIST (1 << 10)
|
||||
|
||||
/// @brief Bootloader has the capability of storing data in an internal or
|
||||
/// external storage medium
|
||||
#define BOOTLOADER_CAPABILITY_STORAGE (1 << 16)
|
||||
/// @brief Bootloader has the capability of communicating with host processors
|
||||
/// using a communication interface
|
||||
#define BOOTLOADER_CAPABILITY_COMMUNICATION (1 << 20)
|
||||
|
||||
// --------------------------------
|
||||
// Magic constants for bootloader tables
|
||||
|
||||
/// Magic word indicating first stage bootloader table
|
||||
#define BOOTLOADER_MAGIC_FIRST_STAGE (0xB00710ADUL)
|
||||
/// Magic word indicating main bootloader table
|
||||
#define BOOTLOADER_MAGIC_MAIN (0x5ECDB007UL)
|
||||
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
#define BOOTLOADER_HEADER_VERSION_FIRST_STAGE (0x00000001UL)
|
||||
#define BOOTLOADER_HEADER_VERSION_MAIN (0x00000002UL)
|
||||
/// @endcond
|
||||
|
||||
// --------------------------------
|
||||
// Bootloader table access
|
||||
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
|
||||
#if defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT) || defined(MAIN_BOOTLOADER_TEST)
|
||||
// No first stage on devices with SE
|
||||
#define BTL_FIRST_STAGE_SIZE (0UL)
|
||||
#else
|
||||
// First stage takes a single flash page
|
||||
#define BTL_FIRST_STAGE_SIZE (FLASH_PAGE_SIZE)
|
||||
#define BOOTLOADER_HAS_FIRST_STAGE
|
||||
#endif
|
||||
|
||||
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
|
||||
// No writeable bootloader area: Place the bootloader in main flash
|
||||
#define BTL_FIRST_STAGE_BASE 0x00000000UL
|
||||
#define BTL_APPLICATION_BASE 0x00004000UL
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (BTL_APPLICATION_BASE \
|
||||
- BTL_FIRST_STAGE_SIZE)
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_84)
|
||||
// Dedicated bootloader area of 38k
|
||||
// Place the bootloader in the dedicated bootloader area of the
|
||||
// information block
|
||||
#define BTL_FIRST_STAGE_BASE 0x0FE10000UL
|
||||
#define BTL_APPLICATION_BASE 0x00000000UL
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (0x00009800UL - BTL_FIRST_STAGE_SIZE)
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89)
|
||||
#define BTL_FIRST_STAGE_BASE 0x0FE10000UL
|
||||
#if defined(MAIN_BOOTLOADER_IN_MAIN_FLASH)
|
||||
#define BTL_APPLICATION_BASE 0x00004800UL
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE BTL_APPLICATION_BASE
|
||||
#else
|
||||
// Dedicated bootloader area of 16k
|
||||
// Place the bootloader in the dedicated bootloader area of the
|
||||
// information block
|
||||
#define BTL_APPLICATION_BASE 0x00000000UL
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (0x00004000UL - BTL_FIRST_STAGE_SIZE)
|
||||
#endif
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_95)
|
||||
#define BTL_FIRST_STAGE_BASE 0x0FE10000UL
|
||||
#if defined(MAIN_BOOTLOADER_IN_MAIN_FLASH)
|
||||
#define BTL_APPLICATION_BASE 0x00004800UL
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE BTL_APPLICATION_BASE
|
||||
#else
|
||||
// Dedicated bootloader area of 18k
|
||||
// Place the bootloader in the dedicated bootloader area of the
|
||||
// information block
|
||||
#define BTL_APPLICATION_BASE 0x00000000UL
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (0x00004800UL - BTL_FIRST_STAGE_SIZE)
|
||||
#endif
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_100) || defined(_SILICON_LABS_GECKO_INTERNAL_SDID_106)
|
||||
// Dedicated bootloader area of 32k
|
||||
// Place the bootloader in the dedicated bootloader area of the
|
||||
// information block
|
||||
#define BTL_FIRST_STAGE_BASE 0x0FE10000UL
|
||||
#define BTL_APPLICATION_BASE 0x00000000UL
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (0x00008000UL - BTL_FIRST_STAGE_SIZE)
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_103)
|
||||
// Dedicated bootloader area of 18k
|
||||
// Place the bootloader in the dedicated bootloader area of the
|
||||
// information block
|
||||
#define BTL_FIRST_STAGE_BASE 0x0FE10000UL
|
||||
#define BTL_APPLICATION_BASE 0x00000000UL
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (0x00004800UL - BTL_FIRST_STAGE_SIZE)
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_200)
|
||||
// No bootloader area: Place the bootloader in main flash
|
||||
#define BTL_FIRST_STAGE_BASE FLASH_BASE
|
||||
#if defined(BOOTLOADER_APPLOADER)
|
||||
#if defined(BOOTLOADER_SECURE)
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00014000UL)
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00012000UL)
|
||||
#endif // BOOTLOADER_SECURE
|
||||
#elif defined(BOOTLOADER_SECURE) && defined(BOOTLOADER_SUPPORT_COMMUNICATION)
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00006000UL)
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00004000UL)
|
||||
#endif // BOOTLOADER_APPLOADER
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (BTL_APPLICATION_BASE \
|
||||
- BTL_FIRST_STAGE_SIZE)
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_205)
|
||||
// No bootloader area: Place the bootloader in main flash
|
||||
#define BTL_FIRST_STAGE_BASE FLASH_BASE
|
||||
#if defined(BOOTLOADER_APPLOADER)
|
||||
#if defined(BOOTLOADER_SECURE)
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00014000UL)
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00012000UL)
|
||||
#endif // BOOTLOADER_SECURE
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00006000UL)
|
||||
#endif // BOOTLOADER_APPLOADER
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (BTL_APPLICATION_BASE \
|
||||
- BTL_FIRST_STAGE_SIZE)
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_210)
|
||||
// No bootloader area: Place the bootloader in main flash
|
||||
#define BTL_FIRST_STAGE_BASE FLASH_BASE
|
||||
#if defined(BOOTLOADER_APPLOADER)
|
||||
#if defined(BOOTLOADER_SECURE)
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00014000UL)
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00012000UL)
|
||||
#endif // BOOTLOADER_SECURE
|
||||
#elif defined(BOOTLOADER_CUSTOM_SIZE)
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00004000UL)
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00006000UL)
|
||||
#endif // BOOTLOADER_APPLOADER
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (BTL_APPLICATION_BASE \
|
||||
- (BTL_FIRST_STAGE_BASE \
|
||||
+ BTL_FIRST_STAGE_SIZE))
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_215)
|
||||
// No bootloader area: Place the bootloader in main flash
|
||||
#define BTL_FIRST_STAGE_BASE FLASH_BASE
|
||||
#if defined(BOOTLOADER_APPLOADER)
|
||||
#if defined(BOOTLOADER_SECURE)
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00014000UL)
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00012000UL)
|
||||
#endif // BOOTLOADER_SECURE
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00006000UL)
|
||||
#endif // BOOTLOADER_APPLOADER
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (BTL_APPLICATION_BASE \
|
||||
- (BTL_FIRST_STAGE_BASE \
|
||||
+ BTL_FIRST_STAGE_SIZE))
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_220)
|
||||
// No bootloader area: Place the bootloader in main flash
|
||||
#define BTL_FIRST_STAGE_BASE FLASH_BASE
|
||||
#if defined(BOOTLOADER_APPLOADER)
|
||||
#if defined(BOOTLOADER_SECURE)
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00014000UL)
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00012000UL)
|
||||
#endif // BOOTLOADER_SECURE
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00006000UL)
|
||||
#endif // BOOTLOADER_APPLOADER
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (BTL_APPLICATION_BASE \
|
||||
- (BTL_FIRST_STAGE_BASE \
|
||||
+ BTL_FIRST_STAGE_SIZE))
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_225)
|
||||
// No bootloader area: Place the bootloader in main flash
|
||||
#define BTL_FIRST_STAGE_BASE FLASH_BASE
|
||||
#if defined(BOOTLOADER_APPLOADER)
|
||||
#if defined(BOOTLOADER_SECURE)
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00014000UL)
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00012000UL)
|
||||
#endif // BOOTLOADER_SECURE
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00006000UL)
|
||||
#endif // BOOTLOADER_APPLOADER
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (BTL_APPLICATION_BASE \
|
||||
- (BTL_FIRST_STAGE_BASE \
|
||||
+ BTL_FIRST_STAGE_SIZE))
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_230)
|
||||
// No bootloader area: Place the bootloader in main flash
|
||||
#define BTL_FIRST_STAGE_BASE FLASH_BASE
|
||||
#if defined(BOOTLOADER_APPLOADER)
|
||||
#if defined(BOOTLOADER_SECURE)
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00014000UL)
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00012000UL)
|
||||
#endif // BOOTLOADER_SECURE
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00006000UL)
|
||||
#endif // BOOTLOADER_APPLOADER
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (BTL_APPLICATION_BASE \
|
||||
- (BTL_FIRST_STAGE_BASE \
|
||||
+ BTL_FIRST_STAGE_SIZE))
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_235)
|
||||
// No bootloader area: Place the bootloader in main flash
|
||||
#define BTL_FIRST_STAGE_BASE FLASH_BASE
|
||||
#if defined(BOOTLOADER_APPLOADER)
|
||||
#if defined(BOOTLOADER_SECURE)
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00014000UL)
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00012000UL)
|
||||
#endif // BOOTLOADER_SECURE
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00006000UL)
|
||||
#endif // BOOTLOADER_APPLOADER
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (BTL_APPLICATION_BASE \
|
||||
- (BTL_FIRST_STAGE_BASE \
|
||||
+ BTL_FIRST_STAGE_SIZE))
|
||||
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_240)
|
||||
// No bootloader area: Place the bootloader in main flash
|
||||
#define BTL_FIRST_STAGE_BASE FLASH_BASE
|
||||
#if defined(BOOTLOADER_APPLOADER)
|
||||
#if defined(BOOTLOADER_SECURE)
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00014000UL)
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00012000UL)
|
||||
#endif // BOOTLOADER_SECURE
|
||||
#else
|
||||
#define BTL_APPLICATION_BASE (FLASH_BASE + 0x00006000UL)
|
||||
#endif // BOOTLOADER_APPLOADER
|
||||
#define BTL_MAIN_STAGE_MAX_SIZE (BTL_APPLICATION_BASE \
|
||||
- (BTL_FIRST_STAGE_BASE \
|
||||
+ BTL_FIRST_STAGE_SIZE))
|
||||
#else
|
||||
#error "This part is not supported in this bootloader version."
|
||||
#endif
|
||||
|
||||
#if defined(MAIN_BOOTLOADER_TEST) || defined(MAIN_BOOTLOADER_IN_MAIN_FLASH)
|
||||
#define BTL_MAIN_STAGE_BASE (FLASH_BASE)
|
||||
#else
|
||||
#define BTL_MAIN_STAGE_BASE (BTL_FIRST_STAGE_BASE \
|
||||
+ BTL_FIRST_STAGE_SIZE)
|
||||
#endif
|
||||
|
||||
#if defined(BOOTLOADER_HAS_FIRST_STAGE)
|
||||
#define BTL_FIRST_BOOTLOADER_TABLE_BASE (BTL_FIRST_STAGE_BASE \
|
||||
+ offsetof(BareBootTable_t, table))
|
||||
#endif
|
||||
#define BTL_MAIN_BOOTLOADER_TABLE_BASE (BTL_MAIN_STAGE_BASE \
|
||||
+ offsetof(BareBootTable_t, table))
|
||||
|
||||
/// @endcond // DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
|
||||
#if defined(MAIN_BOOTLOADER_TEST)
|
||||
#if defined(BOOTLOADER_HAS_FIRST_STAGE)
|
||||
extern FirstBootloaderTable_t * firstBootloaderTable;
|
||||
#endif
|
||||
extern MainBootloaderTable_t *mainBootloaderTable;
|
||||
#else
|
||||
#if defined(BOOTLOADER_HAS_FIRST_STAGE)
|
||||
/// Pointer to first stage bootloader table
|
||||
#define firstBootloaderTable (*(FirstBootloaderTable_t **) \
|
||||
(BTL_FIRST_BOOTLOADER_TABLE_BASE))
|
||||
#endif // BOOTLOADER_HAS_FIRST_STAGE
|
||||
/// Pointer to main bootloader table
|
||||
#define mainBootloaderTable (*(MainBootloaderTable_t **) \
|
||||
(BTL_MAIN_BOOTLOADER_TABLE_BASE))
|
||||
#endif // MAIN_BOOTLOADER_TEST
|
||||
// --------------------------------
|
||||
// Functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get information about the bootloader on this device.
|
||||
*
|
||||
* The returned information is fetched from the main bootloader
|
||||
* information table.
|
||||
*
|
||||
* @param[out] info Pointer to the bootloader information struct.
|
||||
******************************************************************************/
|
||||
void bootloader_getInfo(BootloaderInformation_t *info);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initialize components of the bootloader
|
||||
* so the app can use the interface. This typically includes initializing
|
||||
* serial peripherals for communication with external SPI flashes, and so on.
|
||||
*
|
||||
* @return Error code. @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_INIT_BASE range.
|
||||
******************************************************************************/
|
||||
int32_t bootloader_init(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* De-initialize components of the bootloader that were previously initialized.
|
||||
* This typically includes powering down external SPI flashes and
|
||||
* de-initializing the serial peripheral used for communication with the
|
||||
* external flash.
|
||||
*
|
||||
* @return Error code. @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_INIT_BASE range.
|
||||
******************************************************************************/
|
||||
int32_t bootloader_deinit(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Reboot into the bootloader to perform an install.
|
||||
*
|
||||
* If there is a storage component and a slot is marked for bootload, install
|
||||
* the image in that slot after verifying it.
|
||||
*
|
||||
* If a communication component is present, open the communication channel and
|
||||
* receive an image to be installed.
|
||||
******************************************************************************/
|
||||
void bootloader_rebootAndInstall(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Verify the application image stored in the Flash memory starting at
|
||||
* the address startAddress.
|
||||
*
|
||||
* If the secure boot is enforced, the function will only return true if the
|
||||
* cryptographic signature of the application is valid. Otherwise, the
|
||||
* application is verified according to the signature type defined in the
|
||||
* ApplicationProperties_t structure embedded in the application. Silicon Labs
|
||||
* wireless stacks include a declaration of this structure. However,
|
||||
* applications not using a full wireless stack may need to instantiate
|
||||
* the structure.
|
||||
*
|
||||
* Examples of results when the secure boot is not enforced:
|
||||
* - App has no signature: Valid if initial stack pointer and program counter
|
||||
* have reasonable values.
|
||||
* - App has CRC checksum: Valid if checksum is valid.
|
||||
* - App has ECDSA signature: Valid if ECDSA signature is valid.
|
||||
*
|
||||
* When secure boot is enforced, only ECDSA signed applications with
|
||||
* a valid signature are considered valid.
|
||||
*
|
||||
*
|
||||
* @param[in] startAddress Starting address of the application.
|
||||
*
|
||||
* @return True if the application is valid, else false.
|
||||
******************************************************************************/
|
||||
bool bootloader_verifyApplication(uint32_t startAddress);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Check whether signature verification on the application image in internal flash
|
||||
* is enforced before every boot.
|
||||
*
|
||||
* @return True if signature verification is enforced, else false.
|
||||
******************************************************************************/
|
||||
bool bootloader_secureBootEnforced(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get base address of the bootloader upgrade image.
|
||||
*
|
||||
* @param[out] location the base address of bootloader upgrade image.
|
||||
*
|
||||
* @return Returns true if the location was found.
|
||||
******************************************************************************/
|
||||
bool bootloader_getUpgradeLocation(uint32_t *location);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
/***************************************************************************//**
|
||||
* Get the list of the peripheral that is used by the bootloader.
|
||||
*
|
||||
* @param[out] ppusatd0 Word containing all the peripherals used by the
|
||||
* bootloader. Each bit represents a peripheral,
|
||||
* which is ordered after the PPUSATD0 register bit
|
||||
* fields.
|
||||
*
|
||||
* @param[out] ppusatd1 Word containing all the peripherals used by the
|
||||
* bootloader. Each bit represents a peripheral,
|
||||
* which is ordered after the PPUSATD1 register bit
|
||||
* fields.
|
||||
******************************************************************************/
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
|
||||
void bootloader_getPeripheralList(uint32_t *ppusatd0, uint32_t *ppusatd1, uint32_t *ppusatd2);
|
||||
#else
|
||||
void bootloader_getPeripheralList(uint32_t *ppusatd0, uint32_t *ppusatd1);
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Save PPUSATDn state in RAM.
|
||||
* Configure the peripheral attributes before calling into the bootloader.
|
||||
*
|
||||
* @note Enters ATOMIC section.
|
||||
*
|
||||
* @param[out] ctx Context struct to save register state into
|
||||
*
|
||||
* @return True if a valid certificate version is found.
|
||||
******************************************************************************/
|
||||
void bootloader_ppusatdnSaveReconfigureState(Bootloader_PPUSATDnCLKENnState_t *ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Restore PPUSATDn state from RAM.
|
||||
* Store the USART used by the bootloader if this is unknown.
|
||||
*
|
||||
* @note Exits ATOMIC section.
|
||||
*
|
||||
* @param[in] ctx Context struct to restore register state from
|
||||
*
|
||||
* @return True if a valid certificate version is found.
|
||||
******************************************************************************/
|
||||
void bootloader_ppusatdnRestoreState(Bootloader_PPUSATDnCLKENnState_t *ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Called before the bootloader is initialized.
|
||||
*
|
||||
* This function implementation does not perform anything, but it is __weak
|
||||
* so that it can be implemented by another application.
|
||||
******************************************************************************/
|
||||
void sli_bootloader_preHook(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Called after the bootloader is de-initialized.
|
||||
*
|
||||
* This function implementation does not perform anything, but it is __weak
|
||||
* so that it can be implemented by another application.
|
||||
******************************************************************************/
|
||||
void sli_bootloader_postHook(void);
|
||||
#endif
|
||||
|
||||
#if !defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
|
||||
/***************************************************************************//**
|
||||
* Count the total remaining number of application upgrades.
|
||||
*
|
||||
* @return remaining number of application upgrades.
|
||||
******************************************************************************/
|
||||
uint32_t bootloader_remainingApplicationUpgrades(void);
|
||||
#endif
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
/***************************************************************************//**
|
||||
* Get bootloader certificate version.
|
||||
*
|
||||
* @param[out] version Bootloader certificate version
|
||||
*
|
||||
* @return True if a valid certificate version is found.
|
||||
******************************************************************************/
|
||||
bool bootloader_getCertificateVersion(uint32_t *version);
|
||||
#endif // _SILICON_LABS_32B_SERIES_2
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get reset cause of the bootloader.
|
||||
*
|
||||
* @return Reset cause of the bootloader.
|
||||
******************************************************************************/
|
||||
BootloaderResetCause_t bootloader_getResetReason(void);
|
||||
|
||||
#if defined(BOOTLOADER_HAS_FIRST_STAGE)
|
||||
/***************************************************************************//**
|
||||
* Check if a pointer is valid and if it points to the bootloader first stage.
|
||||
*
|
||||
* This function checks pointers to bootloader
|
||||
* jump tables.
|
||||
*
|
||||
*
|
||||
* @param[in] ptr The pointer to check
|
||||
*
|
||||
* @return True if the pointer points to the bootloader first stage,
|
||||
* false if not.
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE bool bootloader_pointerToFirstStageValid(const void *ptr);
|
||||
__STATIC_INLINE bool bootloader_pointerToFirstStageValid(const void *ptr)
|
||||
{
|
||||
#if defined(MAIN_BOOTLOADER_TEST)
|
||||
// In main bootloader tests, no first stage is present
|
||||
(void) ptr;
|
||||
return false;
|
||||
#elif BTL_FIRST_STAGE_BASE > 0U
|
||||
if (((size_t)(ptr) >= BTL_FIRST_STAGE_BASE)
|
||||
&& ((size_t)(ptr) < (BTL_FIRST_STAGE_BASE + BTL_FIRST_STAGE_SIZE))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
// First stage starts at address 0, don't need to check lower bound
|
||||
if ((size_t)(ptr) < (BTL_FIRST_STAGE_BASE + BTL_FIRST_STAGE_SIZE)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif // BOOTLOADER_HAS_FIRST_STAGE
|
||||
|
||||
/***************************************************************************//**
|
||||
* Check if a pointer is valid and if it points to the bootloader main stage.
|
||||
*
|
||||
* This function checks pointers to bootloader
|
||||
* jump tables.
|
||||
*
|
||||
*
|
||||
* @param[in] ptr The pointer to check
|
||||
*
|
||||
* @return True if the pointer points into the bootloader main stage,
|
||||
* false if not.
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE bool bootloader_pointerValid(const void *ptr);
|
||||
__STATIC_INLINE bool bootloader_pointerValid(const void *ptr)
|
||||
{
|
||||
#if defined(MAIN_BOOTLOADER_TEST)
|
||||
// In main bootloader tests, all of memory is considered part of the bootloader
|
||||
(void) ptr;
|
||||
return true;
|
||||
#elif BTL_MAIN_STAGE_BASE > 0U
|
||||
if (((size_t)ptr >= BTL_MAIN_STAGE_BASE)
|
||||
&& ((size_t)ptr < (BTL_MAIN_STAGE_BASE + BTL_MAIN_STAGE_MAX_SIZE))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if ((size_t)ptr < (BTL_MAIN_STAGE_BASE + BTL_MAIN_STAGE_MAX_SIZE)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @} (end addtogroup CommonInterface) */
|
||||
/** @} (end addtogroup Interface) */
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // BTL_INTERFACE_H
|
||||
138
Libs/platform/bootloader/api/btl_interface_parser.h
Normal file
138
Libs/platform/bootloader/api/btl_interface_parser.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Application interface to the bootloader parser.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc. Your use of this
|
||||
* software is governed by the terms of Silicon Labs Master Software License
|
||||
* Agreement (MSLA) available at
|
||||
* www.silabs.com/about-us/legal/master-software-license-agreement. This
|
||||
* software is distributed to you in Source Code format and is governed by the
|
||||
* sections of the MSLA applicable to Source Code.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef BTL_INTERFACE_PARSER_H
|
||||
#define BTL_INTERFACE_PARSER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup Interface
|
||||
* @{
|
||||
* @addtogroup ParserInterface Application Parser Interface
|
||||
* @brief Application interface for the bootloader image
|
||||
* parser.
|
||||
* @details The Parser Interface can be used to parse upgrade images from the
|
||||
* context of the application.
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Typedefs
|
||||
|
||||
/***************************************************************************//**
|
||||
* Bootloader parser callback
|
||||
*
|
||||
* @param address Address of the data
|
||||
* @param data Raw data
|
||||
* @param length Size in bytes of raw data.
|
||||
* @param context A context variable defined by the implementation that
|
||||
* is implementing this callback.
|
||||
******************************************************************************/
|
||||
typedef void (*BootloaderParserCallback_t)(uint32_t address,
|
||||
uint8_t *data,
|
||||
size_t length,
|
||||
void *context);
|
||||
|
||||
/// Context for the bootloader image parser routine.
|
||||
typedef struct BootloaderParserContext BootloaderParserContext_t;
|
||||
|
||||
/// Function pointers to parser callbacks
|
||||
typedef struct {
|
||||
/// Opaque pointer passed to the callback functions
|
||||
void *context;
|
||||
/// Callback function pointer for application image data
|
||||
BootloaderParserCallback_t applicationCallback;
|
||||
/// Callback function pointer for image metadata
|
||||
BootloaderParserCallback_t metadataCallback;
|
||||
/// Callback function pointer for bootloader upgrade image data
|
||||
BootloaderParserCallback_t bootloaderCallback;
|
||||
} BootloaderParserCallbacks_t;
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initialize the image parser.
|
||||
*
|
||||
* @param[in] context Pointer to the parser context struct.
|
||||
* @param[in] contextSize Size of the context struct.
|
||||
*
|
||||
* @return BOOTLOADER_OK if success, BOOTLOADER_ERROR_PARSE_CONTEXT if context
|
||||
* struct is too small.
|
||||
******************************************************************************/
|
||||
int32_t bootloader_initParser(BootloaderParserContext_t *context,
|
||||
size_t contextSize);
|
||||
|
||||
#if !defined(SL_TRUSTZONE_NONSECURE)
|
||||
/***************************************************************************//**
|
||||
* Parse a buffer.
|
||||
* @param[in] context Pointer to the parser context struct.
|
||||
* @param[in] callbacks Callbacks to be called by the parser.
|
||||
* @param[in] data Data to be parsed.
|
||||
* @param[in] numBytes Size of the data buffer.
|
||||
*
|
||||
* @return BOOTLOADER_ERROR_PARSE_CONTINUE if the chunk was parsed correctly,
|
||||
* and a new chunk is expected. BOOTLOADER_ERROR_PARSE_ERROR if
|
||||
* something went wrong while parsing. BOOTLOADER_ERROR_PARSE_SUCCESS
|
||||
* if the entire file was successfully parsed.
|
||||
******************************************************************************/
|
||||
int32_t bootloader_parseBuffer(BootloaderParserContext_t *context,
|
||||
BootloaderParserCallbacks_t *callbacks,
|
||||
uint8_t data[],
|
||||
size_t numBytes);
|
||||
#endif // SL_TRUSTZONE_NONSECURE
|
||||
|
||||
/***************************************************************************//**
|
||||
* Parse a buffer and get application and bootloader upgrade metadata
|
||||
* from the buffer.
|
||||
*
|
||||
* @note \p appInfo and \p bootloaderVersion will default to zeros.
|
||||
*
|
||||
* @param[in] context Pointer to the parser context struct.
|
||||
* @param[in] data Data to be parsed.
|
||||
* @param[in] numBytes Size of the data buffer.
|
||||
* @param[out] appInfo Pointer to @ref ApplicationData_t struct.
|
||||
* @param[out] bootloaderVersion Pointer to an integer representing bootloader
|
||||
* version.
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK if metadata was filled successfully.
|
||||
******************************************************************************/
|
||||
#if !defined(SL_TRUSTZONE_NONSECURE)
|
||||
int32_t bootloader_parseImageInfo(BootloaderParserContext_t *context,
|
||||
uint8_t data[],
|
||||
size_t numBytes,
|
||||
ApplicationData_t *appInfo,
|
||||
uint32_t *bootloaderVersion);
|
||||
#else
|
||||
int32_t bootloader_parseImageInfo(uint8_t data[],
|
||||
size_t numBytes,
|
||||
ApplicationData_t *appInfo,
|
||||
uint32_t *bootloaderVersion);
|
||||
#endif // SL_TRUSTZONE_NONSECURE
|
||||
|
||||
/***************************************************************************//**
|
||||
* Find the size of the context struct BootloaderParserContext used by the bootloader
|
||||
* image parser to store parser state.
|
||||
*
|
||||
* @return size of BootloaderParserContext, returns 0 if something went wrong.
|
||||
******************************************************************************/
|
||||
uint32_t bootloader_parserContextSize(void);
|
||||
|
||||
/** @} (end addtogroup ParserInterface) */
|
||||
/** @} (end addtogroup Interface) */
|
||||
|
||||
#endif // BTL_INTERFACE_PARSER_H
|
||||
769
Libs/platform/bootloader/api/btl_interface_storage.c
Normal file
769
Libs/platform/bootloader/api/btl_interface_storage.c
Normal file
@@ -0,0 +1,769 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Application interface to the storage component of the bootloader.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc. Your use of this
|
||||
* software is governed by the terms of Silicon Labs Master Software License
|
||||
* Agreement (MSLA) available at
|
||||
* www.silabs.com/about-us/legal/master-software-license-agreement. This
|
||||
* software is distributed to you in Source Code format and is governed by the
|
||||
* sections of the MSLA applicable to Source Code.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "btl_interface.h"
|
||||
#include "btl_internal_flash.h"
|
||||
#include <string.h>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
// Make assert no-op if not configured
|
||||
#ifndef BTL_ASSERT
|
||||
#define BTL_ASSERT(x)
|
||||
#endif
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif
|
||||
// -----------------------------------------------------------------------------
|
||||
// Static variables
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
static Bootloader_PPUSATDnCLKENnState_t blPPUSATDnCLKENnState = { 0 };
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Functions
|
||||
|
||||
static bool verifyAddressRange(uint32_t address,
|
||||
uint32_t length)
|
||||
{
|
||||
// Flash starts at FLASH_BASE, and is FLASH_SIZE large
|
||||
if ((length > FLASH_SIZE)
|
||||
#if (FLASH_BASE > 0x0UL)
|
||||
|| (address < FLASH_BASE)
|
||||
#endif
|
||||
|| (address > FLASH_BASE + FLASH_SIZE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((address + length) <= FLASH_BASE + FLASH_SIZE) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool verifyErased(uint32_t address,
|
||||
uint32_t length)
|
||||
{
|
||||
for (uint32_t i = 0; i < length; i += 4) {
|
||||
if (*(uint32_t *)(address + i) != 0xFFFFFFFF) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void bootloader_getStorageInfo(BootloaderStorageInformation_t *info)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return;
|
||||
}
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
mainBootloaderTable->storage->getInfo(info);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
}
|
||||
|
||||
int32_t bootloader_getStorageSlotInfo(uint32_t slotId,
|
||||
BootloaderStorageSlot_t *slot)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_INIT_TABLE;
|
||||
}
|
||||
return mainBootloaderTable->storage->getSlotInfo(slotId, slot);
|
||||
}
|
||||
|
||||
int32_t bootloader_readStorage(uint32_t slotId,
|
||||
uint32_t offset,
|
||||
uint8_t *buffer,
|
||||
size_t length)
|
||||
{
|
||||
int32_t retVal;
|
||||
BootloaderStorageInformation_t storageInfo;
|
||||
BootloaderStorageSlot_t storageSlot;
|
||||
|
||||
//Check for the storageType of the device
|
||||
bootloader_getStorageInfo(&storageInfo);
|
||||
|
||||
if (storageInfo.storageType == INTERNAL_FLASH) {
|
||||
// Ensure slot is valid
|
||||
if (slotId >= storageInfo.numStorageSlots) {
|
||||
return BOOTLOADER_ERROR_STORAGE_INVALID_SLOT;
|
||||
}
|
||||
|
||||
retVal = bootloader_getStorageSlotInfo(slotId, &storageSlot);
|
||||
if (retVal != BOOTLOADER_OK) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
// Ensure address is within slot
|
||||
if ((offset + length > storageSlot.length) \
|
||||
|| (offset > storageSlot.length) \
|
||||
|| (length > storageSlot.length)) {
|
||||
return BOOTLOADER_ERROR_STORAGE_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
// Address range is valid; read data
|
||||
retVal = bootloader_readRawStorage(storageSlot.address + offset,
|
||||
buffer,
|
||||
length);
|
||||
}
|
||||
//END OF INTERNAL_FLASH
|
||||
else {
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_INIT_TABLE;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
retVal = mainBootloaderTable->storage->read(slotId, offset, buffer, length);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_writeStorage(uint32_t slotId,
|
||||
uint32_t offset,
|
||||
uint8_t *buffer,
|
||||
size_t length)
|
||||
{
|
||||
int32_t retVal;
|
||||
BootloaderStorageInformation_t storageInfo;
|
||||
BootloaderStorageSlot_t storageSlot;
|
||||
|
||||
//Check for the storageType of the device
|
||||
bootloader_getStorageInfo(&storageInfo);
|
||||
|
||||
if (storageInfo.storageType == INTERNAL_FLASH) {
|
||||
// Ensure slot is valid
|
||||
if (slotId >= storageInfo.numStorageSlots) {
|
||||
return BOOTLOADER_ERROR_STORAGE_INVALID_SLOT;
|
||||
}
|
||||
|
||||
retVal = bootloader_getStorageSlotInfo(slotId, &storageSlot);
|
||||
if (retVal != BOOTLOADER_OK) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
// Ensure address is within slot
|
||||
if ((offset + length > storageSlot.length) \
|
||||
|| (offset > storageSlot.length) \
|
||||
|| (length > storageSlot.length)) {
|
||||
return BOOTLOADER_ERROR_STORAGE_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
retVal = bootloader_writeRawStorage(storageSlot.address + offset,
|
||||
buffer,
|
||||
length);
|
||||
} else {
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_INIT_TABLE;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
retVal = mainBootloaderTable->storage->write(slotId, offset, buffer, length);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_eraseWriteStorage(uint32_t slotId,
|
||||
uint32_t offset,
|
||||
uint8_t *buffer,
|
||||
size_t length)
|
||||
{
|
||||
int32_t retVal;
|
||||
uint16_t flashPageSize;
|
||||
uint32_t storageStartAddr;
|
||||
uint32_t eraseOffset;
|
||||
uint32_t eraseLength;
|
||||
BootloaderStorageSlot_t storageSlot;
|
||||
BootloaderStorageInformation_t storageInfo;
|
||||
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_INIT_TABLE;
|
||||
}
|
||||
|
||||
bootloader_getStorageInfo(&storageInfo);
|
||||
flashPageSize = storageInfo.info->pageSize;
|
||||
if (flashPageSize == 0) {
|
||||
return BOOTLOADER_ERROR_STORAGE_INVALID_SLOT;
|
||||
}
|
||||
|
||||
retVal = bootloader_getStorageSlotInfo(slotId, &storageSlot);
|
||||
if (retVal != BOOTLOADER_OK) {
|
||||
return retVal;
|
||||
}
|
||||
storageStartAddr = storageSlot.address;
|
||||
|
||||
if (offset + length > storageSlot.length) {
|
||||
return BOOTLOADER_ERROR_STORAGE_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
if (offset % flashPageSize) {
|
||||
// Erase from next page:
|
||||
eraseOffset = (offset & ~(flashPageSize - 1)) + flashPageSize;
|
||||
|
||||
if ((offset + length) % flashPageSize) {
|
||||
// Example case for this if/else section:
|
||||
// 0 1 2 3
|
||||
// |----|----|----|
|
||||
// ^ ^
|
||||
// O L
|
||||
eraseLength = ((offset + length) & ~(flashPageSize - 1)) + flashPageSize - eraseOffset;
|
||||
} else {
|
||||
// Example case for this if/else section:
|
||||
// 0 1 2 3
|
||||
// |----|----|----|
|
||||
// ^ ^
|
||||
// O L
|
||||
eraseLength = length - (flashPageSize - (offset % flashPageSize));
|
||||
}
|
||||
eraseOffset = storageStartAddr + eraseOffset;
|
||||
} else {
|
||||
eraseOffset = storageStartAddr + offset;
|
||||
if (length % flashPageSize) {
|
||||
// Example case for this if/else section:
|
||||
// 0 1 2 3
|
||||
// |----|----|----|
|
||||
// ^ ^
|
||||
// O L
|
||||
eraseLength = (length & ~(flashPageSize - 1)) + flashPageSize;
|
||||
} else {
|
||||
// Example case for this if/else section:
|
||||
// 0 1 2 3
|
||||
// |----|----|----|
|
||||
// ^ ^
|
||||
// O L
|
||||
eraseLength = length;
|
||||
}
|
||||
}
|
||||
if (eraseLength != 0) {
|
||||
retVal = bootloader_eraseRawStorage(eraseOffset, eraseLength);
|
||||
if (retVal != BOOTLOADER_OK) {
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
retVal = bootloader_writeRawStorage(storageStartAddr + offset, buffer, length);
|
||||
if (retVal != BOOTLOADER_OK) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
return BOOTLOADER_OK;
|
||||
}
|
||||
|
||||
int32_t bootloader_eraseStorageSlot(uint32_t slotId)
|
||||
{
|
||||
int32_t retVal;
|
||||
BootloaderStorageInformation_t storageInfo;
|
||||
BootloaderStorageSlot_t storageSlot;
|
||||
|
||||
//Check for the storageType of the device
|
||||
bootloader_getStorageInfo(&storageInfo);
|
||||
|
||||
if (storageInfo.storageType == INTERNAL_FLASH) {
|
||||
// Ensure slot is valid
|
||||
if (slotId >= storageInfo.numStorageSlots) {
|
||||
return BOOTLOADER_ERROR_STORAGE_INVALID_SLOT;
|
||||
}
|
||||
|
||||
retVal = bootloader_getStorageSlotInfo(slotId, &storageSlot);
|
||||
if (retVal != BOOTLOADER_OK) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
retVal = bootloader_eraseRawStorage(storageSlot.address, storageSlot.length);
|
||||
} else {
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_INIT_TABLE;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
retVal = mainBootloaderTable->storage->erase(slotId);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_initChunkedEraseStorageSlot(uint32_t slotId,
|
||||
BootloaderEraseStatus_t *eraseStat)
|
||||
{
|
||||
int32_t retVal;
|
||||
BootloaderStorageInformation_t storageInfo;
|
||||
bootloader_getStorageInfo(&storageInfo);
|
||||
|
||||
retVal = bootloader_getStorageSlotInfo(slotId, &eraseStat->storageSlotInfo);
|
||||
if (retVal != BOOTLOADER_OK) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
eraseStat->currentPageAddr = eraseStat->storageSlotInfo.address;
|
||||
eraseStat->pageSize = storageInfo.info->pageSize;
|
||||
|
||||
return BOOTLOADER_OK;
|
||||
}
|
||||
|
||||
int32_t bootloader_chunkedEraseStorageSlot(BootloaderEraseStatus_t *eraseStat)
|
||||
{
|
||||
int32_t retVal;
|
||||
if (eraseStat->currentPageAddr
|
||||
== (eraseStat->storageSlotInfo.address + eraseStat->storageSlotInfo.length)) {
|
||||
return BOOTLOADER_OK;
|
||||
}
|
||||
|
||||
retVal = bootloader_eraseRawStorage(eraseStat->currentPageAddr, eraseStat->pageSize);
|
||||
if (retVal != BOOTLOADER_OK) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
eraseStat->currentPageAddr += eraseStat->pageSize;
|
||||
if (eraseStat->currentPageAddr
|
||||
== (eraseStat->storageSlotInfo.address + eraseStat->storageSlotInfo.length)) {
|
||||
return BOOTLOADER_OK;
|
||||
}
|
||||
|
||||
return BOOTLOADER_ERROR_STORAGE_CONTINUE;
|
||||
}
|
||||
|
||||
int32_t bootloader_setImageToBootload(int32_t slotId)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_INIT_TABLE;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
int32_t retVal = mainBootloaderTable->storage->setImagesToBootload(&slotId, 1);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_setImagesToBootload(int32_t *slotIds, size_t length)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_INIT_TABLE;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
int32_t retVal = mainBootloaderTable->storage->setImagesToBootload(slotIds, length);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_getImagesToBootload(int32_t *slotIds, size_t length)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_INIT_TABLE;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
int32_t retVal = mainBootloaderTable->storage->getImagesToBootload(slotIds, length);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_appendImageToBootloadList(int32_t slotId)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_INIT_TABLE;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
int32_t retVal = mainBootloaderTable->storage->appendImageToBootloadList(slotId);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_initVerifyImage(uint32_t slotId,
|
||||
void *context,
|
||||
size_t contextSize)
|
||||
{
|
||||
int32_t retVal;
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
return BOOTLOADER_ERROR_PARSE_STORAGE;
|
||||
}
|
||||
|
||||
// Check that the bootloader has image verification capability
|
||||
if (mainBootloaderTable->storage == NULL) {
|
||||
return BOOTLOADER_ERROR_PARSE_STORAGE;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
retVal = mainBootloaderTable->storage->initParseImage(
|
||||
slotId,
|
||||
(BootloaderParserContext_t*)context,
|
||||
contextSize);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_continueVerifyImage(void *context,
|
||||
BootloaderParserCallback_t metadataCallback)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_PARSE_STORAGE;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
int32_t retVal = mainBootloaderTable->storage->verifyImage(
|
||||
(BootloaderParserContext_t *)context,
|
||||
metadataCallback);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_verifyImage(uint32_t slotId,
|
||||
BootloaderParserCallback_t metadataCallback)
|
||||
{
|
||||
int32_t retval;
|
||||
uint8_t context[BOOTLOADER_STORAGE_VERIFICATION_CONTEXT_SIZE];
|
||||
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)) {
|
||||
return BOOTLOADER_ERROR_PARSE_STORAGE;
|
||||
}
|
||||
|
||||
retval = bootloader_initVerifyImage(slotId,
|
||||
context,
|
||||
BOOTLOADER_STORAGE_VERIFICATION_CONTEXT_SIZE);
|
||||
|
||||
if (retval != BOOTLOADER_OK) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
do {
|
||||
retval = bootloader_continueVerifyImage(context, metadataCallback);
|
||||
} while (retval == BOOTLOADER_ERROR_PARSE_CONTINUE);
|
||||
|
||||
if (retval == BOOTLOADER_ERROR_PARSE_SUCCESS) {
|
||||
return BOOTLOADER_OK;
|
||||
} else {
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t bootloader_getImageInfo(uint32_t slotId,
|
||||
ApplicationData_t *appInfo,
|
||||
uint32_t *bootloaderVersion)
|
||||
{
|
||||
int32_t retval;
|
||||
uint8_t context[BOOTLOADER_STORAGE_VERIFICATION_CONTEXT_SIZE];
|
||||
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_PARSE_STORAGE;
|
||||
}
|
||||
|
||||
// Check that the bootloader has image verification capability
|
||||
BTL_ASSERT(mainBootloaderTable->storage != NULL);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
retval = mainBootloaderTable->storage->initParseImage(
|
||||
slotId,
|
||||
(BootloaderParserContext_t *)context,
|
||||
BOOTLOADER_STORAGE_VERIFICATION_CONTEXT_SIZE);
|
||||
if (retval != BOOTLOADER_OK) {
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
return retval;
|
||||
}
|
||||
retval = mainBootloaderTable->storage->getImageInfo(
|
||||
(BootloaderParserContext_t *)context,
|
||||
appInfo,
|
||||
bootloaderVersion);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool bootloader_storageIsBusy(void)
|
||||
{
|
||||
bool isBusy = false;
|
||||
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return true;
|
||||
}
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
isBusy = mainBootloaderTable->storage->isBusy();
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
return isBusy;
|
||||
}
|
||||
|
||||
int32_t bootloader_readRawStorage(uint32_t address,
|
||||
uint8_t *buffer,
|
||||
size_t length)
|
||||
{
|
||||
int32_t retVal;
|
||||
BootloaderStorageInformation_t storageInfo;
|
||||
|
||||
//Check for the storageType of the device
|
||||
bootloader_getStorageInfo(&storageInfo);
|
||||
|
||||
if (storageInfo.storageType == INTERNAL_FLASH) {
|
||||
// Ensure address is is within flash
|
||||
if (!verifyAddressRange(address, length)) {
|
||||
return BOOTLOADER_ERROR_STORAGE_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
memcpy(buffer, (void *)address, length);
|
||||
|
||||
retVal = BOOTLOADER_OK;
|
||||
} else {
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_INIT_STORAGE;
|
||||
}
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
retVal = mainBootloaderTable->storage->readRaw(address, buffer, length);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_writeRawStorage(uint32_t address,
|
||||
uint8_t *buffer,
|
||||
size_t length)
|
||||
{
|
||||
int32_t retVal;
|
||||
BootloaderStorageInformation_t storageInfo;
|
||||
|
||||
//Check for the storageType of the device
|
||||
bootloader_getStorageInfo(&storageInfo);
|
||||
|
||||
if (storageInfo.storageType == INTERNAL_FLASH) {
|
||||
// Ensure address is is within chip
|
||||
if (!verifyAddressRange(address, length)) {
|
||||
return BOOTLOADER_ERROR_STORAGE_INVALID_ADDRESS;
|
||||
}
|
||||
// Ensure space is empty
|
||||
if (!verifyErased(address, length)) {
|
||||
return BOOTLOADER_ERROR_STORAGE_NEEDS_ERASE;
|
||||
}
|
||||
|
||||
if (flash_writeBuffer(address, buffer, length)) {
|
||||
retVal = BOOTLOADER_OK;
|
||||
} else {
|
||||
retVal = BOOTLOADER_ERROR_STORAGE_INVALID_ADDRESS;
|
||||
}
|
||||
//END OF INTERNAL FLASH
|
||||
} else {
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_INIT_STORAGE;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
retVal = mainBootloaderTable->storage->writeRaw(address, buffer, length);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int32_t bootloader_getAllocatedDMAChannel(void)
|
||||
{
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_INIT_STORAGE;
|
||||
}
|
||||
|
||||
BootloaderInformation_t info = { .type = SL_BOOTLOADER, .version = 0U, .capabilities = 0U };
|
||||
bootloader_getInfo(&info);
|
||||
|
||||
if ((info.capabilities & BOOTLOADER_CAPABILITY_STORAGE) == 0u) {
|
||||
return BOOTLOADER_ERROR_INIT_STORAGE;
|
||||
}
|
||||
|
||||
uint32_t blMajorVersion = ((info.version & BOOTLOADER_VERSION_MAJOR_MASK)
|
||||
>> BOOTLOADER_VERSION_MAJOR_SHIFT);
|
||||
uint32_t blMinorVersion = ((info.version & BOOTLOADER_VERSION_MINOR_MASK)
|
||||
>> BOOTLOADER_VERSION_MINOR_SHIFT);
|
||||
|
||||
if ((blMajorVersion < 1UL) || (blMajorVersion == 1UL && blMinorVersion < 11UL)) {
|
||||
return BOOTLOADER_ERROR_INIT_STORAGE;
|
||||
}
|
||||
|
||||
return mainBootloaderTable->storage->getDMAchannel();
|
||||
}
|
||||
|
||||
int32_t bootloader_eraseRawStorage(uint32_t address,
|
||||
size_t length)
|
||||
{
|
||||
int32_t retVal;
|
||||
BootloaderStorageInformation_t storageInfo;
|
||||
|
||||
//Check for the storageType of the device
|
||||
bootloader_getStorageInfo(&storageInfo);
|
||||
|
||||
if (storageInfo.storageType == INTERNAL_FLASH) {
|
||||
// Ensure erase covers an integer number of pages
|
||||
if (length % FLASH_PAGE_SIZE) {
|
||||
return BOOTLOADER_ERROR_STORAGE_NEEDS_ALIGN;
|
||||
}
|
||||
// Ensure erase is page aligned
|
||||
if (address % FLASH_PAGE_SIZE) {
|
||||
return BOOTLOADER_ERROR_STORAGE_NEEDS_ALIGN;
|
||||
}
|
||||
// Ensure address is is within flash
|
||||
if (!verifyAddressRange(address, length)) {
|
||||
return BOOTLOADER_ERROR_STORAGE_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
|
||||
do {
|
||||
ret = flash_erasePage(address);
|
||||
address += FLASH_PAGE_SIZE;
|
||||
length -= FLASH_PAGE_SIZE;
|
||||
} while (length > 0 && ret);
|
||||
|
||||
if (ret) {
|
||||
retVal = BOOTLOADER_OK;
|
||||
} else {
|
||||
retVal = BOOTLOADER_ERROR_STORAGE_INVALID_ADDRESS;
|
||||
}
|
||||
} else {
|
||||
if (!bootloader_pointerValid(mainBootloaderTable)
|
||||
|| !bootloader_pointerValid(mainBootloaderTable->storage)) {
|
||||
return BOOTLOADER_ERROR_INIT_STORAGE;
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnSaveReconfigureState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
|
||||
retVal = mainBootloaderTable->storage->eraseRaw(address, length);
|
||||
|
||||
#if defined(BOOTLOADER_INTERFACE_TRUSTZONE_AWARE)
|
||||
bootloader_ppusatdnRestoreState(&blPPUSATDnCLKENnState);
|
||||
#endif // BOOTLOADER_INTERFACE_TRUSTZONE_AWARE
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
653
Libs/platform/bootloader/api/btl_interface_storage.h
Normal file
653
Libs/platform/bootloader/api/btl_interface_storage.h
Normal file
@@ -0,0 +1,653 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Application interface to the storage component of the bootloader.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc. Your use of this
|
||||
* software is governed by the terms of Silicon Labs Master Software License
|
||||
* Agreement (MSLA) available at
|
||||
* www.silabs.com/about-us/legal/master-software-license-agreement. This
|
||||
* software is distributed to you in Source Code format and is governed by the
|
||||
* sections of the MSLA applicable to Source Code.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef BTL_INTERFACE_STORAGE_H
|
||||
#define BTL_INTERFACE_STORAGE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// Get part series version.
|
||||
#include "em_device.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup Interface
|
||||
* @{
|
||||
* @addtogroup StorageInterface Application Storage Interface
|
||||
* @brief Application interface for interfacing with the bootloader storage.
|
||||
* @note These Bootloader APIs are not reentrant and should be wrapped in critical section
|
||||
* where needed.
|
||||
* @details The Storage Interface is only available on bootloaders that declare
|
||||
* they support @ref BOOTLOADER_CAPABILITY_STORAGE.
|
||||
*
|
||||
* @li @ref bootloader_interface_example
|
||||
*
|
||||
* @n @section bootloader_interface_example Example
|
||||
*
|
||||
* @brief Snippet for the OTA use case:
|
||||
* @verbatim
|
||||
* OTA Example
|
||||
* Assuming the user has an upgrade image downloaded which will be used to upgrade the application
|
||||
*
|
||||
* Initialize the bootloader interface
|
||||
* bootloader_init();
|
||||
*
|
||||
* Erase the storage slot in internal/SPI flash memory
|
||||
* bootloader_eraseStorageSlot(0);
|
||||
*
|
||||
* Write the upgrade image (GBL file data) to the slot. blinkGbl uint8 array holding the GBL data in memory
|
||||
* bootloader_writeStorage(0, 0, blinkGbl, sizeof(blinkGbl));
|
||||
*
|
||||
* Reboot into the bootloader to install the new image
|
||||
* bootloader_rebootAndInstall();
|
||||
*
|
||||
* The general flow for bootloader interface APIs from the application is:
|
||||
*
|
||||
* General flow
|
||||
*
|
||||
* Initialize the bootloader interface
|
||||
* bootloader_init();
|
||||
*
|
||||
* Interface API accesses
|
||||
* ……………
|
||||
* ……………
|
||||
* ……………
|
||||
*
|
||||
* De-initialize the bootloader interface
|
||||
* bootloader_deinit();
|
||||
* @endverbatim
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Typedefs
|
||||
|
||||
/// Possible storage types
|
||||
typedef enum {
|
||||
/// Storage backend is a SPI flash
|
||||
SPIFLASH,
|
||||
/// Storage backend is internal flash
|
||||
INTERNAL_FLASH,
|
||||
/// Storage backend is custom
|
||||
CUSTOM_STORAGE
|
||||
} BootloaderStorageType_t;
|
||||
|
||||
/// Information about a storage slot
|
||||
typedef struct {
|
||||
/// Address of the slot.
|
||||
uint32_t address;
|
||||
/// Size of the slot.
|
||||
uint32_t length;
|
||||
} BootloaderStorageSlot_t;
|
||||
|
||||
/// Information about the bootloader storage implementation
|
||||
/// <b>Note:</b> From Gecko Bootloader version >= 2.1,
|
||||
/// the pointer <b>partType</b> will only contain a zero value.
|
||||
/// The <b>partType</b> variable can be used to find information
|
||||
/// about the attached storage.
|
||||
typedef struct {
|
||||
/// The version of this data structure
|
||||
uint16_t version;
|
||||
/// A bitmask describing the capabilities of this particular storage
|
||||
uint16_t capabilitiesMask;
|
||||
/// Maximum time it takes to erase a page. (in milliseconds)
|
||||
uint32_t pageEraseMs;
|
||||
/// Maximum time it takes to erase the entire part. (in milliseconds)
|
||||
uint32_t partEraseMs;
|
||||
/// The size of a single erasable page in bytes
|
||||
uint32_t pageSize;
|
||||
/// The total size of the storage in bytes
|
||||
uint32_t partSize;
|
||||
/// Pointer to a string describing the attached storage
|
||||
char *partDescription;
|
||||
/// The number of bytes in a word for the storage
|
||||
uint8_t wordSizeBytes;
|
||||
/// Value representing the attached storage
|
||||
uint32_t partType;
|
||||
} BootloaderStorageImplementationInformation_t;
|
||||
|
||||
/// Information about the bootloader storage \n
|
||||
/// <b>Note:</b> The <b>flashInfo</b> variable is only usable with
|
||||
/// Gecko Bootloader version >= 2.0. All previous versions of the
|
||||
/// Gecko Bootloader do not support the <b>flashInfo</b> data field.
|
||||
typedef struct {
|
||||
/// The version of this data structure
|
||||
uint32_t version;
|
||||
/// The capabilities of the storage component
|
||||
uint32_t capabilities;
|
||||
/// Type of storage
|
||||
BootloaderStorageType_t storageType;
|
||||
/// Number of storage slots
|
||||
uint32_t numStorageSlots;
|
||||
/// A pointer to detailed information about the attached storage
|
||||
BootloaderStorageImplementationInformation_t *info;
|
||||
/// Detailed information about the attached storage(<b>available for use only with Gecko Bootloader version >= 2.0</b>)
|
||||
BootloaderStorageImplementationInformation_t flashInfo;
|
||||
} BootloaderStorageInformation_t;
|
||||
|
||||
/// Erase status struct
|
||||
typedef struct {
|
||||
/// Address of the current page to be erased
|
||||
uint32_t currentPageAddr;
|
||||
/// The size of a single erasable page in bytes
|
||||
uint32_t pageSize;
|
||||
/// Information about a storage slot
|
||||
BootloaderStorageSlot_t storageSlotInfo;
|
||||
} BootloaderEraseStatus_t;
|
||||
|
||||
/// Storage API accessible from the application
|
||||
typedef struct BootloaderStorageFunctions {
|
||||
/// Version of this struct
|
||||
uint32_t version;
|
||||
/// Get information about the storage -- capabilities, layout, configuration
|
||||
void (*getInfo)(BootloaderStorageInformation_t *info);
|
||||
/// Get information about storage slot -- size, location
|
||||
int32_t (*getSlotInfo)(uint32_t slotId, BootloaderStorageSlot_t *slot);
|
||||
/// Read bytes from slot into buffer
|
||||
int32_t (*read)(uint32_t slotId,
|
||||
uint32_t offset,
|
||||
uint8_t *buffer,
|
||||
size_t length);
|
||||
/// Write bytes from buffer into slot
|
||||
int32_t (*write)(uint32_t slotId,
|
||||
uint32_t offset,
|
||||
uint8_t *buffer,
|
||||
size_t length);
|
||||
/// Erase an entire slot
|
||||
int32_t (*erase)(uint32_t slotId);
|
||||
// ------------------------------
|
||||
/// Mark a list of slots for bootload
|
||||
int32_t (*setImagesToBootload)(int32_t *slotIds, size_t length);
|
||||
/// Mark a list of slots for bootload
|
||||
int32_t (*getImagesToBootload)(int32_t *slotIds, size_t length);
|
||||
/// Append a slot to bootload list
|
||||
int32_t (*appendImageToBootloadList)(int32_t slotId);
|
||||
// ------------------------------
|
||||
/// Start image parsing
|
||||
int32_t (*initParseImage)(uint32_t slotId,
|
||||
BootloaderParserContext_t *context,
|
||||
size_t contextSize);
|
||||
/// Continue image verification
|
||||
int32_t (*verifyImage)(BootloaderParserContext_t *context,
|
||||
BootloaderParserCallback_t metadataCallback);
|
||||
/// Get app and bootloader upgrade information from storage slot
|
||||
int32_t (*getImageInfo)(BootloaderParserContext_t *context,
|
||||
ApplicationData_t *appInfo,
|
||||
uint32_t *bootloaderVersion);
|
||||
/// Check whether the bootloader storage is busy
|
||||
bool (*isBusy)(void);
|
||||
/// Read raw bytes from storage
|
||||
int32_t (*readRaw)(uint32_t address, uint8_t *buffer, size_t length);
|
||||
/// Write bytes to raw storage
|
||||
int32_t (*writeRaw)(uint32_t address, uint8_t *buffer, size_t length);
|
||||
/// Erase storage
|
||||
int32_t (*eraseRaw)(uint32_t address, size_t length);
|
||||
/// Get configured DMA channel
|
||||
int32_t (*getDMAchannel)(void);
|
||||
} BootloaderStorageFunctions_t;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
/// Context size for bootloader verification context
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
/// Context size(701) includes counter(16) plus stream_block(16 (block size) * 8 (Maximum blocks))
|
||||
#define BOOTLOADER_STORAGE_VERIFICATION_CONTEXT_SIZE (705)
|
||||
#else
|
||||
#define BOOTLOADER_STORAGE_VERIFICATION_CONTEXT_SIZE (593)
|
||||
#endif
|
||||
#else
|
||||
#define BOOTLOADER_STORAGE_VERIFICATION_CONTEXT_SIZE (384)
|
||||
#endif
|
||||
|
||||
/// Current version of the BootloaderStorageInformation_t struct
|
||||
#define BOOTLOADER_STORAGE_INFO_VERSION (0x30000U)
|
||||
/// Current version of the BootloaderStorageImplementationInformation_t struct
|
||||
#define BOOTLOADER_STORAGE_IMPL_INFO_VERSION (0x0210U)
|
||||
/// Major version of the BootloaderStorageImplementationInformation_t struct
|
||||
#define BOOTLOADER_STORAGE_IMPL_INFO_VERSION_MAJOR (0x0200U)
|
||||
/// Major version mask for @ref BOOTLOADER_STORAGE_IMPL_INFO_VERSION
|
||||
#define BOOTLOADER_STORAGE_IMPL_INFO_VERSION_MAJOR_MASK (0xFF00U)
|
||||
|
||||
/// Spiflash capability indicating that it supports erase
|
||||
#define BOOTLOADER_STORAGE_IMPL_CAPABILITY_ERASE_SUPPORTED (1 << 0)
|
||||
/// @brief Spiflash capability indicating it requires full page erases before
|
||||
/// new data can be written
|
||||
#define BOOTLOADER_STORAGE_IMPL_CAPABILITY_PAGE_ERASE_REQUIRED (1 << 1)
|
||||
/// Spiflash capability indicating that the write function is blocking
|
||||
#define BOOTLOADER_STORAGE_IMPL_CAPABILITY_BLOCKING_WRITE (1 << 2)
|
||||
/// Spiflash capability indicating that the erase function is blocking
|
||||
#define BOOTLOADER_STORAGE_IMPL_CAPABILITY_BLOCKING_ERASE (1 << 3)
|
||||
|
||||
/// ISSI IS25LQ040B SPI Flash
|
||||
#define BOOTLOADER_STORAGE_ISSI_IS25LQ040B (1U << 0)
|
||||
/// ISSI IS25LQ020B SPI Flash
|
||||
#define BOOTLOADER_STORAGE_ISSI_IS25LQ020B (1U << 1)
|
||||
/// ISSI IS25LQ010B SPI Flash
|
||||
#define BOOTLOADER_STORAGE_ISSI_IS25LQ010B (1U << 2)
|
||||
/// ISSI IS25LQ512B SPI Flash
|
||||
#define BOOTLOADER_STORAGE_ISSI_IS25LQ512B (1U << 3)
|
||||
/// ISSI IS25LQ025B SPI Flash
|
||||
#define BOOTLOADER_STORAGE_ISSI_IS25LQ025B (1U << 4)
|
||||
/// Numonyx M25P16 SPI Flash
|
||||
#define BOOTLOADER_STORAGE_NUMONYX_M25P16 (1U << 5)
|
||||
/// Numonyx M25P80 SPI Flash
|
||||
#define BOOTLOADER_STORAGE_NUMONYX_M25P80 (1U << 6)
|
||||
/// Numonyx M25P40 SPI Flash
|
||||
#define BOOTLOADER_STORAGE_NUMONYX_M25P40 (1U << 7)
|
||||
/// Numonyx M25P20 SPI Flash
|
||||
#define BOOTLOADER_STORAGE_NUMONYX_M25P20 (1U << 8)
|
||||
/// Adesto AT25SF041 SPI Flash
|
||||
#define BOOTLOADER_STORAGE_ADESTO_AT25SF041 (1U << 9)
|
||||
/// Atmel AT25DF081A SPI Flash
|
||||
#define BOOTLOADER_STORAGE_ATMEL_AT25DF081A (1U << 10)
|
||||
/// Atmel AT25DF041A SPI Flash
|
||||
#define BOOTLOADER_STORAGE_ATMEL_AT25DF041A (1U << 11)
|
||||
/// Macronix MX25R6435F SPI Flash
|
||||
#define BOOTLOADER_STORAGE_MACRONIX_MX25R6435F (1U << 12)
|
||||
/// Macronix MX25R6435F SPI Flash
|
||||
#define BOOTLOADER_STORAGE_MACRONIX_MX25R3235F (1U << 13)
|
||||
/// Macronix MX25U1635E SPI Flash
|
||||
#define BOOTLOADER_STORAGE_MACRONIX_MX25U1635E (1U << 14)
|
||||
/// Macronix MX25L1606E SPI Flash
|
||||
#define BOOTLOADER_STORAGE_MACRONIX_MX25L1606E (1U << 15)
|
||||
/// Macronix MX25R8035F SPI Flash
|
||||
#define BOOTLOADER_STORAGE_MACRONIX_MX25R8035F (1U << 16)
|
||||
/// Macronix MX25L8006E SPI Flash
|
||||
#define BOOTLOADER_STORAGE_MACRONIX_MX25L8006E (1U << 17)
|
||||
/// Macronix MX25L4006E SPI Flash
|
||||
#define BOOTLOADER_STORAGE_MACRONIX_MX25L4006E (1U << 18)
|
||||
/// Macronix MX25L2006E SPI Flash
|
||||
#define BOOTLOADER_STORAGE_MACRONIX_MX25L2006E (1U << 19)
|
||||
/// Winbond W25Q80BV SPI Flash
|
||||
#define BOOTLOADER_STORAGE_WINBOND_W25Q80BV (1U << 20)
|
||||
/// Winbond W25X20BV SPI Flash
|
||||
#define BOOTLOADER_STORAGE_WINBOND_W25X20BV (1U << 21)
|
||||
/// Spansion S25L208K SPI Flash
|
||||
#define BOOTLOADER_STORAGE_SPANSION_S25FL208K (1U << 22)
|
||||
/// Internal storage
|
||||
#define BOOTLOADER_STORAGE_INTERNAL_STORAGE (1U << 30)
|
||||
/// JEDEC Supported SPI Flash
|
||||
#define BOOTLOADER_STORAGE_JEDEC (1U << 31)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get information about the storage component.
|
||||
*
|
||||
* @param[out] info Information about the storage component.
|
||||
******************************************************************************/
|
||||
void bootloader_getStorageInfo(BootloaderStorageInformation_t *info);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get information about a storage slot.
|
||||
*
|
||||
* @param[in] slotId ID of the slot to get information about
|
||||
* @param[out] slot Information about the storage slot
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_STORAGE_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_getStorageSlotInfo(uint32_t slotId,
|
||||
BootloaderStorageSlot_t *slot);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Read data from a storage slot.
|
||||
*
|
||||
* @param[in] slotId ID of the slot
|
||||
* @param[in] offset Offset into the slot to start reading from
|
||||
* @param[out] buffer Buffer to store the data
|
||||
* @param[in] length Amount of data to read
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_STORAGE_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_readStorage(uint32_t slotId,
|
||||
uint32_t offset,
|
||||
uint8_t *buffer,
|
||||
size_t length);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Write data to a storage slot.
|
||||
*
|
||||
* @note
|
||||
* If DMA-based MSC write is enabled on the bootloader, writing data from
|
||||
* flash to flash is not supported on Series-1 devices. DMA-based MSC write is
|
||||
* enabled, both offset and buffer should be word aligned. In case the buffer
|
||||
* is not aligned, the normal write procedure is used instead of DMA.
|
||||
*
|
||||
* @param[in] slotId ID of the slot
|
||||
* @param[in] offset Offset into the slot to start writing to
|
||||
* @param[in] buffer Buffer to read data to write from
|
||||
* @param[in] length Amount of data to write. Must be a multiple of 4.
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_STORAGE_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_writeStorage(uint32_t slotId,
|
||||
uint32_t offset,
|
||||
uint8_t *buffer,
|
||||
size_t length);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Erase and write data to a storage slot.
|
||||
*
|
||||
* @note This function automatically erases the following Flash page whenever
|
||||
* the written data crosses a page boundary. In other words, the function
|
||||
* can't be used to perform multiple sequential writes to the same
|
||||
* address range unless the range starts at a page boundary.
|
||||
* For a sequential write, the first call to this function should have
|
||||
* a start address at a page boundary. Otherwise, the corresponding page
|
||||
* of the starting address needs to be erased explicitly. If DMA-based
|
||||
* MSC write is enabled on the bootloader, writing data from flash to
|
||||
* flash is not supported on Series-1 devices.
|
||||
*
|
||||
* @param[in] slotId ID of the slot
|
||||
* @param[in] offset Offset into the slot to start writing to
|
||||
* @param[in] buffer Buffer to read data to write from
|
||||
* @param[in] length Amount of data to write. Must be a multiple of 4.
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_STORAGE_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_eraseWriteStorage(uint32_t slotId,
|
||||
uint32_t offset,
|
||||
uint8_t *buffer,
|
||||
size_t length);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Erase all contents of a storage slot.
|
||||
*
|
||||
* @param[in] slotId ID of the slot
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_STORAGE_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_eraseStorageSlot(uint32_t slotId);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initialize chunked erase of a storage slot.
|
||||
*
|
||||
* @note This function must be called before calling
|
||||
* @ref bootloader_chunkedEraseStorageSlot in a loop.
|
||||
*
|
||||
* @param[in] slotId ID of the slot
|
||||
* @param[in] eraseStat Erase status struct
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_STORAGE_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_initChunkedEraseStorageSlot(uint32_t slotId,
|
||||
BootloaderEraseStatus_t *eraseStat);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Erase one page from a storage slot according to
|
||||
* the struct BootloaderEraseStatus_t.
|
||||
*
|
||||
* @note @ref bootloader_initChunkedEraseStorageSlot must be called
|
||||
* before calling this function, in order to prepare
|
||||
* BootloaderEraseStatus_t.
|
||||
*
|
||||
* @note This can be called sequentially to, for example, erase all contents
|
||||
* of a storage slot.
|
||||
*
|
||||
* @param[in] eraseStat Erase status struct
|
||||
*
|
||||
* @return @ref BOOTLOADER_ERROR_STORAGE_CONTINUE if erasing a page was
|
||||
* successful. Erase can be continued by calling this function again.
|
||||
* @ref BOOTLOADER_OK if the entire slot has been erased,
|
||||
* else error code in @ref BOOTLOADER_ERROR_STORAGE_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_chunkedEraseStorageSlot(BootloaderEraseStatus_t *eraseStat);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set a prioritized list of images to attempt to bootload. The last call to
|
||||
* this function determines which slot will be installed when
|
||||
* @ref bootloader_rebootAndInstall is called.
|
||||
*
|
||||
* @param[in] slotIds Prioritized list of slot IDs to attempt to bootload. The
|
||||
* first image to pass verification will be bootloaded.
|
||||
* @param[in] length Length of the slotIds array
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_BOOTLOAD_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_setImagesToBootload(int32_t *slotIds, size_t length);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get the prioritized list of images the bootloader will attempt to bootload.
|
||||
*
|
||||
* @param[out] slotIds Prioritized list of slot IDs to attempt to bootload. The
|
||||
* first image to pass verification will be bootloaded.
|
||||
* @param[in] length Length of the slotIds array
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_BOOTLOAD_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_getImagesToBootload(int32_t *slotIds, size_t length);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Append a single image to the list of images to attempt to bootload.
|
||||
*
|
||||
* @param[in] slotId ID of the slot to append
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_BOOTLOAD_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_appendImageToBootloadList(int32_t slotId);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set a single image to attempt to bootload.
|
||||
*
|
||||
* @param[in] slotId ID of the slot
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_BOOTLOAD_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_setImageToBootload(int32_t slotId);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initialize image verification.
|
||||
*
|
||||
* Initialize verification of an upgrade image stored in a bootloader storage
|
||||
* slot.
|
||||
*
|
||||
* @note This function must be called before calling
|
||||
* @ref bootloader_continueVerifyImage in a loop.
|
||||
*
|
||||
* @note The context pointer must point to memory allocated by the caller.
|
||||
* The caller must ensure that the context pointer is 32 bit aligned.
|
||||
* The required size of this context may depend on the version
|
||||
* of the bootloader. The required size for the bootloader associated with
|
||||
* this version of the application interface is given by the define
|
||||
* @ref BOOTLOADER_STORAGE_VERIFICATION_CONTEXT_SIZE.
|
||||
*
|
||||
* @note Instead of calling @ref bootloader_initVerifyImage followed by
|
||||
* @ref bootloader_continueVerifyImage, call
|
||||
* @ref bootloader_verifyImage if no
|
||||
* time-critical tasks are needed and sufficient stack space is
|
||||
* available for the automatically allocated context. The purpose of the
|
||||
* init-and-continue functions is to allow the caller to service system
|
||||
* needs during verification.
|
||||
*
|
||||
*
|
||||
* @param[in] slotId ID of the slot to check.
|
||||
* @param context Pointer to memory used to hold the parser context.
|
||||
* @param[in] contextSize Size of the context. An error is returned if the
|
||||
* supplied context is too small.
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK if the image parser was initialized, else error
|
||||
* code.
|
||||
******************************************************************************/
|
||||
#if !defined(SL_TRUSTZONE_NONSECURE)
|
||||
int32_t bootloader_initVerifyImage(uint32_t slotId,
|
||||
void *context,
|
||||
size_t contextSize);
|
||||
#else
|
||||
int32_t bootloader_initVerifyImage(uint32_t slotId);
|
||||
#endif // SL_TRUSTZONE_NONSECURE
|
||||
|
||||
/***************************************************************************//**
|
||||
* Continue image verification.
|
||||
*
|
||||
* Continue verification of an upgrade image stored in a bootloader storage
|
||||
* slot.
|
||||
*
|
||||
* @note This function must be called in a loop until anything other than
|
||||
* @ref BOOTLOADER_ERROR_PARSE_CONTINUE is returned.
|
||||
*
|
||||
* @note @ref bootloader_initVerifyImage must be called before calling this
|
||||
* function to reset the parser.
|
||||
*
|
||||
* @note Instead of calling @ref bootloader_initVerifyImage followed by
|
||||
* @ref bootloader_continueVerifyImage, call
|
||||
* @ref bootloader_verifyImage if no
|
||||
* time-critical tasks are needed. The purpose of the
|
||||
* init-and-continue functions is to allow the caller to service system
|
||||
* needs during verification.
|
||||
*
|
||||
*
|
||||
* @param context Pointer to a context structure that has
|
||||
* been initialized by calling
|
||||
* @ref bootloader_initVerifyImage()
|
||||
* @param[in] metadataCallback Function pointer, which is called when
|
||||
* the binary metadata in the image is currently
|
||||
* verified. Set to NULL if not required.
|
||||
*
|
||||
* @return @ref BOOTLOADER_ERROR_PARSE_CONTINUE if parsing was successful, and
|
||||
* the parser expects more data. @ref BOOTLOADER_ERROR_PARSE_SUCCESS if
|
||||
* the parser has successfully parsed the image and it passes
|
||||
* verification. Else error code.
|
||||
******************************************************************************/
|
||||
#if !defined(SL_TRUSTZONE_NONSECURE)
|
||||
int32_t bootloader_continueVerifyImage(void *context,
|
||||
BootloaderParserCallback_t metadataCallback);
|
||||
#else
|
||||
int32_t bootloader_continueVerifyImage(void);
|
||||
#endif // SL_TRUSTZONE_NONSECURE
|
||||
|
||||
/***************************************************************************//**
|
||||
* Verify that the image in the given storage slot is valid.
|
||||
*
|
||||
* @param[in] slotId ID of the slot to check
|
||||
* @param[in] metadataCallback Function pointer, which is called when
|
||||
* binary metadata is present in the storage slot.
|
||||
* Set to NULL if not required.
|
||||
*
|
||||
* @note This function allocates a context structure of the size given by
|
||||
* @ref BOOTLOADER_STORAGE_VERIFICATION_CONTEXT_SIZE on the caller's
|
||||
* stack. To manage memory and allocate the
|
||||
* context elsewhere (on the heap, as a global variable, and so on), use
|
||||
* @ref bootloader_initVerifyImage and @ref bootloader_continueVerifyImage
|
||||
* functions instead.
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK if the image is valid, else error code.
|
||||
******************************************************************************/
|
||||
#if !defined(SL_TRUSTZONE_NONSECURE)
|
||||
int32_t bootloader_verifyImage(uint32_t slotId,
|
||||
BootloaderParserCallback_t metadataCallback);
|
||||
#else
|
||||
int32_t bootloader_verifyImage(uint32_t slotId);
|
||||
#endif // SL_TRUSTZONE_NONSECURE
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get application and bootloader upgrade metadata from the storage slot.
|
||||
*
|
||||
* @param[in] slotId ID of the slot to check
|
||||
* @param[out] appInfo Pointer to @ref ApplicationData_t struct
|
||||
* @param[out] bootloaderVersion Pointer to an integer representing bootloader
|
||||
* version
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK if metadata was filled successfully
|
||||
******************************************************************************/
|
||||
int32_t bootloader_getImageInfo(uint32_t slotId,
|
||||
ApplicationData_t *appInfo,
|
||||
uint32_t *bootloaderVersion);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Check whether the bootloader storage is busy.
|
||||
*
|
||||
* @return True if the storage is busy
|
||||
******************************************************************************/
|
||||
bool bootloader_storageIsBusy(void);
|
||||
|
||||
#if !defined(SL_TRUSTZONE_NONSECURE)
|
||||
/***************************************************************************//**
|
||||
* Read raw data from storage.
|
||||
*
|
||||
* @param[in] address Address to start reading from
|
||||
* @param[out] buffer Buffer to store the data
|
||||
* @param[in] length Amount of data to read
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_STORAGE_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_readRawStorage(uint32_t address,
|
||||
uint8_t *buffer,
|
||||
size_t length);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Write data to storage.
|
||||
*
|
||||
* @note
|
||||
* If DMA-based MSC write is enabled on the bootloader, writing data from
|
||||
* flash to flash is not supported on Series-1 devices.
|
||||
*
|
||||
* @param[in] address Address to start writing to
|
||||
* @param[in] buffer Buffer to read data to write from
|
||||
* @param[in] length Amount of data to write. Must be a multiple of 4.
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_STORAGE_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_writeRawStorage(uint32_t address,
|
||||
uint8_t *buffer,
|
||||
size_t length);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Erase data from storage.
|
||||
*
|
||||
* @note Erasing storage must adhere to the limitations of the underlying
|
||||
* storage medium, such as requiring full page erases. Use
|
||||
* @ref bootloader_getStorageInfo to learn about the limitations of the
|
||||
* configured storage medium.
|
||||
*
|
||||
* @param[in] address Address to start erasing from
|
||||
* @param[in] length Length of data to erase
|
||||
*
|
||||
* @return @ref BOOTLOADER_OK on success, else error code in
|
||||
* @ref BOOTLOADER_ERROR_STORAGE_BASE range
|
||||
******************************************************************************/
|
||||
int32_t bootloader_eraseRawStorage(uint32_t address, size_t length);
|
||||
#endif // !SL_TRUSTZONE_NONSECURE
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get allocated DMA channel for MSC write.
|
||||
*
|
||||
* @return A positive number channel. -1 if DMA-based MSC write
|
||||
* is not enabled. Otherwise, the error code
|
||||
* BOOTLOADER_ERROR_INIT_STORAGE.
|
||||
******************************************************************************/
|
||||
int32_t bootloader_getAllocatedDMAChannel(void);
|
||||
|
||||
/** @} (end addtogroup StorageInterface) */
|
||||
/** @} (end addtogroup Interface) */
|
||||
|
||||
#endif // BTL_INTERFACE_STORAGE_H
|
||||
104
Libs/platform/bootloader/api/btl_reset_info.h
Normal file
104
Libs/platform/bootloader/api/btl_reset_info.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Reset information for the Silicon Labs Gecko bootloader
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc. Your use of this
|
||||
* software is governed by the terms of Silicon Labs Master Software License
|
||||
* Agreement (MSLA) available at
|
||||
* www.silabs.com/about-us/legal/master-software-license-agreement. This
|
||||
* software is distributed to you in Source Code format and is governed by the
|
||||
* sections of the MSLA applicable to Source Code.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTL_RESET_INFO_H
|
||||
#define BTL_RESET_INFO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup Interface
|
||||
* @{
|
||||
* @addtogroup CommonInterface
|
||||
* @{
|
||||
* @addtogroup ResetInterface Reset Information
|
||||
* @brief Passing information when resetting into and out of the bootloader
|
||||
* @details
|
||||
* To signal the bootloader to run, the
|
||||
* application needs to write the @ref BootloaderResetCause_t structure
|
||||
* to the first address of RAM, setting @ref BootloaderResetCause_t.reason
|
||||
* to @ref BOOTLOADER_RESET_REASON_BOOTLOAD.
|
||||
*
|
||||
* The reset cause is only valid if @ref BootloaderResetCause_t.signature
|
||||
* is set to @ref BOOTLOADER_RESET_SIGNATURE_VALID.
|
||||
* @code BootloaderResetCause_t resetCause = {
|
||||
* .reason = BOOTLOADER_RESET_REASON_BOOTLOAD,
|
||||
* .signature = BOOTLOADER_RESET_SIGNATURE_VALID
|
||||
* } @endcode
|
||||
*
|
||||
* When the bootloader reboots back into the app, it sets the reset
|
||||
* reason to @ref BOOTLOADER_RESET_REASON_GO if the bootload succeeded,
|
||||
* or @ref BOOTLOADER_RESET_REASON_BADIMAGE if the bootload failed due
|
||||
* to errors when parsing the upgrade image.
|
||||
*
|
||||
* @note
|
||||
* The reset information is automatically filled out before reset if the
|
||||
* @ref bootloader_rebootAndInstall function is called.
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/// Reset cause of the bootloader
|
||||
typedef struct {
|
||||
/// Reset reason as defined in the [reset information](@ref ResetInterface)
|
||||
uint16_t reason;
|
||||
/// Signature indicating whether the reset reason is valid
|
||||
uint16_t signature;
|
||||
} BootloaderResetCause_t;
|
||||
|
||||
/// Unknown bootloader cause (should never occur)
|
||||
#define BOOTLOADER_RESET_REASON_UNKNOWN 0x0200u
|
||||
/// Bootloader caused reset telling app to run
|
||||
#define BOOTLOADER_RESET_REASON_GO 0x0201u
|
||||
/// Application requested that bootloader runs
|
||||
#define BOOTLOADER_RESET_REASON_BOOTLOAD 0x0202u
|
||||
/// Bootloader detected bad external upgrade image
|
||||
#define BOOTLOADER_RESET_REASON_BADIMAGE 0x0203u
|
||||
/// Fatal Error or assert in bootloader
|
||||
#define BOOTLOADER_RESET_REASON_FATAL 0x0204u
|
||||
/// Forced bootloader activation
|
||||
#define BOOTLOADER_RESET_REASON_FORCE 0x0205u
|
||||
/// OTA Bootloader mode activation
|
||||
#define BOOTLOADER_RESET_REASON_OTAVALID 0x0206u
|
||||
/// Bootloader initiated deep sleep
|
||||
#define BOOTLOADER_RESET_REASON_DEEPSLEEP 0x0207u
|
||||
/// Application verification failed
|
||||
#define BOOTLOADER_RESET_REASON_BADAPP 0x0208u
|
||||
/// Bootloader requested that first stage upgrades main bootloader
|
||||
#define BOOTLOADER_RESET_REASON_UPGRADE 0x0209u
|
||||
/// Bootloader timed out waiting for upgrade image
|
||||
#define BOOTLOADER_RESET_REASON_TIMEOUT 0x020Au
|
||||
/// Soft-reset was forced to handle a fault
|
||||
#define BOOTLOADER_RESET_REASON_FAULT 0x020Bu
|
||||
/// Soft-reset was forced to handle a security fault
|
||||
#define BOOTLOADER_RESET_REASON_TZ_FAULT 0x020Cu
|
||||
|
||||
/// Insufficient slot space to re-create a new firmware
|
||||
#define BOOTLOADER_RESET_REASON_NO_SLOT_SPACE 0x020Du
|
||||
/// CRC mismatch of the newly re-constructed firmware
|
||||
#define BOOTLOADER_RESET_REASON_BADCRC 0x020Eu
|
||||
/// Re-creation of the new application using the DDFU library failed
|
||||
#define BOOTLOADER_RESET_REASON_DDFU_FAIL 0x020Fu
|
||||
|
||||
/// Reset signature is valid
|
||||
#define BOOTLOADER_RESET_SIGNATURE_VALID 0xF00Fu
|
||||
/// Reset signature is invalid
|
||||
#define BOOTLOADER_RESET_SIGNATURE_INVALID 0xC33Cu
|
||||
|
||||
/** @} (end addtogroup ResetInterface) */
|
||||
/** @} (end addtogroup CommonInterface) */
|
||||
/** @} (end addtogroup Interface) */
|
||||
|
||||
#endif // BTL_RESET_INFO_H
|
||||
Reference in New Issue
Block a user