| // 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_ |