Software APIs
test_rom.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 
14 #include "sw/device/lib/dif/dif_rv_core_ibex.h"
19 #include "sw/device/lib/testing/pinmux_testutils.h"
20 #include "sw/device/lib/testing/test_framework/check.h"
21 #include "sw/device/lib/testing/test_framework/status.h"
23 #include "sw/device/silicon_creator/lib/chip_info.h"
24 #include "sw/device/silicon_creator/lib/manifest.h"
25 
26 #ifdef HAS_RETENTION_RAM
27 #include "sw/device/silicon_creator/lib/drivers/retention_sram.h"
28 #endif
29 
30 // FIXME disabled for now
31 #ifndef OPENTITAN_IS_DARJEELING
32 #include "sw/device/silicon_creator/rom/bootstrap.h"
33 #endif
34 
35 #ifdef HAS_FLASH_CTRL
36 #include "dt/dt_flash_ctrl.h"
38 #include "sw/device/lib/testing/flash_ctrl_testutils.h"
39 #include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
40 
41 #include "flash_ctrl_regs.h"
42 #endif
43 
44 #ifdef HAS_OTP_CTRL
45 #include "dt/dt_otp_ctrl.h"
46 
47 #include "otp_ctrl_regs.h"
48 #endif
49 
50 #ifdef OPENTITAN_IS_DARJEELING
51 #include "dt/dt_soc_proxy.h"
52 #endif
53 
54 static const dt_pinmux_t kPinmuxDt = kDtPinmuxAon;
55 static const dt_rstmgr_t kRstmgrDt = kDtRstmgrAon;
56 
57 #ifdef HAS_FLASH_CTRL
58 static const dt_flash_ctrl_t kFlashCtrlDt = kDtFlashCtrl;
59 static dif_flash_ctrl_state_t flash_ctrl;
60 #endif
61 
62 static const dt_uart_t kUart0Dt = kDtUart0;
63 static const dt_rv_core_ibex_t kRvCoreIbexDt = kDtRvCoreIbex;
64 
65 #ifdef HAS_OTP_CTRL
66 static const dt_otp_ctrl_t kOtpCtrlDt = kDtOtpCtrl;
67 #endif
68 
69 /* These symbols are defined in
70  * `opentitan/sw/device/lib/testing/test_rom/test_rom.ld`, and describes the
71  * location of the flash header and manifest.
72  */
73 extern char _rom_ext_virtual_start_address[];
74 extern char _rom_ext_virtual_size[];
75 extern char _manifest_address[];
76 
77 /**
78  * Type alias for the OTTF entry point.
79  *
80  * The entry point address obtained from the OTTF manifest must be cast to a
81  * pointer to this type before being called.
82  */
83 typedef void ottf_entry_point(void);
84 
85 static dif_pinmux_t pinmux;
86 static dif_rstmgr_t rstmgr;
87 static dif_uart_t uart0;
88 static dif_rv_core_ibex_t ibex;
89 
90 /**
91  * Compute the virtual address corresponding to the physical address `lma_addr`.
92  *
93  * @param manifest Pointer to the current manifest.
94  * @param lma_addr Load address or physical address.
95  * @return the computed virtual address.
96  */
97 static inline uintptr_t rom_ext_vma_get(const manifest_t *manifest,
98  uintptr_t lma_addr) {
99  return (lma_addr - (uintptr_t)manifest +
100  (uintptr_t)_rom_ext_virtual_start_address);
101 }
102 
103 // `test_in_rom = True` tests can override this symbol to provide their own
104 // rom tests. By default, it simply jumps into the OTTF's flash.
105 OT_WEAK
106 bool rom_test_main(void) {
107 #ifdef HAS_OTP_CTRL
108  // Check the otp to see if execute should start
109  const uint32_t otp_ctrl_base = dt_otp_ctrl_primary_reg_block(kOtpCtrlDt);
110  uint32_t otp_val =
111  abs_mmio_read32(otp_ctrl_base + OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET +
112  OTP_CTRL_PARAM_CREATOR_SW_CFG_ROM_EXEC_EN_OFFSET);
113 
114  if (otp_val == 0) {
115  test_status_set(kTestStatusInBootRomHalt);
116  // Abort simply forever loops on a wait_for_interrupt;
117  abort();
118  }
119 #endif
120 
121 #ifndef OPENTITAN_IS_ENGLISHBREAKFAST
122  // Initialize Ibex cpuctrl (contains icache / security feature enablements).
123  uint32_t cpuctrl_csr;
124  CSR_READ(CSR_REG_CPUCTRL, &cpuctrl_csr);
125  uint32_t cpuctrl_otp_val =
126  abs_mmio_read32(otp_ctrl_base + OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET +
127  OTP_CTRL_PARAM_CREATOR_SW_CFG_CPUCTRL_OFFSET);
128  cpuctrl_csr = bitfield_field32_write(
129  cpuctrl_csr, (bitfield_field32_t){.mask = 0x3f, .index = 0},
130  cpuctrl_otp_val);
131  CSR_WRITE(CSR_REG_CPUCTRL, cpuctrl_csr);
132 #endif
133 
134  // Initial sec_mmio, required by bootstrap and its dependencies.
135  sec_mmio_init();
136 
137  // Configure the pinmux.
138  CHECK_DIF_OK(dif_pinmux_init_from_dt(kPinmuxDt, &pinmux));
139  pinmux_testutils_init(&pinmux);
140 
141  CHECK_DIF_OK(dif_rstmgr_init_from_dt(kRstmgrDt, &rstmgr));
142 
143  // Initialize the flash.
144 #ifdef HAS_FLASH_CTRL
145  CHECK_DIF_OK(dif_flash_ctrl_init_state_from_dt(&flash_ctrl, kFlashCtrlDt));
146  CHECK_DIF_OK(dif_flash_ctrl_start_controller_init(&flash_ctrl));
147  CHECK_STATUS_OK(flash_ctrl_testutils_wait_for_init(&flash_ctrl));
148 #ifdef HAS_OTP_CTRL
149  // Check the otp to see if flash scramble should be enabled.
150  otp_val = abs_mmio_read32(
151  otp_ctrl_base + OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET +
152  OTP_CTRL_PARAM_CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG_OFFSET);
153  if (otp_val != 0) {
154  dif_flash_ctrl_region_properties_t default_properties;
156  &flash_ctrl, &default_properties));
157  default_properties.scramble_en =
158  bitfield_field32_read(otp_val, FLASH_CTRL_OTP_FIELD_SCRAMBLING);
159  default_properties.ecc_en =
160  bitfield_field32_read(otp_val, FLASH_CTRL_OTP_FIELD_ECC);
161  default_properties.high_endurance_en =
162  bitfield_field32_read(otp_val, FLASH_CTRL_OTP_FIELD_HE);
164  &flash_ctrl, default_properties));
165  }
166 #endif /* HAS_OTP_CTRL */
167  CHECK_DIF_OK(
169 #endif /* HAS_FLASH_CTRL */
170 
171  // Setup the UART for printing messages to the console.
172  if (kDeviceType != kDeviceSimDV) {
173  CHECK_DIF_OK(dif_uart_init_from_dt(kUart0Dt, &uart0));
174  CHECK(kUartBaudrate <= UINT32_MAX, "kUartBaudrate must fit in uint32_t");
175  CHECK(kClockFreqPeripheralHz <= UINT32_MAX,
176  "kClockFreqPeripheralHz must fit in uint32_t");
177  CHECK_DIF_OK(dif_uart_configure(
178  &uart0, (dif_uart_config_t){
179  .baudrate = (uint32_t)kUartBaudrate,
180  .clk_freq_hz = (uint32_t)kClockFreqPeripheralHz,
181  .parity_enable = kDifToggleDisabled,
182  .parity = kDifUartParityEven,
183  .tx_enable = kDifToggleEnabled,
184  .rx_enable = kDifToggleEnabled,
185  }));
186  base_uart_stdout(&uart0);
187  }
188 
189  // Print the chip version information
190  LOG_INFO("kChipInfo: scm_revision=%x", kChipInfo.scm_revision);
191 
192  // Skip sram_init for test_rom
193  dif_rstmgr_reset_info_bitfield_t reset_reasons;
194  CHECK_DIF_OK(dif_rstmgr_reset_info_get(&rstmgr, &reset_reasons));
195 
196 #ifdef HAS_RETENTION_RAM
197  // Store the reset reason in retention RAM and clear the register.
198  volatile retention_sram_t *ret_ram = retention_sram_get();
199  ret_ram->creator.reset_reasons = reset_reasons;
200  CHECK_DIF_OK(dif_rstmgr_reset_info_clear(&rstmgr));
201 
202  // Write 0x54534554 (ASCII: TEST) to the end of the retention SRAM creator
203  // area to be able to determine the type of ROM in tests.
204  volatile uint32_t *creator_last_word =
205  &ret_ram->creator.reserved[ARRAYSIZE(ret_ram->creator.reserved) - 1];
206  *creator_last_word = TEST_ROM_IDENTIFIER;
207 #endif
208 
209  // Print the FPGA version-id.
210  // This is guaranteed to be zero on all non-FPGA implementations.
211  dif_rv_core_ibex_fpga_info_t fpga;
212  CHECK_DIF_OK(dif_rv_core_ibex_init_from_dt(kRvCoreIbexDt, &ibex));
213  CHECK_DIF_OK(dif_rv_core_ibex_read_fpga_info(&ibex, &fpga));
214  if (fpga != 0) {
215  LOG_INFO("TestROM:%08x", fpga);
216  }
217 
218  // FIXME Disabled for now
219 #ifndef OPENTITAN_IS_DARJEELING
220  if (bootstrap_requested() == kHardenedBoolTrue) {
221  // This log statement is used to synchronize the rom and DV testbench
222  // for specific test cases.
223  LOG_INFO("Boot strap requested");
224 
225  rom_error_t bootstrap_err = bootstrap();
226  if (bootstrap_err != kErrorOk) {
227  LOG_ERROR("Bootstrap failed with status code: %08x",
228  (uint32_t)bootstrap_err);
229  // Currently the only way to recover is by a hard reset.
230  test_status_set(kTestStatusFailed);
231  }
232  }
233 #endif
234 
235 #ifdef OPENTITAN_IS_EARLGREY
236  CHECK_DIF_OK(
238 #endif
239 
240  const manifest_t *manifest = (const manifest_t *)_manifest_address;
241 
242  uintptr_t entry_point = manifest_entry_point_get(manifest);
243  // Enable address translation if manifest says to
246  .matching_addr = (uintptr_t)_rom_ext_virtual_start_address,
247  .remap_addr = (uintptr_t)manifest,
248  .size = (size_t)_rom_ext_virtual_size,
249  };
250  CHECK_DIF_OK(dif_rv_core_ibex_configure_addr_translation(
251  &ibex, kDifRvCoreIbexAddrTranslationSlot_0,
252  kDifRvCoreIbexAddrTranslationDBus, addr_map));
253  CHECK_DIF_OK(dif_rv_core_ibex_configure_addr_translation(
254  &ibex, kDifRvCoreIbexAddrTranslationSlot_0,
255  kDifRvCoreIbexAddrTranslationIBus, addr_map));
256  CHECK_DIF_OK(dif_rv_core_ibex_enable_addr_translation(
257  &ibex, kDifRvCoreIbexAddrTranslationSlot_0,
258  kDifRvCoreIbexAddrTranslationDBus));
259  CHECK_DIF_OK(dif_rv_core_ibex_enable_addr_translation(
260  &ibex, kDifRvCoreIbexAddrTranslationSlot_0,
261  kDifRvCoreIbexAddrTranslationIBus));
262  entry_point = rom_ext_vma_get(manifest, entry_point);
263  }
264 
265  // Jump to the OTTF in flash. Within the flash binary, it is the
266  // responsibily of the OTTF to set up its own stack, and to never return.
267  LOG_INFO("Test ROM complete, jumping to flash (addr: %x)!", entry_point);
268  ((ottf_entry_point *)entry_point)();
269 
270  // If the flash image returns, we should abort anyway.
271  abort();
272 }
273 
274 void _boot_start(void) {
275  test_status_set(kTestStatusInBootRom);
276  test_status_set(rom_test_main() ? kTestStatusPassed : kTestStatusFailed);
277 
278  abort();
279 }