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 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 */ 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 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 */ 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 */ 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 */ 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 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 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 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 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 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 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