Software APIs
sram_ctrl_memset_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 //! This test writes some data to SRAM, sets the `INIT` bit in the `ctrl` CSR,
6 //! then tries to read back that written data to ensure the SRAM was scrambled.
7 //!
8 //! The test currently only checks the retention SRAM so that it can be run out
9 //! of executable main SRAM on silicon.
10 
16 #include "sw/device/lib/testing/test_framework/check.h"
18 #include "sw/device/silicon_creator/lib/drivers/retention_sram.h"
19 
21 #include "sram_ctrl_regs.h" // Generated.
22 
23 // Define some amount of data we should leave in SRAM to check it gets wiped.
24 enum {
25  kSramCtrlTestDataSizeWords = 16,
26 };
27 
28 OTTF_DEFINE_TEST_CONFIG();
29 
30 static const uint32_t kStatusRegMask = kDifSramCtrlStatusBusIntegErr |
33 
34 static const uint32_t kRandomData[kSramCtrlTestDataSizeWords] = {
35  0x6b4abfae, 0x63bdb6e7, 0x87f99b1a, 0xa214dffe, 0xb12291f9, 0xd0cd1abe,
36  0x5c95e716, 0xe887aab1, 0x307f6ef9, 0x6f5c0464, 0x5882279d, 0x44c19574,
37  0x1bd20079, 0xf8250ead, 0x4bf362a4, 0xad41437d};
38 
39 /// Write `kRandomData` to an SRAM region.
40 static void write_data(mmio_region_t sram_region) {
41  for (int i = 0; i < kSramCtrlTestDataSizeWords; ++i) {
42  mmio_region_write32(sram_region, i * (ptrdiff_t)sizeof(uint32_t),
43  kRandomData[i]);
44  }
45 }
46 
47 /// Check that the contents of an SRAM region match `kRandomData`.
48 ///
49 /// The `matches` arg is used to specify whether you expect the SRAM region to
50 /// match `kRandomData`, or whether it should have been re-scrambled and no
51 /// longer match.
52 static void check_data_matches(mmio_region_t sram_region, bool matches) {
53  for (int i = 0; i < kSramCtrlTestDataSizeWords; ++i) {
54  uint32_t word =
55  mmio_region_read32(sram_region, i * (ptrdiff_t)sizeof(uint32_t));
56 
57  if (matches) {
58  CHECK(word == kRandomData[i],
59  "Data at index %u mismached, expected: %04x, got: %04x", i,
60  kRandomData[i], word);
61  } else if (word != kRandomData[i]) {
62  return;
63  }
64  }
65 
66  // If we got to this point and expected _not_ to match, fail.
67  CHECK(matches, "Data in SRAM was not rescrambled correctly");
68 }
69 
70 /// (Re-)initialize an SRAM region with pseudorandom data.
71 static void init_sram(dif_sram_ctrl_t sram_ctrl) {
72  uint32_t init = bitfield_bit32_write(0, SRAM_CTRL_CTRL_INIT_BIT, true);
73  mmio_region_write32(sram_ctrl.base_addr, SRAM_CTRL_CTRL_REG_OFFSET, init);
74 
75  // Spin until SRAM_CTRL is ready.
77  do {
78  CHECK_DIF_OK(dif_sram_ctrl_get_status(&sram_ctrl, &status));
79  } while ((status & kDifSramCtrlStatusInitDone) == 0x0);
80 
81  CHECK((status & kStatusRegMask) == 0x0,
82  "SRAM ret status error bits set, status = %08x.", status);
83 }
84 
85 bool test_main(void) {
86  // Initialize SRAM_CTRL hardware.
87  dif_sram_ctrl_t sram_ctrl_ret;
88  CHECK_DIF_OK(dif_sram_ctrl_init(
90  &sram_ctrl_ret));
91 
92  init_sram(sram_ctrl_ret);
93 
94  uintptr_t sram_ret_buffer_addr =
96  offsetof(retention_sram_t, owner);
97 
98  mmio_region_t sram_region_ret_addr =
99  mmio_region_from_addr(sram_ret_buffer_addr);
100 
101  // Write some data to retention SRAM and read it back to validate.
102  write_data(sram_region_ret_addr);
103  // Read back the data to validate it was written.
104  check_data_matches(sram_region_ret_addr, true);
105 
106  // Run initialization on the retention SRAM and check that the data is gone.
107  init_sram(sram_ctrl_ret);
108  check_data_matches(sram_region_ret_addr, false);
109 
110  return true;
111 }