ahci-test.c (59257B)
1/* 2 * AHCI test cases 3 * 4 * Copyright (c) 2014 John Snow <jsnow@redhat.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25#include "qemu/osdep.h" 26#include <getopt.h> 27 28#include "libqos/libqtest.h" 29#include "libqos/libqos-pc.h" 30#include "libqos/ahci.h" 31#include "libqos/pci-pc.h" 32 33#include "qemu-common.h" 34#include "qapi/qmp/qdict.h" 35#include "qemu/host-utils.h" 36 37#include "hw/pci/pci_ids.h" 38#include "hw/pci/pci_regs.h" 39 40/* TODO actually test the results and get rid of this */ 41#define qmp_discard_response(s, ...) qobject_unref(qtest_qmp(s, __VA_ARGS__)) 42 43/* Test images sizes in MB */ 44#define TEST_IMAGE_SIZE_MB_LARGE (200 * 1024) 45#define TEST_IMAGE_SIZE_MB_SMALL 64 46 47/*** Globals ***/ 48static char tmp_path[] = "/tmp/qtest.XXXXXX"; 49static char debug_path[] = "/tmp/qtest-blkdebug.XXXXXX"; 50static char mig_socket[] = "/tmp/qtest-migration.XXXXXX"; 51static bool ahci_pedantic; 52static const char *imgfmt; 53static unsigned test_image_size_mb; 54 55/*** Function Declarations ***/ 56static void ahci_test_port_spec(AHCIQState *ahci, uint8_t port); 57static void ahci_test_pci_spec(AHCIQState *ahci); 58static void ahci_test_pci_caps(AHCIQState *ahci, uint16_t header, 59 uint8_t offset); 60static void ahci_test_satacap(AHCIQState *ahci, uint8_t offset); 61static void ahci_test_msicap(AHCIQState *ahci, uint8_t offset); 62static void ahci_test_pmcap(AHCIQState *ahci, uint8_t offset); 63 64/*** Utilities ***/ 65 66static uint64_t mb_to_sectors(uint64_t image_size_mb) 67{ 68 return (image_size_mb * 1024 * 1024) / AHCI_SECTOR_SIZE; 69} 70 71static void string_bswap16(uint16_t *s, size_t bytes) 72{ 73 g_assert_cmphex((bytes & 1), ==, 0); 74 bytes /= 2; 75 76 while (bytes--) { 77 *s = bswap16(*s); 78 s++; 79 } 80} 81 82/** 83 * Verify that the transfer did not corrupt our state at all. 84 */ 85static void verify_state(AHCIQState *ahci, uint64_t hba_old) 86{ 87 int i, j; 88 uint32_t ahci_fingerprint; 89 uint64_t hba_base; 90 AHCICommandHeader cmd; 91 92 ahci_fingerprint = qpci_config_readl(ahci->dev, PCI_VENDOR_ID); 93 g_assert_cmphex(ahci_fingerprint, ==, ahci->fingerprint); 94 95 /* If we haven't initialized, this is as much as can be validated. */ 96 if (!ahci->enabled) { 97 return; 98 } 99 100 hba_base = (uint64_t)qpci_config_readl(ahci->dev, PCI_BASE_ADDRESS_5); 101 g_assert_cmphex(hba_base, ==, hba_old); 102 103 g_assert_cmphex(ahci_rreg(ahci, AHCI_CAP), ==, ahci->cap); 104 g_assert_cmphex(ahci_rreg(ahci, AHCI_CAP2), ==, ahci->cap2); 105 106 for (i = 0; i < 32; i++) { 107 g_assert_cmphex(ahci_px_rreg(ahci, i, AHCI_PX_FB), ==, 108 ahci->port[i].fb); 109 g_assert_cmphex(ahci_px_rreg(ahci, i, AHCI_PX_CLB), ==, 110 ahci->port[i].clb); 111 for (j = 0; j < 32; j++) { 112 ahci_get_command_header(ahci, i, j, &cmd); 113 g_assert_cmphex(cmd.prdtl, ==, ahci->port[i].prdtl[j]); 114 g_assert_cmphex(cmd.ctba, ==, ahci->port[i].ctba[j]); 115 } 116 } 117} 118 119static void ahci_migrate(AHCIQState *from, AHCIQState *to, const char *uri) 120{ 121 QOSState *tmp = to->parent; 122 QPCIDevice *dev = to->dev; 123 char *uri_local = NULL; 124 uint64_t hba_old; 125 126 if (uri == NULL) { 127 uri_local = g_strdup_printf("%s%s", "unix:", mig_socket); 128 uri = uri_local; 129 } 130 131 hba_old = (uint64_t)qpci_config_readl(from->dev, PCI_BASE_ADDRESS_5); 132 133 /* context will be 'to' after completion. */ 134 migrate(from->parent, to->parent, uri); 135 136 /* We'd like for the AHCIState objects to still point 137 * to information specific to its specific parent 138 * instance, but otherwise just inherit the new data. */ 139 memcpy(to, from, sizeof(AHCIQState)); 140 to->parent = tmp; 141 to->dev = dev; 142 143 tmp = from->parent; 144 dev = from->dev; 145 memset(from, 0x00, sizeof(AHCIQState)); 146 from->parent = tmp; 147 from->dev = dev; 148 149 verify_state(to, hba_old); 150 g_free(uri_local); 151} 152 153/*** Test Setup & Teardown ***/ 154 155/** 156 * Start a Q35 machine and bookmark a handle to the AHCI device. 157 */ 158static AHCIQState *ahci_vboot(const char *cli, va_list ap) 159{ 160 AHCIQState *s; 161 162 s = g_new0(AHCIQState, 1); 163 s->parent = qtest_pc_vboot(cli, ap); 164 alloc_set_flags(&s->parent->alloc, ALLOC_LEAK_ASSERT); 165 166 /* Verify that we have an AHCI device present. */ 167 s->dev = get_ahci_device(s->parent->qts, &s->fingerprint); 168 169 return s; 170} 171 172/** 173 * Start a Q35 machine and bookmark a handle to the AHCI device. 174 */ 175static AHCIQState *ahci_boot(const char *cli, ...) 176{ 177 AHCIQState *s; 178 va_list ap; 179 180 if (cli) { 181 va_start(ap, cli); 182 s = ahci_vboot(cli, ap); 183 va_end(ap); 184 } else { 185 cli = "-drive if=none,id=drive0,file=%s,cache=writeback,format=%s" 186 " -M q35 " 187 "-device ide-hd,drive=drive0 " 188 "-global ide-hd.serial=%s " 189 "-global ide-hd.ver=%s"; 190 s = ahci_boot(cli, tmp_path, imgfmt, "testdisk", "version"); 191 } 192 193 return s; 194} 195 196/** 197 * Clean up the PCI device, then terminate the QEMU instance. 198 */ 199static void ahci_shutdown(AHCIQState *ahci) 200{ 201 QOSState *qs = ahci->parent; 202 203 ahci_clean_mem(ahci); 204 free_ahci_device(ahci->dev); 205 g_free(ahci); 206 qtest_shutdown(qs); 207} 208 209/** 210 * Boot and fully enable the HBA device. 211 * @see ahci_boot, ahci_pci_enable and ahci_hba_enable. 212 */ 213static AHCIQState *ahci_boot_and_enable(const char *cli, ...) 214{ 215 AHCIQState *ahci; 216 va_list ap; 217 uint16_t buff[256]; 218 uint8_t port; 219 uint8_t hello; 220 221 if (cli) { 222 va_start(ap, cli); 223 ahci = ahci_vboot(cli, ap); 224 va_end(ap); 225 } else { 226 ahci = ahci_boot(NULL); 227 } 228 229 ahci_pci_enable(ahci); 230 ahci_hba_enable(ahci); 231 /* Initialize test device */ 232 port = ahci_port_select(ahci); 233 ahci_port_clear(ahci, port); 234 if (is_atapi(ahci, port)) { 235 hello = CMD_PACKET_ID; 236 } else { 237 hello = CMD_IDENTIFY; 238 } 239 ahci_io(ahci, port, hello, &buff, sizeof(buff), 0); 240 241 return ahci; 242} 243 244/*** Specification Adherence Tests ***/ 245 246/** 247 * Implementation for test_pci_spec. Ensures PCI configuration space is sane. 248 */ 249static void ahci_test_pci_spec(AHCIQState *ahci) 250{ 251 uint8_t datab; 252 uint16_t data; 253 uint32_t datal; 254 255 /* Most of these bits should start cleared until we turn them on. */ 256 data = qpci_config_readw(ahci->dev, PCI_COMMAND); 257 ASSERT_BIT_CLEAR(data, PCI_COMMAND_MEMORY); 258 ASSERT_BIT_CLEAR(data, PCI_COMMAND_MASTER); 259 ASSERT_BIT_CLEAR(data, PCI_COMMAND_SPECIAL); /* Reserved */ 260 ASSERT_BIT_CLEAR(data, PCI_COMMAND_VGA_PALETTE); /* Reserved */ 261 ASSERT_BIT_CLEAR(data, PCI_COMMAND_PARITY); 262 ASSERT_BIT_CLEAR(data, PCI_COMMAND_WAIT); /* Reserved */ 263 ASSERT_BIT_CLEAR(data, PCI_COMMAND_SERR); 264 ASSERT_BIT_CLEAR(data, PCI_COMMAND_FAST_BACK); 265 ASSERT_BIT_CLEAR(data, PCI_COMMAND_INTX_DISABLE); 266 ASSERT_BIT_CLEAR(data, 0xF800); /* Reserved */ 267 268 data = qpci_config_readw(ahci->dev, PCI_STATUS); 269 ASSERT_BIT_CLEAR(data, 0x01 | 0x02 | 0x04); /* Reserved */ 270 ASSERT_BIT_CLEAR(data, PCI_STATUS_INTERRUPT); 271 ASSERT_BIT_SET(data, PCI_STATUS_CAP_LIST); /* must be set */ 272 ASSERT_BIT_CLEAR(data, PCI_STATUS_UDF); /* Reserved */ 273 ASSERT_BIT_CLEAR(data, PCI_STATUS_PARITY); 274 ASSERT_BIT_CLEAR(data, PCI_STATUS_SIG_TARGET_ABORT); 275 ASSERT_BIT_CLEAR(data, PCI_STATUS_REC_TARGET_ABORT); 276 ASSERT_BIT_CLEAR(data, PCI_STATUS_REC_MASTER_ABORT); 277 ASSERT_BIT_CLEAR(data, PCI_STATUS_SIG_SYSTEM_ERROR); 278 ASSERT_BIT_CLEAR(data, PCI_STATUS_DETECTED_PARITY); 279 280 /* RID occupies the low byte, CCs occupy the high three. */ 281 datal = qpci_config_readl(ahci->dev, PCI_CLASS_REVISION); 282 if (ahci_pedantic) { 283 /* AHCI 1.3 specifies that at-boot, the RID should reset to 0x00, 284 * Though in practice this is likely seldom true. */ 285 ASSERT_BIT_CLEAR(datal, 0xFF); 286 } 287 288 /* BCC *must* equal 0x01. */ 289 g_assert_cmphex(PCI_BCC(datal), ==, 0x01); 290 if (PCI_SCC(datal) == 0x01) { 291 /* IDE */ 292 ASSERT_BIT_SET(0x80000000, datal); 293 ASSERT_BIT_CLEAR(0x60000000, datal); 294 } else if (PCI_SCC(datal) == 0x04) { 295 /* RAID */ 296 g_assert_cmphex(PCI_PI(datal), ==, 0); 297 } else if (PCI_SCC(datal) == 0x06) { 298 /* AHCI */ 299 g_assert_cmphex(PCI_PI(datal), ==, 0x01); 300 } else { 301 g_assert_not_reached(); 302 } 303 304 datab = qpci_config_readb(ahci->dev, PCI_CACHE_LINE_SIZE); 305 g_assert_cmphex(datab, ==, 0); 306 307 datab = qpci_config_readb(ahci->dev, PCI_LATENCY_TIMER); 308 g_assert_cmphex(datab, ==, 0); 309 310 /* Only the bottom 7 bits must be off. */ 311 datab = qpci_config_readb(ahci->dev, PCI_HEADER_TYPE); 312 ASSERT_BIT_CLEAR(datab, 0x7F); 313 314 /* BIST is optional, but the low 7 bits must always start off regardless. */ 315 datab = qpci_config_readb(ahci->dev, PCI_BIST); 316 ASSERT_BIT_CLEAR(datab, 0x7F); 317 318 /* BARS 0-4 do not have a boot spec, but ABAR/BAR5 must be clean. */ 319 datal = qpci_config_readl(ahci->dev, PCI_BASE_ADDRESS_5); 320 g_assert_cmphex(datal, ==, 0); 321 322 qpci_config_writel(ahci->dev, PCI_BASE_ADDRESS_5, 0xFFFFFFFF); 323 datal = qpci_config_readl(ahci->dev, PCI_BASE_ADDRESS_5); 324 /* ABAR must be 32-bit, memory mapped, non-prefetchable and 325 * must be >= 512 bytes. To that end, bits 0-8 must be off. */ 326 ASSERT_BIT_CLEAR(datal, 0xFF); 327 328 /* Capability list MUST be present, */ 329 datal = qpci_config_readl(ahci->dev, PCI_CAPABILITY_LIST); 330 /* But these bits are reserved. */ 331 ASSERT_BIT_CLEAR(datal, ~0xFF); 332 g_assert_cmphex(datal, !=, 0); 333 334 /* Check specification adherence for capability extenstions. */ 335 data = qpci_config_readw(ahci->dev, datal); 336 337 switch (ahci->fingerprint) { 338 case AHCI_INTEL_ICH9: 339 /* Intel ICH9 Family Datasheet 14.1.19 p.550 */ 340 g_assert_cmphex((data & 0xFF), ==, PCI_CAP_ID_MSI); 341 break; 342 default: 343 /* AHCI 1.3, Section 2.1.14 -- CAP must point to PMCAP. */ 344 g_assert_cmphex((data & 0xFF), ==, PCI_CAP_ID_PM); 345 } 346 347 ahci_test_pci_caps(ahci, data, (uint8_t)datal); 348 349 /* Reserved. */ 350 datal = qpci_config_readl(ahci->dev, PCI_CAPABILITY_LIST + 4); 351 g_assert_cmphex(datal, ==, 0); 352 353 /* IPIN might vary, but ILINE must be off. */ 354 datab = qpci_config_readb(ahci->dev, PCI_INTERRUPT_LINE); 355 g_assert_cmphex(datab, ==, 0); 356} 357 358/** 359 * Test PCI capabilities for AHCI specification adherence. 360 */ 361static void ahci_test_pci_caps(AHCIQState *ahci, uint16_t header, 362 uint8_t offset) 363{ 364 uint8_t cid = header & 0xFF; 365 uint8_t next = header >> 8; 366 367 g_test_message("CID: %02x; next: %02x", cid, next); 368 369 switch (cid) { 370 case PCI_CAP_ID_PM: 371 ahci_test_pmcap(ahci, offset); 372 break; 373 case PCI_CAP_ID_MSI: 374 ahci_test_msicap(ahci, offset); 375 break; 376 case PCI_CAP_ID_SATA: 377 ahci_test_satacap(ahci, offset); 378 break; 379 380 default: 381 g_test_message("Unknown CAP 0x%02x", cid); 382 } 383 384 if (next) { 385 ahci_test_pci_caps(ahci, qpci_config_readw(ahci->dev, next), next); 386 } 387} 388 389/** 390 * Test SATA PCI capabilitity for AHCI specification adherence. 391 */ 392static void ahci_test_satacap(AHCIQState *ahci, uint8_t offset) 393{ 394 uint16_t dataw; 395 uint32_t datal; 396 397 g_test_message("Verifying SATACAP"); 398 399 /* Assert that the SATACAP version is 1.0, And reserved bits are empty. */ 400 dataw = qpci_config_readw(ahci->dev, offset + 2); 401 g_assert_cmphex(dataw, ==, 0x10); 402 403 /* Grab the SATACR1 register. */ 404 datal = qpci_config_readw(ahci->dev, offset + 4); 405 406 switch (datal & 0x0F) { 407 case 0x04: /* BAR0 */ 408 case 0x05: /* BAR1 */ 409 case 0x06: 410 case 0x07: 411 case 0x08: 412 case 0x09: /* BAR5 */ 413 case 0x0F: /* Immediately following SATACR1 in PCI config space. */ 414 break; 415 default: 416 /* Invalid BARLOC for the Index Data Pair. */ 417 g_assert_not_reached(); 418 } 419 420 /* Reserved. */ 421 g_assert_cmphex((datal >> 24), ==, 0x00); 422} 423 424/** 425 * Test MSI PCI capability for AHCI specification adherence. 426 */ 427static void ahci_test_msicap(AHCIQState *ahci, uint8_t offset) 428{ 429 uint16_t dataw; 430 uint32_t datal; 431 432 g_test_message("Verifying MSICAP"); 433 434 dataw = qpci_config_readw(ahci->dev, offset + PCI_MSI_FLAGS); 435 ASSERT_BIT_CLEAR(dataw, PCI_MSI_FLAGS_ENABLE); 436 ASSERT_BIT_CLEAR(dataw, PCI_MSI_FLAGS_QSIZE); 437 ASSERT_BIT_CLEAR(dataw, PCI_MSI_FLAGS_RESERVED); 438 439 datal = qpci_config_readl(ahci->dev, offset + PCI_MSI_ADDRESS_LO); 440 g_assert_cmphex(datal, ==, 0); 441 442 if (dataw & PCI_MSI_FLAGS_64BIT) { 443 g_test_message("MSICAP is 64bit"); 444 datal = qpci_config_readl(ahci->dev, offset + PCI_MSI_ADDRESS_HI); 445 g_assert_cmphex(datal, ==, 0); 446 dataw = qpci_config_readw(ahci->dev, offset + PCI_MSI_DATA_64); 447 g_assert_cmphex(dataw, ==, 0); 448 } else { 449 g_test_message("MSICAP is 32bit"); 450 dataw = qpci_config_readw(ahci->dev, offset + PCI_MSI_DATA_32); 451 g_assert_cmphex(dataw, ==, 0); 452 } 453} 454 455/** 456 * Test Power Management PCI capability for AHCI specification adherence. 457 */ 458static void ahci_test_pmcap(AHCIQState *ahci, uint8_t offset) 459{ 460 uint16_t dataw; 461 462 g_test_message("Verifying PMCAP"); 463 464 dataw = qpci_config_readw(ahci->dev, offset + PCI_PM_PMC); 465 ASSERT_BIT_CLEAR(dataw, PCI_PM_CAP_PME_CLOCK); 466 ASSERT_BIT_CLEAR(dataw, PCI_PM_CAP_RESERVED); 467 ASSERT_BIT_CLEAR(dataw, PCI_PM_CAP_D1); 468 ASSERT_BIT_CLEAR(dataw, PCI_PM_CAP_D2); 469 470 dataw = qpci_config_readw(ahci->dev, offset + PCI_PM_CTRL); 471 ASSERT_BIT_CLEAR(dataw, PCI_PM_CTRL_STATE_MASK); 472 ASSERT_BIT_CLEAR(dataw, PCI_PM_CTRL_RESERVED); 473 ASSERT_BIT_CLEAR(dataw, PCI_PM_CTRL_DATA_SEL_MASK); 474 ASSERT_BIT_CLEAR(dataw, PCI_PM_CTRL_DATA_SCALE_MASK); 475} 476 477static void ahci_test_hba_spec(AHCIQState *ahci) 478{ 479 unsigned i; 480 uint32_t reg; 481 uint32_t ports; 482 uint8_t nports_impl; 483 uint8_t maxports; 484 485 g_assert(ahci != NULL); 486 487 /* 488 * Note that the AHCI spec does expect the BIOS to set up a few things: 489 * CAP.SSS - Support for staggered spin-up (t/f) 490 * CAP.SMPS - Support for mechanical presence switches (t/f) 491 * PI - Ports Implemented (1-32) 492 * PxCMD.HPCP - Hot Plug Capable Port 493 * PxCMD.MPSP - Mechanical Presence Switch Present 494 * PxCMD.CPD - Cold Presence Detection support 495 * 496 * Additional items are touched if CAP.SSS is on, see AHCI 10.1.1 p.97: 497 * Foreach Port Implemented: 498 * -PxCMD.ST, PxCMD.CR, PxCMD.FRE, PxCMD.FR, PxSCTL.DET are 0 499 * -PxCLB/U and PxFB/U are set to valid regions in memory 500 * -PxSUD is set to 1. 501 * -PxSSTS.DET is polled for presence; if detected, we continue: 502 * -PxSERR is cleared with 1's. 503 * -If PxTFD.STS.BSY, PxTFD.STS.DRQ, and PxTFD.STS.ERR are all zero, 504 * the device is ready. 505 */ 506 507 /* 1 CAP - Capabilities Register */ 508 ahci->cap = ahci_rreg(ahci, AHCI_CAP); 509 ASSERT_BIT_CLEAR(ahci->cap, AHCI_CAP_RESERVED); 510 511 /* 2 GHC - Global Host Control */ 512 reg = ahci_rreg(ahci, AHCI_GHC); 513 ASSERT_BIT_CLEAR(reg, AHCI_GHC_HR); 514 ASSERT_BIT_CLEAR(reg, AHCI_GHC_IE); 515 ASSERT_BIT_CLEAR(reg, AHCI_GHC_MRSM); 516 if (BITSET(ahci->cap, AHCI_CAP_SAM)) { 517 g_test_message("Supports AHCI-Only Mode: GHC_AE is Read-Only."); 518 ASSERT_BIT_SET(reg, AHCI_GHC_AE); 519 } else { 520 g_test_message("Supports AHCI/Legacy mix."); 521 ASSERT_BIT_CLEAR(reg, AHCI_GHC_AE); 522 } 523 524 /* 3 IS - Interrupt Status */ 525 reg = ahci_rreg(ahci, AHCI_IS); 526 g_assert_cmphex(reg, ==, 0); 527 528 /* 4 PI - Ports Implemented */ 529 ports = ahci_rreg(ahci, AHCI_PI); 530 /* Ports Implemented must be non-zero. */ 531 g_assert_cmphex(ports, !=, 0); 532 /* Ports Implemented must be <= Number of Ports. */ 533 nports_impl = ctpopl(ports); 534 g_assert_cmpuint(((AHCI_CAP_NP & ahci->cap) + 1), >=, nports_impl); 535 536 /* Ports must be within the proper range. Given a mapping of SIZE, 537 * 256 bytes are used for global HBA control, and the rest is used 538 * for ports data, at 0x80 bytes each. */ 539 g_assert_cmphex(ahci->barsize, >, 0); 540 maxports = (ahci->barsize - HBA_DATA_REGION_SIZE) / HBA_PORT_DATA_SIZE; 541 /* e.g, 30 ports for 4K of memory. (4096 - 256) / 128 = 30 */ 542 g_assert_cmphex((reg >> maxports), ==, 0); 543 544 /* 5 AHCI Version */ 545 reg = ahci_rreg(ahci, AHCI_VS); 546 switch (reg) { 547 case AHCI_VERSION_0_95: 548 case AHCI_VERSION_1_0: 549 case AHCI_VERSION_1_1: 550 case AHCI_VERSION_1_2: 551 case AHCI_VERSION_1_3: 552 break; 553 default: 554 g_assert_not_reached(); 555 } 556 557 /* 6 Command Completion Coalescing Control: depends on CAP.CCCS. */ 558 reg = ahci_rreg(ahci, AHCI_CCCCTL); 559 if (BITSET(ahci->cap, AHCI_CAP_CCCS)) { 560 ASSERT_BIT_CLEAR(reg, AHCI_CCCCTL_EN); 561 ASSERT_BIT_CLEAR(reg, AHCI_CCCCTL_RESERVED); 562 ASSERT_BIT_SET(reg, AHCI_CCCCTL_CC); 563 ASSERT_BIT_SET(reg, AHCI_CCCCTL_TV); 564 } else { 565 g_assert_cmphex(reg, ==, 0); 566 } 567 568 /* 7 CCC_PORTS */ 569 reg = ahci_rreg(ahci, AHCI_CCCPORTS); 570 /* Must be zeroes initially regardless of CAP.CCCS */ 571 g_assert_cmphex(reg, ==, 0); 572 573 /* 8 EM_LOC */ 574 reg = ahci_rreg(ahci, AHCI_EMLOC); 575 if (BITCLR(ahci->cap, AHCI_CAP_EMS)) { 576 g_assert_cmphex(reg, ==, 0); 577 } 578 579 /* 9 EM_CTL */ 580 reg = ahci_rreg(ahci, AHCI_EMCTL); 581 if (BITSET(ahci->cap, AHCI_CAP_EMS)) { 582 ASSERT_BIT_CLEAR(reg, AHCI_EMCTL_STSMR); 583 ASSERT_BIT_CLEAR(reg, AHCI_EMCTL_CTLTM); 584 ASSERT_BIT_CLEAR(reg, AHCI_EMCTL_CTLRST); 585 ASSERT_BIT_CLEAR(reg, AHCI_EMCTL_RESERVED); 586 } else { 587 g_assert_cmphex(reg, ==, 0); 588 } 589 590 /* 10 CAP2 -- Capabilities Extended */ 591 ahci->cap2 = ahci_rreg(ahci, AHCI_CAP2); 592 ASSERT_BIT_CLEAR(ahci->cap2, AHCI_CAP2_RESERVED); 593 594 /* 11 BOHC -- Bios/OS Handoff Control */ 595 reg = ahci_rreg(ahci, AHCI_BOHC); 596 g_assert_cmphex(reg, ==, 0); 597 598 /* 12 -- 23: Reserved */ 599 g_test_message("Verifying HBA reserved area is empty."); 600 for (i = AHCI_RESERVED; i < AHCI_NVMHCI; ++i) { 601 reg = ahci_rreg(ahci, i); 602 g_assert_cmphex(reg, ==, 0); 603 } 604 605 /* 24 -- 39: NVMHCI */ 606 if (BITCLR(ahci->cap2, AHCI_CAP2_NVMP)) { 607 g_test_message("Verifying HBA/NVMHCI area is empty."); 608 for (i = AHCI_NVMHCI; i < AHCI_VENDOR; ++i) { 609 reg = ahci_rreg(ahci, i); 610 g_assert_cmphex(reg, ==, 0); 611 } 612 } 613 614 /* 40 -- 63: Vendor */ 615 g_test_message("Verifying HBA/Vendor area is empty."); 616 for (i = AHCI_VENDOR; i < AHCI_PORTS; ++i) { 617 reg = ahci_rreg(ahci, i); 618 g_assert_cmphex(reg, ==, 0); 619 } 620 621 /* 64 -- XX: Port Space */ 622 for (i = 0; ports || (i < maxports); ports >>= 1, ++i) { 623 if (BITSET(ports, 0x1)) { 624 g_test_message("Testing port %u for spec", i); 625 ahci_test_port_spec(ahci, i); 626 } else { 627 uint16_t j; 628 uint16_t low = AHCI_PORTS + (32 * i); 629 uint16_t high = AHCI_PORTS + (32 * (i + 1)); 630 g_test_message("Asserting unimplemented port %u " 631 "(reg [%u-%u]) is empty.", 632 i, low, high - 1); 633 for (j = low; j < high; ++j) { 634 reg = ahci_rreg(ahci, j); 635 g_assert_cmphex(reg, ==, 0); 636 } 637 } 638 } 639} 640 641/** 642 * Test the memory space for one port for specification adherence. 643 */ 644static void ahci_test_port_spec(AHCIQState *ahci, uint8_t port) 645{ 646 uint32_t reg; 647 unsigned i; 648 649 /* (0) CLB */ 650 reg = ahci_px_rreg(ahci, port, AHCI_PX_CLB); 651 ASSERT_BIT_CLEAR(reg, AHCI_PX_CLB_RESERVED); 652 653 /* (1) CLBU */ 654 if (BITCLR(ahci->cap, AHCI_CAP_S64A)) { 655 reg = ahci_px_rreg(ahci, port, AHCI_PX_CLBU); 656 g_assert_cmphex(reg, ==, 0); 657 } 658 659 /* (2) FB */ 660 reg = ahci_px_rreg(ahci, port, AHCI_PX_FB); 661 ASSERT_BIT_CLEAR(reg, AHCI_PX_FB_RESERVED); 662 663 /* (3) FBU */ 664 if (BITCLR(ahci->cap, AHCI_CAP_S64A)) { 665 reg = ahci_px_rreg(ahci, port, AHCI_PX_FBU); 666 g_assert_cmphex(reg, ==, 0); 667 } 668 669 /* (4) IS */ 670 reg = ahci_px_rreg(ahci, port, AHCI_PX_IS); 671 g_assert_cmphex(reg, ==, 0); 672 673 /* (5) IE */ 674 reg = ahci_px_rreg(ahci, port, AHCI_PX_IE); 675 g_assert_cmphex(reg, ==, 0); 676 677 /* (6) CMD */ 678 reg = ahci_px_rreg(ahci, port, AHCI_PX_CMD); 679 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_FRE); 680 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_RESERVED); 681 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_CCS); 682 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_FR); 683 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_CR); 684 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_PMA); /* And RW only if CAP.SPM */ 685 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_APSTE); /* RW only if CAP2.APST */ 686 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_ATAPI); 687 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_DLAE); 688 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_ALPE); /* RW only if CAP.SALP */ 689 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_ASP); /* RW only if CAP.SALP */ 690 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_ICC); 691 /* If CPDetect support does not exist, CPState must be off. */ 692 if (BITCLR(reg, AHCI_PX_CMD_CPD)) { 693 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_CPS); 694 } 695 /* If MPSPresence is not set, MPSState must be off. */ 696 if (BITCLR(reg, AHCI_PX_CMD_MPSP)) { 697 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_MPSS); 698 } 699 /* If we do not support MPS, MPSS and MPSP must be off. */ 700 if (BITCLR(ahci->cap, AHCI_CAP_SMPS)) { 701 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_MPSS); 702 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_MPSP); 703 } 704 /* If, via CPD or MPSP we detect a drive, HPCP must be on. */ 705 if (BITANY(reg, AHCI_PX_CMD_CPD | AHCI_PX_CMD_MPSP)) { 706 ASSERT_BIT_SET(reg, AHCI_PX_CMD_HPCP); 707 } 708 /* HPCP and ESP cannot both be active. */ 709 g_assert(!BITSET(reg, AHCI_PX_CMD_HPCP | AHCI_PX_CMD_ESP)); 710 /* If CAP.FBSS is not set, FBSCP must not be set. */ 711 if (BITCLR(ahci->cap, AHCI_CAP_FBSS)) { 712 ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_FBSCP); 713 } 714 715 /* (7) RESERVED */ 716 reg = ahci_px_rreg(ahci, port, AHCI_PX_RES1); 717 g_assert_cmphex(reg, ==, 0); 718 719 /* (8) TFD */ 720 reg = ahci_px_rreg(ahci, port, AHCI_PX_TFD); 721 /* At boot, prior to an FIS being received, the TFD register should be 0x7F, 722 * which breaks down as follows, as seen in AHCI 1.3 sec 3.3.8, p. 27. */ 723 ASSERT_BIT_SET(reg, AHCI_PX_TFD_STS_ERR); 724 ASSERT_BIT_SET(reg, AHCI_PX_TFD_STS_CS1); 725 ASSERT_BIT_SET(reg, AHCI_PX_TFD_STS_DRQ); 726 ASSERT_BIT_SET(reg, AHCI_PX_TFD_STS_CS2); 727 ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_STS_BSY); 728 ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_ERR); 729 ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_RESERVED); 730 731 /* (9) SIG */ 732 /* Though AHCI specifies the boot value should be 0xFFFFFFFF, 733 * Even when GHC.ST is zero, the AHCI HBA may receive the initial 734 * D2H register FIS and update the signature asynchronously, 735 * so we cannot expect a value here. AHCI 1.3, sec 3.3.9, pp 27-28 */ 736 737 /* (10) SSTS / SCR0: SStatus */ 738 reg = ahci_px_rreg(ahci, port, AHCI_PX_SSTS); 739 ASSERT_BIT_CLEAR(reg, AHCI_PX_SSTS_RESERVED); 740 /* Even though the register should be 0 at boot, it is asynchronous and 741 * prone to change, so we cannot test any well known value. */ 742 743 /* (11) SCTL / SCR2: SControl */ 744 reg = ahci_px_rreg(ahci, port, AHCI_PX_SCTL); 745 g_assert_cmphex(reg, ==, 0); 746 747 /* (12) SERR / SCR1: SError */ 748 reg = ahci_px_rreg(ahci, port, AHCI_PX_SERR); 749 g_assert_cmphex(reg, ==, 0); 750 751 /* (13) SACT / SCR3: SActive */ 752 reg = ahci_px_rreg(ahci, port, AHCI_PX_SACT); 753 g_assert_cmphex(reg, ==, 0); 754 755 /* (14) CI */ 756 reg = ahci_px_rreg(ahci, port, AHCI_PX_CI); 757 g_assert_cmphex(reg, ==, 0); 758 759 /* (15) SNTF */ 760 reg = ahci_px_rreg(ahci, port, AHCI_PX_SNTF); 761 g_assert_cmphex(reg, ==, 0); 762 763 /* (16) FBS */ 764 reg = ahci_px_rreg(ahci, port, AHCI_PX_FBS); 765 ASSERT_BIT_CLEAR(reg, AHCI_PX_FBS_EN); 766 ASSERT_BIT_CLEAR(reg, AHCI_PX_FBS_DEC); 767 ASSERT_BIT_CLEAR(reg, AHCI_PX_FBS_SDE); 768 ASSERT_BIT_CLEAR(reg, AHCI_PX_FBS_DEV); 769 ASSERT_BIT_CLEAR(reg, AHCI_PX_FBS_DWE); 770 ASSERT_BIT_CLEAR(reg, AHCI_PX_FBS_RESERVED); 771 if (BITSET(ahci->cap, AHCI_CAP_FBSS)) { 772 /* if Port-Multiplier FIS-based switching avail, ADO must >= 2 */ 773 g_assert((reg & AHCI_PX_FBS_ADO) >> ctzl(AHCI_PX_FBS_ADO) >= 2); 774 } 775 776 /* [17 -- 27] RESERVED */ 777 for (i = AHCI_PX_RES2; i < AHCI_PX_VS; ++i) { 778 reg = ahci_px_rreg(ahci, port, i); 779 g_assert_cmphex(reg, ==, 0); 780 } 781 782 /* [28 -- 31] Vendor-Specific */ 783 for (i = AHCI_PX_VS; i < 32; ++i) { 784 reg = ahci_px_rreg(ahci, port, i); 785 if (reg) { 786 g_test_message("INFO: Vendor register %u non-empty", i); 787 } 788 } 789} 790 791/** 792 * Utilizing an initialized AHCI HBA, issue an IDENTIFY command to the first 793 * device we see, then read and check the response. 794 */ 795static void ahci_test_identify(AHCIQState *ahci) 796{ 797 uint16_t buff[256]; 798 unsigned px; 799 int rc; 800 uint16_t sect_size; 801 const size_t buffsize = 512; 802 803 g_assert(ahci != NULL); 804 805 /** 806 * This serves as a bit of a tutorial on AHCI device programming: 807 * 808 * (1) Create a data buffer for the IDENTIFY response to be sent to 809 * (2) Create a Command Table buffer, where we will store the 810 * command and PRDT (Physical Region Descriptor Table) 811 * (3) Construct an FIS host-to-device command structure, and write it to 812 * the top of the Command Table buffer. 813 * (4) Create one or more Physical Region Descriptors (PRDs) that describe 814 * a location in memory where data may be stored/retrieved. 815 * (5) Write these PRDTs to the bottom (offset 0x80) of the Command Table. 816 * (6) Each AHCI port has up to 32 command slots. Each slot contains a 817 * header that points to a Command Table buffer. Pick an unused slot 818 * and update it to point to the Command Table we have built. 819 * (7) Now: Command #n points to our Command Table, and our Command Table 820 * contains the FIS (that describes our command) and the PRDTL, which 821 * describes our buffer. 822 * (8) We inform the HBA via PxCI (Command Issue) that the command in slot 823 * #n is ready for processing. 824 */ 825 826 /* Pick the first implemented and running port */ 827 px = ahci_port_select(ahci); 828 g_test_message("Selected port %u for test", px); 829 830 /* Clear out the FIS Receive area and any pending interrupts. */ 831 ahci_port_clear(ahci, px); 832 833 /* "Read" 512 bytes using CMD_IDENTIFY into the host buffer. */ 834 ahci_io(ahci, px, CMD_IDENTIFY, &buff, buffsize, 0); 835 836 /* Check serial number/version in the buffer */ 837 /* NB: IDENTIFY strings are packed in 16bit little endian chunks. 838 * Since we copy byte-for-byte in ahci-test, on both LE and BE, we need to 839 * unchunk this data. By contrast, ide-test copies 2 bytes at a time, and 840 * as a consequence, only needs to unchunk the data on LE machines. */ 841 string_bswap16(&buff[10], 20); 842 rc = memcmp(&buff[10], "testdisk ", 20); 843 g_assert_cmphex(rc, ==, 0); 844 845 string_bswap16(&buff[23], 8); 846 rc = memcmp(&buff[23], "version ", 8); 847 g_assert_cmphex(rc, ==, 0); 848 849 sect_size = le16_to_cpu(*((uint16_t *)(&buff[5]))); 850 g_assert_cmphex(sect_size, ==, AHCI_SECTOR_SIZE); 851} 852 853static void ahci_test_io_rw_simple(AHCIQState *ahci, unsigned bufsize, 854 uint64_t sector, uint8_t read_cmd, 855 uint8_t write_cmd) 856{ 857 uint64_t ptr; 858 uint8_t port; 859 unsigned char *tx = g_malloc(bufsize); 860 unsigned char *rx = g_malloc0(bufsize); 861 862 g_assert(ahci != NULL); 863 864 /* Pick the first running port and clear it. */ 865 port = ahci_port_select(ahci); 866 ahci_port_clear(ahci, port); 867 868 /*** Create pattern and transfer to guest ***/ 869 /* Data buffer in the guest */ 870 ptr = ahci_alloc(ahci, bufsize); 871 g_assert(ptr); 872 873 /* Write some indicative pattern to our buffer. */ 874 generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE); 875 qtest_bufwrite(ahci->parent->qts, ptr, tx, bufsize); 876 877 /* Write this buffer to disk, then read it back to the DMA buffer. */ 878 ahci_guest_io(ahci, port, write_cmd, ptr, bufsize, sector); 879 qtest_memset(ahci->parent->qts, ptr, 0x00, bufsize); 880 ahci_guest_io(ahci, port, read_cmd, ptr, bufsize, sector); 881 882 /*** Read back the Data ***/ 883 qtest_bufread(ahci->parent->qts, ptr, rx, bufsize); 884 g_assert_cmphex(memcmp(tx, rx, bufsize), ==, 0); 885 886 ahci_free(ahci, ptr); 887 g_free(tx); 888 g_free(rx); 889} 890 891static uint8_t ahci_test_nondata(AHCIQState *ahci, uint8_t ide_cmd) 892{ 893 uint8_t port; 894 895 /* Sanitize */ 896 port = ahci_port_select(ahci); 897 ahci_port_clear(ahci, port); 898 899 ahci_io(ahci, port, ide_cmd, NULL, 0, 0); 900 901 return port; 902} 903 904static void ahci_test_flush(AHCIQState *ahci) 905{ 906 ahci_test_nondata(ahci, CMD_FLUSH_CACHE); 907} 908 909static void ahci_test_max(AHCIQState *ahci) 910{ 911 RegD2HFIS *d2h = g_malloc0(0x20); 912 uint64_t nsect; 913 uint8_t port; 914 uint8_t cmd; 915 uint64_t config_sect = mb_to_sectors(test_image_size_mb) - 1; 916 917 if (config_sect > 0xFFFFFF) { 918 cmd = CMD_READ_MAX_EXT; 919 } else { 920 cmd = CMD_READ_MAX; 921 } 922 923 port = ahci_test_nondata(ahci, cmd); 924 qtest_memread(ahci->parent->qts, ahci->port[port].fb + 0x40, d2h, 0x20); 925 nsect = (uint64_t)d2h->lba_hi[2] << 40 | 926 (uint64_t)d2h->lba_hi[1] << 32 | 927 (uint64_t)d2h->lba_hi[0] << 24 | 928 (uint64_t)d2h->lba_lo[2] << 16 | 929 (uint64_t)d2h->lba_lo[1] << 8 | 930 (uint64_t)d2h->lba_lo[0]; 931 932 g_assert_cmphex(nsect, ==, config_sect); 933 g_free(d2h); 934} 935 936 937/******************************************************************************/ 938/* Test Interfaces */ 939/******************************************************************************/ 940 941/** 942 * Basic sanity test to boot a machine, find an AHCI device, and shutdown. 943 */ 944static void test_sanity(void) 945{ 946 AHCIQState *ahci; 947 ahci = ahci_boot(NULL); 948 ahci_shutdown(ahci); 949} 950 951/** 952 * Ensure that the PCI configuration space for the AHCI device is in-line with 953 * the AHCI 1.3 specification for initial values. 954 */ 955static void test_pci_spec(void) 956{ 957 AHCIQState *ahci; 958 ahci = ahci_boot(NULL); 959 ahci_test_pci_spec(ahci); 960 ahci_shutdown(ahci); 961} 962 963/** 964 * Engage the PCI AHCI device and sanity check the response. 965 * Perform additional PCI config space bringup for the HBA. 966 */ 967static void test_pci_enable(void) 968{ 969 AHCIQState *ahci; 970 ahci = ahci_boot(NULL); 971 ahci_pci_enable(ahci); 972 ahci_shutdown(ahci); 973} 974 975/** 976 * Investigate the memory mapped regions of the HBA, 977 * and test them for AHCI specification adherence. 978 */ 979static void test_hba_spec(void) 980{ 981 AHCIQState *ahci; 982 983 ahci = ahci_boot(NULL); 984 ahci_pci_enable(ahci); 985 ahci_test_hba_spec(ahci); 986 ahci_shutdown(ahci); 987} 988 989/** 990 * Engage the HBA functionality of the AHCI PCI device, 991 * and bring it into a functional idle state. 992 */ 993static void test_hba_enable(void) 994{ 995 AHCIQState *ahci; 996 997 ahci = ahci_boot(NULL); 998 ahci_pci_enable(ahci); 999 ahci_hba_enable(ahci); 1000 ahci_shutdown(ahci); 1001} 1002 1003/** 1004 * Bring up the device and issue an IDENTIFY command. 1005 * Inspect the state of the HBA device and the data returned. 1006 */ 1007static void test_identify(void) 1008{ 1009 AHCIQState *ahci; 1010 1011 ahci = ahci_boot_and_enable(NULL); 1012 ahci_test_identify(ahci); 1013 ahci_shutdown(ahci); 1014} 1015 1016/** 1017 * Fragmented DMA test: Perform a standard 4K DMA read/write 1018 * test, but make sure the physical regions are fragmented to 1019 * be very small, each just 32 bytes, to see how AHCI performs 1020 * with chunks defined to be much less than a sector. 1021 */ 1022static void test_dma_fragmented(void) 1023{ 1024 AHCIQState *ahci; 1025 AHCICommand *cmd; 1026 uint8_t px; 1027 size_t bufsize = 4096; 1028 unsigned char *tx = g_malloc(bufsize); 1029 unsigned char *rx = g_malloc0(bufsize); 1030 uint64_t ptr; 1031 1032 ahci = ahci_boot_and_enable(NULL); 1033 px = ahci_port_select(ahci); 1034 ahci_port_clear(ahci, px); 1035 1036 /* create pattern */ 1037 generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE); 1038 1039 /* Create a DMA buffer in guest memory, and write our pattern to it. */ 1040 ptr = guest_alloc(&ahci->parent->alloc, bufsize); 1041 g_assert(ptr); 1042 qtest_bufwrite(ahci->parent->qts, ptr, tx, bufsize); 1043 1044 cmd = ahci_command_create(CMD_WRITE_DMA); 1045 ahci_command_adjust(cmd, 0, ptr, bufsize, 32); 1046 ahci_command_commit(ahci, cmd, px); 1047 ahci_command_issue(ahci, cmd); 1048 ahci_command_verify(ahci, cmd); 1049 ahci_command_free(cmd); 1050 1051 cmd = ahci_command_create(CMD_READ_DMA); 1052 ahci_command_adjust(cmd, 0, ptr, bufsize, 32); 1053 ahci_command_commit(ahci, cmd, px); 1054 ahci_command_issue(ahci, cmd); 1055 ahci_command_verify(ahci, cmd); 1056 ahci_command_free(cmd); 1057 1058 /* Read back the guest's receive buffer into local memory */ 1059 qtest_bufread(ahci->parent->qts, ptr, rx, bufsize); 1060 guest_free(&ahci->parent->alloc, ptr); 1061 1062 g_assert_cmphex(memcmp(tx, rx, bufsize), ==, 0); 1063 1064 ahci_shutdown(ahci); 1065 1066 g_free(rx); 1067 g_free(tx); 1068} 1069 1070/* 1071 * Write sector 1 with random data to make AHCI storage dirty 1072 * Needed for flush tests so that flushes actually go though the block layer 1073 */ 1074static void make_dirty(AHCIQState* ahci, uint8_t port) 1075{ 1076 uint64_t ptr; 1077 unsigned bufsize = 512; 1078 1079 ptr = ahci_alloc(ahci, bufsize); 1080 g_assert(ptr); 1081 1082 ahci_guest_io(ahci, port, CMD_WRITE_DMA, ptr, bufsize, 1); 1083 ahci_free(ahci, ptr); 1084} 1085 1086static void test_flush(void) 1087{ 1088 AHCIQState *ahci; 1089 uint8_t port; 1090 1091 ahci = ahci_boot_and_enable(NULL); 1092 1093 port = ahci_port_select(ahci); 1094 ahci_port_clear(ahci, port); 1095 1096 make_dirty(ahci, port); 1097 1098 ahci_test_flush(ahci); 1099 ahci_shutdown(ahci); 1100} 1101 1102static void test_flush_retry(void) 1103{ 1104 AHCIQState *ahci; 1105 AHCICommand *cmd; 1106 uint8_t port; 1107 1108 prepare_blkdebug_script(debug_path, "flush_to_disk"); 1109 ahci = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0," 1110 "format=%s,cache=writeback," 1111 "rerror=stop,werror=stop " 1112 "-M q35 " 1113 "-device ide-hd,drive=drive0 ", 1114 debug_path, 1115 tmp_path, imgfmt); 1116 1117 port = ahci_port_select(ahci); 1118 ahci_port_clear(ahci, port); 1119 1120 /* Issue write so that flush actually goes to disk */ 1121 make_dirty(ahci, port); 1122 1123 /* Issue Flush Command and wait for error */ 1124 cmd = ahci_guest_io_halt(ahci, port, CMD_FLUSH_CACHE, 0, 0, 0); 1125 ahci_guest_io_resume(ahci, cmd); 1126 1127 ahci_shutdown(ahci); 1128} 1129 1130/** 1131 * Basic sanity test to boot a machine, find an AHCI device, and shutdown. 1132 */ 1133static void test_migrate_sanity(void) 1134{ 1135 AHCIQState *src, *dst; 1136 char *uri = g_strdup_printf("unix:%s", mig_socket); 1137 1138 src = ahci_boot("-m 384 -M q35 " 1139 "-drive if=ide,file=%s,format=%s ", tmp_path, imgfmt); 1140 dst = ahci_boot("-m 384 -M q35 " 1141 "-drive if=ide,file=%s,format=%s " 1142 "-incoming %s", tmp_path, imgfmt, uri); 1143 1144 ahci_migrate(src, dst, uri); 1145 1146 ahci_shutdown(src); 1147 ahci_shutdown(dst); 1148 g_free(uri); 1149} 1150 1151/** 1152 * Simple migration test: Write a pattern, migrate, then read. 1153 */ 1154static void ahci_migrate_simple(uint8_t cmd_read, uint8_t cmd_write) 1155{ 1156 AHCIQState *src, *dst; 1157 uint8_t px; 1158 size_t bufsize = 4096; 1159 unsigned char *tx = g_malloc(bufsize); 1160 unsigned char *rx = g_malloc0(bufsize); 1161 char *uri = g_strdup_printf("unix:%s", mig_socket); 1162 1163 src = ahci_boot_and_enable("-m 384 -M q35 " 1164 "-drive if=ide,format=%s,file=%s ", 1165 imgfmt, tmp_path); 1166 dst = ahci_boot("-m 384 -M q35 " 1167 "-drive if=ide,format=%s,file=%s " 1168 "-incoming %s", imgfmt, tmp_path, uri); 1169 1170 /* initialize */ 1171 px = ahci_port_select(src); 1172 ahci_port_clear(src, px); 1173 1174 /* create pattern */ 1175 generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE); 1176 1177 /* Write, migrate, then read. */ 1178 ahci_io(src, px, cmd_write, tx, bufsize, 0); 1179 ahci_migrate(src, dst, uri); 1180 ahci_io(dst, px, cmd_read, rx, bufsize, 0); 1181 1182 /* Verify pattern */ 1183 g_assert_cmphex(memcmp(tx, rx, bufsize), ==, 0); 1184 1185 ahci_shutdown(src); 1186 ahci_shutdown(dst); 1187 g_free(rx); 1188 g_free(tx); 1189 g_free(uri); 1190} 1191 1192static void test_migrate_dma(void) 1193{ 1194 ahci_migrate_simple(CMD_READ_DMA, CMD_WRITE_DMA); 1195} 1196 1197static void test_migrate_ncq(void) 1198{ 1199 ahci_migrate_simple(READ_FPDMA_QUEUED, WRITE_FPDMA_QUEUED); 1200} 1201 1202/** 1203 * Halted IO Error Test 1204 * 1205 * Simulate an error on first write, Try to write a pattern, 1206 * Confirm the VM has stopped, resume the VM, verify command 1207 * has completed, then read back the data and verify. 1208 */ 1209static void ahci_halted_io_test(uint8_t cmd_read, uint8_t cmd_write) 1210{ 1211 AHCIQState *ahci; 1212 uint8_t port; 1213 size_t bufsize = 4096; 1214 unsigned char *tx = g_malloc(bufsize); 1215 unsigned char *rx = g_malloc0(bufsize); 1216 uint64_t ptr; 1217 AHCICommand *cmd; 1218 1219 prepare_blkdebug_script(debug_path, "write_aio"); 1220 1221 ahci = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0," 1222 "format=%s,cache=writeback," 1223 "rerror=stop,werror=stop " 1224 "-M q35 " 1225 "-device ide-hd,drive=drive0 ", 1226 debug_path, 1227 tmp_path, imgfmt); 1228 1229 /* Initialize and prepare */ 1230 port = ahci_port_select(ahci); 1231 ahci_port_clear(ahci, port); 1232 1233 /* create DMA source buffer and write pattern */ 1234 generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE); 1235 ptr = ahci_alloc(ahci, bufsize); 1236 g_assert(ptr); 1237 qtest_memwrite(ahci->parent->qts, ptr, tx, bufsize); 1238 1239 /* Attempt to write (and fail) */ 1240 cmd = ahci_guest_io_halt(ahci, port, cmd_write, 1241 ptr, bufsize, 0); 1242 1243 /* Attempt to resume the command */ 1244 ahci_guest_io_resume(ahci, cmd); 1245 ahci_free(ahci, ptr); 1246 1247 /* Read back and verify */ 1248 ahci_io(ahci, port, cmd_read, rx, bufsize, 0); 1249 g_assert_cmphex(memcmp(tx, rx, bufsize), ==, 0); 1250 1251 /* Cleanup and go home */ 1252 ahci_shutdown(ahci); 1253 g_free(rx); 1254 g_free(tx); 1255} 1256 1257static void test_halted_dma(void) 1258{ 1259 ahci_halted_io_test(CMD_READ_DMA, CMD_WRITE_DMA); 1260} 1261 1262static void test_halted_ncq(void) 1263{ 1264 ahci_halted_io_test(READ_FPDMA_QUEUED, WRITE_FPDMA_QUEUED); 1265} 1266 1267/** 1268 * IO Error Migration Test 1269 * 1270 * Simulate an error on first write, Try to write a pattern, 1271 * Confirm the VM has stopped, migrate, resume the VM, 1272 * verify command has completed, then read back the data and verify. 1273 */ 1274static void ahci_migrate_halted_io(uint8_t cmd_read, uint8_t cmd_write) 1275{ 1276 AHCIQState *src, *dst; 1277 uint8_t port; 1278 size_t bufsize = 4096; 1279 unsigned char *tx = g_malloc(bufsize); 1280 unsigned char *rx = g_malloc0(bufsize); 1281 uint64_t ptr; 1282 AHCICommand *cmd; 1283 char *uri = g_strdup_printf("unix:%s", mig_socket); 1284 1285 prepare_blkdebug_script(debug_path, "write_aio"); 1286 1287 src = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0," 1288 "format=%s,cache=writeback," 1289 "rerror=stop,werror=stop " 1290 "-M q35 " 1291 "-device ide-hd,drive=drive0 ", 1292 debug_path, 1293 tmp_path, imgfmt); 1294 1295 dst = ahci_boot("-drive file=%s,if=none,id=drive0," 1296 "format=%s,cache=writeback," 1297 "rerror=stop,werror=stop " 1298 "-M q35 " 1299 "-device ide-hd,drive=drive0 " 1300 "-incoming %s", 1301 tmp_path, imgfmt, uri); 1302 1303 /* Initialize and prepare */ 1304 port = ahci_port_select(src); 1305 ahci_port_clear(src, port); 1306 generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE); 1307 1308 /* create DMA source buffer and write pattern */ 1309 ptr = ahci_alloc(src, bufsize); 1310 g_assert(ptr); 1311 qtest_memwrite(src->parent->qts, ptr, tx, bufsize); 1312 1313 /* Write, trigger the VM to stop, migrate, then resume. */ 1314 cmd = ahci_guest_io_halt(src, port, cmd_write, 1315 ptr, bufsize, 0); 1316 ahci_migrate(src, dst, uri); 1317 ahci_guest_io_resume(dst, cmd); 1318 ahci_free(dst, ptr); 1319 1320 /* Read back */ 1321 ahci_io(dst, port, cmd_read, rx, bufsize, 0); 1322 1323 /* Verify TX and RX are identical */ 1324 g_assert_cmphex(memcmp(tx, rx, bufsize), ==, 0); 1325 1326 /* Cleanup and go home. */ 1327 ahci_shutdown(src); 1328 ahci_shutdown(dst); 1329 g_free(rx); 1330 g_free(tx); 1331 g_free(uri); 1332} 1333 1334static void test_migrate_halted_dma(void) 1335{ 1336 ahci_migrate_halted_io(CMD_READ_DMA, CMD_WRITE_DMA); 1337} 1338 1339static void test_migrate_halted_ncq(void) 1340{ 1341 ahci_migrate_halted_io(READ_FPDMA_QUEUED, WRITE_FPDMA_QUEUED); 1342} 1343 1344/** 1345 * Migration test: Try to flush, migrate, then resume. 1346 */ 1347static void test_flush_migrate(void) 1348{ 1349 AHCIQState *src, *dst; 1350 AHCICommand *cmd; 1351 uint8_t px; 1352 char *uri = g_strdup_printf("unix:%s", mig_socket); 1353 1354 prepare_blkdebug_script(debug_path, "flush_to_disk"); 1355 1356 src = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0," 1357 "cache=writeback,rerror=stop,werror=stop," 1358 "format=%s " 1359 "-M q35 " 1360 "-device ide-hd,drive=drive0 ", 1361 debug_path, tmp_path, imgfmt); 1362 dst = ahci_boot("-drive file=%s,if=none,id=drive0," 1363 "cache=writeback,rerror=stop,werror=stop," 1364 "format=%s " 1365 "-M q35 " 1366 "-device ide-hd,drive=drive0 " 1367 "-incoming %s", tmp_path, imgfmt, uri); 1368 1369 px = ahci_port_select(src); 1370 ahci_port_clear(src, px); 1371 1372 /* Dirty device so that flush reaches disk */ 1373 make_dirty(src, px); 1374 1375 /* Issue Flush Command */ 1376 cmd = ahci_command_create(CMD_FLUSH_CACHE); 1377 ahci_command_commit(src, cmd, px); 1378 ahci_command_issue_async(src, cmd); 1379 qtest_qmp_eventwait(src->parent->qts, "STOP"); 1380 1381 /* Migrate over */ 1382 ahci_migrate(src, dst, uri); 1383 1384 /* Complete the command */ 1385 qtest_qmp_send(dst->parent->qts, "{'execute':'cont' }"); 1386 qtest_qmp_eventwait(dst->parent->qts, "RESUME"); 1387 ahci_command_wait(dst, cmd); 1388 ahci_command_verify(dst, cmd); 1389 1390 ahci_command_free(cmd); 1391 ahci_shutdown(src); 1392 ahci_shutdown(dst); 1393 g_free(uri); 1394} 1395 1396static void test_max(void) 1397{ 1398 AHCIQState *ahci; 1399 1400 ahci = ahci_boot_and_enable(NULL); 1401 ahci_test_max(ahci); 1402 ahci_shutdown(ahci); 1403} 1404 1405static void test_reset(void) 1406{ 1407 AHCIQState *ahci; 1408 int i; 1409 1410 ahci = ahci_boot(NULL); 1411 ahci_test_pci_spec(ahci); 1412 ahci_pci_enable(ahci); 1413 1414 for (i = 0; i < 2; i++) { 1415 ahci_test_hba_spec(ahci); 1416 ahci_hba_enable(ahci); 1417 ahci_test_identify(ahci); 1418 ahci_test_io_rw_simple(ahci, 4096, 0, 1419 CMD_READ_DMA_EXT, 1420 CMD_WRITE_DMA_EXT); 1421 ahci_set(ahci, AHCI_GHC, AHCI_GHC_HR); 1422 ahci_clean_mem(ahci); 1423 } 1424 1425 ahci_shutdown(ahci); 1426} 1427 1428static void test_ncq_simple(void) 1429{ 1430 AHCIQState *ahci; 1431 1432 ahci = ahci_boot_and_enable(NULL); 1433 ahci_test_io_rw_simple(ahci, 4096, 0, 1434 READ_FPDMA_QUEUED, 1435 WRITE_FPDMA_QUEUED); 1436 ahci_shutdown(ahci); 1437} 1438 1439static int prepare_iso(size_t size, unsigned char **buf, char **name) 1440{ 1441 char cdrom_path[] = "/tmp/qtest.iso.XXXXXX"; 1442 unsigned char *patt; 1443 ssize_t ret; 1444 int fd = mkstemp(cdrom_path); 1445 1446 g_assert(fd != -1); 1447 g_assert(buf); 1448 g_assert(name); 1449 patt = g_malloc(size); 1450 1451 /* Generate a pattern and build a CDROM image to read from */ 1452 generate_pattern(patt, size, ATAPI_SECTOR_SIZE); 1453 ret = write(fd, patt, size); 1454 g_assert(ret == size); 1455 1456 *name = g_strdup(cdrom_path); 1457 *buf = patt; 1458 return fd; 1459} 1460 1461static void remove_iso(int fd, char *name) 1462{ 1463 unlink(name); 1464 g_free(name); 1465 close(fd); 1466} 1467 1468static int ahci_cb_cmp_buff(AHCIQState *ahci, AHCICommand *cmd, 1469 const AHCIOpts *opts) 1470{ 1471 unsigned char *tx = opts->opaque; 1472 unsigned char *rx; 1473 1474 if (!opts->size) { 1475 return 0; 1476 } 1477 1478 rx = g_malloc0(opts->size); 1479 qtest_bufread(ahci->parent->qts, opts->buffer, rx, opts->size); 1480 g_assert_cmphex(memcmp(tx, rx, opts->size), ==, 0); 1481 g_free(rx); 1482 1483 return 0; 1484} 1485 1486static void ahci_test_cdrom(int nsectors, bool dma, uint8_t cmd, 1487 bool override_bcl, uint16_t bcl) 1488{ 1489 AHCIQState *ahci; 1490 unsigned char *tx; 1491 char *iso; 1492 int fd; 1493 AHCIOpts opts = { 1494 .size = ((uint64_t)ATAPI_SECTOR_SIZE * nsectors), 1495 .atapi = true, 1496 .atapi_dma = dma, 1497 .post_cb = ahci_cb_cmp_buff, 1498 .set_bcl = override_bcl, 1499 .bcl = bcl, 1500 }; 1501 uint64_t iso_size = (uint64_t)ATAPI_SECTOR_SIZE * (nsectors + 1); 1502 1503 /* Prepare ISO and fill 'tx' buffer */ 1504 fd = prepare_iso(iso_size, &tx, &iso); 1505 opts.opaque = tx; 1506 1507 /* Standard startup wonkery, but use ide-cd and our special iso file */ 1508 ahci = ahci_boot_and_enable("-drive if=none,id=drive0,file=%s,format=raw " 1509 "-M q35 " 1510 "-device ide-cd,drive=drive0 ", iso); 1511 1512 /* Build & Send AHCI command */ 1513 ahci_exec(ahci, ahci_port_select(ahci), cmd, &opts); 1514 1515 /* Cleanup */ 1516 g_free(tx); 1517 ahci_shutdown(ahci); 1518 remove_iso(fd, iso); 1519} 1520 1521static void ahci_test_cdrom_read10(int nsectors, bool dma) 1522{ 1523 ahci_test_cdrom(nsectors, dma, CMD_ATAPI_READ_10, false, 0); 1524} 1525 1526static void test_cdrom_dma(void) 1527{ 1528 ahci_test_cdrom_read10(1, true); 1529} 1530 1531static void test_cdrom_dma_multi(void) 1532{ 1533 ahci_test_cdrom_read10(3, true); 1534} 1535 1536static void test_cdrom_pio(void) 1537{ 1538 ahci_test_cdrom_read10(1, false); 1539} 1540 1541static void test_cdrom_pio_multi(void) 1542{ 1543 ahci_test_cdrom_read10(3, false); 1544} 1545 1546/* Regression test: Test that a READ_CD command with a BCL of 0 but a size of 0 1547 * completes as a NOP instead of erroring out. */ 1548static void test_atapi_bcl(void) 1549{ 1550 ahci_test_cdrom(0, false, CMD_ATAPI_READ_CD, true, 0); 1551} 1552 1553 1554static void atapi_wait_tray(AHCIQState *ahci, bool open) 1555{ 1556 QDict *rsp = qtest_qmp_eventwait_ref(ahci->parent->qts, 1557 "DEVICE_TRAY_MOVED"); 1558 QDict *data = qdict_get_qdict(rsp, "data"); 1559 if (open) { 1560 g_assert(qdict_get_bool(data, "tray-open")); 1561 } else { 1562 g_assert(!qdict_get_bool(data, "tray-open")); 1563 } 1564 qobject_unref(rsp); 1565} 1566 1567static void test_atapi_tray(void) 1568{ 1569 AHCIQState *ahci; 1570 unsigned char *tx; 1571 char *iso; 1572 int fd; 1573 uint8_t port, sense, asc; 1574 uint64_t iso_size = ATAPI_SECTOR_SIZE; 1575 QDict *rsp; 1576 1577 fd = prepare_iso(iso_size, &tx, &iso); 1578 ahci = ahci_boot_and_enable("-blockdev node-name=drive0,driver=file,filename=%s " 1579 "-M q35 " 1580 "-device ide-cd,id=cd0,drive=drive0 ", iso); 1581 port = ahci_port_select(ahci); 1582 1583 ahci_atapi_eject(ahci, port); 1584 atapi_wait_tray(ahci, true); 1585 1586 ahci_atapi_load(ahci, port); 1587 atapi_wait_tray(ahci, false); 1588 1589 /* Remove media */ 1590 qtest_qmp_send(ahci->parent->qts, "{'execute': 'blockdev-open-tray', " 1591 "'arguments': {'id': 'cd0'}}"); 1592 atapi_wait_tray(ahci, true); 1593 rsp = qtest_qmp_receive(ahci->parent->qts); 1594 qobject_unref(rsp); 1595 1596 qmp_discard_response(ahci->parent->qts, 1597 "{'execute': 'blockdev-remove-medium', " 1598 "'arguments': {'id': 'cd0'}}"); 1599 1600 /* Test the tray without a medium */ 1601 ahci_atapi_load(ahci, port); 1602 atapi_wait_tray(ahci, false); 1603 1604 ahci_atapi_eject(ahci, port); 1605 atapi_wait_tray(ahci, true); 1606 1607 /* Re-insert media */ 1608 qmp_discard_response(ahci->parent->qts, 1609 "{'execute': 'blockdev-add', " 1610 "'arguments': {'node-name': 'node0', " 1611 "'driver': 'raw', " 1612 "'file': { 'driver': 'file', " 1613 "'filename': %s }}}", iso); 1614 qmp_discard_response(ahci->parent->qts, 1615 "{'execute': 'blockdev-insert-medium'," 1616 "'arguments': { 'id': 'cd0', " 1617 "'node-name': 'node0' }}"); 1618 1619 /* Again, the event shows up first */ 1620 qtest_qmp_send(ahci->parent->qts, "{'execute': 'blockdev-close-tray', " 1621 "'arguments': {'id': 'cd0'}}"); 1622 atapi_wait_tray(ahci, false); 1623 rsp = qtest_qmp_receive(ahci->parent->qts); 1624 qobject_unref(rsp); 1625 1626 /* Now, to convince ATAPI we understand the media has changed... */ 1627 ahci_atapi_test_ready(ahci, port, false, SENSE_NOT_READY); 1628 ahci_atapi_get_sense(ahci, port, &sense, &asc); 1629 g_assert_cmpuint(sense, ==, SENSE_NOT_READY); 1630 g_assert_cmpuint(asc, ==, ASC_MEDIUM_NOT_PRESENT); 1631 1632 ahci_atapi_test_ready(ahci, port, false, SENSE_UNIT_ATTENTION); 1633 ahci_atapi_get_sense(ahci, port, &sense, &asc); 1634 g_assert_cmpuint(sense, ==, SENSE_UNIT_ATTENTION); 1635 g_assert_cmpuint(asc, ==, ASC_MEDIUM_MAY_HAVE_CHANGED); 1636 1637 ahci_atapi_test_ready(ahci, port, true, SENSE_NO_SENSE); 1638 ahci_atapi_get_sense(ahci, port, &sense, &asc); 1639 g_assert_cmpuint(sense, ==, SENSE_NO_SENSE); 1640 1641 /* Final tray test. */ 1642 ahci_atapi_eject(ahci, port); 1643 atapi_wait_tray(ahci, true); 1644 1645 ahci_atapi_load(ahci, port); 1646 atapi_wait_tray(ahci, false); 1647 1648 /* Cleanup */ 1649 g_free(tx); 1650 ahci_shutdown(ahci); 1651 remove_iso(fd, iso); 1652} 1653 1654/******************************************************************************/ 1655/* AHCI I/O Test Matrix Definitions */ 1656 1657enum BuffLen { 1658 LEN_BEGIN = 0, 1659 LEN_SIMPLE = LEN_BEGIN, 1660 LEN_DOUBLE, 1661 LEN_LONG, 1662 LEN_SHORT, 1663 NUM_LENGTHS 1664}; 1665 1666static const char *buff_len_str[NUM_LENGTHS] = { "simple", "double", 1667 "long", "short" }; 1668 1669enum AddrMode { 1670 ADDR_MODE_BEGIN = 0, 1671 ADDR_MODE_LBA28 = ADDR_MODE_BEGIN, 1672 ADDR_MODE_LBA48, 1673 NUM_ADDR_MODES 1674}; 1675 1676static const char *addr_mode_str[NUM_ADDR_MODES] = { "lba28", "lba48" }; 1677 1678enum IOMode { 1679 MODE_BEGIN = 0, 1680 MODE_PIO = MODE_BEGIN, 1681 MODE_DMA, 1682 NUM_MODES 1683}; 1684 1685static const char *io_mode_str[NUM_MODES] = { "pio", "dma" }; 1686 1687enum IOOps { 1688 IO_BEGIN = 0, 1689 IO_READ = IO_BEGIN, 1690 IO_WRITE, 1691 NUM_IO_OPS 1692}; 1693 1694enum OffsetType { 1695 OFFSET_BEGIN = 0, 1696 OFFSET_ZERO = OFFSET_BEGIN, 1697 OFFSET_LOW, 1698 OFFSET_HIGH, 1699 NUM_OFFSETS 1700}; 1701 1702static const char *offset_str[NUM_OFFSETS] = { "zero", "low", "high" }; 1703 1704typedef struct AHCIIOTestOptions { 1705 enum BuffLen length; 1706 enum AddrMode address_type; 1707 enum IOMode io_type; 1708 enum OffsetType offset; 1709} AHCIIOTestOptions; 1710 1711static uint64_t offset_sector(enum OffsetType ofst, 1712 enum AddrMode addr_type, 1713 uint64_t buffsize) 1714{ 1715 uint64_t ceil; 1716 uint64_t nsectors; 1717 1718 switch (ofst) { 1719 case OFFSET_ZERO: 1720 return 0; 1721 case OFFSET_LOW: 1722 return 1; 1723 case OFFSET_HIGH: 1724 ceil = (addr_type == ADDR_MODE_LBA28) ? 0xfffffff : 0xffffffffffff; 1725 ceil = MIN(ceil, mb_to_sectors(test_image_size_mb) - 1); 1726 nsectors = buffsize / AHCI_SECTOR_SIZE; 1727 return ceil - nsectors + 1; 1728 default: 1729 g_assert_not_reached(); 1730 } 1731} 1732 1733/** 1734 * Table of possible I/O ATA commands given a set of enumerations. 1735 */ 1736static const uint8_t io_cmds[NUM_MODES][NUM_ADDR_MODES][NUM_IO_OPS] = { 1737 [MODE_PIO] = { 1738 [ADDR_MODE_LBA28] = { 1739 [IO_READ] = CMD_READ_PIO, 1740 [IO_WRITE] = CMD_WRITE_PIO }, 1741 [ADDR_MODE_LBA48] = { 1742 [IO_READ] = CMD_READ_PIO_EXT, 1743 [IO_WRITE] = CMD_WRITE_PIO_EXT } 1744 }, 1745 [MODE_DMA] = { 1746 [ADDR_MODE_LBA28] = { 1747 [IO_READ] = CMD_READ_DMA, 1748 [IO_WRITE] = CMD_WRITE_DMA }, 1749 [ADDR_MODE_LBA48] = { 1750 [IO_READ] = CMD_READ_DMA_EXT, 1751 [IO_WRITE] = CMD_WRITE_DMA_EXT } 1752 } 1753}; 1754 1755/** 1756 * Test a Read/Write pattern using various commands, addressing modes, 1757 * transfer modes, and buffer sizes. 1758 */ 1759static void test_io_rw_interface(enum AddrMode lba48, enum IOMode dma, 1760 unsigned bufsize, uint64_t sector) 1761{ 1762 AHCIQState *ahci; 1763 1764 ahci = ahci_boot_and_enable(NULL); 1765 ahci_test_io_rw_simple(ahci, bufsize, sector, 1766 io_cmds[dma][lba48][IO_READ], 1767 io_cmds[dma][lba48][IO_WRITE]); 1768 ahci_shutdown(ahci); 1769} 1770 1771/** 1772 * Demultiplex the test data and invoke the actual test routine. 1773 */ 1774static void test_io_interface(gconstpointer opaque) 1775{ 1776 AHCIIOTestOptions *opts = (AHCIIOTestOptions *)opaque; 1777 unsigned bufsize; 1778 uint64_t sector; 1779 1780 switch (opts->length) { 1781 case LEN_SIMPLE: 1782 bufsize = 4096; 1783 break; 1784 case LEN_DOUBLE: 1785 bufsize = 8192; 1786 break; 1787 case LEN_LONG: 1788 bufsize = 4096 * 64; 1789 break; 1790 case LEN_SHORT: 1791 bufsize = 512; 1792 break; 1793 default: 1794 g_assert_not_reached(); 1795 } 1796 1797 sector = offset_sector(opts->offset, opts->address_type, bufsize); 1798 test_io_rw_interface(opts->address_type, opts->io_type, bufsize, sector); 1799 g_free(opts); 1800 return; 1801} 1802 1803static void create_ahci_io_test(enum IOMode type, enum AddrMode addr, 1804 enum BuffLen len, enum OffsetType offset) 1805{ 1806 char *name; 1807 AHCIIOTestOptions *opts; 1808 1809 opts = g_new(AHCIIOTestOptions, 1); 1810 opts->length = len; 1811 opts->address_type = addr; 1812 opts->io_type = type; 1813 opts->offset = offset; 1814 1815 name = g_strdup_printf("ahci/io/%s/%s/%s/%s", 1816 io_mode_str[type], 1817 addr_mode_str[addr], 1818 buff_len_str[len], 1819 offset_str[offset]); 1820 1821 if ((addr == ADDR_MODE_LBA48) && (offset == OFFSET_HIGH) && 1822 (mb_to_sectors(test_image_size_mb) <= 0xFFFFFFF)) { 1823 g_test_message("%s: skipped; test image too small", name); 1824 g_free(opts); 1825 g_free(name); 1826 return; 1827 } 1828 1829 qtest_add_data_func(name, opts, test_io_interface); 1830 g_free(name); 1831} 1832 1833/******************************************************************************/ 1834 1835int main(int argc, char **argv) 1836{ 1837 const char *arch; 1838 int ret; 1839 int fd; 1840 int c; 1841 int i, j, k, m; 1842 1843 static struct option long_options[] = { 1844 {"pedantic", no_argument, 0, 'p' }, 1845 {0, 0, 0, 0}, 1846 }; 1847 1848 /* Should be first to utilize g_test functionality, So we can see errors. */ 1849 g_test_init(&argc, &argv, NULL); 1850 1851 while (1) { 1852 c = getopt_long(argc, argv, "", long_options, NULL); 1853 if (c == -1) { 1854 break; 1855 } 1856 switch (c) { 1857 case -1: 1858 break; 1859 case 'p': 1860 ahci_pedantic = 1; 1861 break; 1862 default: 1863 fprintf(stderr, "Unrecognized ahci_test option.\n"); 1864 g_assert_not_reached(); 1865 } 1866 } 1867 1868 /* Check architecture */ 1869 arch = qtest_get_arch(); 1870 if (strcmp(arch, "i386") && strcmp(arch, "x86_64")) { 1871 g_test_message("Skipping test for non-x86"); 1872 return 0; 1873 } 1874 1875 /* Create a temporary image */ 1876 fd = mkstemp(tmp_path); 1877 g_assert(fd >= 0); 1878 if (have_qemu_img()) { 1879 imgfmt = "qcow2"; 1880 test_image_size_mb = TEST_IMAGE_SIZE_MB_LARGE; 1881 mkqcow2(tmp_path, TEST_IMAGE_SIZE_MB_LARGE); 1882 } else { 1883 g_test_message("QTEST_QEMU_IMG not set or qemu-img missing; " 1884 "skipping LBA48 high-sector tests"); 1885 imgfmt = "raw"; 1886 test_image_size_mb = TEST_IMAGE_SIZE_MB_SMALL; 1887 ret = ftruncate(fd, test_image_size_mb * 1024 * 1024); 1888 g_assert(ret == 0); 1889 } 1890 close(fd); 1891 1892 /* Create temporary blkdebug instructions */ 1893 fd = mkstemp(debug_path); 1894 g_assert(fd >= 0); 1895 close(fd); 1896 1897 /* Reserve a hollow file to use as a socket for migration tests */ 1898 fd = mkstemp(mig_socket); 1899 g_assert(fd >= 0); 1900 close(fd); 1901 1902 /* Run the tests */ 1903 qtest_add_func("/ahci/sanity", test_sanity); 1904 qtest_add_func("/ahci/pci_spec", test_pci_spec); 1905 qtest_add_func("/ahci/pci_enable", test_pci_enable); 1906 qtest_add_func("/ahci/hba_spec", test_hba_spec); 1907 qtest_add_func("/ahci/hba_enable", test_hba_enable); 1908 qtest_add_func("/ahci/identify", test_identify); 1909 1910 for (i = MODE_BEGIN; i < NUM_MODES; i++) { 1911 for (j = ADDR_MODE_BEGIN; j < NUM_ADDR_MODES; j++) { 1912 for (k = LEN_BEGIN; k < NUM_LENGTHS; k++) { 1913 for (m = OFFSET_BEGIN; m < NUM_OFFSETS; m++) { 1914 create_ahci_io_test(i, j, k, m); 1915 } 1916 } 1917 } 1918 } 1919 1920 qtest_add_func("/ahci/io/dma/lba28/fragmented", test_dma_fragmented); 1921 1922 qtest_add_func("/ahci/flush/simple", test_flush); 1923 qtest_add_func("/ahci/flush/retry", test_flush_retry); 1924 qtest_add_func("/ahci/flush/migrate", test_flush_migrate); 1925 1926 qtest_add_func("/ahci/migrate/sanity", test_migrate_sanity); 1927 qtest_add_func("/ahci/migrate/dma/simple", test_migrate_dma); 1928 qtest_add_func("/ahci/io/dma/lba28/retry", test_halted_dma); 1929 qtest_add_func("/ahci/migrate/dma/halted", test_migrate_halted_dma); 1930 1931 qtest_add_func("/ahci/max", test_max); 1932 qtest_add_func("/ahci/reset", test_reset); 1933 1934 qtest_add_func("/ahci/io/ncq/simple", test_ncq_simple); 1935 qtest_add_func("/ahci/migrate/ncq/simple", test_migrate_ncq); 1936 qtest_add_func("/ahci/io/ncq/retry", test_halted_ncq); 1937 qtest_add_func("/ahci/migrate/ncq/halted", test_migrate_halted_ncq); 1938 1939 qtest_add_func("/ahci/cdrom/dma/single", test_cdrom_dma); 1940 qtest_add_func("/ahci/cdrom/dma/multi", test_cdrom_dma_multi); 1941 qtest_add_func("/ahci/cdrom/pio/single", test_cdrom_pio); 1942 qtest_add_func("/ahci/cdrom/pio/multi", test_cdrom_pio_multi); 1943 1944 qtest_add_func("/ahci/cdrom/pio/bcl", test_atapi_bcl); 1945 qtest_add_func("/ahci/cdrom/eject", test_atapi_tray); 1946 1947 ret = g_test_run(); 1948 1949 /* Cleanup */ 1950 unlink(tmp_path); 1951 unlink(debug_path); 1952 unlink(mig_socket); 1953 1954 return ret; 1955}