1 /*
2 * QTest testcase for am53c974
3 *
4 * Copyright (c) 2021 Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2 or
7 * later. See the COPYING file in the top-level directory.
8 */
9
10 #include "qemu/osdep.h"
11
12 #include "libqtest.h"
13
14
test_cmdfifo_underflow_ok(void)15 static void test_cmdfifo_underflow_ok(void)
16 {
17 QTestState *s = qtest_init(
18 "-device am53c974,id=scsi "
19 "-device scsi-hd,drive=disk0 -drive "
20 "id=disk0,if=none,file=null-co://,format=raw -nodefaults");
21 qtest_outl(s, 0xcf8, 0x80001004);
22 qtest_outw(s, 0xcfc, 0x01);
23 qtest_outl(s, 0xcf8, 0x8000100e);
24 qtest_outl(s, 0xcfc, 0x8a000000);
25 qtest_outl(s, 0x8a09, 0x42000000);
26 qtest_outl(s, 0x8a0d, 0x00);
27 qtest_outl(s, 0x8a0b, 0x1000);
28 qtest_quit(s);
29 }
30
31 /* Reported as crash_1548bd10e7 */
test_cmdfifo_underflow2_ok(void)32 static void test_cmdfifo_underflow2_ok(void)
33 {
34 QTestState *s = qtest_init(
35 "-device am53c974,id=scsi -device scsi-hd,drive=disk0 "
36 "-drive id=disk0,if=none,file=null-co://,format=raw -nodefaults");
37 qtest_outl(s, 0xcf8, 0x80001010);
38 qtest_outl(s, 0xcfc, 0xc000);
39 qtest_outl(s, 0xcf8, 0x80001004);
40 qtest_outw(s, 0xcfc, 0x01);
41 qtest_outw(s, 0xc00c, 0x41);
42 qtest_outw(s, 0xc00a, 0x00);
43 qtest_outl(s, 0xc00a, 0x00);
44 qtest_outw(s, 0xc00c, 0x43);
45 qtest_outw(s, 0xc00b, 0x00);
46 qtest_outw(s, 0xc00b, 0x00);
47 qtest_outw(s, 0xc00c, 0x00);
48 qtest_outl(s, 0xc00a, 0x00);
49 qtest_outw(s, 0xc00a, 0x00);
50 qtest_outl(s, 0xc00a, 0x00);
51 qtest_outw(s, 0xc00c, 0x00);
52 qtest_outl(s, 0xc00a, 0x00);
53 qtest_outw(s, 0xc00a, 0x00);
54 qtest_outl(s, 0xc00a, 0x00);
55 qtest_outw(s, 0xc00c, 0x00);
56 qtest_outl(s, 0xc00a, 0x00);
57 qtest_outw(s, 0xc00a, 0x00);
58 qtest_outl(s, 0xc00a, 0x00);
59 qtest_outw(s, 0xc00c, 0x00);
60 qtest_outl(s, 0xc00a, 0x00);
61 qtest_outl(s, 0xc006, 0x00);
62 qtest_outl(s, 0xc00b, 0x00);
63 qtest_outw(s, 0xc00b, 0x0800);
64 qtest_outw(s, 0xc00b, 0x00);
65 qtest_outw(s, 0xc00b, 0x00);
66 qtest_outl(s, 0xc006, 0x00);
67 qtest_outl(s, 0xc00b, 0x00);
68 qtest_outw(s, 0xc00b, 0x0800);
69 qtest_outw(s, 0xc00b, 0x00);
70 qtest_outw(s, 0xc00b, 0x4100);
71 qtest_outw(s, 0xc00a, 0x00);
72 qtest_outl(s, 0xc00a, 0x100000);
73 qtest_outl(s, 0xc00a, 0x00);
74 qtest_outw(s, 0xc00c, 0x43);
75 qtest_outl(s, 0xc00a, 0x100000);
76 qtest_outl(s, 0xc00a, 0x100000);
77 qtest_quit(s);
78 }
79
test_cmdfifo_overflow_ok(void)80 static void test_cmdfifo_overflow_ok(void)
81 {
82 QTestState *s = qtest_init(
83 "-device am53c974,id=scsi "
84 "-device scsi-hd,drive=disk0 -drive "
85 "id=disk0,if=none,file=null-co://,format=raw -nodefaults");
86 qtest_outl(s, 0xcf8, 0x80001004);
87 qtest_outw(s, 0xcfc, 0x01);
88 qtest_outl(s, 0xcf8, 0x8000100e);
89 qtest_outl(s, 0xcfc, 0x0e000000);
90 qtest_outl(s, 0xe40, 0x03);
91 qtest_outl(s, 0xe0b, 0x4100);
92 qtest_outl(s, 0xe0b, 0x9000);
93 qtest_quit(s);
94 }
95
96 /* Reported as crash_530ff2e211 */
test_cmdfifo_overflow2_ok(void)97 static void test_cmdfifo_overflow2_ok(void)
98 {
99 QTestState *s = qtest_init(
100 "-device am53c974,id=scsi -device scsi-hd,drive=disk0 "
101 "-drive id=disk0,if=none,file=null-co://,format=raw -nodefaults");
102 qtest_outl(s, 0xcf8, 0x80001010);
103 qtest_outl(s, 0xcfc, 0xc000);
104 qtest_outl(s, 0xcf8, 0x80001004);
105 qtest_outw(s, 0xcfc, 0x01);
106 qtest_outl(s, 0xc00b, 0x4100);
107 qtest_outw(s, 0xc00b, 0xc200);
108 qtest_outl(s, 0xc03f, 0x0300);
109 qtest_quit(s);
110 }
111
112 /* Reported as https://issues.oss-fuzz.com/issues/439878564 */
test_cmdfifo_overflow3_ok(void)113 static void test_cmdfifo_overflow3_ok(void)
114 {
115 QTestState *s = qtest_init(
116 "-device am53c974,id=scsi -device scsi-hd,drive=disk0 "
117 "-drive id=disk0,if=none,file=null-co://,format=raw -nodefaults");
118 qtest_outl(s, 0xcf8, 0x80001010);
119 qtest_outl(s, 0xcfc, 0xc000);
120 qtest_outl(s, 0xcf8, 0x80001004);
121 qtest_outw(s, 0xcfc, 0x01);
122 qtest_outb(s, 0xc00c, 0x43);
123 qtest_outl(s, 0xc00b, 0x9100);
124 qtest_outl(s, 0xc009, 0x02000000);
125 qtest_outl(s, 0xc000, 0x0b);
126 qtest_outl(s, 0xc00b, 0x00);
127 qtest_outl(s, 0xc00b, 0x00);
128 qtest_outl(s, 0xc00b, 0xc200);
129 qtest_outl(s, 0xc00b, 0x1000);
130 qtest_outl(s, 0xc00b, 0x9000);
131 qtest_outb(s, 0xc008, 0x00);
132 qtest_outb(s, 0xc008, 0x00);
133 qtest_outl(s, 0xc03f, 0x0300);
134 qtest_outl(s, 0xc00b, 0x00);
135 qtest_outw(s, 0xc00b, 0x4200);
136 qtest_outl(s, 0xc00b, 0x00);
137 qtest_outw(s, 0xc00b, 0x1200);
138 qtest_outl(s, 0xc00b, 0x00);
139 qtest_outb(s, 0xc00c, 0x43);
140 qtest_outl(s, 0xc00b, 0x00);
141 qtest_outl(s, 0xc00b, 0x00);
142 qtest_outl(s, 0xc007, 0x00);
143 qtest_outl(s, 0xc007, 0x00);
144 qtest_outl(s, 0xc007, 0x00);
145 qtest_outl(s, 0xc00b, 0x1000);
146 qtest_outl(s, 0xc007, 0x00);
147 qtest_quit(s);
148 }
149
150 /* Reported as crash_0900379669 */
test_fifo_pop_buf(void)151 static void test_fifo_pop_buf(void)
152 {
153 QTestState *s = qtest_init(
154 "-device am53c974,id=scsi -device scsi-hd,drive=disk0 "
155 "-drive id=disk0,if=none,file=null-co://,format=raw -nodefaults");
156 qtest_outl(s, 0xcf8, 0x80001010);
157 qtest_outl(s, 0xcfc, 0xc000);
158 qtest_outl(s, 0xcf8, 0x80001004);
159 qtest_outw(s, 0xcfc, 0x01);
160 qtest_outb(s, 0xc000, 0x4);
161 qtest_outb(s, 0xc008, 0xa0);
162 qtest_outl(s, 0xc03f, 0x0300);
163 qtest_outl(s, 0xc00b, 0xc300);
164 qtest_outw(s, 0xc00b, 0x9000);
165 qtest_outl(s, 0xc00b, 0xc300);
166 qtest_outl(s, 0xc00b, 0xc300);
167 qtest_outl(s, 0xc00b, 0xc300);
168 qtest_outw(s, 0xc00b, 0x9000);
169 qtest_outw(s, 0xc00b, 0x1000);
170 qtest_quit(s);
171 }
172
test_target_selected_ok(void)173 static void test_target_selected_ok(void)
174 {
175 QTestState *s = qtest_init(
176 "-device am53c974,id=scsi "
177 "-device scsi-hd,drive=disk0 -drive "
178 "id=disk0,if=none,file=null-co://,format=raw -nodefaults");
179 qtest_outl(s, 0xcf8, 0x80001001);
180 qtest_outl(s, 0xcfc, 0x01000000);
181 qtest_outl(s, 0xcf8, 0x8000100e);
182 qtest_outl(s, 0xcfc, 0xef800000);
183 qtest_outl(s, 0xef8b, 0x4100);
184 qtest_outw(s, 0xef80, 0x01);
185 qtest_outl(s, 0xefc0, 0x03);
186 qtest_outl(s, 0xef8b, 0xc100);
187 qtest_outl(s, 0xef8b, 0x9000);
188 qtest_quit(s);
189 }
190
test_fifo_underflow_on_write_ok(void)191 static void test_fifo_underflow_on_write_ok(void)
192 {
193 QTestState *s = qtest_init(
194 "-device am53c974,id=scsi "
195 "-device scsi-hd,drive=disk0 -drive "
196 "id=disk0,if=none,file=null-co://,format=raw -nodefaults");
197 qtest_outl(s, 0xcf8, 0x80001010);
198 qtest_outl(s, 0xcfc, 0xc000);
199 qtest_outl(s, 0xcf8, 0x80001004);
200 qtest_outw(s, 0xcfc, 0x01);
201 qtest_outl(s, 0xc008, 0x0a);
202 qtest_outl(s, 0xc009, 0x41000000);
203 qtest_outl(s, 0xc009, 0x41000000);
204 qtest_outl(s, 0xc00b, 0x1000);
205 qtest_quit(s);
206 }
207
test_cancelled_request_ok(void)208 static void test_cancelled_request_ok(void)
209 {
210 QTestState *s = qtest_init(
211 "-device am53c974,id=scsi "
212 "-device scsi-hd,drive=disk0 -drive "
213 "id=disk0,if=none,file=null-co://,format=raw -nodefaults");
214 qtest_outl(s, 0xcf8, 0x80001010);
215 qtest_outl(s, 0xcfc, 0xc000);
216 qtest_outl(s, 0xcf8, 0x80001004);
217 qtest_outw(s, 0xcfc, 0x05);
218 qtest_outb(s, 0xc046, 0x02);
219 qtest_outl(s, 0xc00b, 0xc100);
220 qtest_outl(s, 0xc040, 0x03);
221 qtest_outl(s, 0xc040, 0x03);
222 qtest_bufwrite(s, 0x0, "\x41", 0x1);
223 qtest_outl(s, 0xc00b, 0xc100);
224 qtest_outw(s, 0xc040, 0x02);
225 qtest_outw(s, 0xc040, 0x81);
226 qtest_outl(s, 0xc00b, 0x9000);
227 qtest_quit(s);
228 }
229
test_inflight_cancel_ok(void)230 static void test_inflight_cancel_ok(void)
231 {
232 QTestState *s = qtest_init(
233 "-device am53c974,id=scsi "
234 "-device scsi-hd,drive=disk0 -drive "
235 "id=disk0,if=none,file=null-co://,format=raw -nodefaults");
236 qtest_outl(s, 0xcf8, 0x80001000);
237 qtest_inw(s, 0xcfc);
238 qtest_outl(s, 0xcf8, 0x80001010);
239 qtest_outl(s, 0xcfc, 0xffffffff);
240 qtest_outl(s, 0xcf8, 0x80001010);
241 qtest_inl(s, 0xcfc);
242 qtest_outl(s, 0xcf8, 0x80001010);
243 qtest_outl(s, 0xcfc, 0xc001);
244 qtest_outl(s, 0xcf8, 0x80001004);
245 qtest_inw(s, 0xcfc);
246 qtest_outl(s, 0xcf8, 0x80001004);
247 qtest_outw(s, 0xcfc, 0x7);
248 qtest_outl(s, 0xcf8, 0x80001004);
249 qtest_inw(s, 0xcfc);
250 qtest_inb(s, 0xc000);
251 qtest_outb(s, 0xc008, 0x8);
252 qtest_outw(s, 0xc00b, 0x4100);
253 qtest_outb(s, 0xc009, 0x0);
254 qtest_outb(s, 0xc009, 0x0);
255 qtest_outw(s, 0xc00b, 0xc212);
256 qtest_outl(s, 0xc042, 0x2c2c5a88);
257 qtest_outw(s, 0xc00b, 0xc212);
258 qtest_outw(s, 0xc00b, 0x415a);
259 qtest_outl(s, 0xc03f, 0x3060303);
260 qtest_outl(s, 0xc00b, 0x5afa9054);
261 qtest_quit(s);
262 }
263
test_reset_before_transfer_ok(void)264 static void test_reset_before_transfer_ok(void)
265 {
266 QTestState *s = qtest_init(
267 "-device am53c974,id=scsi "
268 "-device scsi-hd,drive=disk0 -drive "
269 "id=disk0,if=none,file=null-co://,format=raw -nodefaults");
270
271 qtest_outl(s, 0xcf8, 0x80001010);
272 qtest_outl(s, 0xcfc, 0xc000);
273 qtest_outl(s, 0xcf8, 0x80001004);
274 qtest_outw(s, 0xcfc, 0x01);
275 qtest_outl(s, 0xc007, 0x2500);
276 qtest_outl(s, 0xc00a, 0x410000);
277 qtest_outl(s, 0xc00a, 0x410000);
278 qtest_outw(s, 0xc00b, 0x0200);
279 qtest_outw(s, 0xc040, 0x03);
280 qtest_outw(s, 0xc009, 0x00);
281 qtest_outw(s, 0xc00b, 0x00);
282 qtest_outw(s, 0xc009, 0x00);
283 qtest_outw(s, 0xc00b, 0x00);
284 qtest_outw(s, 0xc009, 0x00);
285 qtest_outw(s, 0xc003, 0x1000);
286 qtest_outw(s, 0xc00b, 0x1000);
287 qtest_outl(s, 0xc00b, 0x9000);
288 qtest_outw(s, 0xc00b, 0x1000);
289 qtest_quit(s);
290 }
291
main(int argc,char ** argv)292 int main(int argc, char **argv)
293 {
294 const char *arch = qtest_get_arch();
295
296 g_test_init(&argc, &argv, NULL);
297
298 if (strcmp(arch, "i386") == 0) {
299 qtest_add_func("am53c974/test_cmdfifo_underflow_ok",
300 test_cmdfifo_underflow_ok);
301 qtest_add_func("am53c974/test_cmdfifo_underflow2_ok",
302 test_cmdfifo_underflow2_ok);
303 qtest_add_func("am53c974/test_cmdfifo_overflow_ok",
304 test_cmdfifo_overflow_ok);
305 qtest_add_func("am53c974/test_cmdfifo_overflow2_ok",
306 test_cmdfifo_overflow2_ok);
307 qtest_add_func("am53c974/test_cmdfifo_overflow3_ok",
308 test_cmdfifo_overflow3_ok);
309 qtest_add_func("am53c974/test_fifo_pop_buf",
310 test_fifo_pop_buf);
311 qtest_add_func("am53c974/test_target_selected_ok",
312 test_target_selected_ok);
313 qtest_add_func("am53c974/test_fifo_underflow_on_write_ok",
314 test_fifo_underflow_on_write_ok);
315 qtest_add_func("am53c974/test_cancelled_request_ok",
316 test_cancelled_request_ok);
317 qtest_add_func("am53c974/test_inflight_cancel_ok",
318 test_inflight_cancel_ok);
319 qtest_add_func("am53c974/test_reset_before_transfer_ok",
320 test_reset_before_transfer_ok);
321 }
322
323 return g_test_run();
324 }
325