Software APIs
bootstrap_unittest.cc
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/silicon_creator/rom/bootstrap.h"
6 
7 #include <cstring>
8 #include <limits>
9 
10 #include "gtest/gtest.h"
11 #include "sw/device/lib/base/mock_abs_mmio.h"
13 #include "sw/device/silicon_creator/lib/bootstrap_unittest_util.h"
14 #include "sw/device/silicon_creator/lib/drivers/mock_flash_ctrl.h"
15 #include "sw/device/silicon_creator/lib/drivers/mock_otp.h"
16 #include "sw/device/silicon_creator/lib/drivers/mock_rstmgr.h"
17 #include "sw/device/silicon_creator/lib/drivers/mock_spi_device.h"
18 #include "sw/device/silicon_creator/testing/rom_test.h"
19 
20 #include "flash_ctrl_regs.h"
21 #include "gpio_regs.h"
23 #include "otp_ctrl_regs.h"
24 
25 namespace bootstrap_unittest {
26 namespace {
27 
29 using bootstrap_unittest_util::ChipEraseCmd;
30 using bootstrap_unittest_util::PageProgramCmd;
31 using bootstrap_unittest_util::ResetCmd;
32 using bootstrap_unittest_util::SectorEraseCmd;
33 
34 using ::testing::NotNull;
35 using ::testing::Return;
36 
37 MATCHER_P(HasBytes, bytes, "") {
38  return std::memcmp(arg, bytes.data(), bytes.size()) == 0;
39 }
40 
41 TEST_F(BootstrapTest, RequestedDisabled) {
42  EXPECT_CALL(otp_,
43  read32(OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_BOOTSTRAP_DIS_OFFSET))
44  .WillOnce(Return(kHardenedBoolTrue));
45 
46  EXPECT_EQ(bootstrap_requested(), kHardenedBoolFalse);
47 }
48 
49 TEST_F(BootstrapTest, RequestedEnabled) {
50  EXPECT_CALL(otp_,
51  read32(OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_BOOTSTRAP_DIS_OFFSET))
52  .WillOnce(Return(kHardenedBoolFalse));
53  EXPECT_ABS_READ32(TOP_EARLGREY_GPIO_BASE_ADDR + GPIO_DATA_IN_REG_OFFSET,
55  EXPECT_EQ(bootstrap_requested(), kHardenedBoolTrue);
56 
57  EXPECT_CALL(otp_,
58  read32(OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_BOOTSTRAP_DIS_OFFSET))
59  .WillOnce(Return(kHardenedBoolFalse));
60  EXPECT_ABS_READ32(TOP_EARLGREY_GPIO_BASE_ADDR + GPIO_DATA_IN_REG_OFFSET,
62  EXPECT_EQ(bootstrap_requested(), kHardenedBoolFalse);
63 }
64 
65 TEST_F(BootstrapTest, PayloadOverflowErase) {
66  ExpectBootstrapRequestCheck(true);
67  EXPECT_CALL(spi_device_, Init());
68  EXPECT_CALL(spi_device_, CmdGet(NotNull()))
69  .WillOnce(Return(kErrorSpiDevicePayloadOverflow));
70 
71  EXPECT_EQ(bootstrap(), kErrorSpiDevicePayloadOverflow);
72 }
73 
74 TEST_F(BootstrapTest, PayloadOverflowProgram) {
75  // Erase
76  ExpectBootstrapRequestCheck(true);
77  EXPECT_CALL(spi_device_, Init());
78  ExpectSpiCmd(ChipEraseCmd());
79  ExpectSpiFlashStatusGet(true);
80  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
81  // Verify
82  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorOk);
83  EXPECT_CALL(spi_device_, FlashStatusClear());
84  // Program
85  EXPECT_CALL(spi_device_, CmdGet(NotNull()))
86  .WillOnce(Return(kErrorSpiDevicePayloadOverflow));
87 
88  EXPECT_EQ(bootstrap(), kErrorSpiDevicePayloadOverflow);
89 }
90 
91 TEST_F(BootstrapTest, BootstrapSimple) {
92  // Erase
93  ExpectBootstrapRequestCheck(true);
94  EXPECT_CALL(spi_device_, Init());
95  ExpectSpiCmd(ChipEraseCmd());
96  ExpectSpiFlashStatusGet(true);
97  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
98  // Verify
99  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorOk);
100  EXPECT_CALL(spi_device_, FlashStatusClear());
101  // Program
102  auto cmd = PageProgramCmd(0, 16);
103  ExpectSpiCmd(cmd);
104  ExpectSpiFlashStatusGet(true);
105 
106  std::vector<uint8_t> flash_bytes(cmd.payload,
107  cmd.payload + cmd.payload_byte_count);
108 
109  ExpectFlashCtrlWriteEnable();
110  EXPECT_CALL(flash_ctrl_, DataWrite(0, 4, HasBytes(flash_bytes)))
111  .WillOnce(Return(kErrorOk));
112  ExpectFlashCtrlAllDisable();
113 
114  EXPECT_CALL(spi_device_, FlashStatusClear());
115  // Reset
116  ExpectSpiCmd(ResetCmd());
117  EXPECT_CALL(rstmgr_, Reset());
118 
119  EXPECT_EQ(bootstrap(), kErrorUnknown);
120 }
121 
122 TEST_F(BootstrapTest, BootstrapOddPayload) {
123  // Erase
124  ExpectBootstrapRequestCheck(true);
125  EXPECT_CALL(spi_device_, Init());
126  ExpectSpiCmd(ChipEraseCmd());
127  ExpectSpiFlashStatusGet(true);
128  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
129  // Verify
130  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorOk);
131  EXPECT_CALL(spi_device_, FlashStatusClear());
132  // Program
133  auto cmd = PageProgramCmd(0, 17);
134  ExpectSpiCmd(cmd);
135  ExpectSpiFlashStatusGet(true);
136 
137  std::vector<uint8_t> flash_bytes(cmd.payload,
138  cmd.payload + cmd.payload_byte_count);
139  for (size_t i = 0; i < 7; ++i) {
140  flash_bytes.push_back(0xff);
141  }
142 
143  ExpectFlashCtrlWriteEnable();
144  EXPECT_CALL(flash_ctrl_, DataWrite(cmd.address, 6, HasBytes(flash_bytes)))
145  .WillOnce(Return(kErrorOk));
146  ExpectFlashCtrlAllDisable();
147 
148  EXPECT_CALL(spi_device_, FlashStatusClear());
149  // Reset
150  ExpectSpiCmd(ResetCmd());
151  EXPECT_CALL(rstmgr_, Reset());
152 
153  EXPECT_EQ(bootstrap(), kErrorUnknown);
154 }
155 
156 TEST_F(BootstrapTest, BootstrapMisalignedAddrLongPayload) {
157  // Erase
158  ExpectBootstrapRequestCheck(true);
159  EXPECT_CALL(spi_device_, Init());
160  ExpectSpiCmd(ChipEraseCmd());
161  ExpectSpiFlashStatusGet(true);
162  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
163  // Verify
164  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorOk);
165  EXPECT_CALL(spi_device_, FlashStatusClear());
166  // Program
167  auto cmd = PageProgramCmd(0xfff0, 256);
168  ExpectSpiCmd(cmd);
169  ExpectSpiFlashStatusGet(true);
170 
171  std::vector<uint8_t> flash_bytes_0(cmd.payload, cmd.payload + 16);
172  std::vector<uint8_t> flash_bytes_1(cmd.payload + 16,
173  cmd.payload + cmd.payload_byte_count);
174 
175  ExpectFlashCtrlWriteEnable();
176  EXPECT_CALL(flash_ctrl_, DataWrite(0xfff0, 4, HasBytes(flash_bytes_0)))
177  .WillOnce(Return(kErrorOk));
178  EXPECT_CALL(flash_ctrl_, DataWrite(0xff00, 60, HasBytes(flash_bytes_1)))
179  .WillOnce(Return(kErrorOk));
180  ExpectFlashCtrlAllDisable();
181 
182  EXPECT_CALL(spi_device_, FlashStatusClear());
183  // Reset
184  ExpectSpiCmd(ResetCmd());
185  EXPECT_CALL(rstmgr_, Reset());
186 
187  EXPECT_EQ(bootstrap(), kErrorUnknown);
188 }
189 
190 TEST_F(BootstrapTest, BootstrapMisalignedAddrShortPayload) {
191  // Erase
192  ExpectBootstrapRequestCheck(true);
193  EXPECT_CALL(spi_device_, Init());
194  ExpectSpiCmd(ChipEraseCmd());
195  ExpectSpiFlashStatusGet(true);
196  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
197  // Verify
198  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorOk);
199  EXPECT_CALL(spi_device_, FlashStatusClear());
200  // Program
201  auto cmd = PageProgramCmd(816, 8);
202  ExpectSpiCmd(cmd);
203  ExpectSpiFlashStatusGet(true);
204 
205  std::vector<uint8_t> flash_bytes(cmd.payload,
206  cmd.payload + cmd.payload_byte_count);
207 
208  ExpectFlashCtrlWriteEnable();
209  EXPECT_CALL(flash_ctrl_, DataWrite(816, 2, HasBytes(flash_bytes)))
210  .WillOnce(Return(kErrorOk));
211  ExpectFlashCtrlAllDisable();
212 
213  EXPECT_CALL(spi_device_, FlashStatusClear());
214  // Reset
215  ExpectSpiCmd(ResetCmd());
216  EXPECT_CALL(rstmgr_, Reset());
217 
218  EXPECT_EQ(bootstrap(), kErrorUnknown);
219 }
220 
221 TEST_F(BootstrapTest, BootstrapStartWithSectorErase) {
222  // Erase
223  ExpectBootstrapRequestCheck(true);
224  EXPECT_CALL(spi_device_, Init());
225  ExpectSpiCmd(SectorEraseCmd(0));
226  ExpectSpiFlashStatusGet(true);
227  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
228  // Verify
229  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorOk);
230  EXPECT_CALL(spi_device_, FlashStatusClear());
231  // Program
232  auto cmd = PageProgramCmd(0, 16);
233  ExpectSpiCmd(cmd);
234  ExpectSpiFlashStatusGet(true);
235 
236  std::vector<uint8_t> flash_bytes(cmd.payload,
237  cmd.payload + cmd.payload_byte_count);
238 
239  ExpectFlashCtrlWriteEnable();
240  EXPECT_CALL(flash_ctrl_,
241  DataWrite(cmd.address, cmd.payload_byte_count / sizeof(uint32_t),
242  HasBytes(flash_bytes)))
243  .WillOnce(Return(kErrorOk));
244  ExpectFlashCtrlAllDisable();
245 
246  EXPECT_CALL(spi_device_, FlashStatusClear());
247  // Reset
248  ExpectSpiCmd(ResetCmd());
249  EXPECT_CALL(rstmgr_, Reset());
250 
251  EXPECT_EQ(bootstrap(), kErrorUnknown);
252 }
253 
254 TEST_F(BootstrapTest, BootstrapProgramWithErase) {
255  // Erase
256  ExpectBootstrapRequestCheck(true);
257  EXPECT_CALL(spi_device_, Init());
258  ExpectSpiCmd(ChipEraseCmd());
259  ExpectSpiFlashStatusGet(true);
260  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
261  // Verify
262  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorOk);
263  EXPECT_CALL(spi_device_, FlashStatusClear());
264  // Program
265  auto cmd = PageProgramCmd(0, 16);
266  ExpectSpiCmd(cmd);
267  ExpectSpiFlashStatusGet(true);
268 
269  std::vector<uint8_t> flash_bytes(cmd.payload,
270  cmd.payload + cmd.payload_byte_count);
271 
272  ExpectFlashCtrlWriteEnable();
273  EXPECT_CALL(flash_ctrl_,
274  DataWrite(cmd.address, cmd.payload_byte_count / sizeof(uint32_t),
275  HasBytes(flash_bytes)))
276  .WillOnce(Return(kErrorOk));
277  ExpectFlashCtrlAllDisable();
278 
279  EXPECT_CALL(spi_device_, FlashStatusClear());
280  // Chip erase
281  ExpectSpiCmd(ChipEraseCmd());
282  ExpectSpiFlashStatusGet(true);
283  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
284  EXPECT_CALL(spi_device_, FlashStatusClear());
285  // Sector erase
286  ExpectSpiCmd(SectorEraseCmd(0));
287  ExpectSpiFlashStatusGet(true);
288  ExpectFlashCtrlSectorErase(kErrorOk, kErrorOk, 0);
289  EXPECT_CALL(spi_device_, FlashStatusClear());
290 
291  // Reset
292  ExpectSpiCmd(ResetCmd());
293  EXPECT_CALL(rstmgr_, Reset());
294 
295  EXPECT_EQ(bootstrap(), kErrorUnknown);
296 }
297 
298 TEST_F(BootstrapTest, MisalignedEraseAddress) {
299  // Erase
300  ExpectBootstrapRequestCheck(true);
301  EXPECT_CALL(spi_device_, Init());
302  ExpectSpiCmd(ChipEraseCmd());
303  ExpectSpiFlashStatusGet(true);
304  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
305  // Verify
306  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorOk);
307  EXPECT_CALL(spi_device_, FlashStatusClear());
308  // Erase with misaligned and aligned addresses
309  ExpectSpiCmd(SectorEraseCmd(5));
310  ExpectSpiFlashStatusGet(true);
311  ExpectFlashCtrlSectorErase(kErrorOk, kErrorOk, 0);
312  EXPECT_CALL(spi_device_, FlashStatusClear());
313 
314  ExpectSpiCmd(SectorEraseCmd(4096));
315  ExpectSpiFlashStatusGet(true);
316  ExpectFlashCtrlSectorErase(kErrorOk, kErrorOk, 4096);
317  EXPECT_CALL(spi_device_, FlashStatusClear());
318 
319  ExpectSpiCmd(SectorEraseCmd(8195));
320  ExpectSpiFlashStatusGet(true);
321  ExpectFlashCtrlSectorErase(kErrorOk, kErrorOk, 8192);
322  EXPECT_CALL(spi_device_, FlashStatusClear());
323  // Reset
324  ExpectSpiCmd(ResetCmd());
325  EXPECT_CALL(rstmgr_, Reset());
326 
327  EXPECT_EQ(bootstrap(), kErrorUnknown);
328 }
329 
330 TEST_F(BootstrapTest, IgnoredCommands) {
331  // Phase 1: Erase
332  ExpectBootstrapRequestCheck(true);
333  EXPECT_CALL(spi_device_, Init());
334  ExpectSpiCmd(ChipEraseCmd()); // Ignored, missing WREN.
335  ExpectSpiFlashStatusGet(false);
336  ExpectSpiCmd(ResetCmd()); // Ignored, not supported.
337  ExpectSpiFlashStatusGet(true);
338  EXPECT_CALL(spi_device_, FlashStatusClear());
339  ExpectSpiCmd(ChipEraseCmd());
340  ExpectSpiFlashStatusGet(true);
341  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
342  // Phase 1: Verify
343  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorOk);
344  EXPECT_CALL(spi_device_, FlashStatusClear());
345  // Phase 2: Erase/Program
346  ExpectSpiCmd(SectorEraseCmd(0));
347  ExpectSpiFlashStatusGet(false);
348  ExpectSpiCmd(ChipEraseCmd());
349  ExpectSpiFlashStatusGet(false);
350  ExpectSpiCmd(PageProgramCmd(0, 16));
351  ExpectSpiFlashStatusGet(false);
352  // Reset
353  ExpectSpiCmd(ResetCmd());
354  EXPECT_CALL(rstmgr_, Reset());
355 
356  EXPECT_EQ(bootstrap(), kErrorUnknown);
357 }
358 
359 TEST_F(BootstrapTest, EraseBank0Error) {
360  ExpectBootstrapRequestCheck(true);
361  EXPECT_CALL(spi_device_, Init());
362  ExpectSpiCmd(ChipEraseCmd());
363  ExpectSpiFlashStatusGet(true);
364  ExpectFlashCtrlChipErase(kErrorUnknown, kErrorOk);
365 
366  EXPECT_EQ(bootstrap(), kErrorUnknown);
367 }
368 
369 TEST_F(BootstrapTest, EraseBank1Error) {
370  ExpectBootstrapRequestCheck(true);
371  EXPECT_CALL(spi_device_, Init());
372  ExpectSpiCmd(ChipEraseCmd());
373  ExpectSpiFlashStatusGet(true);
374  ExpectFlashCtrlChipErase(kErrorOk, kErrorUnknown);
375 
376  EXPECT_EQ(bootstrap(), kErrorUnknown);
377 }
378 
379 TEST_F(BootstrapTest, EraseVerifyBank0Error) {
380  // Erase
381  ExpectBootstrapRequestCheck(true);
382  EXPECT_CALL(spi_device_, Init());
383  ExpectSpiCmd(ChipEraseCmd());
384  ExpectSpiFlashStatusGet(true);
385  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
386  // Verify
387  ExpectFlashCtrlEraseVerify(kErrorUnknown, kErrorOk);
388 
389  EXPECT_EQ(bootstrap(), kErrorUnknown);
390 }
391 
392 TEST_F(BootstrapTest, EraseVerifyBank1Error) {
393  // Erase
394  ExpectBootstrapRequestCheck(true);
395  EXPECT_CALL(spi_device_, Init());
396  ExpectSpiCmd(ChipEraseCmd());
397  ExpectSpiFlashStatusGet(true);
398  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
399  // Verify
400  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorUnknown);
401 
402  EXPECT_EQ(bootstrap(), kErrorUnknown);
403 }
404 
405 TEST_F(BootstrapTest, DataWriteError) {
406  // Erase
407  ExpectBootstrapRequestCheck(true);
408  EXPECT_CALL(spi_device_, Init());
409  ExpectSpiCmd(ChipEraseCmd());
410  ExpectSpiFlashStatusGet(true);
411  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
412  // Verify
413  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorOk);
414  EXPECT_CALL(spi_device_, FlashStatusClear());
415  // Program
416  auto cmd = PageProgramCmd(0, 16);
417  ExpectSpiCmd(cmd);
418  ExpectSpiFlashStatusGet(true);
419 
420  std::vector<uint8_t> flash_bytes(cmd.payload,
421  cmd.payload + cmd.payload_byte_count);
422 
423  ExpectFlashCtrlWriteEnable();
424  EXPECT_CALL(flash_ctrl_,
425  DataWrite(cmd.address, cmd.payload_byte_count / sizeof(uint32_t),
426  HasBytes(flash_bytes)))
427  .WillOnce(Return(kErrorUnknown));
428  ExpectFlashCtrlAllDisable();
429 
430  EXPECT_EQ(bootstrap(), kErrorUnknown);
431 }
432 
433 TEST_F(BootstrapTest, DataWriteErrorMisalignedAddr) {
434  // Erase
435  ExpectBootstrapRequestCheck(true);
436  EXPECT_CALL(spi_device_, Init());
437  ExpectSpiCmd(ChipEraseCmd());
438  ExpectSpiFlashStatusGet(true);
439  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
440  // Verify
441  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorOk);
442  EXPECT_CALL(spi_device_, FlashStatusClear());
443  // Program
444  auto cmd = PageProgramCmd(0xf0, 16);
445  ExpectSpiCmd(cmd);
446  ExpectSpiFlashStatusGet(true);
447 
448  std::vector<uint8_t> flash_bytes(cmd.payload,
449  cmd.payload + cmd.payload_byte_count);
450 
451  ExpectFlashCtrlWriteEnable();
452  EXPECT_CALL(flash_ctrl_, DataWrite(0xf0, 4, HasBytes(flash_bytes)))
453  .WillOnce(Return(kErrorUnknown));
454  ExpectFlashCtrlAllDisable();
455 
456  EXPECT_EQ(bootstrap(), kErrorUnknown);
457 }
458 
459 TEST_F(BootstrapTest, BadProgramAddress) {
460  // Erase
461  ExpectBootstrapRequestCheck(true);
462  EXPECT_CALL(spi_device_, Init());
463  ExpectSpiCmd(ChipEraseCmd());
464  ExpectSpiFlashStatusGet(true);
465  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
466  // Verify
467  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorOk);
468  EXPECT_CALL(spi_device_, FlashStatusClear());
469  // Program
470  auto page_program_cmd = PageProgramCmd(3, 16);
471  ExpectSpiCmd(page_program_cmd);
472  ExpectSpiFlashStatusGet(true);
473 
474  EXPECT_EQ(bootstrap(), kErrorBootstrapProgramAddress);
475 }
476 
477 TEST_F(BootstrapTest, BadEraseAddress) {
478  // Erase
479  ExpectBootstrapRequestCheck(true);
480  EXPECT_CALL(spi_device_, Init());
481  ExpectSpiCmd(ChipEraseCmd());
482  ExpectSpiFlashStatusGet(true);
483  ExpectFlashCtrlChipErase(kErrorOk, kErrorOk);
484  // Verify
485  ExpectFlashCtrlEraseVerify(kErrorOk, kErrorOk);
486  EXPECT_CALL(spi_device_, FlashStatusClear());
487  // Erase
488  ExpectSpiCmd(SectorEraseCmd(FLASH_CTRL_PARAM_BYTES_PER_BANK *
489  FLASH_CTRL_PARAM_REG_NUM_BANKS));
490  ExpectSpiFlashStatusGet(true);
491 
492  EXPECT_EQ(bootstrap(), kErrorBootstrapEraseAddress);
493 }
494 
495 TEST_F(BootstrapTest, NotRequested) {
496  ExpectBootstrapRequestCheck(false);
497 
498  EXPECT_EQ(bootstrap(), kErrorBootstrapNotRequested);
499 }
500 
501 } // namespace
502 } // namespace bootstrap_unittest