blob: 74ade0af0083b28a6b4e1de68929f0173c71d5df [file] [log] [blame]
// 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_