| // Copyright lowRISC contributors. | |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. | |
| // SPDX-License-Identifier: Apache-2.0 | |
| #ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_FLASH_CTRL_H_ | |
| #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_FLASH_CTRL_H_ | |
| /** | |
| * @file | |
| * @brief <a href="/hw/ip/flash_ctrl/doc/">Flash Controller</a> Device | |
| * Interface Functions | |
| */ | |
| #include "sw/device/lib/base/macros.h" | |
| #include "sw/device/lib/base/multibits.h" | |
| #include "sw/device/lib/dif/autogen/dif_flash_ctrl_autogen.h" | |
| #ifdef __cplusplus | |
| extern "C" { | |
| #endif // __cplusplus | |
| /** | |
| * Carries state for a flash controller device. | |
| * | |
| * All members except the `dev` should be considered private and should not be | |
| * accessed directly outside of the DIF implementation. | |
| */ | |
| typedef struct dif_flash_ctrl_state { | |
| /** | |
| * Contains autogenerated device information, like the base address for | |
| * registers in the flash controller device. | |
| */ | |
| dif_flash_ctrl_t dev; | |
| /* Private members below. */ | |
| /** Number of words remaining for the current transaction. */ | |
| uint32_t words_remaining; | |
| /** Whether a transaction is pending completion. */ | |
| bool transaction_pending; | |
| } dif_flash_ctrl_state_t; | |
| /** | |
| * Initialize the DIF state for the flash controller. | |
| * | |
| * @param handle The flash controller DIF state to initialize. | |
| * @param base_addr The base address for the flash controller. | |
| * @return `kDifBadArg` if `handle` is null. `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_init_state(dif_flash_ctrl_state_t *handle, | |
| mmio_region_t base_addr); | |
| typedef struct dif_flash_ctrl_device_info { | |
| /** Number of banks under this flash controller. */ | |
| uint32_t num_banks; | |
| /** Number of bytes per flash word. */ | |
| uint32_t bytes_per_word; | |
| /** Number of bytes per flash page. */ | |
| uint32_t bytes_per_page; | |
| /** Number of pages per bank in the data partition. */ | |
| uint32_t data_pages; | |
| /** Number of pages per bank in the info partition, type 0. */ | |
| uint32_t info0_pages; | |
| /** Number of pages per bank in the info partition, type 1. */ | |
| uint32_t info1_pages; | |
| /** Number of pages per bank in the info partition, type 2. */ | |
| uint32_t info2_pages; | |
| } dif_flash_ctrl_device_info_t; | |
| // TODO: Associate the data with a base address or acknowledge that there | |
| // should only ever be one flash controller in the system. | |
| /** | |
| * Get information on the flash controller sizes. | |
| * | |
| * @return A `dif_flash_ctrl_device_info_t` representing the feature sizes for | |
| * various components of the flash. | |
| */ | |
| dif_flash_ctrl_device_info_t dif_flash_ctrl_get_device_info(void); | |
| /** | |
| * Set whether the flash is enabled. | |
| * | |
| * Generally, this is used to disable flash functionality in case of an | |
| * emergency. Flash functionality is ordinarily enabled. | |
| * | |
| * @param handle The flash controller to operate on. | |
| * @param enable Enable/disable flash functionality. | |
| * @return `kDifBadArg` if `handle` is null. `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_set_flash_enablement(dif_flash_ctrl_state_t *handle, | |
| dif_toggle_t enable); | |
| /** | |
| * Get whether flash functionality is enabled. | |
| * | |
| * @param handle The flash controller to operate on. | |
| * @param enabled_out Out parameter, where to store whether flash is enabled. | |
| * @return `kDifBadArg` if `handle` or `enabled_out` are null and `kDifOk` | |
| * otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_flash_enablement( | |
| const dif_flash_ctrl_state_t *handle, dif_toggle_t *enabled_out); | |
| /** | |
| * Set whether execution / fetch access is enabled. | |
| * | |
| * @param handle The flash controller to operate on. | |
| * @param enable Enable/disable execution / fetch access. | |
| * @return `kDifBadArg` if `handle` or `enabled_out` are null and `kDifOk` | |
| * otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_set_exec_enablement(dif_flash_ctrl_state_t *handle, | |
| dif_toggle_t enable); | |
| /** | |
| * Get whether execution / fetch access is enabled. | |
| * | |
| * @param handle The flash controller to operate on. | |
| * @param enabled_out Out parameter, whether execution / fetch access is | |
| * allowed. | |
| * @return `kDifBadArg` if `handle` or `enabled_out` are null and `kDifOk` | |
| * otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_exec_enablement( | |
| const dif_flash_ctrl_state_t *handle, dif_toggle_t *enabled_out); | |
| /** | |
| * Begins the flash controller's initialization sequence. The flash controller | |
| * will read out the root seeds before allowing other usage of the controller. | |
| * This operation will only be performed once, and controller initialization | |
| * cannot be requested again until after a reset. | |
| * | |
| * @param handle The flash controller to operate on. | |
| * @return `kDifBadArg` if `handle` is null, `kDifError` if initialization has | |
| * already been started, and `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_start_controller_init( | |
| dif_flash_ctrl_state_t *handle); | |
| /** | |
| * Status bits that can be queried. | |
| */ | |
| typedef struct dif_flash_ctrl_status { | |
| /** | |
| * Flash read FIFO full, software must consume data. | |
| */ | |
| bool read_fifo_full : 1; | |
| /** | |
| * Flash read FIFO empty. | |
| */ | |
| bool read_fifo_empty : 1; | |
| /** | |
| * Flash program FIFO full. | |
| */ | |
| bool prog_fifo_full : 1; | |
| /** | |
| * Flash program FIFO empty, software must provide data. | |
| */ | |
| bool prog_fifo_empty : 1; | |
| /** | |
| * Flash controller undergoing init. | |
| */ | |
| bool controller_init_wip : 1; | |
| } dif_flash_ctrl_status_t; | |
| /** | |
| * Query the status registers on the flash controller. | |
| * | |
| * This function checks the various status bits as described in | |
| * `dif_flash_ctrl_status_t`. | |
| * | |
| * @param handle flash controller device to check the status bits for. | |
| * @param status_out Out parameter. The current status of the flash controller. | |
| * @return `kDifBadArg` if `handle` or `status_out` is null, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_status(const dif_flash_ctrl_state_t *handle, | |
| dif_flash_ctrl_status_t *status_out); | |
| /** | |
| * Represents programming capabilities of the flash controller. The meaning of | |
| * the boolean values is context-sensitive. For the result of a query, they | |
| * represent which types are allowed. As an argument to a function that disables | |
| * capabilities, a true value indicates that the function should disable that | |
| * type. | |
| */ | |
| typedef struct dif_flash_ctrl_prog_capabilities { | |
| /** Normal programming type. */ | |
| bool normal_prog_type : 1; | |
| /** Repair programming type. */ | |
| bool repair_prog_type : 1; | |
| } dif_flash_ctrl_prog_capabilities_t; | |
| /** | |
| * Query the allowed programming types. | |
| * | |
| * Note that this function is a check of a permission only. For checking whether | |
| * the flash supports a given type, use `dif_flash_ctrl_get_phy_status()`. | |
| * @sa dif_flash_ctrl_get_phy_status | |
| * | |
| * @param handle The flash controller to query. | |
| * @param allowed_types_out Out parameter. Points to location where the allowed | |
| * types should be written. | |
| * @return `kDifBadArg` if `handle` or `allowed_types_out` are null. `kDifOk` | |
| * otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_allowed_prog_types( | |
| const dif_flash_ctrl_state_t *handle, | |
| dif_flash_ctrl_prog_capabilities_t *allowed_types_out); | |
| /** | |
| * Disallow the indicated programming operations. | |
| * | |
| * Note that this is a one-way operation. Programming types that are disabled | |
| * cannot be enabled again without a reset. | |
| * | |
| * @param handle The flash controller to operate on. | |
| * @param types_to_disallow A programming type marked true indicates that the | |
| * given type should be *disabled*. | |
| * @return `kDifBadArg` if handle is null. `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_disallow_prog_types( | |
| dif_flash_ctrl_state_t *handle, | |
| dif_flash_ctrl_prog_capabilities_t types_to_disable); | |
| /** | |
| * Enum to represent the flash partition type (data or info). | |
| */ | |
| typedef enum dif_flash_ctrl_partition_type { | |
| kDifFlashCtrlPartitionTypeData = 0, | |
| kDifFlashCtrlPartitionTypeInfo = 1 | |
| } dif_flash_ctrl_partition_type_t; | |
| typedef enum dif_flash_ctrl_operation { | |
| /** Read the specified number of words. */ | |
| kDifFlashCtrlOpRead = 0, | |
| /** Program the specified number of words (normal mode). */ | |
| kDifFlashCtrlOpProgram = 1, | |
| /** | |
| * Program the specified number of words in repair mode. Support for this | |
| * mode depends on the underlying flash technology. See | |
| * `dif_flash_ctrl_supports_repair_operation`. | |
| */ | |
| kDifFlashCtrlOpProgramRepair = 5, | |
| /** Erase the specified page. */ | |
| kDifFlashCtrlOpPageErase = 2, | |
| /** Erase the specified bank. */ | |
| kDifFlashCtrlOpBankErase = 10, | |
| } dif_flash_ctrl_operation_t; | |
| typedef struct dif_flash_ctrl_transaction { | |
| dif_flash_ctrl_operation_t op; | |
| /** | |
| * The partition type for the transaction. | |
| * | |
| * Note: For bank erase operations, the data partition is *always* erased, | |
| * even when `partition_type` is `kFlashCtrlPartitionTypeInfo`. | |
| * | |
| */ | |
| dif_flash_ctrl_partition_type_t partition_type; | |
| /** | |
| * The index / ID of the info partition. Unused for data partitions, since | |
| * there is only one in a given bank. | |
| */ | |
| uint32_t partition_id; | |
| /** | |
| * Byte address (in the flash address space) to start the operation. | |
| * | |
| * For operations at a granularity of words, the flash controller will | |
| * truncate to the closest, lower word aligned address. For example, if 0x13 | |
| * is supplied for a read, the controller will perform a read at address 0x10. | |
| * | |
| * Similarly, for page erase and bank erase operations, the flash controller | |
| * will truncate to the closest lower page-aligned or bank-aligned address, | |
| * respectively. | |
| */ | |
| uint32_t byte_address; | |
| /** | |
| * Number of 32-bit words in the operation. Must be in the range [1,4096] | |
| * (inclusive) for program or read operations. Unused for erase operations. | |
| */ | |
| uint32_t word_count; | |
| } dif_flash_ctrl_transaction_t; | |
| /** | |
| * Start a flash controller operation. | |
| * | |
| * Note that not all underlying flash memory supports the | |
| * `kDifFlashCtrlOpProgramRepair` operation. When specifying this in the `op`, | |
| * `dif_flash_ctrl_get_phy_status()` can first be used to ensure the operation | |
| * is supported. | |
| * | |
| * @param handle The flash controller device to execute the transaction on. | |
| * @param transaction The parameters that constitute the operation to start. | |
| * @return `kDifBadArg` if `handle` is null or `transaction` contains an invalid | |
| * or unsupported operation, `kDifUnavailable` if a flash transaction is in | |
| * progress at the controller, `kDifIpFifoFull` if the FIFOs are not empty, and | |
| * `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_start(dif_flash_ctrl_state_t *handle, | |
| dif_flash_ctrl_transaction_t transaction); | |
| /** | |
| * Start a flash controller operation, with fewer safeguards. (unsafe version) | |
| * | |
| * Unlike `dif_flash_ctrl_start()`, this variant does not check whether the info | |
| * partition id is valid, whether the word count is valid, or whether the FIFOs | |
| * have been emptied. This function is intended to be used to trigger errors on | |
| * purpose, for testing the hardware responses. | |
| * | |
| * Note that not all underlying flash memory supports the | |
| * `kDifFlashCtrlOpProgramRepair` operation. When specifying this in the `op`, | |
| * `dif_flash_ctrl_get_phy_status()` can first be used to ensure the operation | |
| * is supported. | |
| * | |
| * @param handle The flash controller device to execute the transaction on. | |
| * @param transaction The parameters that constitute the operation to start. | |
| * @return `kDifBadArg` if `handle` is null, `kDifUnavailable` if a flash | |
| * transaction is in progress, and `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_start_unsafe( | |
| dif_flash_ctrl_state_t *handle, dif_flash_ctrl_transaction_t transaction); | |
| /** | |
| * Suspend an ongoing erase transaction. | |
| * | |
| * If no erase transaction is ongoing, returns with no effect. | |
| * | |
| * @param handle flash controller device to operate on. | |
| * @return `kDifBadArg` if `handle` is null. Otherwise, `kDifOk`. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_suspend_erase(dif_flash_ctrl_state_t *handle); | |
| /** | |
| * Query the controller for any erase suspension requests pending. | |
| * | |
| * @param handle The flash controller to query. | |
| * @param request_pending_out Out parameter. The location to write whether an | |
| * erase suspension request is pending. | |
| * @return `kDifBadArg` if `handle` or `request_pending_out` are null. `kDifOk` | |
| * otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_erase_suspend_status( | |
| dif_flash_ctrl_state_t *handle, bool *request_pending_out); | |
| /** | |
| * Push data to the program FIFO. (unsafe version) | |
| * | |
| * This function is primarily for testing hardware error responses. If you are | |
| * not specifically trying to force an error, consider | |
| * `dif_flash_ctrl_prog_fifo_push()` instead. This function does not check if a | |
| * program transaction has begun, nor if the number of words would exceed the | |
| * size of the current transaction. | |
| * | |
| * Attempts to write the contents of `data` to the program FIFO without | |
| * consideration for the current controller state. | |
| * | |
| * It is up to the caller to call `dif_flash_ctrl_end()` to ensure the | |
| * flash controller completed this transaction successfully. | |
| * | |
| * @param handle flash controller device to push data to. | |
| * @param word_count The number of words to write. | |
| * @param data The data to write. | |
| * @return `kDifBadArg` if `handle` or `data` are null. `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_prog_fifo_push_unsafe( | |
| dif_flash_ctrl_state_t *handle, uint32_t word_count, const uint32_t *data); | |
| /** | |
| * Push data to the program FIFO. | |
| * | |
| * Attempts to write the contents of `data` to the program FIFO. It is required | |
| * that a program transaction be started prior to calling this function, else | |
| * the call will fail with `kDifError`. | |
| * | |
| * The following conditions are also required: | |
| * - `data` must reference a contiguous, allocated, readable region of at | |
| * least `word_count` words, violation of this will produce undefined | |
| * behavior. | |
| * - The first call to this function after starting the program transaction | |
| * the same `word_count` must not exceed what was supplied at the start of | |
| * the program transaction. | |
| * - Each subsequent call the new `word_count` must not exceed `word_count - | |
| * words_sent_out` from the previous call. | |
| * All deviations on the above will produce a `kDifBadArg` error | |
| * unless otherwise specified. | |
| * | |
| * If the FIFO fills up, this function will cause the CPU to block until the | |
| * flash controller frees up more space. | |
| * | |
| * It is up to the caller to call `dif_flash_ctrl_end()` to ensure the | |
| * flash controller completed this transaction successfully. | |
| * | |
| * @param handle flash controller device to push data to. | |
| * @param word_count The number of words to write. | |
| * @param data The data to write. | |
| * program FIFO, will contain the number of words pushed. | |
| * @return `kDifBadArg` if `handle` or `data` are null or if the value of | |
| * `word_count` is illegal. `kDifError` if a program transaction was not | |
| * started. `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_prog_fifo_push(dif_flash_ctrl_state_t *handle, | |
| uint32_t word_count, | |
| const uint32_t *data); | |
| /** | |
| * Read data from the read FIFO. (unsafe version) | |
| * | |
| * This function is primarily for testing hardware error responses. If you are | |
| * not specifically trying to force an error, consider | |
| * `dif_flash_ctrl_read_fifo_pop()` instead. This function does not check if a | |
| * transaction is currently in progress, nor if this would cause a read beyond | |
| * the number of words for the current operation. | |
| * | |
| * Attempts to read `word_count` words from the read FIFO without consideration | |
| * for the current controller state. | |
| * | |
| * It is up to the caller to call `dif_flash_ctrl_end()` to ensure the | |
| * flash controller completed this transaction successfully. | |
| * | |
| * @param handle flash controller device to push data to. | |
| * @param word_count The number of words to read. | |
| * @param data_out The region in memory to store the data read off the FIFO. | |
| * @return `kDifBadArg` if `handle` or `data` are null. `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_read_fifo_pop_unsafe(dif_flash_ctrl_state_t *handle, | |
| uint32_t word_count, | |
| uint32_t *data_out); | |
| /** | |
| * Read data from the read FIFO. | |
| * | |
| * Attempts to read `word_count` words from the read FIFO. | |
| * | |
| * The following conditions are required: | |
| * - `data_out` must reference a contiguous, allocated, writable region of at | |
| * least `word_count` words, violation of this will produce undefined | |
| * behavior. | |
| * - The first call to this function after starting the program transaction | |
| * the same `word_count` must not exceed what was supplied at the start of | |
| * the read transaction. | |
| * - Each subsequent call the new `word_count` must not exceed `word_count - | |
| * words_received` from the previous call. | |
| * All deviations on the above will produce a `kDifBadArg` error unless | |
| * otherwise specified. | |
| * | |
| * If the FIFO empties this function will cause the CPU to block until the flash | |
| * controller fills the FIFO with more data. | |
| * | |
| * It is up to the caller to call `dif_flash_ctrl_end()` to ensure the | |
| * flash controller completed this transaction successfully. | |
| * | |
| * @param handle flash controller device to pull data from. | |
| * @param word_count The number of words to read. | |
| * @param data_out The region in memory to store the data read off the FIFO. | |
| * @param words_read_out Out-parameter, the number of words read. | |
| * @return `kDifBadArg` if `handle` or `data_out` are null, or if the value of | |
| * `word_count` is illegal. `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_read_fifo_pop(dif_flash_ctrl_state_t *handle, | |
| uint32_t word_count, | |
| uint32_t *data_out); | |
| typedef struct dif_flash_ctrl_error_codes { | |
| /** | |
| * Access permission error. | |
| */ | |
| bool memory_properties_error : 1; | |
| /** | |
| * Uncorrectable flash read data error. | |
| */ | |
| bool read_error : 1; | |
| /** | |
| * Flash program has a window resolution error. In other words, the start of | |
| * program and end of program are in different windows. | |
| */ | |
| bool prog_window_error : 1; | |
| /** | |
| * Flash program operation selected an unavailable type. For example, the | |
| * repair type of programming was selected, but the flash did not support it. | |
| */ | |
| bool prog_type_error : 1; | |
| /** | |
| * A shadow register encountered an update error. | |
| */ | |
| bool shadow_register_error : 1; | |
| } dif_flash_ctrl_error_codes_t; | |
| /** | |
| * Represents recoverable errors and synchronous errors caused by software. | |
| */ | |
| typedef struct dif_flash_ctrl_error { | |
| /** | |
| * For errors associated with an address, the address where the error | |
| * occurred. | |
| */ | |
| uint32_t address; | |
| /** | |
| * A set of error codes. | |
| */ | |
| dif_flash_ctrl_error_codes_t codes; | |
| } dif_flash_ctrl_error_t; | |
| /** | |
| * Get the error codes and address of the last associated error. | |
| * | |
| * @param handle flash controller device to query. | |
| * @param error_code_out Output parameter. The location where the current status | |
| * is to be stored. | |
| * @return `kDifBadArg` if `handle` or `error_code_out` are null. `kDifOk` | |
| * otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_error_codes( | |
| const dif_flash_ctrl_state_t *handle, | |
| dif_flash_ctrl_error_t *error_code_out); | |
| /** | |
| * Clear the error codes. | |
| * | |
| * @param handle flash controller device to set. | |
| * @return `kDifBadArg` if `handle` is null. `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_clear_error_codes( | |
| dif_flash_ctrl_state_t *handle, dif_flash_ctrl_error_codes_t codes); | |
| typedef struct dif_flash_ctrl_output { | |
| /** | |
| * The error code associated with an `operation_error`. This field is only | |
| * valid if `operation_error` is true. | |
| */ | |
| dif_flash_ctrl_error_t error_code; | |
| /** | |
| * Flash operation done. | |
| */ | |
| bool operation_done : 1; | |
| /** | |
| * Flash operation error. | |
| */ | |
| bool operation_error : 1; | |
| } dif_flash_ctrl_output_t; | |
| /** | |
| * Check that the transaction has completed and return any resulting error | |
| * codes. Does not clear the error codes, but does clear the operation status if | |
| * the operation has terminated. | |
| * | |
| * @param handle flash controller device for completing the transaction. | |
| * @param out Out parameter. Contains the transaction status and error codes. | |
| * @return `kDifBadArg` if `handle` or `out` are null, `kDifError` if no | |
| * transaction was pending, `kDifUnavailable` if the controller is still | |
| * processing the transaction, `kDifIpFifoFull` if there are still words | |
| * remaining for the FIFOs, and `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_end(dif_flash_ctrl_state_t *handle, | |
| dif_flash_ctrl_output_t *out); | |
| /** | |
| * Memory protection configuration options. | |
| */ | |
| typedef struct dif_flash_ctrl_region_properties { | |
| /** Read enable flag. */ | |
| multi_bit_bool_t rd_en; | |
| /** Program enable flag. */ | |
| multi_bit_bool_t prog_en; | |
| /** Erase enable flag. */ | |
| multi_bit_bool_t erase_en; | |
| /** Scramble enable flag*/ | |
| multi_bit_bool_t scramble_en; | |
| /** ECC enable flag. */ | |
| multi_bit_bool_t ecc_en; | |
| /** High-endurance enable flag. */ | |
| multi_bit_bool_t high_endurance_en; | |
| } dif_flash_ctrl_region_properties_t; | |
| /** | |
| * A composite of a data region and its memory properties. | |
| */ | |
| typedef struct dif_flash_ctrl_data_region_properties { | |
| /** Region base page index. */ | |
| uint32_t base; | |
| /** Region config size (in number of pages). */ | |
| uint32_t size; | |
| /** Memory properties of the region. */ | |
| dif_flash_ctrl_region_properties_t properties; | |
| } dif_flash_ctrl_data_region_properties_t; | |
| /** | |
| * Representation of the memory protection regions for the info pages. | |
| */ | |
| typedef struct dif_flash_ctrl_info_region { | |
| /** Region bank ID. */ | |
| uint32_t bank; | |
| /** Region info partition ID. */ | |
| uint32_t partition_id; | |
| /** Region page index. */ | |
| uint32_t page; | |
| } dif_flash_ctrl_info_region_t; | |
| /** | |
| * Enable/disable the data region of flash indexed by `region`. | |
| * | |
| * This may only be done if region configuration has not been locked. | |
| * | |
| * @param handle flash controller device to configure. | |
| * @param region The region to operate on. | |
| * @param enable Enable or disable this `region`. | |
| * @return `kDifBadArg` if `handle` is null or `region` is invalid, `kDifLocked` | |
| * if region configuration has been locked, and `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_set_data_region_enablement( | |
| dif_flash_ctrl_state_t *handle, uint32_t region, dif_toggle_t enable); | |
| /** | |
| * Get the enabled/disabled state for the indicated data `region`. | |
| * | |
| * @param handle flash controller device to query. | |
| * @param region The region in question. | |
| * @param enabled_out Out-parameter, the enabled/disabled state of this region. | |
| * @return `kDifBadArg ` if `handle` or `enabled_out` is null, or if `region` is | |
| * invalid, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_data_region_enablement( | |
| const dif_flash_ctrl_state_t *handle, uint32_t region, | |
| dif_toggle_t *enabled_out); | |
| /** | |
| * Enable/disable the info region of flash identified by `region`. | |
| * | |
| * This may only be done if region configuration has not been locked. | |
| * | |
| * @param handle flash controller device to configure. | |
| * @param region The region to operate on. | |
| * @param enable Enable or disable this `region`. | |
| * @return `kDifBadArg` if `handle` is null or `region` is invalid, `kDifLocked` | |
| * if region configuration has been locked, and `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_set_info_region_enablement( | |
| dif_flash_ctrl_state_t *handle, dif_flash_ctrl_info_region_t region, | |
| dif_toggle_t enable); | |
| /** | |
| * Get the enabled/disabled state for the indicated info `region`. | |
| * | |
| * @param handle flash controller device to query. | |
| * @param region The region in question. | |
| * @param enabled_out Out-parameter, the enabled/disabled state of this region. | |
| * @return `kDifBadArg ` if `handle` or `enabled_out` is null, or if `region` is | |
| * invalid, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_info_region_enablement( | |
| const dif_flash_ctrl_state_t *handle, dif_flash_ctrl_info_region_t region, | |
| dif_toggle_t *enabled_out); | |
| /** | |
| * Set the default memory properties for data regions, when not overridden by a | |
| * specific entry in the data region memory properties table. | |
| * | |
| * @param handle flash controller device to configure. | |
| * @param properties The memory properties to control. | |
| * @return `kDifBadArg` if `handle` is null, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_set_default_region_properties( | |
| dif_flash_ctrl_state_t *handle, | |
| dif_flash_ctrl_region_properties_t properties); | |
| /** | |
| * Get the default memory properties for data regions, when they are not | |
| * overridden by a specific entry in the data region memory properties table. | |
| * | |
| * @param handle flash controller device to query. | |
| * @param properties_out Out-parameter, a pointer to a | |
| * `dif_flash_ctrl_region_properties_t` struct for writing the memory | |
| * properties. | |
| * @return `kDifBadArg` if `handle` or `properties_out` are null. `kDifOk` | |
| * otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_default_region_properties( | |
| const dif_flash_ctrl_state_t *handle, | |
| dif_flash_ctrl_region_properties_t *properties_out); | |
| /** | |
| * Set memory properties for the data region of flash indexed by `region`. | |
| * | |
| * This may only be done if region configuration has not been locked. | |
| * | |
| * @param handle flash controller device to configure. | |
| * @param region The region to operate on. | |
| * @param config The memory properties to control for this `region`. | |
| * @return `kDifBadArg` if `handle` is null or `region` is invalid, `kDifLocked` | |
| * if region configuration has been locked, and `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_set_data_region_properties( | |
| dif_flash_ctrl_state_t *handle, uint32_t region, | |
| dif_flash_ctrl_data_region_properties_t config); | |
| /** | |
| * Get the memory properties for the data region of flash indexed by `region`. | |
| * | |
| * @param handle flash controller device to query. | |
| * @param region The index of the region entry in question. | |
| * @param config_out Out-parameter, a pointer to a | |
| * `dif_flash_ctrl_data_region_properties_t` struct for writing the full entry | |
| * showing the region configuration and its memory properties. | |
| * @return `kDifBadArg` if `handle` or `properties_out` are null or if `region` | |
| * is invalid. `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_data_region_properties( | |
| const dif_flash_ctrl_state_t *handle, uint32_t region, | |
| dif_flash_ctrl_data_region_properties_t *config_out); | |
| /** | |
| * Set memory properties for the info region of flash identified by `region`. | |
| * | |
| * This may only be done if region configuration has not been locked. | |
| * | |
| * @param handle flash controller device to configure. | |
| * @param region The region to operate on. | |
| * @param properties The memory properties to control for this `region`. | |
| * @return `kDifBadArg` if `handle` is null or `region` is invalid, `kDifLocked` | |
| * if region configuration has been locked, and `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_set_info_region_properties( | |
| dif_flash_ctrl_state_t *handle, dif_flash_ctrl_info_region_t region, | |
| dif_flash_ctrl_region_properties_t properties); | |
| /** | |
| * Get the memory properties for the info region of flash identified by | |
| * `region`. | |
| * | |
| * @param handle flash controller device to query. | |
| * @param region The index of the region entry in question. | |
| * @param properties_out Out-parameter, a pointer to a | |
| * `dif_flash_ctrl_region_properties_t` struct for writing memory properties | |
| * associated with the indicated `region`. | |
| * @return `kDifBadArg` if `handle` or `properties_out` are null or if `region` | |
| * is invalid. `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_info_region_properties( | |
| const dif_flash_ctrl_state_t *handle, dif_flash_ctrl_info_region_t region, | |
| dif_flash_ctrl_region_properties_t *properties_out); | |
| /** | |
| * Lock data region memory properties configuration until the device is reset. | |
| * | |
| * This will prevent any further configuration of region properties until device | |
| * reset. Future calls to functions that set data region memory properties will | |
| * return `kDifLocked`. | |
| * | |
| * @param handle flash controller device to lock region configuration on. | |
| * @param region The region to lock. | |
| * @return `kDifBadArg` if `handle` is null, or if `region` is invalid, | |
| * `kDifLocked` if configuration is already locked, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_lock_data_region_properties( | |
| dif_flash_ctrl_state_t *handle, uint32_t region); | |
| /** | |
| * Lock info region memory properties configuration until the device is reset. | |
| * | |
| * This will prevent any further configuration of region properties until device | |
| * reset. Future calls to functions that set info region memory properties will | |
| * return `kDifLocked`. | |
| * | |
| * @param handle flash controller device to lock region configuration on. | |
| * @param region The region to lock. | |
| * @return `kDifBadArg` if `handle` is null, or if `region` is invalid, | |
| * `kDifLocked` if configuration is already locked, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_lock_info_region_properties( | |
| dif_flash_ctrl_state_t *handle, dif_flash_ctrl_info_region_t region); | |
| /** | |
| * Query the state of the region configuration lock for the given data `region` | |
| * entry's index. | |
| * | |
| * This function checks if memory region configuration is still enabled or if it | |
| * has been locked. Once locked, region configuration cannot be enabled again, | |
| * and all calls to region configuration functions will return `kDifLocked` | |
| * until the device is restarted. | |
| * | |
| * @param handle flash controller device to check the lock state for. | |
| * @param region The region in question. | |
| * @param locked_out Out-parameter, the current state of the region's | |
| * configuration lock. | |
| * @return `kDifBadArg` if `handle` or `locked_out` is null, or if `region` is | |
| * invalid, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_data_region_is_locked( | |
| const dif_flash_ctrl_state_t *handle, uint32_t region, bool *locked_out); | |
| /** | |
| * Query the state of the region configuration lock for the given info `region`. | |
| * | |
| * This function checks if memory region configuration is still enabled or if it | |
| * has been locked. Once locked, region configuration cannot be enabled again, | |
| * and all calls to region configuration functions will return `kDifLocked` | |
| * until the device is restarted. | |
| * | |
| * @param handle flash controller device to check the lock state for. | |
| * @param region The region in question. | |
| * @param locked_out Out-parameter, the current state of the region's | |
| * configuration lock. | |
| * @return `kDifBadArg` if `handle` or `locked_out` is null, or if `region` is | |
| * invalid, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_info_region_is_locked( | |
| const dif_flash_ctrl_state_t *handle, dif_flash_ctrl_info_region_t region, | |
| bool *locked_out); | |
| /** | |
| * Enable/disable erase operations for a particular flash bank. | |
| * | |
| * This may only be done if bank configuration is still enabled. | |
| * | |
| * @param handle flash controller device to operate on. | |
| * @param bank The bank to configure. | |
| * @param enable Enable/disable erase access for this bank. | |
| * @return `kDifBadArg` if `handle` is null or `bank` is invalid, `kDifLocked` | |
| * if bank configuration is locked, and `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_set_bank_erase_enablement( | |
| dif_flash_ctrl_state_t *handle, uint32_t bank, dif_toggle_t enable); | |
| /** | |
| * Query the erase permissions for a particular flash bank. | |
| * | |
| * @param handle flash controller device to query. | |
| * @param bank The bank to query. | |
| * @param enabled_out Out-parameter, the erase permissions for this bank. | |
| * @return `kDifBadArg` if `handle` or `enabled_out` is null and `kDifOk` | |
| * otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_bank_erase_enablement( | |
| const dif_flash_ctrl_state_t *handle, uint32_t bank, | |
| dif_toggle_t *enabled_out); | |
| /** | |
| * Lock bank configuration until the device is reset. | |
| * | |
| * This will prevent any further configuration of memory banks until device | |
| * reset. Future calls to bank configuration functions will return `kDifLocked`. | |
| * | |
| * @param handle flash controller device to lock region configuration on. | |
| * @return `kDifBadArg` if `handle` is null, `kDifLocked` if already locked, | |
| * and `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_lock_bank_configuration( | |
| dif_flash_ctrl_state_t *handle); | |
| /** | |
| * Query the state of the bank configuration lock. | |
| * | |
| * This function checks if memory bank configuration is still enabled or if it | |
| * has been locked. Once locked, bank configuration cannot be enabled again, and | |
| * all calls to bank configuration functions will return `kDifLocked` until the | |
| * device is restarted. | |
| * | |
| * @param handle flash controller device to check the lock state for. | |
| * @param locked_out Out-parameter, the current state of the bank configuration | |
| * lock. | |
| * @return `kDifBadArg` if `handle` or `locked_out` is null, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_bank_configuration_is_locked( | |
| const dif_flash_ctrl_state_t *handle, bool *locked_out); | |
| /** | |
| * Set the interrupt watermarks for the program FIFO. | |
| * | |
| * The value of `level` defines the level the program FIFO must drain to before | |
| * triggering a `prog_lvl` interrupt. | |
| * | |
| * This interrupts will only trigger if enabled through the interrupt API. | |
| * | |
| * @param handle flash controller to set FIFO level watermarks for. | |
| * @param prog Trigger an interrupt when the program FIFO drains to this level. | |
| * @return `kDifBadArg` if `handle` is null or if the value `level` is out of | |
| * range, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_set_prog_fifo_watermark( | |
| dif_flash_ctrl_state_t *handle, uint32_t level); | |
| /** | |
| * Set the interrupt watermarks for the read FIFO. | |
| * | |
| * The value of `level` defines the level the read FIFO must fill to before | |
| * triggering a `rd_lvl` interrupt. | |
| * | |
| * This interrupt will only trigger if enabled through the interrupt API. | |
| * | |
| * @param handle flash controller to set FIFO level watermarks for. | |
| * @param level Trigger an interrupt when the read FIFO fills to this level. | |
| * @return `kDifBadArg` if `flash_ctrl` is null or if the value of `prog` is out | |
| * of range, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_set_read_fifo_watermark( | |
| dif_flash_ctrl_state_t *handle, uint32_t level); | |
| /** | |
| * Get the interrupt watermarks for the program and read FIFOs. | |
| * | |
| * @param handle flash controller to get FIFO level watermarks from. | |
| * @param prog_out Out-parameter, the prog FIFO watermark level. If the prog | |
| * FIFO empties to this level, a corresponding status bit and possibly an | |
| * interrupt may be generated. May be null. | |
| * @param read_out Out-parameter, the read FIFO watermark level. If the read | |
| * FIFO fills to this level, a corresponding status bit and possibly an | |
| * interrupt may be generated. May be null. | |
| * @return `kDifBadArg` if `handle` is null, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_fifo_watermarks( | |
| const dif_flash_ctrl_state_t *handle, uint32_t *prog_out, | |
| uint32_t *read_out); | |
| /** | |
| * Resets both the program and read FIFOs. | |
| * | |
| * This is useful in the event of an unexpected error as a means of reseting | |
| * state. | |
| * | |
| * @param handle flash controller device to clear FIFOs on. | |
| * @return `kDifBadArg` if `handle` is null, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_reset_fifos(dif_flash_ctrl_state_t *handle); | |
| typedef struct dif_flash_ctrl_faults { | |
| /** The flash hardware interface encountered a memory permission error. */ | |
| bool memory_properties_error : 1; | |
| /** The flash hardware interface encountered a read data error. */ | |
| bool read_error : 1; | |
| /** The flash hardware interface encountered a program resolution error. */ | |
| bool prog_window_error : 1; | |
| /** The flash hardware interface encountered a program type error. */ | |
| bool prog_type_error : 1; | |
| /** A host transaction was granted with illegal properties. */ | |
| bool host_gnt_error : 1; | |
| /** The flash controller encountered a register integrity error. */ | |
| bool register_integrity_error : 1; | |
| /** The flash memory encountered a register integrity error. */ | |
| bool phy_integrity_error : 1; | |
| /** The lifecycle management interface encountered a fatal error. */ | |
| bool lifecycle_manager_error : 1; | |
| /** A shadow register encountered a storage fault. */ | |
| bool shadow_storage_error : 1; | |
| } dif_flash_ctrl_faults_t; | |
| /** | |
| * Gets the unrecoverable or hardware faults. | |
| * | |
| * @param handle flash controller device to query | |
| * @param faults_out Out parameter, a pointer to the location to write the fault | |
| * values. | |
| * @return `kDifBadArg` if `handle` or `fault_out` are null. `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_faults(const dif_flash_ctrl_state_t *handle, | |
| dif_flash_ctrl_faults_t *faults_out); | |
| typedef struct dif_flash_ctrl_ecc_errors { | |
| /** Count of the number of single-bit ECC errors. */ | |
| uint32_t single_bit_error_count; | |
| /** The last address that produced a single-bit ECC error. */ | |
| uint32_t last_error_address; | |
| } dif_flash_ctrl_ecc_errors_t; | |
| /** | |
| * Get the ECC error information for the specified flash `bank`. | |
| * | |
| * @param handle The flash controller device to query. | |
| * @param bank The desired bank to look up errors for. | |
| * @return `kDifBadArg` if `handle` or `errors_out` are null or if `bank` is | |
| * invalid. `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_ecc_errors( | |
| const dif_flash_ctrl_state_t *handle, uint32_t bank, | |
| dif_flash_ctrl_ecc_errors_t *errors_out); | |
| typedef struct dif_flash_ctrl_phy_status { | |
| /** Flash phy controller is initializing. */ | |
| bool phy_init_wip : 1; | |
| /** Normal programming is supported. */ | |
| bool prog_normal_available : 1; | |
| /** Repair programming is supported. */ | |
| bool prog_repair_available : 1; | |
| } dif_flash_ctrl_phy_status_t; | |
| /** | |
| * Query the status registers on the flash controller. | |
| * | |
| * This function checks the various status bits as described in | |
| * `dif_flash_ctrl_phy_status_t`. | |
| * | |
| * @param handle The flash controller device with the desired phy's status bit | |
| * to check. | |
| * @param status_out Out-parameter, the current status of the flash phy. | |
| * @return `kDifBadArg` if `handle` or `status_out` is null, `kDifOk` | |
| * otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_phy_status( | |
| const dif_flash_ctrl_state_t *handle, | |
| dif_flash_ctrl_phy_status_t *status_out); | |
| /** | |
| * Set the value of the scratch register. | |
| * | |
| * @param handle The flash controller device to operate on. | |
| * @param value The value to set the scratch register to. | |
| * @return `kDifBadArg` if `handle` is null, `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_set_scratch(dif_flash_ctrl_state_t *handle, | |
| uint32_t value); | |
| /** | |
| * Get the value of the scratch register. | |
| * | |
| * @param handle The flash controller device to query. | |
| * @param value_out Out parameter. The location to write the scratch register's | |
| * value to. | |
| * @return `kDifBadArg` if `handle` or `value_out` are null. `kDifOk` otherwise. | |
| */ | |
| OT_WARN_UNUSED_RESULT | |
| dif_result_t dif_flash_ctrl_get_scratch(const dif_flash_ctrl_state_t *handle, | |
| uint32_t *value_out); | |
| // TODO: PHY alerts, which are separate from the autogenerated alerts. | |
| #ifdef __cplusplus | |
| } // extern "C" | |
| #endif // __cplusplus | |
| #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_FLASH_CTRL_H_ |