Software APIs
boot_svc_min_sec_ver_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 "sw/device/lib/base/status.h"
7 #include "sw/device/lib/testing/test_framework/check.h"
9 #include "sw/device/silicon_creator/lib/boot_svc/boot_svc_min_bl0_sec_ver.h"
10 #include "sw/device/silicon_creator/lib/drivers/retention_sram.h"
11 #include "sw/device/silicon_creator/lib/drivers/rstmgr.h"
12 #include "sw/device/silicon_creator/rom_ext/e2e/boot_svc/boot_svc_test_lib.h"
13 
14 OTTF_DEFINE_TEST_CONFIG();
15 
16 #define MANIFEST_SEC_VER 4
17 
18 static status_t initialize(retention_sram_t *retram, boot_svc_retram_t *state) {
19  boot_svc_msg_t msg = {0};
20  boot_svc_min_bl0_sec_ver_req_init(2, &msg.min_bl0_sec_ver_req);
21  retram->creator.boot_svc_msg = msg;
22  state->state = kBootSvcTestStateMinSecAdvance;
23  rstmgr_reset();
24  return INTERNAL();
25 }
26 
27 static status_t advance(retention_sram_t *retram, boot_svc_retram_t *state) {
28  boot_svc_msg_t msg = retram->creator.boot_svc_msg;
29  TRY(boot_svc_header_check(&msg.header));
30  TRY_CHECK(msg.header.type == kBootSvcMinBl0SecVerResType);
31  LOG_INFO("Response: status=%08x min_bl0_sec_ver=%d",
32  msg.min_bl0_sec_ver_res.status,
33  msg.min_bl0_sec_ver_res.min_bl0_sec_ver);
34 
35  TRY_CHECK(msg.min_bl0_sec_ver_res.status == kErrorOk);
36 
37  if (msg.min_bl0_sec_ver_res.min_bl0_sec_ver < MANIFEST_SEC_VER) {
38  // Advance by one and check again for success
39  boot_svc_min_bl0_sec_ver_req_init(
40  msg.min_bl0_sec_ver_res.min_bl0_sec_ver + 1, &msg.min_bl0_sec_ver_req);
41  retram->creator.boot_svc_msg = msg;
42  rstmgr_reset();
43  }
44 
45  if (msg.min_bl0_sec_ver_res.min_bl0_sec_ver == MANIFEST_SEC_VER) {
46  // Advance by one and check for failure
47  state->state = kBootSvcTestStateMinSecTooFar;
48  boot_svc_min_bl0_sec_ver_req_init(
49  msg.min_bl0_sec_ver_res.min_bl0_sec_ver + 1, &msg.min_bl0_sec_ver_req);
50  retram->creator.boot_svc_msg = msg;
51  rstmgr_reset();
52  }
53  return INTERNAL();
54 }
55 
56 static status_t too_far(retention_sram_t *retram, boot_svc_retram_t *state) {
57  boot_svc_msg_t msg = retram->creator.boot_svc_msg;
58  TRY(boot_svc_header_check(&msg.header));
59  TRY_CHECK(msg.header.type == kBootSvcMinBl0SecVerResType);
60  LOG_INFO("Response: status=%08x min_bl0_sec_ver=%d",
61  msg.min_bl0_sec_ver_res.status,
62  msg.min_bl0_sec_ver_res.min_bl0_sec_ver);
63  TRY_CHECK(msg.min_bl0_sec_ver_res.status == kErrorBootSvcBadSecVer);
64  TRY_CHECK(msg.min_bl0_sec_ver_res.min_bl0_sec_ver == MANIFEST_SEC_VER);
65 
66  // Try to go back
67  state->state = kBootSvcTestStateMinSecGoBack;
68  boot_svc_min_bl0_sec_ver_req_init(msg.min_bl0_sec_ver_res.min_bl0_sec_ver - 1,
69  &msg.min_bl0_sec_ver_req);
70  retram->creator.boot_svc_msg = msg;
71  rstmgr_reset();
72  return INTERNAL();
73 }
74 
75 static status_t go_back(retention_sram_t *retram, boot_svc_retram_t *state) {
76  boot_svc_msg_t msg = retram->creator.boot_svc_msg;
77  TRY(boot_svc_header_check(&msg.header));
78  TRY_CHECK(msg.header.type == kBootSvcMinBl0SecVerResType);
79  LOG_INFO("Response: status=%08x min_bl0_sec_ver=%d",
80  msg.min_bl0_sec_ver_res.status,
81  msg.min_bl0_sec_ver_res.min_bl0_sec_ver);
82  TRY_CHECK(msg.min_bl0_sec_ver_res.status == kErrorBootSvcBadSecVer);
83  TRY_CHECK(msg.min_bl0_sec_ver_res.min_bl0_sec_ver == MANIFEST_SEC_VER);
84 
85  // End of test sequence.
86  state->state = kBootSvcTestStateFinal;
87  return OK_STATUS();
88 }
89 
90 static status_t min_sec_ver_test(void) {
91  retention_sram_t *retram = retention_sram_get();
92  TRY(boot_svc_test_init(retram, kBootSvcTestBl0MinSecVer));
93  boot_svc_retram_t *state = (boot_svc_retram_t *)&retram->owner;
94 
95  for (;;) {
96  LOG_INFO("Test state = %d", state->state);
97  switch (state->state) {
98  case kBootSvcTestStateInit:
99  TRY(initialize(retram, state));
100  break;
101  case kBootSvcTestStateMinSecAdvance:
102  TRY(advance(retram, state));
103  break;
104  case kBootSvcTestStateMinSecTooFar:
105  TRY(too_far(retram, state));
106  break;
107  case kBootSvcTestStateMinSecGoBack:
108  TRY(go_back(retram, state));
109  break;
110  case kBootSvcTestStateFinal:
111  LOG_INFO("FinalBootLog: %d:%s", state->boots, state->partition);
112  return OK_STATUS();
113  default:
114  return UNKNOWN();
115  }
116  }
117 }
118 
119 bool test_main(void) {
120  status_t sts = min_sec_ver_test();
121  if (status_err(sts)) {
122  LOG_ERROR("min_sec_ver_test: %r", sts);
123  }
124  return status_ok(sts);
125 }