master
c 200 lines 7.5 KB
Raw
1 /*
2 * QTest testcase for K230 GZIP decompression engine
3 *
4 * Copyright (c) 2026 Tao Ding <dingtao0430@163.com>
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9 #include "qemu/osdep.h"
10 #include "qemu/bitops.h"
11 #include "libqtest.h"
12 #include "hw/dma/k230_gsdma.h"
13 #include "hw/misc/k230_decomp_gzip.h"
14
15 #define K230_DECOMP_GZIP_BASE 0x80808000
16 #define K230_GSDMA_BASE 0x80800000
17 #define K230_SRAM_BASE 0x80200000
18 #define TEST_LLT_ADDR0 0x01000000
19 #define TEST_LLT_ADDR1 0x01000040
20 #define TEST_SRC_ADDR 0x01100000
21 #define TEST_DST_ADDR 0x01200000
22
23 #define TEST_PAYLOAD_LEN (sizeof(test_payload) - 1)
24
25 static inline uint64_t gzip_reg(hwaddr off)
26 {
27 return K230_DECOMP_GZIP_BASE + off;
28 }
29
30 static inline uint64_t gsdma_reg(hwaddr off)
31 {
32 return K230_GSDMA_BASE + off;
33 }
34
35 static inline uint64_t gsdma_ch_reg(unsigned int ch, hwaddr off)
36 {
37 return K230_GSDMA_BASE + K230_GSDMA_CH_BASE +
38 ch * K230_GSDMA_CH_STRIDE + off;
39 }
40
41 static inline hwaddr k230_sram_addr(hwaddr off)
42 {
43 return K230_SRAM_BASE + off;
44 }
45
46 static inline hwaddr k230_sram_input_addr(unsigned int slot)
47 {
48 return k230_sram_addr(K230_DECOMP_GZIP_SRAM_IN_BASE +
49 slot * K230_DECOMP_GZIP_BLOCK_SIZE);
50 }
51
52 /*
53 * test_gzip_data was generated by compressing test_payload in gzip format
54 * using Dynamic Huffman coding. The compression method byte in the gzip
55 * header was then changed from the standard value 0x08 to the K230-specific
56 * value 0x09.
57 */
58 static const uint8_t test_gzip_data[] = {
59 0x1f, 0x8b, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x04, 0x03, 0x05, 0xc1, 0xb1, 0x0d, 0x00, 0x20,
61 0x08, 0x04, 0xc0, 0x9e, 0x29, 0x7e, 0x04, 0x23,
62 0x63, 0x38, 0x85, 0x05, 0x21, 0x14, 0x10, 0x23,
63 0x5f, 0x39, 0xbd, 0x77, 0x6b, 0xea, 0x80, 0xbf,
64 0x38, 0x68, 0x5e, 0xdb, 0x19, 0xe5, 0xa0, 0x35,
65 0x65, 0x4d, 0x1d, 0xf0, 0x17, 0x07, 0xcd, 0x6b,
66 0x3b, 0xa3, 0x1c, 0xb4, 0xa6, 0xac, 0xa9, 0x03,
67 0xfe, 0xe2, 0xa0, 0x79, 0x6d, 0x67, 0x94, 0x83,
68 0xd6, 0x94, 0x35, 0x75, 0xc0, 0x5f, 0x1c, 0x34,
69 0xaf, 0xed, 0x8c, 0x72, 0xd0, 0x9a, 0xb2, 0xa6,
70 0x0e, 0xf8, 0x8b, 0x83, 0xe6, 0xb5, 0x9d, 0x51,
71 0x0e, 0x5a, 0x53, 0xd6, 0xd4, 0x01, 0x7f, 0x71,
72 0xd0, 0xbc, 0xb6, 0x33, 0xca, 0x41, 0x6b, 0xca,
73 0x9a, 0x3a, 0xe0, 0x2f, 0x0e, 0x9a, 0xd7, 0x76,
74 0x46, 0x39, 0x68, 0x4d, 0x59, 0x53, 0x07, 0xfc,
75 0xc5, 0x41, 0xf3, 0xda, 0xce, 0x28, 0x07, 0xad,
76 0x29, 0x1f, 0xdb, 0x9d, 0xbc, 0xdd, 0xc8, 0x00,
77 0x00, 0x00,
78 };
79
80 static const uint8_t test_payload[] =
81 "K230 gzip streaming test\n"
82 "K230 gzip streaming test\n"
83 "K230 gzip streaming test\n"
84 "K230 gzip streaming test\n"
85 "K230 gzip streaming test\n"
86 "K230 gzip streaming test\n"
87 "K230 gzip streaming test\n"
88 "K230 gzip streaming test\n";
89
90 static void write_sdma_llt_node(QTestState *qts, hwaddr addr, uint32_t src,
91 uint32_t dst, uint32_t len, uint32_t next)
92 {
93 qtest_writel(qts, addr + offsetof(K230GSDMALLT, cfg), 0);
94 qtest_writel(qts, addr + offsetof(K230GSDMALLT, src_addr), src);
95 qtest_writel(qts, addr + offsetof(K230GSDMALLT, line_size), len);
96 qtest_writel(qts, addr + offsetof(K230GSDMALLT, line_cfg), 0x1);
97 qtest_writel(qts, addr + offsetof(K230GSDMALLT, dst_addr), dst);
98 qtest_writel(qts, addr + offsetof(K230GSDMALLT, next_llt_addr), next);
99 }
100
101 static void test_reset_and_rw(void)
102 {
103 QTestState *qts = qtest_init("-machine k230");
104
105 g_assert_cmphex(qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_DECOMP_START)),
106 ==, 0);
107 g_assert_cmphex(qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_SRC_SIZE)),
108 ==, 0);
109 g_assert_cmphex(qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_OUT_SIZE)),
110 ==, 0);
111 g_assert_cmphex(qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_DECOMP_STAT)),
112 ==, 0);
113
114 qtest_writel(qts, gzip_reg(K230_DECOMP_GZIP_DECOMP_START),
115 K230_DECOMP_GZIP_START);
116
117 qtest_writel(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_SRC_SIZE), 0xffffffff);
118 g_assert_cmphex(qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_SRC_SIZE)),
119 ==, 0xffffffff);
120
121 qtest_writel(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_OUT_SIZE), 0x12345678);
122 g_assert_cmphex(qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_OUT_SIZE)),
123 ==, 0x12345678);
124
125 qtest_quit(qts);
126 }
127
128 static void test_gsdma_handshake_flow(void)
129 {
130 QTestState *qts = qtest_init("-machine k230");
131 uint32_t stat;
132 uint8_t output[TEST_PAYLOAD_LEN];
133
134 qtest_memwrite(qts, TEST_SRC_ADDR, test_gzip_data, sizeof(test_gzip_data));
135 write_sdma_llt_node(qts, TEST_LLT_ADDR0, TEST_SRC_ADDR,
136 k230_sram_input_addr(0),
137 sizeof(test_gzip_data), 0);
138 write_sdma_llt_node(qts, TEST_LLT_ADDR1,
139 k230_sram_addr(K230_DECOMP_GZIP_SRAM_OUT_BASE),
140 TEST_DST_ADDR, TEST_PAYLOAD_LEN, 0);
141
142 qtest_writel(qts, gsdma_reg(K230_GSDMA_DMA_CH_EN), BIT(0) | BIT(1));
143 qtest_writel(qts, gsdma_ch_reg(0, K230_GSDMA_CH_CFG),
144 K230_GSDMA_CH0_CFG_DECOMP_CTRL_EN);
145 qtest_writel(qts, gsdma_ch_reg(1, K230_GSDMA_CH_CFG), 0);
146 qtest_writel(qts, gsdma_ch_reg(0, K230_GSDMA_CH_LLT_SADDR), TEST_LLT_ADDR0);
147 qtest_writel(qts, gsdma_ch_reg(1, K230_GSDMA_CH_LLT_SADDR), TEST_LLT_ADDR1);
148 qtest_writel(qts, gsdma_ch_reg(0, K230_GSDMA_CH_CTL), K230_GSDMA_CTL_START);
149 qtest_writel(qts, gsdma_ch_reg(1, K230_GSDMA_CH_CTL), K230_GSDMA_CTL_START);
150
151 g_assert_cmphex(qtest_readl(qts, gsdma_reg(K230_GSDMA_DMA_CH_EN)),
152 ==, BIT(0) | BIT(1));
153 g_assert_cmphex(qtest_readl(qts, gsdma_ch_reg(0, K230_GSDMA_CH_CFG)) &
154 K230_GSDMA_CH0_CFG_DECOMP_CTRL_EN,
155 ==, K230_GSDMA_CH0_CFG_DECOMP_CTRL_EN);
156 g_assert_cmphex(qtest_readl(qts, gsdma_ch_reg(0, K230_GSDMA_CH_LLT_SADDR)),
157 ==, TEST_LLT_ADDR0);
158 g_assert_cmphex(qtest_readl(qts, gsdma_ch_reg(1, K230_GSDMA_CH_LLT_SADDR)),
159 ==, TEST_LLT_ADDR1);
160
161 qtest_writel(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_SRC_SIZE),
162 K230_DECOMP_GZIP_CTRL_EN | sizeof(test_gzip_data));
163 qtest_writel(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_OUT_SIZE),
164 TEST_PAYLOAD_LEN);
165 qtest_writel(qts, gzip_reg(K230_DECOMP_GZIP_DECOMP_START),
166 K230_DECOMP_GZIP_START);
167
168 stat = qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_DECOMP_STAT));
169 g_assert_cmphex(stat & K230_DECOMP_GZIP_STAT_CRC_OK, ==,
170 K230_DECOMP_GZIP_STAT_CRC_OK);
171
172 g_assert_cmphex(qtest_readl(qts,
173 gsdma_ch_reg(0, K230_GSDMA_CH_CURRENT_LLT)),
174 ==, TEST_LLT_ADDR0);
175 g_assert_cmphex(qtest_readl(qts,
176 gsdma_ch_reg(1, K230_GSDMA_CH_CURRENT_LLT)),
177 ==, TEST_LLT_ADDR1);
178
179 stat = qtest_readl(qts, gsdma_reg(K230_GSDMA_DMA_INT_STAT));
180 g_assert_cmphex(stat & K230_GSDMA_SDMA_DONE_INT(0), ==,
181 K230_GSDMA_SDMA_DONE_INT(0));
182 g_assert_cmphex(stat & K230_GSDMA_SDMA_DONE_INT(1), ==,
183 K230_GSDMA_SDMA_DONE_INT(1));
184
185 qtest_memread(qts, TEST_DST_ADDR, output, sizeof(output));
186 g_assert_cmpmem(output, sizeof(output), test_payload, TEST_PAYLOAD_LEN);
187
188 qtest_quit(qts);
189 }
190
191 int main(int argc, char **argv)
192 {
193 g_test_init(&argc, &argv, NULL);
194
195 qtest_add_func("/k230-decomp-gzip/reset-and-rw", test_reset_and_rw);
196 qtest_add_func("/k230-decomp-gzip/gsdma-handshake-flow",
197 test_gsdma_handshake_flow);
198
199 return g_test_run();
200 }