Software APIs
boot_svc_bad_next_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"
8 #include "sw/device/silicon_creator/lib/boot_svc/boot_svc_msg.h"
9 #include "sw/device/silicon_creator/lib/boot_svc/boot_svc_next_boot_bl0_slot.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 static status_t initialize(retention_sram_t *retram, boot_svc_retram_t *state) {
17  boot_svc_msg_t msg = {0};
18  // Intentionally request a bad boot slot of 'ZZZZ'.
19  boot_svc_next_boot_bl0_slot_req_init(
20  /*primary_slot=*/kBootSlotUnspecified,
21  /*next_slot=*/0x5a5a5a5a, &msg.next_boot_bl0_slot_req);
22  retram->creator.boot_svc_msg = msg;
23  state->state = kBootSvcTestStateNextSideB;
24  rstmgr_reset();
25  return INTERNAL();
26 }
27 
28 static status_t check_side_b(retention_sram_t *retram,
29  boot_svc_retram_t *state) {
30  boot_svc_msg_t msg = retram->creator.boot_svc_msg;
31  TRY(boot_svc_header_check(&msg.header));
32  TRY_CHECK(msg.header.type == kBootSvcNextBl0SlotResType);
33  TRY_CHECK(msg.next_boot_bl0_slot_res.status == kErrorBootSvcBadSlot);
34  TRY_CHECK(state->current_side == 'A');
35  state->state = kBootSvcTestStateReturnSideA;
36  rstmgr_reset();
37  return INTERNAL();
38 }
39 
40 static status_t check_return_side_a(retention_sram_t *retram,
41  boot_svc_retram_t *state) {
42  TRY_CHECK(state->current_side == 'A');
43  state->state = kBootSvcTestStateFinal;
44  return OK_STATUS();
45 }
46 
47 static status_t bad_next_slot_test(void) {
48  retention_sram_t *retram = retention_sram_get();
49  TRY(boot_svc_test_init(retram, kBootSvcTestEmpty));
50  boot_svc_retram_t *state = (boot_svc_retram_t *)&retram->owner;
51 
52  for (;;) {
53  LOG_INFO("Test state = %d", state->state);
54  switch (state->state) {
55  case kBootSvcTestStateInit:
56  TRY(initialize(retram, state));
57  break;
58  case kBootSvcTestStateNextSideB:
59  TRY(check_side_b(retram, state));
60  break;
61  case kBootSvcTestStateReturnSideA:
62  TRY(check_return_side_a(retram, state));
63  break;
64  case kBootSvcTestStateFinal:
65  LOG_INFO("FinalBootLog: %d:%s", state->boots, state->partition);
66  return OK_STATUS();
67  default:
68  LOG_ERROR("Unknown state: %d", state->state);
69  return UNKNOWN();
70  }
71  }
72 }
73 
74 bool test_main(void) {
75  status_t sts = bad_next_slot_test();
76  if (status_err(sts)) {
77  LOG_ERROR("bad_next_slot_test: %r", sts);
78  }
79  return status_ok(sts);
80 }