Software APIs
rom_ext_upgrade_interrupt.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 
8 #include "sw/device/lib/testing/flash_ctrl_testutils.h"
9 #include "sw/device/lib/testing/nv_counter_testutils.h"
10 #include "sw/device/lib/testing/test_framework/check.h"
12 #include "sw/device/silicon_creator/lib/boot_data.h"
13 #include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
14 #include "sw/device/silicon_creator/lib/drivers/lifecycle.h"
15 #include "sw/device/silicon_creator/lib/drivers/rstmgr.h"
16 #include "sw/device/silicon_creator/lib/manifest_def.h"
17 
19 
20 OTTF_DEFINE_TEST_CONFIG();
21 
22 enum {
23  kNewMinSecVer = 1,
24  kFlashCounterId = 0,
25 };
26 
27 static void print_boot_data(const boot_data_t *boot_data) {
28  LOG_INFO("counter: %d, min_security_version_rom_ext: %d", boot_data->counter,
30 }
31 
32 static void increment_flash_counter(void) {
33  dif_flash_ctrl_state_t flash_ctrl;
34  CHECK_DIF_OK(dif_flash_ctrl_init_state(
35  &flash_ctrl,
37  CHECK_STATUS_OK(flash_ctrl_testutils_default_region_access(
38  &flash_ctrl,
39  /*rd_en*/ true,
40  /*prog_en*/ true, false, false, false, false));
41  CHECK_STATUS_OK(
42  flash_ctrl_testutils_counter_increment(&flash_ctrl, kFlashCounterId));
43  CHECK_STATUS_OK(flash_ctrl_testutils_default_region_access(
44  &flash_ctrl, false, false, false, false, false, false));
45 }
46 
47 static rom_error_t first_boot_test(void) {
48  LOG_INFO("First boot: interrupted upgrade");
50  RETURN_IF_ERROR(boot_data_read(lifecycle_state_get(), &boot_data));
51  print_boot_data(&boot_data);
53 
55  RETURN_IF_ERROR(boot_data_write(&boot_data));
56  RETURN_IF_ERROR(boot_data_read(lifecycle_state_get(), &boot_data));
57  print_boot_data(&boot_data);
58  CHECK(boot_data.min_security_version_rom_ext == kNewMinSecVer);
59 
60  uint32_t corrupted_words[4] = {0};
61  flash_ctrl_info_perms_set(&kFlashCtrlInfoPageBootData0,
63  .read = kMultiBitBool4False,
64  .write = kMultiBitBool4True,
65  .erase = kMultiBitBool4False,
66  });
67  RETURN_IF_ERROR(flash_ctrl_info_write(&kFlashCtrlInfoPageBootData0, 0, 4,
68  &corrupted_words));
69  flash_ctrl_info_perms_set(&kFlashCtrlInfoPageBootData0,
71  .read = kMultiBitBool4False,
72  .write = kMultiBitBool4False,
73  .erase = kMultiBitBool4False,
74  });
75  return kErrorOk;
76 }
77 
78 static rom_error_t second_boot_test(void) {
79  LOG_INFO("Second boot: Recovery");
80 
82  RETURN_IF_ERROR(boot_data_read(lifecycle_state_get(), &boot_data));
83  print_boot_data(&boot_data);
85 
87  RETURN_IF_ERROR(boot_data_write(&boot_data));
88  RETURN_IF_ERROR(boot_data_read(lifecycle_state_get(), &boot_data));
89  print_boot_data(&boot_data);
90  CHECK(boot_data.min_security_version_rom_ext == kNewMinSecVer);
91 
92  return kErrorOk;
93 }
94 
95 static rom_error_t third_boot_test(void) {
96  LOG_INFO("Third boot: Done");
97 
99  RETURN_IF_ERROR(boot_data_read(lifecycle_state_get(), &boot_data));
100  print_boot_data(&boot_data);
101  CHECK(boot_data.min_security_version_rom_ext == kNewMinSecVer);
102 
103  return kErrorOk;
104 }
105 
106 bool test_main(void) {
107  status_t result = OK_STATUS();
108 
109  size_t reboot_counter = 0;
110  CHECK_STATUS_OK(
111  flash_ctrl_testutils_counter_get(kFlashCounterId, &reboot_counter));
112 
113  switch (reboot_counter) {
114  case 0: {
115  const manifest_t *manifest = manifest_def_get();
116  LOG_INFO("Manifest security version: %d", manifest->security_version);
117  CHECK(manifest->security_version > kNewMinSecVer);
118 
119  EXECUTE_TEST(result, first_boot_test);
120 
121  increment_flash_counter();
122  rstmgr_reset();
123  return false;
124  }
125  case 1: {
126  EXECUTE_TEST(result, second_boot_test);
127 
128  increment_flash_counter();
129  rstmgr_reset();
130  return false;
131  }
132  case 2: {
133  EXECUTE_TEST(result, third_boot_test);
134 
135  return status_ok(result);
136  }
137  }
138  return false;
139 }