Software APIs
sram_exec_test.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include <stdint.h>
6 
12 #include "sw/device/lib/testing/otp_ctrl_testutils.h"
13 #include "sw/device/lib/testing/pinmux_testutils.h"
14 #include "sw/device/lib/testing/test_framework/check.h"
15 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
16 #include "sw/device/lib/testing/test_framework/status.h"
17 
19 #include "otp_ctrl_regs.h" // Generated.
20 
21 OTTF_DEFINE_TEST_CONFIG();
22 
23 enum {
24  /**
25  * Device ID OTP offset and sizes.
26  */
27  kDeviceIdOffset =
28  OTP_CTRL_PARAM_DEVICE_ID_OFFSET - OTP_CTRL_PARAM_HW_CFG0_OFFSET,
29  kDeviceIdSizeInBytes = OTP_CTRL_PARAM_DEVICE_ID_SIZE,
30  kDeviceIdSizeIn32BitWords = kDeviceIdSizeInBytes / sizeof(uint32_t),
31 };
32 
33 static dif_uart_t uart0;
34 static dif_pinmux_t pinmux;
35 static dif_otp_ctrl_t otp;
36 
37 static const uint32_t kTestDeviceId[kDeviceIdSizeIn32BitWords] = {
38  0xdeadbeef, 0x12345678, 0xabcdef12, 0xcafebeef,
39  0x87654321, 0x21fedcba, 0xa1b2c3d4, 0xacdc4321,
40 };
41 
42 /**
43  * Initialize all DIF handles used in this program.
44  */
45 static status_t peripheral_handles_init(void) {
47  &pinmux));
48  TRY(dif_otp_ctrl_init(
51  &uart0));
52  return OK_STATUS();
53 }
54 
55 static status_t otp_ctrl_read_hw_cfg0_device_id(uint32_t *device_id) {
56  for (size_t i = kDeviceIdOffset; i < kDeviceIdSizeIn32BitWords; ++i) {
57  TRY(otp_ctrl_testutils_dai_read32(&otp, kDifOtpCtrlPartitionHwCfg0,
58  kDeviceIdOffset + (i * 4),
59  &device_id[i]));
60  LOG_INFO("Device ID (%d) = %08x", i, device_id[i]);
61  }
62  return OK_STATUS();
63 }
64 
65 /**
66  * Check the Device ID has not yet been provisioned in OTP.
67  *
68  * The HW_CFG0 partition should be unlocked and the device ID should be all
69  * zero.
70  */
71 static status_t check_device_id_is_unprovisioned(void) {
72  // Check HW_CFG0 is unlocked.
73  bool is_locked;
75  &is_locked));
76  CHECK(!is_locked);
77 
78  // Check Device ID is all zeros.
79  uint32_t expected_device_id[kDeviceIdSizeIn32BitWords] = {0};
80  uint32_t actual_device_id[kDeviceIdSizeIn32BitWords] = {0};
81  TRY(otp_ctrl_read_hw_cfg0_device_id(actual_device_id));
82  CHECK_ARRAYS_EQ(actual_device_id, expected_device_id,
83  kDeviceIdSizeIn32BitWords);
84  return OK_STATUS();
85 }
86 
87 /**
88  * Check the Device ID has been provisioned in OTP, but not locked.
89  */
90 static status_t check_device_id_is_provisioned(void) {
91  // Check HW_CFG0 is still unlocked.
92  bool is_locked;
94  &is_locked));
95  CHECK(!is_locked);
96 
97  // Check Device ID matches what is expected.
98  uint32_t actual_device_id[kDeviceIdSizeIn32BitWords] = {0};
99  TRY(otp_ctrl_read_hw_cfg0_device_id(actual_device_id));
100  CHECK_ARRAYS_EQ(actual_device_id, kTestDeviceId, kDeviceIdSizeIn32BitWords);
101  return OK_STATUS();
102 }
103 
104 /**
105  * Provisions a Device ID into the HW_CFG0 OTP partition.
106  */
107 static status_t provisioning_device_id_start(void) {
108  LOG_INFO("Provisioning Device ID in OTP.");
109  check_device_id_is_unprovisioned();
110  TRY(otp_ctrl_testutils_dai_write32(&otp, kDifOtpCtrlPartitionHwCfg0,
111  kDeviceIdOffset, kTestDeviceId,
112  kDeviceIdSizeIn32BitWords));
113  return OK_STATUS();
114 }
115 
116 /**
117  * Provisions a Device ID into the HW_CFG0 OTP partition.
118  */
119 static status_t provisioning_device_id_end(void) {
120  LOG_INFO("Provisioning complete.");
121  check_device_id_is_provisioned();
122  return OK_STATUS();
123 }
124 
125 bool test_main(void) {
126  CHECK_STATUS_OK(peripheral_handles_init());
127  // Initialize UART console.
128  pinmux_testutils_init(&pinmux);
129  CHECK(kUartBaudrate <= UINT32_MAX, "kUartBaudrate must fit in uint32_t");
130  CHECK(kClockFreqPeripheralHz <= UINT32_MAX,
131  "kClockFreqPeripheralHz must fit in uint32_t");
132  CHECK_DIF_OK(dif_uart_configure(
133  &uart0, (dif_uart_config_t){
134  .baudrate = (uint32_t)kUartBaudrate,
135  .clk_freq_hz = (uint32_t)kClockFreqPeripheralHz,
136  .parity_enable = kDifToggleDisabled,
137  .parity = kDifUartParityEven,
138  .tx_enable = kDifToggleEnabled,
139  .rx_enable = kDifToggleEnabled,
140  }));
141  base_uart_stdout(&uart0);
142 
143  CHECK_STATUS_OK(provisioning_device_id_start());
144  CHECK_STATUS_OK(provisioning_device_id_end());
145 
146  test_status_set(kTestStatusPassed);
147  return true;
148 }