| --- |
| title: "Reset Manager HWIP Technical Specification" |
| --- |
| |
| # Overview |
| |
| This document describes the functionality of the reset controller and its interaction with the rest of the OpenTitan system. |
| |
| ## Features |
| |
| * Stretch incoming POR. |
| * Cascaded system resets. |
| * Peripheral system reset requests. |
| * RISC-V non-debug-module reset support. |
| * Limited and selective software controlled module reset. |
| * Always-on reset information register. |
| * Always-on alert information register. |
| |
| # Theory of Operation |
| |
| The OpenTitan reset topology and reset controller block diagram are shown in the diagram below. |
| The reset controller is closely related to the [power controller]({{< relref "hw/ip/pwrmgr/doc" >}}), please refer to that spec for details on how reset controller inputs are controlled. |
| |
|  |
| |
| ## Reset Topology |
| |
| The topology can be summarized as follows: |
| |
| * There are two reset domains |
| * Test Domain - Driven by `TRSTn` |
| * Core Domain - Driven by internal [POR circuitry]() and an external pin reset connection. |
| * Test domain is comprised of the following components |
| * SOC TAP and related DFT circuits |
| * RISC-V TAP (part of the `rv_dm` module) |
| |
| The test domain does not have sub reset trees. |
| `TRSTn` is used directly by all components in the domain. |
| |
| The Core domain consists of all remaining logic and contains 4 sub reset trees, see table below. |
| |
| <table> |
| <tr> |
| <td> |
| <strong>Reset Tree</strong> |
| </td> |
| <td><strong>Description</strong> |
| </td> |
| </tr> |
| <tr> |
| <td><code>rst_por_n</code> |
| </td> |
| <td><code>POR reset tree.</code> |
| <p> |
| <code>This reset is driven by ast, stretched inside the reset manager and resets all core domain logic in the design. </code> |
| </td> |
| </tr> |
| <tr> |
| <td><code>rst_lc_n</code> |
| </td> |
| <td><code>Life Cycle reset tree.</code> |
| <p> |
| <code>This reset is derived from rst_por_n and resets all logic in the design except:</code><ul> |
| |
| <li><code>Power manager</code> |
| <li><code>Clock manager </code> |
| <li><code>Reset manager</code></li></ul> |
| |
| </td> |
| </tr> |
| <tr> |
| <td><code>rst_sys_n</code> |
| </td> |
| <td><code>System reset tree.</code> |
| <p> |
| <code>This reset is derived from rst_lc_n and resets all logic in the design except:</code><ul> |
| |
| <li><code>Power manager</code> |
| <li><code>Clock manager</code> |
| <li><code>Reset manager</code> |
| <li><code>OTP controller</code> |
| <li><code>Flash controller</code> |
| <li><code>Life cycle controller</code> |
| <li><code>Alert manager</code> |
| <li><code>Always-on timers</code></li></ul> |
| |
| </td> |
| </tr> |
| <tr> |
| <td><code>rst_{module}_n</code> |
| </td> |
| <td><code>Module specific reset.</code> |
| <p> |
| <code>This reset is derived from rst_sys_n and sets only the targeted module and nothing else.</code> |
| <p> |
| <code>For OpenTitan, the only current targets are spi_device and usb_device.</code> |
| </td> |
| </tr> |
| </table> |
| |
| The reset trees are cascaded upon one another in this order: |
| `rst_por_n` -> `rst_lc_n` -> `rst_sys_n` -> `rst_module_n` |
| This means when a particular reset asserts, all downstream resets also assert. |
| |
| The primary difference between `rst_lc_n` and `rst_sys_n` is that the former controls the reset state of all non-volatile related logic in the system, while the latter can be used to issue system resets for debug. |
| This separation is required because the non-volatile controllers (OTP / Lifecycle) are used to qualify DFT and debug functions of the design. |
| If these modules are reset along with the rest of the system, the TAP and related debug functions would also be reset. |
| By keeping these reset trees separate, we allow the state of the test domain functions to persist while functionally resetting the rest of the core domain. |
| |
| Additionally, modules such as [alert handler]({{< relref "hw/ip/alert_handler/doc" >}}) and [aon timers]() (which contain the watchdog function) are also kept on the `rst_lc_n` tree. |
| This ensures that an erroneously requested system reset through `rst_sys_n` cannot silence the alert mechanism or prevent the system from triggering a watchdog mechanism. |
| |
| The reset topology also contains additional properties: |
| * Selective processor HART resets, such as `hartreset` in `dmcontrol`, are not implemented, as it causes a security policy inconsistency with the remaining system. |
| * Specifically, these selective resets can cause the cascaded property shown above to not be obeyed. |
| * Modules do not implement local resets that wipe configuration registers, especially if there are configuration enable locks. |
| * Modules are allowed to implement local soft resets that clear datapaths; but these are examined on a case by case basis for possible security side channels. |
| * In a production system, the Test Reset Input (`TRSTn`) should be explicitly asserted through system integration. |
| * In a production system, `TRSTn` only needs to be released for RMA transitions and nothing else. |
| . |
| |
| ## Reset Manager |
| |
| The reset manager handles the reset of the core domain, and also holds relevant reset time information such as [reset reason]({{< regref "RESET_INFO" >}}) and [alert_reason]({{< regref "" >}}). |
| * Reset reason indicates why the system was reset. |
| * Alert reason indicates the recorded alert status prior to system reset. |
| * This is useful in case the reset was triggered by an alert escalation. |
| |
| There is another TBD feature for recording [last host state](https://docs.google.com/document/d/1KnmIt7vj8vkfqgAIcx6HJo8KH6zirFNF1TxlL5K6Aso/edit?usp=sharing). |
| * Last host state indicates approximately what the host was doing prior to system reset. |
| * This is useful in case the reset was triggered by a watchdog where the host hung on a particular bus transaction. |
| |
| Additionally, the reset manager, along with the power manager, accepts requests from the system and asserts resets for the appropriate clock trees. |
| These requests primarily come from the following sources: |
| * Peripherals capable of reset requests: such as [rbox]() and [always on timers ](). |
| * Debug modules such as `rv_dm`. |
| * Power manager request for low power entry and exit. |
| |
| ### Shadow Resets |
| |
| OpenTitan supports the concept of shadow registers. |
| These are registers stored in two-or-more constantly checking copies to ensure the values were not maliciously or accidentally disturbed. |
| For these components, the reset manager outputs a shadow reset dedicated to resetting only the shadow storage. |
| This reset separation ensures that a targetted attack on the reset line cannot easily defeat shadow registers. |
| |
| Shadow resets have not been implemented yet. |
| |
| ## Hardware Interfaces |
| |
| {{< hwcfg "hw/top_earlgrey/ip/rstmgr/data/autogen/rstmgr.hjson" >}} |
| |
| ### Signals |
| |
| Signal | Direction | Description |
| ------------------------|-----------|--------------- |
| `ast_i.aon_pok` | `input` | Input from `ast`. This signal is the root reset of the design and is used to generate `rst_por_n`. |
| `cpu_i.rst_cpu_n` | `input` | CPU reset indication. This informs the reset manager that the processor has reset. |
| `cpu_i.ndmreset_req` | `input` | Non-debug-module reset request from `rv_dm`. |
| `pwr_i.rst_lc_req` | `input` | Power manager request to assert the `rst_lc_n` tree. |
| `pwr_i.rst_sys_req` | `input` | Power manager request to assert the `rst_sys_n` tree. |
| `pwr_i.reset_cause` | `input` | Power manager indication for why it requested reset, the cause can be low power entry or peripheral issued request. |
| `pwr_i.rstreqs` | `input` | Peripheral reset requests. |
| `pwr_o.rst_lc_src_n` | `output` | Current state of `rst_lc_n` tree. |
| `pwr_o.rst_sys_src_n` | `output` | Current state of `rst_sys_n` tree. |
| `resets_ast_o` | `output` | Resets used by `ast`. |
| `resets_o` | `output` | Resets used by the rest of the core domain. |
| |
| ## Design Details |
| |
| The reset manager generates the resets required by the system by synchronizing reset tree components to appropriate output clocks. |
| As a result, a particular reset tree (for example `rst_lc_n`) may have multiple outputs depending on the clock domains of its consumers. |
| |
| Each reset tree is discussed in detail below. |
| |
| |
| ## POR Reset Tree |
| |
| The POR reset tree, `rst_por_n`, is the root reset of the entire device. |
| If this reset ever asserts, everything in the design is reset. |
| |
| The `ast` input `aon_pok` is used as the root reset indication. |
| It is filtered and stretched to cover any slow voltage ramp scenarios. |
| The stretch parameters are design time configurations. |
| |
| * The filter acts as a synchronizer and is by default 3 stages. |
| * The count by default is 32. |
| * The counter increments only when the last two stages of the filter are both '1' |
| * If any stage at any point becomes '0', the reset counter returns to 0 and downstream logic is driven to reset again. |
| * Both functions are expected to operate on slow, always available KHz clocks. |
| |
| |
| ## Life Cycle Reset Tree |
| |
| Life cycle reset, `rst_lc_n` asserts under the following conditions: |
| * Whenever `rst_por_n` asserts. |
| * Whenever a peripheral reset request (always on timer watchdog, rbox reset request, alert handler escalation) is received. |
| |
| The `rst_lc_n` tree contains both always-on and non-always-on versions. |
| How many non-always-on versions is dependent on how many power domains are supported by the system. |
| |
| ## System Reset Tree |
| |
| System reset, `rst_sys_n` asserts under the following conditions: |
| * Whenever `rst_lc_n` asserts. |
| * Whenever `ndmreset_req` asserts. |
| |
| The `rst_sys_n` tree contains both always-on and non-always-on versions. |
| How many non-always-on versions is dependent on how many power domains are supported by the system. |
| |
| ## Output Leaf Resets |
| |
| The reset trees discussed above are not directly output to the system for consumption. |
| Instead, the output leaf resets are synchronized versions of the various root resets. |
| How many leaf resets there are and to which clock is decided by the system and templated through the reset manager module. |
| |
| Assuming a leaf output has N power domains and M clock domains, it potentially means one reset tree may output NxM outputs to satisfy all the reset scenario combinations. |
| |
| ## Power Domains and Reset Trees |
| |
| It is alluded above that reset trees may contain both always-on and non-always-on versions. |
| This distinction is required to support power manager's various low power states. |
| When a power domain goes offline, all of its components must assert, regardless of the reset tree to which it belongs. |
| |
| For example, assume a system with two power domains - `Domain A` is always-on, and `Domain B` is non-always-on. |
| When `Domain B` is powered off, all of `Domain B`'s resets, from `rst_lc_n`, `rst_sys_n` to `rst_module_n` are asserted. |
| However, the corresponding resets for `Domain A` are left untouched because it has not been powered off. |
| |
| ## Software Controlled Resets |
| |
| Certain leaf resets can be directly controlled by software. |
| Due to security considerations, most leaf resets cannot be controlled, only a few blocks are given exceptions. |
| The only blocks currently allowed to software reset are `usbdev` and `spidev`. Future potential candidates are `i2cdev`, `i2chost` and `spihost`. |
| |
| The criteria for selecting which block is software reset controllable is meant to be overly restrictive. |
| Unless there is a clear need, the default option is to not provide reset control. |
| |
| In general, the following rules apply: |
| * If a module has configuration register lockdown, it cannot be software resettable. |
| * If a module operates on secret data (keys), it cannot be software resettable. |
| * Or a software reset should render the secret data unusable until some initialization routine is run to reduce the Hamming leakage of secret data. |
| * If a module can alter the software's perception of time or general control flow (timer or interrupt aggregator), it cannot be software resettable. |
| * If a module contains sensor functions for security, it cannot be software resettable. |
| * If a module controls life cycle or related function, it cannot be software resettable. |
| |
| |
| ## Shadow Resets |
| |
| Leaf resets also can be design time configured to output [shadow resets](https://docs.google.com/document/d/1Oiv1ewvxhhk6c8aY2f2bV6tTZMI-zUlLeRZJMmXMBmo/edit?usp=sharing). |
| The details of this function are TBD. |
| |
| ## Reset Information |
| |
| The reset information register is a reflection of the reset state from the perspective of the system. |
| In OpenTitan, since there is only 1 host, it is thus from the perspective of the processor. |
| This also suggests that if the design had multiple processors, there would need to be multiple such registers. |
| |
| If a reset does not cause the processor to reset, there is no reason for the reset information to change (this is also why there is a strong security link between the reset of the processor and the rest of the system). |
| The following are the currently defined reset reasons and their meaning: |
| |
| Reset Cause | Description |
| ------------------------|--------------- |
| `POR` | Cold boot, the system was reset through POR circuitry. |
| `LOW_POWER_EXIT` | Warm boot, the system was reset through low power exit. |
| `NDM RESET` | Warm boot, the system was reset through `rv_dm` non-debug-module request. |
| `HW_REQ` | Warm boot, the system was reset through peripheral requests. There may be multiple such requests. |
| |
| |
| The reset info register is write 1 clear. |
| It is software responsibility to clear old reset reasons; the reset manager simply records based on the rules below. |
| |
| Excluding power on reset, which is always recorded when the device POR circuitry is triggered, the other resets are recorded when authorized by the reset manager. |
| Reset manager authorization in turn is based on reset category as indicated by the power manager. |
| The power manager observes 3 categories of reset states that are mutually exclusive. |
| * No resets are triggered through the power manager. |
| * Resets triggered by low power entry. |
| * Resets triggered by a peripheral request. |
| |
| Whenever the power manager begins one of the latter two sequences, it sends a hint to the reset manager so that the reset manager can decide which reason to record when the processor reset is observed. |
| Whenever the power manager is NOT in one of the two latter states, non-debug-module resets are allowed and directly handled and recorded by the reset manager. |
| |
| Since a reset could be motivated by multiple reasons (a security escalation during low power transition for example), the reset information registers constantly record all reset causes in which it is allowed. |
| The only case where this is not done is `POR`, where active recording is silenced until the first processor reset release. |
| |
| Despite 3 reset causes all labeled as warm boot, their effects on the system are not identical. |
| |
| * When the reset cause is `LOW_POWER_EXIT`, it means only the non-always-on domains have been reset |
| * Always-on domains retain their pre-low power values. |
| * When the reset cause is `NDM_RESET`, it means only the `rst_sys_n` tree has asserted for all power domains. |
| * When the reset cause is `HW_REQ`, it means everything other than power / clock / reset managers have reset. |
| |
| This behavioral difference may be important to software, as it implies the configuration of the system may need to be different. |
| |
| ## Alert Information |
| |
| The alert information register contains the value of the alert crash dump prior to a triggered reset. |
| Since this information differs in length between system implementation, the alert information register only displays 32-bits at a time. |
| |
| The [alert_info_attr]({{< regref "ALERT_INFO_ATTR" >}}) register indicates how many 32-bit data segments must be read. |
| Software then simply needs to pick the segment it wishes to read and then read out the [alert_info]({{< regref "ALERT_INFO_ATTR" >}}) register. |
| |
| # Programmers Guide |
| |
| ## Alert Information Gathering and Reading |
| |
| To enable alert crash dump capture, set {{< regref "ALERT_INFO_CTRL.EN" >}} to 1. |
| Once the system has reset, check {{< regref "ALERT_INFO_ATTR.CNT_AVAIL" >}} for how many reads need to be done. |
| Set {{< regref "ALERT_INFO_CTRL.INDEX" >}} to the desired segment, and then read the output from {{< regref "ALERT_INFO" >}}. |
| |
| ## Register Table |
| |
| {{< registers "hw/top_earlgrey/ip/rstmgr/data/autogen/rstmgr.hjson" >}} |