tests/qtest/ast2700-smc-test: Add Data FIFO mode test
Add two qtest cases exercising the new AST2700 Data FIFO-based flash access path (R_DATA_FIFO at spi_base + 0x200). Write_page_datafifo sends the page-program command and data through the FIFO port, then verifies the result via the regular read path. Read_page_datafifo writes a page the regular way, then reads it back through the FIFO port, so both directions are checked independently. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20260717084559.3477061-10-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
Jamin Lin committed
Jul 17, 2026 at 08:46 UTC
828872aa980ce747e835a4182f9958b9e6e7554c
3 files changed
+110
tests/qtest/aspeed-smc-utils.c
+102
@@ -57,6 +57,28 @@ static inline uint32_t flash_readl(const AspeedSMCTestData *data,
57
return qtest_readl(data->s, data->flash_base + offset);
58
}
59
60
+/*
61
+ * Data FIFO port, in spi_base's register bank (not flash_base). Accesses
62
+ * through the FIFO require the complete user-mode transaction (opcode,
63
+ * address, and data). Assumes CS0, whose FIFO slot is at R_DATA_FIFO.
64
+ */
65
+static inline void datafifo_writeb(const AspeedSMCTestData *data,
66
+ uint8_t value)
67
+{
68
+ qtest_writeb(data->s, data->spi_base + R_DATA_FIFO, value);
69
+}
70
+
71
+static inline void datafifo_writel(const AspeedSMCTestData *data,
72
+ uint32_t value)
73
+{
74
+ spi_writel(data, R_DATA_FIFO, value);
75
+}
76
+
77
+static inline uint32_t datafifo_readl(const AspeedSMCTestData *data)
78
+{
79
+ return spi_readl(data, R_DATA_FIFO);
80
+}
81
+
82
static void spi_conf(const AspeedSMCTestData *data, uint32_t value)
83
{
84
uint32_t conf = spi_readl(data, R_CONF);
@@ -826,3 +848,83 @@ void aspeed_smc_test_write_page_qor(const void *data)
848
{
849
test_write_page(data, read_page_qor);
850
}
851
+
852
+void aspeed_smc_test_write_page_datafifo(const void *data)
853
+{
854
+ const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
855
+ uint32_t my_page_addr = test_data->page_addr;
856
+ uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
857
+ uint32_t page[FLASH_PAGE_SIZE / 4];
858
+ int i;
859
+
860
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
861
+
862
+ /*
863
+ * Send the complete user-mode transaction (opcode, address, data)
864
+ * through the Data FIFO port.
865
+ */
866
+ spi_ctrl_start_user(test_data);
867
+ datafifo_writeb(test_data, EN_4BYTE_ADDR);
868
+ datafifo_writeb(test_data, WREN);
869
+ datafifo_writeb(test_data, PP);
870
+ datafifo_writel(test_data, make_be32(my_page_addr));
871
+
872
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
873
+ datafifo_writel(test_data, make_be32(my_page_addr + i * 4));
874
+ }
875
+ spi_ctrl_stop_user(test_data);
876
+
877
+ /* Check what was written, using the regular read path */
878
+ read_page(test_data, my_page_addr, page);
879
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
880
+ g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
881
+ }
882
+
883
+ /* Check some other page. It should be full of 0xff */
884
+ read_page(test_data, some_page_addr, page);
885
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
886
+ g_assert_cmphex(page[i], ==, 0xffffffff);
887
+ }
888
+
889
+ flash_reset(test_data);
890
+}
891
+
892
+void aspeed_smc_test_read_page_datafifo(const void *data)
893
+{
894
+ const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
895
+ uint32_t my_page_addr = test_data->page_addr;
896
+ uint32_t page[FLASH_PAGE_SIZE / 4];
897
+ int i;
898
+
899
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
900
+
901
+ /* Write the page the regular way */
902
+ spi_ctrl_start_user(test_data);
903
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
904
+ flash_writeb(test_data, 0, WREN);
905
+ flash_writeb(test_data, 0, PP);
906
+ flash_writel(test_data, 0, make_be32(my_page_addr));
907
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
908
+ flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
909
+ }
910
+ spi_ctrl_stop_user(test_data);
911
+
912
+ /*
913
+ * Read it back through the data FIFO port, again sending the whole
914
+ * transaction (opcode, address, data) through it.
915
+ */
916
+ spi_ctrl_start_user(test_data);
917
+ datafifo_writeb(test_data, EN_4BYTE_ADDR);
918
+ datafifo_writeb(test_data, READ);
919
+ datafifo_writel(test_data, make_be32(my_page_addr));
920
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
921
+ page[i] = make_be32(datafifo_readl(test_data));
922
+ }
923
+ spi_ctrl_stop_user(test_data);
924
+
925
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
926
+ g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
927
+ }
928
+
929
+ flash_reset(test_data);
930
+}
tests/qtest/aspeed-smc-utils.h
+4
@@ -33,6 +33,8 @@
33
#define CTRL_DUMMY_LOW_SHIFT 6
34
#define CTRL_DUMMY_HIGH_SHIFT 14
35
#define SR_WEL BIT(1)
36
+/* Data fifo */
37
+#define R_DATA_FIFO 0x200
38
39
/*
40
* Flash commands
@@ -87,5 +89,7 @@ void aspeed_smc_test_read_page_mem_dor(const void *data);
89
void aspeed_smc_test_write_page_dor(const void *data);
90
void aspeed_smc_test_read_page_mem_qor(const void *data);
91
void aspeed_smc_test_write_page_qor(const void *data);
92
+void aspeed_smc_test_write_page_datafifo(const void *data);
93
+void aspeed_smc_test_read_page_datafifo(const void *data);
94
95
#endif /* TESTS_ASPEED_SMC_UTILS_H */
tests/qtest/ast2700-smc-test.c
+4
@@ -64,6 +64,10 @@ static void test_ast2700_evb(AspeedSMCTestData *data)
64
data, aspeed_smc_test_read_page_mem_qor);
65
qtest_add_data_func("/ast2700/smc/write_page_qor",
66
data, aspeed_smc_test_write_page_qor);
67
+ qtest_add_data_func("/ast2700/smc/write_page_datafifo",
68
+ data, aspeed_smc_test_write_page_datafifo);
69
+ qtest_add_data_func("/ast2700/smc/read_page_datafifo",
70
+ data, aspeed_smc_test_read_page_datafifo);
71
}
72
73
int main(int argc, char **argv)