Software APIs
dif_spi_device_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 
6 
7 #include <limits>
8 
9 #include "gtest/gtest.h"
11 #include "sw/device/lib/base/mock_mmio.h"
13 
14 #include "spi_device_regs.h" // Generated.
15 
16 namespace dif_spi_device_unittest {
17 namespace {
18 using ::mock_mmio::LeInt;
19 using ::mock_mmio::MmioTest;
20 using ::mock_mmio::MockDevice;
21 
22 class SpiTest : public testing::Test, public MmioTest {
23  public:
24  static constexpr uint16_t kFifoLen = 0x800;
25 
26  protected:
28  .dev = {.base_addr = dev().region()},
29  };
30 };
31 
32 static constexpr dif_spi_device_config_t kDefaultConfig = {
35  .device_mode = kDifSpiDeviceModeDisabled,
36 };
37 
38 class ConfigTest : public SpiTest {};
39 
40 TEST_F(ConfigTest, BasicInit) {
41  EXPECT_WRITE32(SPI_DEVICE_CFG_REG_OFFSET,
42  {
43  {SPI_DEVICE_CFG_TX_ORDER_BIT, 0},
44  {SPI_DEVICE_CFG_RX_ORDER_BIT, 0},
45  });
46  EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET,
47  {
48  {SPI_DEVICE_CONTROL_MODE_OFFSET, 3},
49  });
50  EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET,
51  {
52  {SPI_DEVICE_CONTROL_MODE_OFFSET, 0},
53  });
54  EXPECT_DIF_OK(dif_spi_device_configure(&spi_, kDefaultConfig));
55 }
56 
57 TEST_F(ConfigTest, NullArgs) {
58  EXPECT_DIF_BADARG(dif_spi_device_configure(nullptr, kDefaultConfig));
61 }
62 
63 class FlashTest : public SpiTest {
64  void SetUp() {
65  const dif_spi_device_config_t config = {
68  .device_mode = kDifSpiDeviceModePassthrough,
69  };
70  EXPECT_DIF_OK(dif_spi_device_init_handle(dev().region(), &spi_));
71  EXPECT_WRITE32(SPI_DEVICE_CFG_REG_OFFSET,
72  {
73  {SPI_DEVICE_CFG_TX_ORDER_BIT, 0},
74  {SPI_DEVICE_CFG_RX_ORDER_BIT, 0},
75  });
76  EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET,
77  {
78  {SPI_DEVICE_CONTROL_MODE_OFFSET, 0},
79  });
80  EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET,
81  {
82  {SPI_DEVICE_CONTROL_MODE_OFFSET,
83  SPI_DEVICE_CONTROL_MODE_VALUE_PASSTHROUGH},
84  });
86  };
87 };
88 
89 TEST_F(FlashTest, NullArgs) {
90  dif_toggle_t toggle_arg;
91  uint32_t uint32_arg;
92  uint16_t uint16_arg;
93  uint8_t uint8_arg;
97  EXPECT_DIF_BADARG(dif_spi_device_init_handle(dev().region(), nullptr));
98  EXPECT_DIF_BADARG(dif_spi_device_enable_mailbox(nullptr, /*address=*/0x1000));
101  nullptr, &toggle_arg, &uint32_arg));
103  dif_spi_device_get_mailbox_configuration(&spi_, nullptr, &uint32_arg));
105  dif_spi_device_get_mailbox_configuration(&spi_, &toggle_arg, nullptr));
115  nullptr, intercept_config));
119  dif_spi_device_set_eflash_read_threshold(nullptr, /*address=*/0));
122  nullptr, /*slot=*/0, &toggle_arg, &command_arg));
124  &spi_, /*slot=*/0, nullptr, &command_arg));
126  &spi_, /*slot=*/0, &toggle_arg, nullptr));
128  nullptr, /*slot=*/0, kDifToggleEnabled, command_arg));
130  nullptr, kDifToggleEnabled, /*opcode=*/0));
132  nullptr, kDifToggleEnabled, /*opcode=*/0));
134  nullptr, kDifToggleEnabled, /*opcode=*/0));
136  nullptr, kDifToggleEnabled, /*opcode=*/0));
138  /*replacement=*/0));
140  /*replacement=*/0));
150  nullptr, &uint16_arg, &uint32_arg));
152  &spi_, nullptr, &uint32_arg));
154  &spi_, &uint16_arg, nullptr));
158  dif_spi_device_pop_flash_address_fifo(nullptr, &uint32_arg));
161  nullptr, /*offset=*/0, /*length=*/1, &uint8_arg));
163  &spi_, /*offset=*/0, /*length=*/1, nullptr));
165  nullptr, kDifSpiDeviceFlashBufferTypeSfdp, /*offset=*/0, /*length=*/1,
166  &uint8_arg));
169  /*offset=*/0, /*length=*/1, nullptr));
171  nullptr, /*command=*/0, &toggle_arg));
173  &spi_, /*command=*/0, nullptr));
175  nullptr, /*command=*/0, kDifToggleEnabled));
177  nullptr, kDifToggleEnabled));
180  dif_spi_device_set_flash_status_registers(nullptr, /*value=*/0));
182  dif_spi_device_get_flash_status_registers(nullptr, &uint32_arg));
184 }
185 
186 TEST_F(FlashTest, CsbGpio) {
187  bool csb;
188  EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET,
189  {
190  {SPI_DEVICE_STATUS_CSB_BIT, 1},
191  });
193  EXPECT_TRUE(csb);
194 
195  EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET,
196  {
197  {SPI_DEVICE_STATUS_CSB_BIT, 0},
198  });
200  EXPECT_FALSE(csb);
201 }
202 
203 TEST_F(FlashTest, PassthroughToggle) {
204  EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET,
205  {
206  {SPI_DEVICE_CONTROL_MODE_OFFSET,
207  SPI_DEVICE_CONTROL_MODE_VALUE_PASSTHROUGH},
208  });
209  EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET,
210  {
211  {SPI_DEVICE_CONTROL_MODE_OFFSET,
212  SPI_DEVICE_CONTROL_MODE_VALUE_FLASHMODE},
213  });
215  EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET,
216  {
217  {SPI_DEVICE_CONTROL_MODE_OFFSET,
218  SPI_DEVICE_CONTROL_MODE_VALUE_FLASHMODE},
219  });
220  EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET,
221  {
222  {SPI_DEVICE_CONTROL_MODE_OFFSET,
223  SPI_DEVICE_CONTROL_MODE_VALUE_PASSTHROUGH},
224  });
226 }
227 
228 TEST_F(FlashTest, MailboxConfigTest) {
229  dif_toggle_t toggle;
230  uint32_t address = 0x3f0000;
231  EXPECT_WRITE32(SPI_DEVICE_MAILBOX_ADDR_REG_OFFSET, address);
232  EXPECT_READ32(SPI_DEVICE_CFG_REG_OFFSET, {
233  {SPI_DEVICE_CFG_TX_ORDER_BIT, 1},
234  {SPI_DEVICE_CFG_RX_ORDER_BIT, 1},
235  });
236  EXPECT_WRITE32(SPI_DEVICE_CFG_REG_OFFSET,
237  {
238  {SPI_DEVICE_CFG_MAILBOX_EN_BIT, 1},
239  {SPI_DEVICE_CFG_TX_ORDER_BIT, 1},
240  {SPI_DEVICE_CFG_RX_ORDER_BIT, 1},
241  });
243  EXPECT_READ32(SPI_DEVICE_CFG_REG_OFFSET,
244  {
245  {SPI_DEVICE_CFG_MAILBOX_EN_BIT, 1},
246  {SPI_DEVICE_CFG_TX_ORDER_BIT, 0},
247  {SPI_DEVICE_CFG_RX_ORDER_BIT, 1},
248  });
249  EXPECT_WRITE32(SPI_DEVICE_CFG_REG_OFFSET,
250  {
251  {SPI_DEVICE_CFG_MAILBOX_EN_BIT, 0},
252  {SPI_DEVICE_CFG_TX_ORDER_BIT, 0},
253  {SPI_DEVICE_CFG_RX_ORDER_BIT, 1},
254  });
256  EXPECT_READ32(SPI_DEVICE_CFG_REG_OFFSET,
257  {
258  {SPI_DEVICE_CFG_MAILBOX_EN_BIT, 1},
259  {SPI_DEVICE_CFG_TX_ORDER_BIT, 1},
260  });
261  EXPECT_READ32(SPI_DEVICE_MAILBOX_ADDR_REG_OFFSET, 0x100000);
263  dif_spi_device_get_mailbox_configuration(&spi_, &toggle, &address));
264  EXPECT_EQ(toggle, kDifToggleEnabled);
265  EXPECT_EQ(address, 0x100000);
266  EXPECT_READ32(SPI_DEVICE_CFG_REG_OFFSET,
267  {
268  {SPI_DEVICE_CFG_MAILBOX_EN_BIT, 0},
269  });
270  EXPECT_READ32(SPI_DEVICE_MAILBOX_ADDR_REG_OFFSET, 0x100000);
272  dif_spi_device_get_mailbox_configuration(&spi_, &toggle, &address));
273  EXPECT_EQ(toggle, kDifToggleDisabled);
274 }
275 
276 TEST_F(FlashTest, Addr4bConfig) {
277  dif_toggle_t toggle;
278  EXPECT_READ32(SPI_DEVICE_ADDR_MODE_REG_OFFSET,
279  {
280  {SPI_DEVICE_ADDR_MODE_PENDING_BIT, 1},
281  });
283  EXPECT_EQ(toggle, kDifToggleDisabled);
284 
285  EXPECT_READ32(SPI_DEVICE_ADDR_MODE_REG_OFFSET,
286  {
287  {SPI_DEVICE_ADDR_MODE_PENDING_BIT, 1},
288  {SPI_DEVICE_ADDR_MODE_ADDR_4B_EN_BIT, 1},
289  });
291  EXPECT_EQ(toggle, kDifToggleEnabled);
292 
293  EXPECT_WRITE32(SPI_DEVICE_ADDR_MODE_REG_OFFSET,
294  {
295  {SPI_DEVICE_ADDR_MODE_ADDR_4B_EN_BIT, 1},
296  });
298  EXPECT_WRITE32(SPI_DEVICE_ADDR_MODE_REG_OFFSET,
299  {
300  {SPI_DEVICE_ADDR_MODE_ADDR_4B_EN_BIT, 0},
301  });
303 }
304 
305 TEST_F(FlashTest, DeviceId) {
307  EXPECT_READ32(SPI_DEVICE_JEDEC_CC_REG_OFFSET,
308  {
309  {SPI_DEVICE_JEDEC_CC_NUM_CC_OFFSET, 10},
310  {SPI_DEVICE_JEDEC_CC_CC_OFFSET, 0x5a},
311  });
312  EXPECT_READ32(SPI_DEVICE_JEDEC_ID_REG_OFFSET,
313  {
314  {SPI_DEVICE_JEDEC_ID_MF_OFFSET, 0xca},
315  {SPI_DEVICE_JEDEC_ID_ID_OFFSET, 0x1234},
316  });
318  EXPECT_EQ(id.num_continuation_code, 10);
319  EXPECT_EQ(id.continuation_code, 0x5a);
320  EXPECT_EQ(id.manufacturer_id, 0xca);
321  EXPECT_EQ(id.device_id, 0x1234);
322 
324  .device_id = 0x2202,
325  .manufacturer_id = 0xd7,
326  .continuation_code = 0x7f,
327  .num_continuation_code = 7,
328  };
329  EXPECT_WRITE32(SPI_DEVICE_JEDEC_CC_REG_OFFSET,
330  {
331  {SPI_DEVICE_JEDEC_CC_NUM_CC_OFFSET, 7},
332  {SPI_DEVICE_JEDEC_CC_CC_OFFSET, 0x7f},
333  });
334  EXPECT_WRITE32(SPI_DEVICE_JEDEC_ID_REG_OFFSET,
335  {
336  {SPI_DEVICE_JEDEC_ID_MF_OFFSET, 0xd7},
337  {SPI_DEVICE_JEDEC_ID_ID_OFFSET, 0x2202},
338  });
340 }
341 
342 TEST_F(FlashTest, InterceptConfig) {
344  .status = false,
345  .jedec_id = true,
346  .sfdp = false,
347  .mailbox = true,
348  };
349  EXPECT_WRITE32(SPI_DEVICE_INTERCEPT_EN_REG_OFFSET,
350  {
351  {SPI_DEVICE_INTERCEPT_EN_STATUS_BIT, 0},
352  {SPI_DEVICE_INTERCEPT_EN_JEDEC_BIT, 1},
353  {SPI_DEVICE_INTERCEPT_EN_SFDP_BIT, 0},
354  {SPI_DEVICE_INTERCEPT_EN_MBX_BIT, 1},
355  });
357 
359  .status = true,
360  .jedec_id = false,
361  .sfdp = true,
362  .mailbox = false,
363  };
364  EXPECT_WRITE32(SPI_DEVICE_INTERCEPT_EN_REG_OFFSET,
365  {
366  {SPI_DEVICE_INTERCEPT_EN_STATUS_BIT, 1},
367  {SPI_DEVICE_INTERCEPT_EN_JEDEC_BIT, 0},
368  {SPI_DEVICE_INTERCEPT_EN_SFDP_BIT, 1},
369  {SPI_DEVICE_INTERCEPT_EN_MBX_BIT, 0},
370  });
372 }
373 
374 TEST_F(FlashTest, FlashWatermark) {
375  uint32_t address;
376  EXPECT_READ32(SPI_DEVICE_LAST_READ_ADDR_REG_OFFSET, 0x1000);
378  EXPECT_EQ(address, 0x1000);
379 
381 
382  EXPECT_WRITE32(SPI_DEVICE_READ_THRESHOLD_REG_OFFSET, 0x26a);
384 
385  EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET,
386  {
387  {SPI_DEVICE_CONTROL_MODE_OFFSET,
388  SPI_DEVICE_CONTROL_MODE_VALUE_PASSTHROUGH},
389  {SPI_DEVICE_CONTROL_FLASH_READ_BUFFER_CLR_BIT, 1},
390  });
392 }
393 
394 TEST_F(FlashTest, CommandInfo) {
395  dif_spi_device_flash_command_t command_info;
396  dif_toggle_t toggle;
397  EXPECT_READ32(SPI_DEVICE_CMD_INFO_0_REG_OFFSET,
398  {
399  {SPI_DEVICE_CMD_INFO_0_OPCODE_0_OFFSET, 0x6b},
400  {SPI_DEVICE_CMD_INFO_0_ADDR_MODE_0_OFFSET,
401  SPI_DEVICE_CMD_INFO_0_ADDR_MODE_0_VALUE_ADDRCFG},
402  {SPI_DEVICE_CMD_INFO_0_DUMMY_EN_0_BIT, 1},
403  {SPI_DEVICE_CMD_INFO_0_DUMMY_SIZE_0_OFFSET, 7},
404  {SPI_DEVICE_CMD_INFO_0_PAYLOAD_EN_0_OFFSET, 0xf},
405  {SPI_DEVICE_CMD_INFO_0_PAYLOAD_DIR_0_BIT, 1},
406  {SPI_DEVICE_CMD_INFO_0_ADDR_SWAP_EN_0_BIT, 0},
407  {SPI_DEVICE_CMD_INFO_0_PAYLOAD_SWAP_EN_0_BIT, 0},
408  {SPI_DEVICE_CMD_INFO_0_UPLOAD_0_BIT, 0},
409  {SPI_DEVICE_CMD_INFO_0_BUSY_0_BIT, 0},
410  {SPI_DEVICE_CMD_INFO_0_VALID_0_BIT, 0},
411  });
413  &toggle, &command_info));
414  EXPECT_EQ(toggle, kDifToggleDisabled);
415 
416  EXPECT_READ32(SPI_DEVICE_CMD_INFO_1_REG_OFFSET,
417  {
418  {SPI_DEVICE_CMD_INFO_1_OPCODE_1_OFFSET, 0x6b},
419  {SPI_DEVICE_CMD_INFO_1_ADDR_MODE_1_OFFSET,
420  SPI_DEVICE_CMD_INFO_0_ADDR_MODE_0_VALUE_ADDRCFG},
421  {SPI_DEVICE_CMD_INFO_1_DUMMY_EN_1_BIT, 1},
422  {SPI_DEVICE_CMD_INFO_1_DUMMY_SIZE_1_OFFSET, 7},
423  {SPI_DEVICE_CMD_INFO_1_PAYLOAD_EN_1_OFFSET, 0xf},
424  {SPI_DEVICE_CMD_INFO_1_PAYLOAD_DIR_1_BIT, 1},
425  {SPI_DEVICE_CMD_INFO_1_ADDR_SWAP_EN_1_BIT, 0},
426  {SPI_DEVICE_CMD_INFO_1_PAYLOAD_SWAP_EN_1_BIT, 0},
427  {SPI_DEVICE_CMD_INFO_1_UPLOAD_1_BIT, 0},
428  {SPI_DEVICE_CMD_INFO_1_BUSY_1_BIT, 0},
429  {SPI_DEVICE_CMD_INFO_1_VALID_1_BIT, 1},
430  });
432  &toggle, &command_info));
433  EXPECT_EQ(toggle, kDifToggleEnabled);
434  EXPECT_EQ(command_info.opcode, 0x6b);
435  EXPECT_EQ(command_info.address_type, kDifSpiDeviceFlashAddrCfg);
436  EXPECT_EQ(command_info.dummy_cycles, 8);
437  EXPECT_EQ(command_info.payload_io_type, kDifSpiDevicePayloadIoQuad);
438  EXPECT_FALSE(command_info.passthrough_swap_address);
439  EXPECT_TRUE(command_info.payload_dir_to_host);
440  EXPECT_FALSE(command_info.payload_swap_enable);
441  EXPECT_FALSE(command_info.upload);
442  EXPECT_FALSE(command_info.set_busy_status);
443 
444  EXPECT_READ32(SPI_DEVICE_CMD_INFO_1_REG_OFFSET,
445  {
446  {SPI_DEVICE_CMD_INFO_1_OPCODE_1_OFFSET, 0x12},
447  {SPI_DEVICE_CMD_INFO_1_ADDR_MODE_1_OFFSET,
448  SPI_DEVICE_CMD_INFO_0_ADDR_MODE_0_VALUE_ADDR4B},
449  {SPI_DEVICE_CMD_INFO_1_DUMMY_EN_1_BIT, 0},
450  {SPI_DEVICE_CMD_INFO_1_DUMMY_SIZE_1_OFFSET, 7},
451  {SPI_DEVICE_CMD_INFO_1_PAYLOAD_EN_1_OFFSET, 0x1},
452  {SPI_DEVICE_CMD_INFO_1_PAYLOAD_DIR_1_BIT, 0},
453  {SPI_DEVICE_CMD_INFO_1_ADDR_SWAP_EN_1_BIT, 1},
454  {SPI_DEVICE_CMD_INFO_1_PAYLOAD_SWAP_EN_1_BIT, 1},
455  {SPI_DEVICE_CMD_INFO_1_UPLOAD_1_BIT, 1},
456  {SPI_DEVICE_CMD_INFO_1_BUSY_1_BIT, 1},
457  {SPI_DEVICE_CMD_INFO_1_VALID_1_BIT, 1},
458  });
460  &toggle, &command_info));
461  EXPECT_EQ(toggle, kDifToggleEnabled);
462  EXPECT_EQ(command_info.opcode, 0x12);
463  EXPECT_EQ(command_info.address_type, kDifSpiDeviceFlashAddr4Byte);
464  EXPECT_EQ(command_info.dummy_cycles, 0);
465  EXPECT_EQ(command_info.payload_io_type, kDifSpiDevicePayloadIoSingle);
466  EXPECT_TRUE(command_info.passthrough_swap_address);
467  EXPECT_FALSE(command_info.payload_dir_to_host);
468  EXPECT_TRUE(command_info.payload_swap_enable);
469  EXPECT_TRUE(command_info.upload);
470  EXPECT_TRUE(command_info.set_busy_status);
471 
472  command_info = (dif_spi_device_flash_command_t){
473  .opcode = 0x06,
474  .address_type = kDifSpiDeviceFlashAddrDisabled,
475  .dummy_cycles = 0,
476  .payload_io_type = kDifSpiDevicePayloadIoSingle,
477  .passthrough_swap_address = false,
478  .payload_dir_to_host = false,
479  .payload_swap_enable = true,
480  .upload = true,
481  .set_busy_status = true,
482  };
483  EXPECT_WRITE32(SPI_DEVICE_CMD_INFO_1_REG_OFFSET,
484  {
485  {SPI_DEVICE_CMD_INFO_1_OPCODE_1_OFFSET, 0x06},
486  {SPI_DEVICE_CMD_INFO_1_ADDR_MODE_1_OFFSET,
487  SPI_DEVICE_CMD_INFO_0_ADDR_MODE_0_VALUE_ADDRDISABLED},
488  {SPI_DEVICE_CMD_INFO_1_DUMMY_EN_1_BIT, 0},
489  {SPI_DEVICE_CMD_INFO_1_DUMMY_SIZE_1_OFFSET, 0},
490  {SPI_DEVICE_CMD_INFO_1_PAYLOAD_EN_1_OFFSET, 0x1},
491  {SPI_DEVICE_CMD_INFO_1_PAYLOAD_DIR_1_BIT, 0},
492  {SPI_DEVICE_CMD_INFO_1_ADDR_SWAP_EN_1_BIT, 0},
493  {SPI_DEVICE_CMD_INFO_1_PAYLOAD_SWAP_EN_1_BIT, 1},
494  {SPI_DEVICE_CMD_INFO_1_UPLOAD_1_BIT, 1},
495  {SPI_DEVICE_CMD_INFO_1_BUSY_1_BIT, 1},
496  {SPI_DEVICE_CMD_INFO_1_VALID_1_BIT, 1},
497  });
499  &spi_, /*slot=*/1, kDifToggleEnabled, command_info));
500  command_info = (dif_spi_device_flash_command_t){
501  .opcode = 0x5a,
502  .address_type = kDifSpiDeviceFlashAddr3Byte,
503  .dummy_cycles = 8,
504  .payload_io_type = kDifSpiDevicePayloadIoSingle,
505  .passthrough_swap_address = false,
506  .payload_dir_to_host = true,
507  .payload_swap_enable = false,
508  .upload = false,
509  .set_busy_status = false,
510  };
511  EXPECT_WRITE32(SPI_DEVICE_CMD_INFO_1_REG_OFFSET,
512  {
513  {SPI_DEVICE_CMD_INFO_1_OPCODE_1_OFFSET, 0x5a},
514  {SPI_DEVICE_CMD_INFO_1_ADDR_MODE_1_OFFSET,
515  SPI_DEVICE_CMD_INFO_0_ADDR_MODE_0_VALUE_ADDR3B},
516  {SPI_DEVICE_CMD_INFO_1_DUMMY_EN_1_BIT, 1},
517  {SPI_DEVICE_CMD_INFO_1_DUMMY_SIZE_1_OFFSET, 7},
518  {SPI_DEVICE_CMD_INFO_1_PAYLOAD_EN_1_OFFSET, 0x2},
519  {SPI_DEVICE_CMD_INFO_1_PAYLOAD_DIR_1_BIT, 1},
520  {SPI_DEVICE_CMD_INFO_1_ADDR_SWAP_EN_1_BIT, 0},
521  {SPI_DEVICE_CMD_INFO_1_PAYLOAD_SWAP_EN_1_BIT, 0},
522  {SPI_DEVICE_CMD_INFO_1_UPLOAD_1_BIT, 0},
523  {SPI_DEVICE_CMD_INFO_1_BUSY_1_BIT, 0},
524  {SPI_DEVICE_CMD_INFO_1_VALID_1_BIT, 1},
525  });
527  &spi_, /*slot=*/1, kDifToggleEnabled, command_info));
528 }
529 
530 TEST_F(FlashTest, HardwareCommandInfo) {
531  EXPECT_WRITE32(SPI_DEVICE_CMD_INFO_EN4B_REG_OFFSET,
532  {
533  {SPI_DEVICE_CMD_INFO_EN4B_OPCODE_OFFSET, 0xb7},
534  {SPI_DEVICE_CMD_INFO_EN4B_VALID_BIT, 1},
535  });
537  &spi_, kDifToggleEnabled, /*opcode=*/0xb7));
538  EXPECT_WRITE32(SPI_DEVICE_CMD_INFO_EX4B_REG_OFFSET,
539  {
540  {SPI_DEVICE_CMD_INFO_EX4B_OPCODE_OFFSET, 0xe9},
541  {SPI_DEVICE_CMD_INFO_EX4B_VALID_BIT, 0},
542  });
544  &spi_, kDifToggleDisabled, /*opcode=*/0xe9));
545  EXPECT_WRITE32(SPI_DEVICE_CMD_INFO_WREN_REG_OFFSET,
546  {
547  {SPI_DEVICE_CMD_INFO_WREN_OPCODE_OFFSET, 0x06},
548  {SPI_DEVICE_CMD_INFO_WREN_VALID_BIT, 1},
549  });
551  &spi_, kDifToggleEnabled, /*opcode=*/0x06));
552  EXPECT_WRITE32(SPI_DEVICE_CMD_INFO_WRDI_REG_OFFSET,
553  {
554  {SPI_DEVICE_CMD_INFO_WRDI_OPCODE_OFFSET, 0x04},
555  {SPI_DEVICE_CMD_INFO_WRDI_VALID_BIT, 0},
556  });
558  &spi_, kDifToggleDisabled, /*opcode=*/0x04));
559 }
560 
561 TEST_F(FlashTest, Swaps) {
562  EXPECT_WRITE32(SPI_DEVICE_ADDR_SWAP_MASK_REG_OFFSET, 0x10203456u);
563  EXPECT_WRITE32(SPI_DEVICE_ADDR_SWAP_DATA_REG_OFFSET, 0xffff0000u);
565  dif_spi_device_set_flash_address_swap(&spi_, 0x10203456u, 0xffff0000u));
566 
567  EXPECT_WRITE32(SPI_DEVICE_PAYLOAD_SWAP_MASK_REG_OFFSET, 0x24587001u);
568  EXPECT_WRITE32(SPI_DEVICE_PAYLOAD_SWAP_DATA_REG_OFFSET, 0xa5a5f00fu);
570  dif_spi_device_set_flash_payload_swap(&spi_, 0x24587001u, 0xa5a5f00fu));
571 }
572 
573 TEST_F(FlashTest, FifoOccupancy) {
574  uint8_t cmd_fifo_occupancy, addr_fifo_occupancy;
575  uint16_t payload_fifo_occupancy;
576  uint32_t payload_start_offset;
577  EXPECT_READ32(SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET,
578  {
579  {SPI_DEVICE_UPLOAD_STATUS_CMDFIFO_DEPTH_OFFSET, 3},
580  {SPI_DEVICE_UPLOAD_STATUS_CMDFIFO_NOTEMPTY_BIT, 1},
581  {SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_DEPTH_OFFSET, 2},
582  {SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_BIT, 1},
583  });
585  &spi_, &cmd_fifo_occupancy));
586  EXPECT_EQ(cmd_fifo_occupancy, 3);
587 
588  EXPECT_READ32(SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET,
589  {
590  {SPI_DEVICE_UPLOAD_STATUS_CMDFIFO_DEPTH_OFFSET, 0},
591  {SPI_DEVICE_UPLOAD_STATUS_CMDFIFO_NOTEMPTY_BIT, 0},
592  {SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_DEPTH_OFFSET, 2},
593  {SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_BIT, 1},
594  });
596  &spi_, &addr_fifo_occupancy));
597  EXPECT_EQ(addr_fifo_occupancy, 2);
598 
599  EXPECT_READ32(SPI_DEVICE_UPLOAD_STATUS2_REG_OFFSET,
600  {
601  {SPI_DEVICE_UPLOAD_STATUS2_PAYLOAD_DEPTH_OFFSET, 256},
602  {SPI_DEVICE_UPLOAD_STATUS2_PAYLOAD_START_IDX_OFFSET, 3},
603  });
605  &spi_, &payload_fifo_occupancy, &payload_start_offset));
606  EXPECT_EQ(payload_fifo_occupancy, 256);
607  EXPECT_EQ(payload_start_offset, 3);
608 }
609 
610 TEST_F(FlashTest, FifoPop) {
611  uint8_t command;
612  uint32_t address;
613  EXPECT_READ32(SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET,
614  {
615  {SPI_DEVICE_UPLOAD_STATUS_CMDFIFO_NOTEMPTY_BIT, 0},
616  {SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_BIT, 1},
617  });
618  EXPECT_EQ(dif_spi_device_pop_flash_command_fifo(&spi_, &command),
620 
621  EXPECT_READ32(SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET,
622  {
623  {SPI_DEVICE_UPLOAD_STATUS_CMDFIFO_NOTEMPTY_BIT, 1},
624  {SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_BIT, 1},
625  });
626  EXPECT_READ32(SPI_DEVICE_UPLOAD_CMDFIFO_REG_OFFSET, 0x06);
628  EXPECT_EQ(command, 0x06);
629 
630  EXPECT_READ32(SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET,
631  {
632  {SPI_DEVICE_UPLOAD_STATUS_CMDFIFO_NOTEMPTY_BIT, 1},
633  {SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_BIT, 0},
634  });
635  EXPECT_EQ(dif_spi_device_pop_flash_address_fifo(&spi_, &address),
637 
638  EXPECT_READ32(SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET,
639  {
640  {SPI_DEVICE_UPLOAD_STATUS_CMDFIFO_NOTEMPTY_BIT, 1},
641  {SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_BIT, 1},
642  });
643  EXPECT_READ32(SPI_DEVICE_UPLOAD_ADDRFIFO_REG_OFFSET, 0x76543210);
645  EXPECT_EQ(address, 0x76543210);
646 }
647 
648 TEST_F(FlashTest, MemoryOps) {
649  constexpr uint32_t kSfdpOffset = 3072;
650 
651  uint32_t buf[64];
652  for (uint32_t i = 0; i < (sizeof(buf) / sizeof(buf[0])); i++) {
653  buf[i] = i;
654  EXPECT_WRITE32(SPI_DEVICE_EGRESS_BUFFER_REG_OFFSET + kSfdpOffset +
655  i * sizeof(uint32_t),
656  i);
657  }
659  &spi_, kDifSpiDeviceFlashBufferTypeSfdp, /*offset=*/0,
660  /*length=*/sizeof(buf), reinterpret_cast<uint8_t *>(buf)));
661  for (uint32_t i = 4; i < (sizeof(buf) / sizeof(buf[0])); i++) {
662  EXPECT_READ32(SPI_DEVICE_INGRESS_BUFFER_REG_OFFSET + i * sizeof(uint32_t),
663  0x1000u - i);
664  }
666  &spi_, /*offset=*/16,
667  /*length=*/sizeof(buf) - 16, reinterpret_cast<uint8_t *>(buf)));
668  for (uint32_t i = 4; i < (sizeof(buf) / sizeof(buf[0])); i++) {
669  EXPECT_EQ(buf[i - 4], 0x1000u - i);
670  }
671 }
672 
673 TEST_F(FlashTest, CommandFilters) {
674  dif_toggle_t toggle;
675  EXPECT_READ32(SPI_DEVICE_CMD_FILTER_0_REG_OFFSET, 0xa5642301u);
677  &spi_, /*opcode=*/18, &toggle));
678  EXPECT_EQ(toggle, kDifToggleEnabled);
679 
680  EXPECT_READ32(SPI_DEVICE_CMD_FILTER_3_REG_OFFSET, 0xa5642301u);
682  &spi_, /*opcode=*/(3 * 32 + 19), &toggle));
683  EXPECT_EQ(toggle, kDifToggleDisabled);
684 
685  EXPECT_READ32(SPI_DEVICE_CMD_FILTER_0_REG_OFFSET, 0xa5a5a5a5u);
686  EXPECT_WRITE32(SPI_DEVICE_CMD_FILTER_0_REG_OFFSET, 0xa585a5a5u);
688  &spi_, /*opcode=*/21, kDifToggleDisabled));
689 
690  EXPECT_READ32(SPI_DEVICE_CMD_FILTER_7_REG_OFFSET, 0x5555aaaau);
691  EXPECT_WRITE32(SPI_DEVICE_CMD_FILTER_7_REG_OFFSET, 0x5555aaabu);
693  &spi_, /*opcode=*/224, kDifToggleEnabled));
694 
695  for (int i = 0; i < 8; i++) {
696  EXPECT_WRITE32(SPI_DEVICE_CMD_FILTER_0_REG_OFFSET + i * sizeof(uint32_t),
697  0);
698  }
700  &spi_, kDifToggleDisabled));
701 
702  for (int i = 0; i < 8; i++) {
703  EXPECT_WRITE32(SPI_DEVICE_CMD_FILTER_0_REG_OFFSET + i * sizeof(uint32_t),
704  UINT32_MAX);
705  }
707  &spi_, kDifToggleEnabled));
708 }
709 
710 TEST_F(FlashTest, StatusRegisters) {
711  uint32_t status;
712  EXPECT_READ32(SPI_DEVICE_FLASH_STATUS_REG_OFFSET,
713  {
714  {SPI_DEVICE_FLASH_STATUS_BUSY_BIT, 1},
715  {SPI_DEVICE_FLASH_STATUS_STATUS_OFFSET, 0x143200},
716  });
717  EXPECT_WRITE32(SPI_DEVICE_FLASH_STATUS_REG_OFFSET,
718  {
719  {SPI_DEVICE_FLASH_STATUS_BUSY_BIT, 0},
720  {SPI_DEVICE_FLASH_STATUS_STATUS_OFFSET, 0x143200},
721  });
723 
724  EXPECT_WRITE32(SPI_DEVICE_FLASH_STATUS_REG_OFFSET, 0x198234);
726  dif_spi_device_set_flash_status_registers(&spi_, /*status=*/0x198234));
727 
728  EXPECT_READ32(SPI_DEVICE_FLASH_STATUS_REG_OFFSET, 0x765432);
730  EXPECT_EQ(status, 0x765432);
731 
732  EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET,
733  {
734  {SPI_DEVICE_CONTROL_MODE_OFFSET,
735  SPI_DEVICE_CONTROL_MODE_VALUE_PASSTHROUGH},
736  {SPI_DEVICE_CONTROL_FLASH_STATUS_FIFO_CLR_BIT, 1},
737  });
739 }
740 
741 class TpmTest : public SpiTest {};
742 
743 TEST_F(TpmTest, NullArgs) {
748  uint8_t uint8_arg;
749  uint32_t uint32_arg;
757  dif_spi_device_tpm_set_access_reg(nullptr, /*locality=*/0, /*value=*/0));
759  dif_spi_device_tpm_get_access_reg(nullptr, /*locality=*/0, &uint8_arg));
761  dif_spi_device_tpm_get_access_reg(&spi_, /*locality=*/0, nullptr));
762  EXPECT_DIF_BADARG(dif_spi_device_tpm_set_sts_reg(nullptr, /*value=*/0));
763  EXPECT_DIF_BADARG(dif_spi_device_tpm_get_sts_reg(nullptr, &uint32_arg));
766  dif_spi_device_tpm_set_intf_capability_reg(nullptr, /*value=*/0));
768  dif_spi_device_tpm_get_intf_capability_reg(nullptr, &uint32_arg));
771  dif_spi_device_tpm_set_int_enable_reg(nullptr, /*value=*/0));
773  dif_spi_device_tpm_get_int_enable_reg(nullptr, &uint32_arg));
776  dif_spi_device_tpm_set_int_vector_reg(nullptr, /*value=*/0));
778  dif_spi_device_tpm_get_int_vector_reg(nullptr, &uint32_arg));
781  dif_spi_device_tpm_set_int_status_reg(nullptr, /*value=*/0));
783  dif_spi_device_tpm_get_int_status_reg(nullptr, &uint32_arg));
789  dif_spi_device_tpm_get_command(nullptr, &uint8_arg, &uint32_arg));
791  dif_spi_device_tpm_get_command(&spi_, nullptr, &uint32_arg));
792  EXPECT_DIF_BADARG(dif_spi_device_tpm_get_command(&spi_, &uint8_arg, nullptr));
794  dif_spi_device_tpm_write_data(nullptr, /*length=*/0, &uint8_arg));
796  dif_spi_device_tpm_write_data(&spi_, /*length=*/0, nullptr));
798  dif_spi_device_tpm_read_data(nullptr, /*length=*/0, &uint8_arg));
799  EXPECT_DIF_BADARG(dif_spi_device_tpm_read_data(&spi_, /*length=*/0, nullptr));
801 }
802 
803 TEST_F(TpmTest, InitDevice) {
805  EXPECT_READ32(SPI_DEVICE_TPM_CAP_REG_OFFSET,
806  {{SPI_DEVICE_TPM_CAP_REV_OFFSET, 3},
807  {SPI_DEVICE_TPM_CAP_LOCALITY_BIT, 1},
808  {SPI_DEVICE_TPM_CAP_MAX_WR_SIZE_OFFSET, 6},
809  {SPI_DEVICE_TPM_CAP_MAX_RD_SIZE_OFFSET, 6}});
811  EXPECT_EQ(caps.revision, 3);
812  EXPECT_TRUE(caps.multi_locality);
813  EXPECT_EQ(caps.max_write_size, 6);
814  EXPECT_EQ(caps.max_read_size, 6);
815 
816  dif_spi_device_tpm_config_t config = {
818  .disable_return_by_hardware = false,
819  .disable_address_prefix_check = true,
820  .disable_locality_check = true,
821  };
822  EXPECT_WRITE32(SPI_DEVICE_TPM_CFG_REG_OFFSET,
823  {
824  {SPI_DEVICE_TPM_CFG_EN_BIT, 1},
825  {SPI_DEVICE_TPM_CFG_TPM_MODE_BIT, 0},
826  {SPI_DEVICE_TPM_CFG_HW_REG_DIS_BIT, 0},
827  {SPI_DEVICE_TPM_CFG_TPM_REG_CHK_DIS_BIT, 1},
828  {SPI_DEVICE_TPM_CFG_INVALID_LOCALITY_BIT, 1},
829  });
831  EXPECT_WRITE32(SPI_DEVICE_TPM_CFG_REG_OFFSET,
832  {
833  {SPI_DEVICE_TPM_CFG_EN_BIT, 0},
834  });
837 }
838 
839 TEST_F(TpmTest, TpmAccess) {
840  uint8_t access;
841  EXPECT_READ32(SPI_DEVICE_TPM_ACCESS_0_REG_OFFSET,
842  {
843  {SPI_DEVICE_TPM_ACCESS_0_ACCESS_0_OFFSET, 6},
844  {SPI_DEVICE_TPM_ACCESS_0_ACCESS_1_OFFSET, 9},
845  {SPI_DEVICE_TPM_ACCESS_0_ACCESS_2_OFFSET, 10},
846  {SPI_DEVICE_TPM_ACCESS_0_ACCESS_3_OFFSET, 5},
847  });
848  EXPECT_WRITE32(SPI_DEVICE_TPM_ACCESS_0_REG_OFFSET,
849  {
850  {SPI_DEVICE_TPM_ACCESS_0_ACCESS_0_OFFSET, 6},
851  {SPI_DEVICE_TPM_ACCESS_0_ACCESS_1_OFFSET, 9},
852  {SPI_DEVICE_TPM_ACCESS_0_ACCESS_2_OFFSET, 78},
853  {SPI_DEVICE_TPM_ACCESS_0_ACCESS_3_OFFSET, 5},
854  });
856 
857  EXPECT_READ32(SPI_DEVICE_TPM_ACCESS_1_REG_OFFSET,
858  {{SPI_DEVICE_TPM_ACCESS_1_ACCESS_4_OFFSET, 3}});
859  EXPECT_WRITE32(SPI_DEVICE_TPM_ACCESS_1_REG_OFFSET,
860  {{SPI_DEVICE_TPM_ACCESS_1_ACCESS_4_OFFSET, 92}});
862 
863  EXPECT_READ32(SPI_DEVICE_TPM_ACCESS_0_REG_OFFSET,
864  {
865  {SPI_DEVICE_TPM_ACCESS_0_ACCESS_0_OFFSET, 0},
866  {SPI_DEVICE_TPM_ACCESS_0_ACCESS_1_OFFSET, 1},
867  {SPI_DEVICE_TPM_ACCESS_0_ACCESS_2_OFFSET, 2},
868  {SPI_DEVICE_TPM_ACCESS_0_ACCESS_3_OFFSET, 3},
869  });
871  EXPECT_EQ(access, 3);
872 
873  EXPECT_READ32(SPI_DEVICE_TPM_ACCESS_1_REG_OFFSET,
874  {{SPI_DEVICE_TPM_ACCESS_1_ACCESS_4_OFFSET, 4}});
876  EXPECT_EQ(access, 4);
877 }
878 
879 TEST_F(TpmTest, HardwareRegs32) {
880  uint32_t reg_val;
881  EXPECT_WRITE32(SPI_DEVICE_TPM_STS_REG_OFFSET, 0x12345678);
882  EXPECT_DIF_OK(dif_spi_device_tpm_set_sts_reg(&spi_, 0x12345678));
883  EXPECT_READ32(SPI_DEVICE_TPM_STS_REG_OFFSET, 0x76543210);
885  EXPECT_EQ(reg_val, 0x76543210);
886 
887  EXPECT_WRITE32(SPI_DEVICE_TPM_INTF_CAPABILITY_REG_OFFSET, 0x12345678);
889  EXPECT_READ32(SPI_DEVICE_TPM_INTF_CAPABILITY_REG_OFFSET, 0x76543210);
891  EXPECT_EQ(reg_val, 0x76543210);
892 
893  EXPECT_WRITE32(SPI_DEVICE_TPM_INT_ENABLE_REG_OFFSET, 0x12345678);
895  EXPECT_READ32(SPI_DEVICE_TPM_INT_ENABLE_REG_OFFSET, 0x76543210);
897  EXPECT_EQ(reg_val, 0x76543210);
898 
899  EXPECT_WRITE32(SPI_DEVICE_TPM_INT_VECTOR_REG_OFFSET, 0x12345678);
901  EXPECT_READ32(SPI_DEVICE_TPM_INT_VECTOR_REG_OFFSET, 0x76543210);
903  EXPECT_EQ(reg_val, 0x76543210);
904 
905  EXPECT_WRITE32(SPI_DEVICE_TPM_INT_STATUS_REG_OFFSET, 0x12345678);
907  EXPECT_READ32(SPI_DEVICE_TPM_INT_STATUS_REG_OFFSET, 0x76543210);
909  EXPECT_EQ(reg_val, 0x76543210);
910 }
911 
912 TEST_F(TpmTest, IdRegs) {
913  dif_spi_device_tpm_id_t tpm_id = {
914  .vendor_id = 0x1234,
915  .device_id = 0x5678,
916  .revision = 0xa5,
917  };
918  EXPECT_WRITE32(SPI_DEVICE_TPM_DID_VID_REG_OFFSET,
919  {
920  {SPI_DEVICE_TPM_DID_VID_VID_OFFSET, tpm_id.vendor_id},
921  {SPI_DEVICE_TPM_DID_VID_DID_OFFSET, tpm_id.device_id},
922  });
923  EXPECT_WRITE32(SPI_DEVICE_TPM_RID_REG_OFFSET,
924  {{SPI_DEVICE_TPM_RID_RID_OFFSET, tpm_id.revision}});
926 
927  EXPECT_READ32(SPI_DEVICE_TPM_DID_VID_REG_OFFSET,
928  {
929  {SPI_DEVICE_TPM_DID_VID_VID_OFFSET, 0x7654},
930  {SPI_DEVICE_TPM_DID_VID_DID_OFFSET, 0x3210},
931  });
932  EXPECT_READ32(SPI_DEVICE_TPM_RID_REG_OFFSET,
933  {{SPI_DEVICE_TPM_RID_RID_OFFSET, 0x68}});
934  EXPECT_DIF_OK(dif_spi_device_tpm_get_id(&spi_, &tpm_id));
935  EXPECT_EQ(tpm_id.vendor_id, 0x7654);
936  EXPECT_EQ(tpm_id.device_id, 0x3210);
937  EXPECT_EQ(tpm_id.revision, 0x68);
938 }
939 
940 TEST_F(TpmTest, CommandAndData) {
942  uint8_t command;
943  uint32_t address;
944  uint8_t data[4] = {17, 34, 51, 68};
945  uint32_t read_data[4];
946  EXPECT_READ32(SPI_DEVICE_TPM_STATUS_REG_OFFSET,
947  {
948  {SPI_DEVICE_TPM_STATUS_CMDADDR_NOTEMPTY_BIT, 0},
949  {SPI_DEVICE_TPM_STATUS_WRFIFO_PENDING_BIT, 1},
950  });
952  EXPECT_FALSE(status.cmd_addr_valid);
953  EXPECT_TRUE(status.wrfifo_acquired);
954 
955  EXPECT_READ32(SPI_DEVICE_TPM_STATUS_REG_OFFSET,
956  {
957  {SPI_DEVICE_TPM_STATUS_CMDADDR_NOTEMPTY_BIT, 1},
958  {SPI_DEVICE_TPM_STATUS_WRFIFO_PENDING_BIT, 0},
959  });
961  EXPECT_TRUE(status.cmd_addr_valid);
962  EXPECT_FALSE(status.wrfifo_acquired);
963 
964  EXPECT_READ32(SPI_DEVICE_TPM_CMD_ADDR_REG_OFFSET,
965  {
966  {SPI_DEVICE_TPM_CMD_ADDR_CMD_OFFSET, 0x43},
967  {SPI_DEVICE_TPM_CMD_ADDR_ADDR_OFFSET, 0xd40124},
968  });
969  EXPECT_DIF_OK(dif_spi_device_tpm_get_command(&spi_, &command, &address));
970  EXPECT_EQ(command, 0x43);
971  EXPECT_EQ(address, 0xd40124);
972 
973  EXPECT_READ32(SPI_DEVICE_TPM_STATUS_REG_OFFSET,
974  {
975  {SPI_DEVICE_TPM_STATUS_CMDADDR_NOTEMPTY_BIT, 0},
976  {SPI_DEVICE_TPM_STATUS_WRFIFO_PENDING_BIT, 0},
977  });
978  EXPECT_WRITE32(SPI_DEVICE_TPM_READ_FIFO_REG_OFFSET,
979  (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0]);
980 
981  EXPECT_DIF_OK(dif_spi_device_tpm_write_data(&spi_, /*length=*/3, data));
982 
983  for (uint32_t i = 0; i < 4; i++) {
984  constexpr uint32_t kSpiDeviceTpmWriteFifoOffset =
985  SPI_DEVICE_INGRESS_BUFFER_REG_OFFSET +
986  SPI_DEVICE_PARAM_SRAM_TPM_WR_FIFO_OFFSET * sizeof(uint32_t);
987  EXPECT_READ32(kSpiDeviceTpmWriteFifoOffset + i * sizeof(uint32_t), 18 * i);
988  }
990  dif_spi_device_tpm_read_data(&spi_, /*length=*/16, (uint8_t *)read_data));
991  for (int i = 0; i < 4; i++) {
992  EXPECT_EQ(read_data[i], 18 * i);
993  }
994  EXPECT_WRITE32(SPI_DEVICE_TPM_STATUS_REG_OFFSET, 0);
996 }
997 
998 } // namespace
999 } // namespace dif_spi_device_unittest