Software APIs
Macros | Typedefs | Enumerations | Functions
ottf_main.h File Reference

(30d7e787c7)

Entrypoint definitions for on-device tests. More...

#include <stdbool.h>
#include "sw/device/lib/base/status.h"
#include "sw/device/lib/dif/dif_uart.h"
#include "sw/device/lib/runtime/ibex.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/test_framework/FreeRTOSConfig.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_test_config.h"

Go to the source code of this file.

Macros

#define EXECUTE_TEST(result_, test_function_, ...)
 Execute a test function, profile the execution and log the test result. More...
 
#define OTTF_OVERRIDE_STATUS_REPORT_LIST(list_size)
 Override the default status report list size. More...
 

Typedefs

typedef void(* ottf_task_t) (void *)
 Forward declaration of the function pointer prototype to which FreeRTOS (and transitively OTTF) task functions must conform. More...
 

Enumerations

enum  { kOttfFreeRtosMinStackSize = configMINIMAL_STACK_SIZE }
 OTTF Constants.
 

Functions

bool test_main (void)
 Entry point for a SW on-device (or chip-level) test. More...
 
bool manufacturer_pre_test_hook (void)
 TODO: add description.
 
bool manufacturer_post_test_hook (void)
 TODO: add description.
 
bool ottf_task_create (ottf_task_t task_function, const char *task_name, configSTACK_DEPTH_TYPE task_stack_depth, uint32_t task_priority)
 Create a FreeRTOS task. More...
 
void ottf_task_yield (void)
 Yield control flow to another FreeRTOS task of equal or higher priority. More...
 
void ottf_task_delete_self (void)
 Delete the calling FreeRTOS task. More...
 
char * ottf_task_get_self_name (void)
 Returns the name of the currently executing FreeRTOS task. More...
 

Detailed Description

Entrypoint definitions for on-device tests.

Definition in file ottf_main.h.

Macro Definition Documentation

◆ EXECUTE_TEST

#define EXECUTE_TEST (   result_,
  test_function_,
  ... 
)
Value:
do { \
LOG_INFO("Starting test " #test_function_ "..."); \
uint64_t t_start_ = ibex_mcycle_read(); \
status_t local_status = INTO_STATUS(test_function_(__VA_ARGS__)); \
uint64_t cycles_ = ibex_mcycle_read() - t_start_; \
CHECK(kClockFreqCpuHz <= UINT32_MAX, ""); \
uint32_t clock_mhz = (uint32_t)kClockFreqCpuHz / 1000000; \
if (status_ok(local_status)) { \
if (cycles_ <= UINT32_MAX) { \
uint32_t micros = (uint32_t)cycles_ / clock_mhz; \
LOG_INFO("Successfully finished test " #test_function_ \
" in %u cycles or %u us @ %u MHz.", \
(uint32_t)cycles_, micros, clock_mhz); \
} else { \
uint32_t cycles_lower_ = (uint32_t)(cycles_ & UINT32_MAX); \
uint32_t cycles_upper_ = (uint32_t)(cycles_ >> 32); \
LOG_INFO("Successfully finished test " #test_function_ \
" in 0x%08x%08x cycles.", \
cycles_upper_, cycles_lower_); \
} \
} else { \
result_ = local_status; \
LOG_ERROR("Finished test " #test_function_ ": %r.", local_status); \
} \
} while (0)

Execute a test function, profile the execution and log the test result.

Update the result value if there is a failure code.

Definition at line 113 of file ottf_main.h.

◆ OTTF_OVERRIDE_STATUS_REPORT_LIST

#define OTTF_OVERRIDE_STATUS_REPORT_LIST (   list_size)
Value:
const size_t kStatusReportListSize = list_size; \
status_t status_report_list[list_size];

Override the default status report list size.

This list is used to store error statuses in case of failed TRY() and are reported when the test fails. This must be used at the global scope.

Definition at line 145 of file ottf_main.h.

Typedef Documentation

◆ ottf_task_t

typedef void(* ottf_task_t) (void *)

Forward declaration of the function pointer prototype to which FreeRTOS (and transitively OTTF) task functions must conform.

We use a forward declaration here to hide FreeRTOS internals from OTTF users.

This declaration should match the TaskFunction_t type declaration in <freertos kernel>/include/projdefs.h.

Definition at line 60 of file ottf_main.h.

Function Documentation

◆ ottf_task_create()

bool ottf_task_create ( ottf_task_t  task_function,
const char *  task_name,
configSTACK_DEPTH_TYPE  task_stack_depth,
uint32_t  task_priority 
)

Create a FreeRTOS task.

Tasks should be implemented as functions that never return. However, they may delete themselves using the ottf_task_delete_self() function defined below.

Additionally, tasks are always run at a priority level higher than that of the FreeRTOS idle task's (which is a priority of 0).

See the FreeRTOS xTaskCreate documentation for more details: https://www.freertos.org/a00125.html.

Parameters
task_functionThe name of the function that implements the task.
task_nameA task identification string used to help debugging.
task_stack_depthThe amount of memory to reserve for the task's stack.
task_priorityThe numerical priority of the task.
Returns
A boolean encoding the success of the operation.

◆ ottf_task_delete_self()

void ottf_task_delete_self ( void  )

Delete the calling FreeRTOS task.

See the FreeRTOS vTaskDelete documentation for more details: https://www.freertos.org/a00126.html.

Definition at line 77 of file ottf_main.c.

◆ ottf_task_get_self_name()

char* ottf_task_get_self_name ( void  )

Returns the name of the currently executing FreeRTOS task.

See the FreeRTOS pcTaskGetName documentation for more details: https://www.freertos.org/a00021.html#pcTaskGetName.

Definition at line 79 of file ottf_main.c.

◆ ottf_task_yield()

void ottf_task_yield ( void  )

Yield control flow to another FreeRTOS task of equal or higher priority.

Note, if there are no other tasks of equal or higher priority, then the calling task will continue executing. See the FreeRTOS taskYIELD documentation for more details: https://www.freertos.org/a00020.html#taskYIELD.

Definition at line 75 of file ottf_main.c.

◆ test_main()

bool test_main ( void  )

Entry point for a SW on-device (or chip-level) test.

This function should be defined externally in a standalone SW test, linked together with this library. This library provides a main() function that does test harness setup, initializes FreeRTOS, and starts a FreeRTOS task that executes test_main().

Returns
success or failure of the test as boolean.

Entry point for a SW on-device (or chip-level) test.

Initializes peripherals and processes simple serial packets received over UART.

  • Verify the first escalation results in NMI interrupt serviced by the CPU.
  • Verify the second results in device being put in escalate state, via the LC JTAG TAP.
  • Verify the third results in chip reset.
  • Ensure that all escalation handshakes complete without errors.

The first escalation is checked via the entry of the NMI handler and polling by dv. The second escalation is directly checked by dv. The third escalation is checked via reset reason.

Entry point for a SW on-device (or chip-level) test.

Prints a message and displays a spinning bar.

Entry point for a SW on-device (or chip-level) test.

Delete those that do not need to be overridden.

See sw/device/lib/testing/test_framework/ottf_isrs.c for implementation details of the default OTTF exception handlers.

Note, the ottf_machine_ecall_handler cannot be overridden when using the full OTTF, as it used to implement FreeRTOS context switching. See its implementation in sw/device/lib/testing/test_framework/ottf_main.c. Override any of the default OTTF ISRs (by uncommenting and implementing them) if this test requires non-default ISR logic. Delete those that do not need to be overridden.

See sw/device/lib/testing/test_framework/ottf_isrs.c for implementation details of the default OTTF ISRs. Save data that will need to persist across resets by placing it in the ".non_volatile_scratch" section. OpenTitan's flash is mapped to its address space for reads. Thus, these variables can be read as usual. Write to this region with the flash controller DIFs, obeying flash constraints. Since the non-volatile scratch region is NOLOAD and bootstrap erases all flash, initial values of variables in this section are always 0xff, regardless of any initialization in the source code. In order to avoid confusion, don't initialize or assign to these values. If needed, they can be initialized at runtime via flash controller DIFs.

Entry point for a SW on-device (or chip-level) test.

Performs a loopback test by writing various values and reading them back. NOTE: This test can currently run only on FPGA and DV.

Entry point for a SW on-device (or chip-level) test.

Entry point for a SW on-device (or chip-level) test.

Control flow passed from sram_start.

Entry point for a SW on-device (or chip-level) test.

  • Trigger a watchdog bark to generate a NMI.
  • Check rv_core_ibex's NMI interrupt register and clear the interrupt.
  • Repeat the previous steps with alert handler.

Entry point for a SW on-device (or chip-level) test.

  • Configure the timer to generate a tick of T microseconds long.
  • Enable the timer.
  • Start a busy loop of 5 milliseconds based on the mcycleh CSR.
  • Read the number of ticks n.
  • Verify that n * T ~= 5 milliseconds within 3% of tolerance.
  • Repeat for T in: [1, 5, 25, 100, 125]

Entry point for a SW on-device (or chip-level) test.

  • Initialize the OTP with HW_CFG.OTP_CTRL_PARAM_EN_CSRNG_SW_APP_READ_OFFSET fuse bit set to enabled in the uvm_test_seq.
  • Issue an instantiate command to request entropy.
  • Verify that SW can read the internal states.
  • Reset the chip and repeat the steps above, but this time, with HW_CFG.OTP_CTRL_PARAM_EN_CSRNG_SW_APP_READ_OFFSET fuse bit set to 0.
  • Verify that the SW reads back all zeros when reading the internal states.

Entry point for a SW on-device (or chip-level) test.

1). Preload OTP RAW image file. 2). DV sequence drives JTAG interface to write RawUnlockToken and transfers LC state to TestUnlock0 state. 3). In TestUnlock0 state, SW programs OTP secret0 partition to write ExitToken and TestUnlockToken. Also programs OTP secret2 partition to write RmaToken. 4). DV sequence issues reset to lock OTP secret0 partition. 5). SW requests a LC state transfer to ProdEnd state with the correct TestLockToken. 6). DV sequence issues reset and SW check if LC transfers to the destination state. 7). If the destination state can be transferred to RMA state, will issue another LC state transfer to RMA state.

Note that the destination state is a runtime input from the testbench.

Entry point for a SW on-device (or chip-level) test.

1). Preload OTP RAW image file. 2). DV sequence drives JTAG interface to write RawUnlockToken and transfers LC state to TestUnlock0 state. 3). In TestUnlock0 state, SW programs OTP secret0 partition to write ExitToken and TestUnlockToken. 4). DV sequence issues reset to lock OTP secret0 partition. 5). SW requests a LC state transfer to TestLock0 state with all zero tokens. 6). DV sequence issues reset and SW check if LC transfers to the destination state. 7). DV sequence requests a LC state transfer to TestUnlock1 state with test unlock tokens. Repeat the above transition until reaches the last TestUnlock state.

Entry point for a SW on-device (or chip-level) test.

Since it uses the key manager to perform some of the testing, this test also checks the impact of lc_keymgr_en on the key manager.

The SECRETT2 partition should only be readable/writable by SW in PROD/RMA/DEV. Once it is locked, the partition is not accessible by SW anymore, but becomes accessible to HW (key manager).

The test can be run in different life cycle states and figure out what to check based on the state exposed in the life cycle controller.

PROD/DEV/RMA: 1) Provision non-constant creator/owner secrets to flash 2) Program SECRET2 partition and read it back 3) Check that the key manager advance errors out due to all-zero root key 4) Reset the chip 5) Check that the SECRET2 partition can still be read 6) Check that the key manager advance errors out due to all-zero root key 7) Lock the SECRET2 partition 8) Reset the chip 9) Check that the SECRET2 partition is not accessible anymore 10) Check that the key manager can generate a SW key without errors

All other life cycle states: 1) Check that key manager cannot be initialized because it is disabled 2) Check the SECRET2 partition is not accessible

Entry point for a SW on-device (or chip-level) test.

The main sequence is driven by JTAG agent in SV sequence chip_sw_otp_ctrl_vendor_test_csr_access_vseq.sv.

Entry point for a SW on-device (or chip-level) test.

The expectation is that no error or fault will be triggered. The ecc eror is injected in the associated SV sequence.

Entry point for a SW on-device (or chip-level) test.

When chip is in one of the lifecycle states where debug functions are enabled, execution from SRAM is enabled if the EN_SRAM_IFETCH (OTP) is disabled. When EN_SRAM_IFETCH (OTP) is enabled, EXEC CSR determines whether the execution from SRAM is enabled.

Definition at line 27 of file sram_program.c.