5 #include "sw/device/silicon_creator/lib/drivers/spi_device.h"
11 #include "gtest/gtest.h"
12 #include "sw/device/lib/base/mock_abs_mmio.h"
13 #include "sw/device/silicon_creator/lib/drivers/mock_lifecycle.h"
14 #include "sw/device/silicon_creator/lib/error.h"
15 #include "sw/device/silicon_creator/testing/rom_test.h"
17 #include "flash_ctrl_regs.h"
19 #include "spi_device_regs.h"
21 namespace spi_device_unittest {
23 using ::testing::NotNull;
24 using ::testing::SetArgPointee;
29 rom_test::MockAbsMmio mmio_;
30 rom_test::MockLifecycle lifecycle_;
36 EXPECT_ABS_WRITE32(base_ + SPI_DEVICE_CFG_REG_OFFSET,
38 {SPI_DEVICE_CFG_TX_ORDER_BIT, 0},
39 {SPI_DEVICE_CFG_RX_ORDER_BIT, 0},
40 {SPI_DEVICE_CFG_MAILBOX_EN_BIT, 0},
42 EXPECT_ABS_WRITE32(base_ + SPI_DEVICE_ADDR_MODE_REG_OFFSET,
44 {SPI_DEVICE_ADDR_MODE_ADDR_4B_EN_BIT, 0},
47 base_ + SPI_DEVICE_JEDEC_CC_REG_OFFSET,
49 {SPI_DEVICE_JEDEC_CC_CC_OFFSET, kSpiDeviceJedecContCode},
50 {SPI_DEVICE_JEDEC_CC_NUM_CC_OFFSET, kSpiDeviceJedecContCodeCount},
53 .silicon_creator_id = 5,
57 EXPECT_CALL(lifecycle_, HwRev(NotNull())).WillOnce(SetArgPointee<0>(hw_rev));
60 base_ + SPI_DEVICE_JEDEC_ID_REG_OFFSET,
62 {SPI_DEVICE_DEV_ID_CHIP_REV_FIELD.index, hw_rev.revision_id},
63 {SPI_DEVICE_DEV_ID_ROM_BOOTSTRAP_BIT, 1},
64 {SPI_DEVICE_DEV_ID_CHIP_GEN_FIELD.index, hw_rev.product_id},
65 {SPI_DEVICE_DEV_ID_DENSITY_FIELD.index,
67 FLASH_CTRL_PARAM_REG_NUM_BANKS *
68 FLASH_CTRL_PARAM_BYTES_PER_BANK)},
69 {SPI_DEVICE_JEDEC_ID_MF_OFFSET, kSpiDeviceJedecManufId},
72 std::array<uint32_t, kSpiDeviceSfdpAreaNumBytes /
sizeof(uint32_t)>
74 sfdp_buffer.fill(std::numeric_limits<uint32_t>::max());
75 std::memcpy(sfdp_buffer.data(), &kSpiDeviceSfdpTable,
76 sizeof(kSpiDeviceSfdpTable));
78 base_ + SPI_DEVICE_EGRESS_BUFFER_REG_OFFSET + kSpiDeviceSfdpAreaOffset;
79 for (
size_t i = 0; i < sfdp_buffer.size(); ++i) {
80 EXPECT_ABS_WRITE32(offset, sfdp_buffer[i]);
81 offset +=
sizeof(uint32_t);
84 EXPECT_ABS_WRITE32(base_ + SPI_DEVICE_FLASH_STATUS_REG_OFFSET, 0);
87 base_ + SPI_DEVICE_CMD_INFO_0_REG_OFFSET,
89 {SPI_DEVICE_CMD_INFO_0_OPCODE_0_OFFSET, kSpiDeviceOpcodeReadStatus},
90 {SPI_DEVICE_CMD_INFO_0_VALID_0_BIT, 1},
94 base_ + SPI_DEVICE_CMD_INFO_3_REG_OFFSET,
96 {SPI_DEVICE_CMD_INFO_3_OPCODE_3_OFFSET, kSpiDeviceOpcodeReadJedecId},
97 {SPI_DEVICE_CMD_INFO_3_VALID_3_BIT, 1},
101 base_ + SPI_DEVICE_CMD_INFO_4_REG_OFFSET,
103 {SPI_DEVICE_CMD_INFO_4_OPCODE_4_OFFSET, kSpiDeviceOpcodeReadSfdp},
104 {SPI_DEVICE_CMD_INFO_4_ADDR_MODE_4_OFFSET,
105 SPI_DEVICE_CMD_INFO_0_ADDR_MODE_0_VALUE_ADDR3B},
106 {SPI_DEVICE_CMD_INFO_4_DUMMY_SIZE_4_OFFSET, 7},
107 {SPI_DEVICE_CMD_INFO_4_DUMMY_EN_4_BIT, 1},
108 {SPI_DEVICE_CMD_INFO_4_VALID_4_BIT, 1},
112 base_ + SPI_DEVICE_CMD_INFO_11_REG_OFFSET,
114 {SPI_DEVICE_CMD_INFO_11_OPCODE_11_OFFSET, kSpiDeviceOpcodeChipErase},
115 {SPI_DEVICE_CMD_INFO_11_UPLOAD_11_BIT, 1},
116 {SPI_DEVICE_CMD_INFO_11_BUSY_11_BIT, 1},
117 {SPI_DEVICE_CMD_INFO_11_VALID_11_BIT, 1},
120 EXPECT_ABS_WRITE32(base_ + SPI_DEVICE_CMD_INFO_12_REG_OFFSET,
122 {SPI_DEVICE_CMD_INFO_12_OPCODE_12_OFFSET,
123 kSpiDeviceOpcodeSectorErase},
124 {SPI_DEVICE_CMD_INFO_12_ADDR_MODE_12_OFFSET,
125 SPI_DEVICE_CMD_INFO_0_ADDR_MODE_0_VALUE_ADDR3B},
126 {SPI_DEVICE_CMD_INFO_12_UPLOAD_12_BIT, 1},
127 {SPI_DEVICE_CMD_INFO_12_BUSY_12_BIT, 1},
128 {SPI_DEVICE_CMD_INFO_12_VALID_12_BIT, 1},
131 EXPECT_ABS_WRITE32(base_ + SPI_DEVICE_CMD_INFO_13_REG_OFFSET,
133 {SPI_DEVICE_CMD_INFO_13_OPCODE_13_OFFSET,
134 kSpiDeviceOpcodePageProgram},
135 {SPI_DEVICE_CMD_INFO_13_ADDR_MODE_13_OFFSET,
136 SPI_DEVICE_CMD_INFO_0_ADDR_MODE_0_VALUE_ADDR3B},
137 {SPI_DEVICE_CMD_INFO_13_UPLOAD_13_BIT, 1},
138 {SPI_DEVICE_CMD_INFO_13_BUSY_13_BIT, 1},
139 {SPI_DEVICE_CMD_INFO_13_VALID_13_BIT, 1},
143 base_ + SPI_DEVICE_CMD_INFO_14_REG_OFFSET,
145 {SPI_DEVICE_CMD_INFO_14_OPCODE_14_OFFSET, kSpiDeviceOpcodeReset},
146 {SPI_DEVICE_CMD_INFO_14_UPLOAD_14_BIT, 1},
147 {SPI_DEVICE_CMD_INFO_14_BUSY_14_BIT, 1},
148 {SPI_DEVICE_CMD_INFO_14_VALID_14_BIT, 1},
152 base_ + SPI_DEVICE_CMD_INFO_WREN_REG_OFFSET,
154 {SPI_DEVICE_CMD_INFO_WREN_OPCODE_OFFSET, kSpiDeviceOpcodeWriteEnable},
155 {SPI_DEVICE_CMD_INFO_WREN_VALID_BIT, 1},
158 EXPECT_ABS_WRITE32(base_ + SPI_DEVICE_CMD_INFO_WRDI_REG_OFFSET,
160 {SPI_DEVICE_CMD_INFO_WRDI_OPCODE_OFFSET,
161 kSpiDeviceOpcodeWriteDisable},
162 {SPI_DEVICE_CMD_INFO_WRDI_VALID_BIT, 1},
168 TEST_F(SpiDeviceTest, FlashStatusClear) {
169 EXPECT_ABS_WRITE32(base_ + SPI_DEVICE_FLASH_STATUS_REG_OFFSET, 0);
171 spi_device_flash_status_clear();
174 TEST_F(SpiDeviceTest, FlashStatusGet) {
175 EXPECT_ABS_READ32(base_ + SPI_DEVICE_FLASH_STATUS_REG_OFFSET, 0xa5);
177 EXPECT_EQ(0xa5, spi_device_flash_status_get());
181 spi_device_opcode_t opcode;
183 std::vector<uint8_t> payload;
187 public testing::WithParamInterface<CmdGetTestCase> {};
190 EXPECT_ABS_READ32(base_ + SPI_DEVICE_INTR_STATE_REG_OFFSET, 0);
191 EXPECT_ABS_READ32(base_ + SPI_DEVICE_INTR_STATE_REG_OFFSET,
193 {SPI_DEVICE_INTR_STATE_UPLOAD_CMDFIFO_NOT_EMPTY_BIT, 1},
194 {SPI_DEVICE_INTR_STATE_UPLOAD_PAYLOAD_OVERFLOW_BIT, 1},
196 EXPECT_ABS_WRITE32(base_ + SPI_DEVICE_INTR_STATE_REG_OFFSET,
197 std::numeric_limits<uint32_t>::max());
200 EXPECT_EQ(spi_device_cmd_get(&cmd), kErrorSpiDevicePayloadOverflow);
203 TEST_P(CmdGetTest, CmdGet) {
204 bool has_address = GetParam().address != kSpiDeviceNoAddress;
206 EXPECT_ABS_READ32(base_ + SPI_DEVICE_INTR_STATE_REG_OFFSET, 0);
207 EXPECT_ABS_READ32(base_ + SPI_DEVICE_INTR_STATE_REG_OFFSET,
208 {{SPI_DEVICE_INTR_STATE_UPLOAD_CMDFIFO_NOT_EMPTY_BIT, 1}});
209 EXPECT_ABS_WRITE32(base_ + SPI_DEVICE_INTR_STATE_REG_OFFSET,
210 std::numeric_limits<uint32_t>::max());
212 EXPECT_ABS_READ32(base_ + SPI_DEVICE_UPLOAD_CMDFIFO_REG_OFFSET,
216 base_ + SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET,
217 {{SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_BIT, has_address}});
219 EXPECT_ABS_READ32(base_ + SPI_DEVICE_UPLOAD_ADDRFIFO_REG_OFFSET,
223 std::vector<uint32_t> payload_area(kSpiDevicePayloadAreaNumWords,
224 std::numeric_limits<uint32_t>::max());
225 std::memcpy(payload_area.data(), GetParam().payload.data(),
226 GetParam().payload.size());
227 EXPECT_ABS_READ32(base_ + SPI_DEVICE_UPLOAD_STATUS2_REG_OFFSET,
228 {{SPI_DEVICE_UPLOAD_STATUS2_PAYLOAD_DEPTH_OFFSET,
229 GetParam().payload.size()}});
230 uint32_t offset = base_ + SPI_DEVICE_INGRESS_BUFFER_REG_OFFSET +
231 kSpiDevicePayloadAreaOffset;
232 for (
size_t i = 0; i < GetParam().payload.size(); i +=
sizeof(uint32_t)) {
233 EXPECT_ABS_READ32(offset + i, payload_area[i /
sizeof(uint32_t)]);
237 EXPECT_EQ(spi_device_cmd_get(&cmd), kErrorOk);
238 EXPECT_EQ(cmd.
opcode, GetParam().opcode);
239 EXPECT_EQ(cmd.
address, GetParam().address);
243 EXPECT_THAT(payload, GetParam().payload);
246 INSTANTIATE_TEST_SUITE_P(
247 CmdGetTestCases, CmdGetTest,
250 .opcode = kSpiDeviceOpcodeChipErase,
251 .address = kSpiDeviceNoAddress,
255 .opcode = kSpiDeviceOpcodeSectorErase,
260 .opcode = kSpiDeviceOpcodePageProgram,
262 .payload = {0x01, 0x02, 0x03, 0x04},
265 .opcode = kSpiDeviceOpcodePageProgram,
267 .payload = {0x01, 0x02, 0x03, 0x04, 0x05},
270 .opcode = kSpiDeviceOpcodePageProgram,
272 .payload = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
275 .opcode = kSpiDeviceOpcodePageProgram,
277 .payload = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07},
280 .opcode = kSpiDeviceOpcodePageProgram,
282 .payload = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},