Software APIs
rom_e2e_ret_ram_init_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 <assert.h>
6 
10 #include "sw/device/silicon_creator/lib/drivers/retention_sram.h"
11 #include "sw/device/silicon_creator/lib/drivers/rstmgr.h"
12 
14 
15 OTTF_DEFINE_TEST_CONFIG();
16 
17 /**
18  * Repeated pattern to fill the Retention RAM with
19  */
20 enum {
21  kPattern = 0xab,
22 };
23 
24 rom_error_t retention_ram_init_test(void) {
25  uint64_t pattern64;
26  memset(&pattern64, kPattern, sizeof(pattern64));
27 
28  retention_sram_t *ret = retention_sram_get();
29  uint32_t reset_reasons = ret->creator.reset_reasons;
30 
31  // Verify that reset_reasons reports POR.
32  if (bitfield_bit32_read(reset_reasons, kRstmgrReasonPowerOn)) {
33  // This branch runs after the POR that occurs after initializing the
34  // testing environment
35  LOG_INFO("Writing known pattern");
36  memset(ret, kPattern, sizeof(retention_sram_t));
37 
38  LOG_INFO("Requesting SW reset");
39  rstmgr_reset();
40  } else if (bitfield_bit32_read(reset_reasons, kRstmgrReasonSoftwareRequest)) {
41  // This branch runs after the SW-requested reset
42  LOG_INFO("Ensuring all sections have changed");
43 
44  static_assert(sizeof(retention_sram_t) % sizeof(uint64_t) == 0,
45  "This test expects the retention SRAM size to be a multiple "
46  "of uint64_t");
47  uint32_t matches = 0;
48  for (size_t i = 0; i < sizeof(retention_sram_t); i += sizeof(uint64_t)) {
49  if (read_64((char *)ret + i) == pattern64) {
50  LOG_ERROR("Retention SRAM unchanged at offset %u.", i);
51  matches += 1;
52  }
53  }
54 
55  // It is possible, albeit extremely unlikely, that scrambling executed
56  // correctly but one or more double words still match. If this occurs in
57  // practice it may be necessary to increase the number of matches that are
58  // tolerated.
59  return matches == 0 ? kErrorOk : kErrorUnknown;
60  }
61  LOG_ERROR("Did not find a reset reason of POR or SW request");
62  return kErrorUnknown;
63 }
64 
65 bool test_main(void) {
66  status_t result = OK_STATUS();
67  EXECUTE_TEST(result, retention_ram_init_test);
68  return status_ok(result);
69 }