ahci-test.c 49.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 * AHCI test cases
 *
 * Copyright (c) 2014 John Snow <jsnow@redhat.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include <stdint.h>
#include <string.h>
#include <stdio.h>
28
#include <getopt.h>
29 30 31
#include <glib.h>

#include "libqtest.h"
J
John Snow 已提交
32
#include "libqos/libqos-pc.h"
J
John Snow 已提交
33
#include "libqos/ahci.h"
34 35 36 37 38 39 40 41
#include "libqos/pci-pc.h"

#include "qemu-common.h"
#include "qemu/host-utils.h"

#include "hw/pci/pci_ids.h"
#include "hw/pci/pci_regs.h"

42 43
/* Test-specific defines -- in MiB */
#define TEST_IMAGE_SIZE_MB (200 * 1024)
44 45
#define TEST_IMAGE_SECTORS ((TEST_IMAGE_SIZE_MB / AHCI_SECTOR_SIZE)     \
                            * 1024 * 1024)
46 47 48

/*** Globals ***/
static char tmp_path[] = "/tmp/qtest.XXXXXX";
J
John Snow 已提交
49
static char debug_path[] = "/tmp/qtest-blkdebug.XXXXXX";
50 51
static bool ahci_pedantic;

52
/*** Function Declarations ***/
53
static void ahci_test_port_spec(AHCIQState *ahci, uint8_t port);
54 55
static void ahci_test_pci_spec(AHCIQState *ahci);
static void ahci_test_pci_caps(AHCIQState *ahci, uint16_t header,
56
                               uint8_t offset);
57 58 59
static void ahci_test_satacap(AHCIQState *ahci, uint8_t offset);
static void ahci_test_msicap(AHCIQState *ahci, uint8_t offset);
static void ahci_test_pmcap(AHCIQState *ahci, uint8_t offset);
60 61 62

/*** Utilities ***/

63 64 65 66 67 68 69 70 71 72 73
static void string_bswap16(uint16_t *s, size_t bytes)
{
    g_assert_cmphex((bytes & 1), ==, 0);
    bytes /= 2;

    while (bytes--) {
        *s = bswap16(*s);
        s++;
    }
}

J
John Snow 已提交
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
/**
 * Verify that the transfer did not corrupt our state at all.
 */
static void verify_state(AHCIQState *ahci)
{
    int i, j;
    uint32_t ahci_fingerprint;
    uint64_t hba_base;
    uint64_t hba_stored;
    AHCICommandHeader cmd;

    ahci_fingerprint = qpci_config_readl(ahci->dev, PCI_VENDOR_ID);
    g_assert_cmphex(ahci_fingerprint, ==, ahci->fingerprint);

    /* If we haven't initialized, this is as much as can be validated. */
    if (!ahci->hba_base) {
        return;
    }

    hba_base = (uint64_t)qpci_config_readl(ahci->dev, PCI_BASE_ADDRESS_5);
    hba_stored = (uint64_t)(uintptr_t)ahci->hba_base;
    g_assert_cmphex(hba_base, ==, hba_stored);

    g_assert_cmphex(ahci_rreg(ahci, AHCI_CAP), ==, ahci->cap);
    g_assert_cmphex(ahci_rreg(ahci, AHCI_CAP2), ==, ahci->cap2);

    for (i = 0; i < 32; i++) {
        g_assert_cmphex(ahci_px_rreg(ahci, i, AHCI_PX_FB), ==,
                        ahci->port[i].fb);
        g_assert_cmphex(ahci_px_rreg(ahci, i, AHCI_PX_CLB), ==,
                        ahci->port[i].clb);
        for (j = 0; j < 32; j++) {
            ahci_get_command_header(ahci, i, j, &cmd);
            g_assert_cmphex(cmd.prdtl, ==, ahci->port[i].prdtl[j]);
            g_assert_cmphex(cmd.ctba, ==, ahci->port[i].ctba[j]);
        }
    }
}

static void ahci_migrate(AHCIQState *from, AHCIQState *to, const char *uri)
{
    QOSState *tmp = to->parent;
    QPCIDevice *dev = to->dev;
    if (uri == NULL) {
        uri = "tcp:127.0.0.1:1234";
    }

    /* context will be 'to' after completion. */
    migrate(from->parent, to->parent, uri);

    /* We'd like for the AHCIState objects to still point
     * to information specific to its specific parent
     * instance, but otherwise just inherit the new data. */
    memcpy(to, from, sizeof(AHCIQState));
    to->parent = tmp;
    to->dev = dev;

    tmp = from->parent;
    dev = from->dev;
    memset(from, 0x00, sizeof(AHCIQState));
    from->parent = tmp;
    from->dev = dev;

    verify_state(to);
}

140 141 142
/*** Test Setup & Teardown ***/

/**
J
John Snow 已提交
143
 * Start a Q35 machine and bookmark a handle to the AHCI device.
144
 */
145
static AHCIQState *ahci_vboot(const char *cli, va_list ap)
146
{
J
John Snow 已提交
147
    AHCIQState *s;
148

J
John Snow 已提交
149
    s = g_malloc0(sizeof(AHCIQState));
150
    s->parent = qtest_pc_vboot(cli, ap);
J
John Snow 已提交
151
    alloc_set_flags(s->parent->alloc, ALLOC_LEAK_ASSERT);
152

J
John Snow 已提交
153
    /* Verify that we have an AHCI device present. */
154
    s->dev = get_ahci_device(&s->fingerprint);
155

J
John Snow 已提交
156
    return s;
157 158
}

159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
/**
 * Start a Q35 machine and bookmark a handle to the AHCI device.
 */
static AHCIQState *ahci_boot(const char *cli, ...)
{
    AHCIQState *s;
    va_list ap;

    if (cli) {
        va_start(ap, cli);
        s = ahci_vboot(cli, ap);
        va_end(ap);
    } else {
        cli = "-drive if=none,id=drive0,file=%s,cache=writeback,serial=%s"
            ",format=qcow2"
            " -M q35 "
            "-device ide-hd,drive=drive0 "
            "-global ide-hd.ver=%s";
        s = ahci_boot(cli, tmp_path, "testdisk", "version");
    }

    return s;
}

183 184 185
/**
 * Clean up the PCI device, then terminate the QEMU instance.
 */
J
John Snow 已提交
186
static void ahci_shutdown(AHCIQState *ahci)
187
{
J
John Snow 已提交
188
    QOSState *qs = ahci->parent;
J
John Snow 已提交
189 190

    set_context(qs);
J
John Snow 已提交
191
    ahci_clean_mem(ahci);
J
John Snow 已提交
192 193 194
    free_ahci_device(ahci->dev);
    g_free(ahci);
    qtest_shutdown(qs);
195 196
}

197 198 199 200
/**
 * Boot and fully enable the HBA device.
 * @see ahci_boot, ahci_pci_enable and ahci_hba_enable.
 */
201
static AHCIQState *ahci_boot_and_enable(const char *cli, ...)
202 203
{
    AHCIQState *ahci;
204
    va_list ap;
205 206
    uint16_t buff[256];
    uint8_t port;
207 208 209 210 211 212 213 214

    if (cli) {
        va_start(ap, cli);
        ahci = ahci_vboot(cli, ap);
        va_end(ap);
    } else {
        ahci = ahci_boot(NULL);
    }
215 216 217

    ahci_pci_enable(ahci);
    ahci_hba_enable(ahci);
218 219 220 221
    /* Initialize test device */
    port = ahci_port_select(ahci);
    ahci_port_clear(ahci, port);
    ahci_io(ahci, port, CMD_IDENTIFY, &buff, sizeof(buff), 0);
222 223 224 225

    return ahci;
}

226 227 228 229 230
/*** Specification Adherence Tests ***/

/**
 * Implementation for test_pci_spec. Ensures PCI configuration space is sane.
 */
231
static void ahci_test_pci_spec(AHCIQState *ahci)
232 233 234 235 236 237
{
    uint8_t datab;
    uint16_t data;
    uint32_t datal;

    /* Most of these bits should start cleared until we turn them on. */
238
    data = qpci_config_readw(ahci->dev, PCI_COMMAND);
239 240 241 242 243 244 245 246 247 248 249
    ASSERT_BIT_CLEAR(data, PCI_COMMAND_MEMORY);
    ASSERT_BIT_CLEAR(data, PCI_COMMAND_MASTER);
    ASSERT_BIT_CLEAR(data, PCI_COMMAND_SPECIAL);     /* Reserved */
    ASSERT_BIT_CLEAR(data, PCI_COMMAND_VGA_PALETTE); /* Reserved */
    ASSERT_BIT_CLEAR(data, PCI_COMMAND_PARITY);
    ASSERT_BIT_CLEAR(data, PCI_COMMAND_WAIT);        /* Reserved */
    ASSERT_BIT_CLEAR(data, PCI_COMMAND_SERR);
    ASSERT_BIT_CLEAR(data, PCI_COMMAND_FAST_BACK);
    ASSERT_BIT_CLEAR(data, PCI_COMMAND_INTX_DISABLE);
    ASSERT_BIT_CLEAR(data, 0xF800);                  /* Reserved */

250
    data = qpci_config_readw(ahci->dev, PCI_STATUS);
251 252 253 254 255 256 257 258 259 260 261 262
    ASSERT_BIT_CLEAR(data, 0x01 | 0x02 | 0x04);     /* Reserved */
    ASSERT_BIT_CLEAR(data, PCI_STATUS_INTERRUPT);
    ASSERT_BIT_SET(data, PCI_STATUS_CAP_LIST);      /* must be set */
    ASSERT_BIT_CLEAR(data, PCI_STATUS_UDF);         /* Reserved */
    ASSERT_BIT_CLEAR(data, PCI_STATUS_PARITY);
    ASSERT_BIT_CLEAR(data, PCI_STATUS_SIG_TARGET_ABORT);
    ASSERT_BIT_CLEAR(data, PCI_STATUS_REC_TARGET_ABORT);
    ASSERT_BIT_CLEAR(data, PCI_STATUS_REC_MASTER_ABORT);
    ASSERT_BIT_CLEAR(data, PCI_STATUS_SIG_SYSTEM_ERROR);
    ASSERT_BIT_CLEAR(data, PCI_STATUS_DETECTED_PARITY);

    /* RID occupies the low byte, CCs occupy the high three. */
263
    datal = qpci_config_readl(ahci->dev, PCI_CLASS_REVISION);
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
    if (ahci_pedantic) {
        /* AHCI 1.3 specifies that at-boot, the RID should reset to 0x00,
         * Though in practice this is likely seldom true. */
        ASSERT_BIT_CLEAR(datal, 0xFF);
    }

    /* BCC *must* equal 0x01. */
    g_assert_cmphex(PCI_BCC(datal), ==, 0x01);
    if (PCI_SCC(datal) == 0x01) {
        /* IDE */
        ASSERT_BIT_SET(0x80000000, datal);
        ASSERT_BIT_CLEAR(0x60000000, datal);
    } else if (PCI_SCC(datal) == 0x04) {
        /* RAID */
        g_assert_cmphex(PCI_PI(datal), ==, 0);
    } else if (PCI_SCC(datal) == 0x06) {
        /* AHCI */
        g_assert_cmphex(PCI_PI(datal), ==, 0x01);
    } else {
        g_assert_not_reached();
    }

286
    datab = qpci_config_readb(ahci->dev, PCI_CACHE_LINE_SIZE);
287 288
    g_assert_cmphex(datab, ==, 0);

289
    datab = qpci_config_readb(ahci->dev, PCI_LATENCY_TIMER);
290 291 292
    g_assert_cmphex(datab, ==, 0);

    /* Only the bottom 7 bits must be off. */
293
    datab = qpci_config_readb(ahci->dev, PCI_HEADER_TYPE);
294 295 296
    ASSERT_BIT_CLEAR(datab, 0x7F);

    /* BIST is optional, but the low 7 bits must always start off regardless. */
297
    datab = qpci_config_readb(ahci->dev, PCI_BIST);
298 299 300
    ASSERT_BIT_CLEAR(datab, 0x7F);

    /* BARS 0-4 do not have a boot spec, but ABAR/BAR5 must be clean. */
301
    datal = qpci_config_readl(ahci->dev, PCI_BASE_ADDRESS_5);
302 303
    g_assert_cmphex(datal, ==, 0);

304 305
    qpci_config_writel(ahci->dev, PCI_BASE_ADDRESS_5, 0xFFFFFFFF);
    datal = qpci_config_readl(ahci->dev, PCI_BASE_ADDRESS_5);
306 307 308 309 310
    /* ABAR must be 32-bit, memory mapped, non-prefetchable and
     * must be >= 512 bytes. To that end, bits 0-8 must be off. */
    ASSERT_BIT_CLEAR(datal, 0xFF);

    /* Capability list MUST be present, */
311
    datal = qpci_config_readl(ahci->dev, PCI_CAPABILITY_LIST);
312 313 314 315 316
    /* But these bits are reserved. */
    ASSERT_BIT_CLEAR(datal, ~0xFF);
    g_assert_cmphex(datal, !=, 0);

    /* Check specification adherence for capability extenstions. */
317
    data = qpci_config_readw(ahci->dev, datal);
318

319
    switch (ahci->fingerprint) {
320 321 322 323 324 325 326 327 328 329 330 331
    case AHCI_INTEL_ICH9:
        /* Intel ICH9 Family Datasheet 14.1.19 p.550 */
        g_assert_cmphex((data & 0xFF), ==, PCI_CAP_ID_MSI);
        break;
    default:
        /* AHCI 1.3, Section 2.1.14 -- CAP must point to PMCAP. */
        g_assert_cmphex((data & 0xFF), ==, PCI_CAP_ID_PM);
    }

    ahci_test_pci_caps(ahci, data, (uint8_t)datal);

    /* Reserved. */
332
    datal = qpci_config_readl(ahci->dev, PCI_CAPABILITY_LIST + 4);
333 334 335
    g_assert_cmphex(datal, ==, 0);

    /* IPIN might vary, but ILINE must be off. */
336
    datab = qpci_config_readb(ahci->dev, PCI_INTERRUPT_LINE);
337 338 339 340 341 342
    g_assert_cmphex(datab, ==, 0);
}

/**
 * Test PCI capabilities for AHCI specification adherence.
 */
343
static void ahci_test_pci_caps(AHCIQState *ahci, uint16_t header,
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
                               uint8_t offset)
{
    uint8_t cid = header & 0xFF;
    uint8_t next = header >> 8;

    g_test_message("CID: %02x; next: %02x", cid, next);

    switch (cid) {
    case PCI_CAP_ID_PM:
        ahci_test_pmcap(ahci, offset);
        break;
    case PCI_CAP_ID_MSI:
        ahci_test_msicap(ahci, offset);
        break;
    case PCI_CAP_ID_SATA:
        ahci_test_satacap(ahci, offset);
        break;

    default:
        g_test_message("Unknown CAP 0x%02x", cid);
    }

    if (next) {
367
        ahci_test_pci_caps(ahci, qpci_config_readw(ahci->dev, next), next);
368 369 370 371 372 373
    }
}

/**
 * Test SATA PCI capabilitity for AHCI specification adherence.
 */
374
static void ahci_test_satacap(AHCIQState *ahci, uint8_t offset)
375 376 377 378 379 380 381
{
    uint16_t dataw;
    uint32_t datal;

    g_test_message("Verifying SATACAP");

    /* Assert that the SATACAP version is 1.0, And reserved bits are empty. */
382
    dataw = qpci_config_readw(ahci->dev, offset + 2);
383 384 385
    g_assert_cmphex(dataw, ==, 0x10);

    /* Grab the SATACR1 register. */
386
    datal = qpci_config_readw(ahci->dev, offset + 4);
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408

    switch (datal & 0x0F) {
    case 0x04: /* BAR0 */
    case 0x05: /* BAR1 */
    case 0x06:
    case 0x07:
    case 0x08:
    case 0x09: /* BAR5 */
    case 0x0F: /* Immediately following SATACR1 in PCI config space. */
        break;
    default:
        /* Invalid BARLOC for the Index Data Pair. */
        g_assert_not_reached();
    }

    /* Reserved. */
    g_assert_cmphex((datal >> 24), ==, 0x00);
}

/**
 * Test MSI PCI capability for AHCI specification adherence.
 */
409
static void ahci_test_msicap(AHCIQState *ahci, uint8_t offset)
410 411 412 413 414 415
{
    uint16_t dataw;
    uint32_t datal;

    g_test_message("Verifying MSICAP");

416
    dataw = qpci_config_readw(ahci->dev, offset + PCI_MSI_FLAGS);
417 418 419 420
    ASSERT_BIT_CLEAR(dataw, PCI_MSI_FLAGS_ENABLE);
    ASSERT_BIT_CLEAR(dataw, PCI_MSI_FLAGS_QSIZE);
    ASSERT_BIT_CLEAR(dataw, PCI_MSI_FLAGS_RESERVED);

421
    datal = qpci_config_readl(ahci->dev, offset + PCI_MSI_ADDRESS_LO);
422 423 424 425
    g_assert_cmphex(datal, ==, 0);

    if (dataw & PCI_MSI_FLAGS_64BIT) {
        g_test_message("MSICAP is 64bit");
426
        datal = qpci_config_readl(ahci->dev, offset + PCI_MSI_ADDRESS_HI);
427
        g_assert_cmphex(datal, ==, 0);
428
        dataw = qpci_config_readw(ahci->dev, offset + PCI_MSI_DATA_64);
429 430 431
        g_assert_cmphex(dataw, ==, 0);
    } else {
        g_test_message("MSICAP is 32bit");
432
        dataw = qpci_config_readw(ahci->dev, offset + PCI_MSI_DATA_32);
433 434 435 436 437 438 439
        g_assert_cmphex(dataw, ==, 0);
    }
}

/**
 * Test Power Management PCI capability for AHCI specification adherence.
 */
440
static void ahci_test_pmcap(AHCIQState *ahci, uint8_t offset)
441 442 443 444 445
{
    uint16_t dataw;

    g_test_message("Verifying PMCAP");

446
    dataw = qpci_config_readw(ahci->dev, offset + PCI_PM_PMC);
447 448 449 450 451
    ASSERT_BIT_CLEAR(dataw, PCI_PM_CAP_PME_CLOCK);
    ASSERT_BIT_CLEAR(dataw, PCI_PM_CAP_RESERVED);
    ASSERT_BIT_CLEAR(dataw, PCI_PM_CAP_D1);
    ASSERT_BIT_CLEAR(dataw, PCI_PM_CAP_D2);

452
    dataw = qpci_config_readw(ahci->dev, offset + PCI_PM_CTRL);
453 454 455 456 457 458
    ASSERT_BIT_CLEAR(dataw, PCI_PM_CTRL_STATE_MASK);
    ASSERT_BIT_CLEAR(dataw, PCI_PM_CTRL_RESERVED);
    ASSERT_BIT_CLEAR(dataw, PCI_PM_CTRL_DATA_SEL_MASK);
    ASSERT_BIT_CLEAR(dataw, PCI_PM_CTRL_DATA_SCALE_MASK);
}

459
static void ahci_test_hba_spec(AHCIQState *ahci)
460 461
{
    unsigned i;
462
    uint32_t reg;
463 464 465 466
    uint32_t ports;
    uint8_t nports_impl;
    uint8_t maxports;

467
    g_assert(ahci != NULL);
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489

    /*
     * Note that the AHCI spec does expect the BIOS to set up a few things:
     * CAP.SSS    - Support for staggered spin-up            (t/f)
     * CAP.SMPS   - Support for mechanical presence switches (t/f)
     * PI         - Ports Implemented                        (1-32)
     * PxCMD.HPCP - Hot Plug Capable Port
     * PxCMD.MPSP - Mechanical Presence Switch Present
     * PxCMD.CPD  - Cold Presence Detection support
     *
     * Additional items are touched if CAP.SSS is on, see AHCI 10.1.1 p.97:
     * Foreach Port Implemented:
     * -PxCMD.ST, PxCMD.CR, PxCMD.FRE, PxCMD.FR, PxSCTL.DET are 0
     * -PxCLB/U and PxFB/U are set to valid regions in memory
     * -PxSUD is set to 1.
     * -PxSSTS.DET is polled for presence; if detected, we continue:
     * -PxSERR is cleared with 1's.
     * -If PxTFD.STS.BSY, PxTFD.STS.DRQ, and PxTFD.STS.ERR are all zero,
     *  the device is ready.
     */

    /* 1 CAP - Capabilities Register */
490
    ahci->cap = ahci_rreg(ahci, AHCI_CAP);
491
    ASSERT_BIT_CLEAR(ahci->cap, AHCI_CAP_RESERVED);
492 493

    /* 2 GHC - Global Host Control */
494
    reg = ahci_rreg(ahci, AHCI_GHC);
495 496 497
    ASSERT_BIT_CLEAR(reg, AHCI_GHC_HR);
    ASSERT_BIT_CLEAR(reg, AHCI_GHC_IE);
    ASSERT_BIT_CLEAR(reg, AHCI_GHC_MRSM);
498
    if (BITSET(ahci->cap, AHCI_CAP_SAM)) {
499 500 501 502 503 504 505 506
        g_test_message("Supports AHCI-Only Mode: GHC_AE is Read-Only.");
        ASSERT_BIT_SET(reg, AHCI_GHC_AE);
    } else {
        g_test_message("Supports AHCI/Legacy mix.");
        ASSERT_BIT_CLEAR(reg, AHCI_GHC_AE);
    }

    /* 3 IS - Interrupt Status */
507
    reg = ahci_rreg(ahci, AHCI_IS);
508 509 510
    g_assert_cmphex(reg, ==, 0);

    /* 4 PI - Ports Implemented */
511
    ports = ahci_rreg(ahci, AHCI_PI);
512 513 514 515
    /* Ports Implemented must be non-zero. */
    g_assert_cmphex(ports, !=, 0);
    /* Ports Implemented must be <= Number of Ports. */
    nports_impl = ctpopl(ports);
516
    g_assert_cmpuint(((AHCI_CAP_NP & ahci->cap) + 1), >=, nports_impl);
517 518 519 520

    /* Ports must be within the proper range. Given a mapping of SIZE,
     * 256 bytes are used for global HBA control, and the rest is used
     * for ports data, at 0x80 bytes each. */
521 522
    g_assert_cmphex(ahci->barsize, >, 0);
    maxports = (ahci->barsize - HBA_DATA_REGION_SIZE) / HBA_PORT_DATA_SIZE;
523 524 525 526
    /* e.g, 30 ports for 4K of memory. (4096 - 256) / 128 = 30 */
    g_assert_cmphex((reg >> maxports), ==, 0);

    /* 5 AHCI Version */
527
    reg = ahci_rreg(ahci, AHCI_VS);
528 529 530 531 532 533 534 535 536 537 538 539
    switch (reg) {
    case AHCI_VERSION_0_95:
    case AHCI_VERSION_1_0:
    case AHCI_VERSION_1_1:
    case AHCI_VERSION_1_2:
    case AHCI_VERSION_1_3:
        break;
    default:
        g_assert_not_reached();
    }

    /* 6 Command Completion Coalescing Control: depends on CAP.CCCS. */
540
    reg = ahci_rreg(ahci, AHCI_CCCCTL);
541
    if (BITSET(ahci->cap, AHCI_CAP_CCCS)) {
542 543 544 545 546 547 548 549 550
        ASSERT_BIT_CLEAR(reg, AHCI_CCCCTL_EN);
        ASSERT_BIT_CLEAR(reg, AHCI_CCCCTL_RESERVED);
        ASSERT_BIT_SET(reg, AHCI_CCCCTL_CC);
        ASSERT_BIT_SET(reg, AHCI_CCCCTL_TV);
    } else {
        g_assert_cmphex(reg, ==, 0);
    }

    /* 7 CCC_PORTS */
551
    reg = ahci_rreg(ahci, AHCI_CCCPORTS);
552 553 554 555
    /* Must be zeroes initially regardless of CAP.CCCS */
    g_assert_cmphex(reg, ==, 0);

    /* 8 EM_LOC */
556
    reg = ahci_rreg(ahci, AHCI_EMLOC);
557
    if (BITCLR(ahci->cap, AHCI_CAP_EMS)) {
558 559 560 561
        g_assert_cmphex(reg, ==, 0);
    }

    /* 9 EM_CTL */
562
    reg = ahci_rreg(ahci, AHCI_EMCTL);
563
    if (BITSET(ahci->cap, AHCI_CAP_EMS)) {
564 565 566 567 568 569 570 571 572
        ASSERT_BIT_CLEAR(reg, AHCI_EMCTL_STSMR);
        ASSERT_BIT_CLEAR(reg, AHCI_EMCTL_CTLTM);
        ASSERT_BIT_CLEAR(reg, AHCI_EMCTL_CTLRST);
        ASSERT_BIT_CLEAR(reg, AHCI_EMCTL_RESERVED);
    } else {
        g_assert_cmphex(reg, ==, 0);
    }

    /* 10 CAP2 -- Capabilities Extended */
573
    ahci->cap2 = ahci_rreg(ahci, AHCI_CAP2);
574
    ASSERT_BIT_CLEAR(ahci->cap2, AHCI_CAP2_RESERVED);
575 576

    /* 11 BOHC -- Bios/OS Handoff Control */
577
    reg = ahci_rreg(ahci, AHCI_BOHC);
578 579 580 581 582
    g_assert_cmphex(reg, ==, 0);

    /* 12 -- 23: Reserved */
    g_test_message("Verifying HBA reserved area is empty.");
    for (i = AHCI_RESERVED; i < AHCI_NVMHCI; ++i) {
583
        reg = ahci_rreg(ahci, i);
584 585 586 587
        g_assert_cmphex(reg, ==, 0);
    }

    /* 24 -- 39: NVMHCI */
588
    if (BITCLR(ahci->cap2, AHCI_CAP2_NVMP)) {
589 590
        g_test_message("Verifying HBA/NVMHCI area is empty.");
        for (i = AHCI_NVMHCI; i < AHCI_VENDOR; ++i) {
591
            reg = ahci_rreg(ahci, i);
592 593 594 595 596 597 598
            g_assert_cmphex(reg, ==, 0);
        }
    }

    /* 40 -- 63: Vendor */
    g_test_message("Verifying HBA/Vendor area is empty.");
    for (i = AHCI_VENDOR; i < AHCI_PORTS; ++i) {
599
        reg = ahci_rreg(ahci, i);
600 601 602 603 604 605 606
        g_assert_cmphex(reg, ==, 0);
    }

    /* 64 -- XX: Port Space */
    for (i = 0; ports || (i < maxports); ports >>= 1, ++i) {
        if (BITSET(ports, 0x1)) {
            g_test_message("Testing port %u for spec", i);
607
            ahci_test_port_spec(ahci, i);
608 609 610 611 612 613 614 615
        } else {
            uint16_t j;
            uint16_t low = AHCI_PORTS + (32 * i);
            uint16_t high = AHCI_PORTS + (32 * (i + 1));
            g_test_message("Asserting unimplemented port %u "
                           "(reg [%u-%u]) is empty.",
                           i, low, high - 1);
            for (j = low; j < high; ++j) {
616
                reg = ahci_rreg(ahci, j);
617 618 619 620 621 622 623 624 625
                g_assert_cmphex(reg, ==, 0);
            }
        }
    }
}

/**
 * Test the memory space for one port for specification adherence.
 */
626
static void ahci_test_port_spec(AHCIQState *ahci, uint8_t port)
627 628 629 630 631
{
    uint32_t reg;
    unsigned i;

    /* (0) CLB */
632
    reg = ahci_px_rreg(ahci, port, AHCI_PX_CLB);
633 634 635
    ASSERT_BIT_CLEAR(reg, AHCI_PX_CLB_RESERVED);

    /* (1) CLBU */
636
    if (BITCLR(ahci->cap, AHCI_CAP_S64A)) {
637
        reg = ahci_px_rreg(ahci, port, AHCI_PX_CLBU);
638 639 640 641
        g_assert_cmphex(reg, ==, 0);
    }

    /* (2) FB */
642
    reg = ahci_px_rreg(ahci, port, AHCI_PX_FB);
643 644 645
    ASSERT_BIT_CLEAR(reg, AHCI_PX_FB_RESERVED);

    /* (3) FBU */
646
    if (BITCLR(ahci->cap, AHCI_CAP_S64A)) {
647
        reg = ahci_px_rreg(ahci, port, AHCI_PX_FBU);
648 649 650 651
        g_assert_cmphex(reg, ==, 0);
    }

    /* (4) IS */
652
    reg = ahci_px_rreg(ahci, port, AHCI_PX_IS);
653 654 655
    g_assert_cmphex(reg, ==, 0);

    /* (5) IE */
656
    reg = ahci_px_rreg(ahci, port, AHCI_PX_IE);
657 658 659
    g_assert_cmphex(reg, ==, 0);

    /* (6) CMD */
660
    reg = ahci_px_rreg(ahci, port, AHCI_PX_CMD);
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
    ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_FRE);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_RESERVED);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_CCS);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_FR);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_CR);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_PMA); /* And RW only if CAP.SPM */
    ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_APSTE); /* RW only if CAP2.APST */
    ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_ATAPI);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_DLAE);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_ALPE);  /* RW only if CAP.SALP */
    ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_ASP);   /* RW only if CAP.SALP */
    ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_ICC);
    /* If CPDetect support does not exist, CPState must be off. */
    if (BITCLR(reg, AHCI_PX_CMD_CPD)) {
        ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_CPS);
    }
    /* If MPSPresence is not set, MPSState must be off. */
    if (BITCLR(reg, AHCI_PX_CMD_MPSP)) {
        ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_MPSS);
    }
    /* If we do not support MPS, MPSS and MPSP must be off. */
682
    if (BITCLR(ahci->cap, AHCI_CAP_SMPS)) {
683 684 685 686
        ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_MPSS);
        ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_MPSP);
    }
    /* If, via CPD or MPSP we detect a drive, HPCP must be on. */
687
    if (BITANY(reg, AHCI_PX_CMD_CPD | AHCI_PX_CMD_MPSP)) {
688 689 690 691 692
        ASSERT_BIT_SET(reg, AHCI_PX_CMD_HPCP);
    }
    /* HPCP and ESP cannot both be active. */
    g_assert(!BITSET(reg, AHCI_PX_CMD_HPCP | AHCI_PX_CMD_ESP));
    /* If CAP.FBSS is not set, FBSCP must not be set. */
693
    if (BITCLR(ahci->cap, AHCI_CAP_FBSS)) {
694 695 696 697
        ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_FBSCP);
    }

    /* (7) RESERVED */
698
    reg = ahci_px_rreg(ahci, port, AHCI_PX_RES1);
699 700 701
    g_assert_cmphex(reg, ==, 0);

    /* (8) TFD */
702
    reg = ahci_px_rreg(ahci, port, AHCI_PX_TFD);
703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
    /* At boot, prior to an FIS being received, the TFD register should be 0x7F,
     * which breaks down as follows, as seen in AHCI 1.3 sec 3.3.8, p. 27. */
    ASSERT_BIT_SET(reg, AHCI_PX_TFD_STS_ERR);
    ASSERT_BIT_SET(reg, AHCI_PX_TFD_STS_CS1);
    ASSERT_BIT_SET(reg, AHCI_PX_TFD_STS_DRQ);
    ASSERT_BIT_SET(reg, AHCI_PX_TFD_STS_CS2);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_STS_BSY);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_ERR);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_RESERVED);

    /* (9) SIG */
    /* Though AHCI specifies the boot value should be 0xFFFFFFFF,
     * Even when GHC.ST is zero, the AHCI HBA may receive the initial
     * D2H register FIS and update the signature asynchronously,
     * so we cannot expect a value here. AHCI 1.3, sec 3.3.9, pp 27-28 */

    /* (10) SSTS / SCR0: SStatus */
720
    reg = ahci_px_rreg(ahci, port, AHCI_PX_SSTS);
721 722 723 724 725
    ASSERT_BIT_CLEAR(reg, AHCI_PX_SSTS_RESERVED);
    /* Even though the register should be 0 at boot, it is asynchronous and
     * prone to change, so we cannot test any well known value. */

    /* (11) SCTL / SCR2: SControl */
726
    reg = ahci_px_rreg(ahci, port, AHCI_PX_SCTL);
727 728 729
    g_assert_cmphex(reg, ==, 0);

    /* (12) SERR / SCR1: SError */
730
    reg = ahci_px_rreg(ahci, port, AHCI_PX_SERR);
731 732 733
    g_assert_cmphex(reg, ==, 0);

    /* (13) SACT / SCR3: SActive */
734
    reg = ahci_px_rreg(ahci, port, AHCI_PX_SACT);
735 736 737
    g_assert_cmphex(reg, ==, 0);

    /* (14) CI */
738
    reg = ahci_px_rreg(ahci, port, AHCI_PX_CI);
739 740 741
    g_assert_cmphex(reg, ==, 0);

    /* (15) SNTF */
742
    reg = ahci_px_rreg(ahci, port, AHCI_PX_SNTF);
743 744 745
    g_assert_cmphex(reg, ==, 0);

    /* (16) FBS */
746
    reg = ahci_px_rreg(ahci, port, AHCI_PX_FBS);
747 748 749 750 751 752
    ASSERT_BIT_CLEAR(reg, AHCI_PX_FBS_EN);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_FBS_DEC);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_FBS_SDE);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_FBS_DEV);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_FBS_DWE);
    ASSERT_BIT_CLEAR(reg, AHCI_PX_FBS_RESERVED);
753
    if (BITSET(ahci->cap, AHCI_CAP_FBSS)) {
754 755 756 757 758 759
        /* if Port-Multiplier FIS-based switching avail, ADO must >= 2 */
        g_assert((reg & AHCI_PX_FBS_ADO) >> ctzl(AHCI_PX_FBS_ADO) >= 2);
    }

    /* [17 -- 27] RESERVED */
    for (i = AHCI_PX_RES2; i < AHCI_PX_VS; ++i) {
760
        reg = ahci_px_rreg(ahci, port, i);
761 762 763 764 765
        g_assert_cmphex(reg, ==, 0);
    }

    /* [28 -- 31] Vendor-Specific */
    for (i = AHCI_PX_VS; i < 32; ++i) {
766
        reg = ahci_px_rreg(ahci, port, i);
767 768 769 770 771 772
        if (reg) {
            g_test_message("INFO: Vendor register %u non-empty", i);
        }
    }
}

773 774 775 776
/**
 * Utilizing an initialized AHCI HBA, issue an IDENTIFY command to the first
 * device we see, then read and check the response.
 */
777
static void ahci_test_identify(AHCIQState *ahci)
778 779
{
    uint16_t buff[256];
J
John Snow 已提交
780
    unsigned px;
781
    int rc;
782
    uint16_t sect_size;
J
John Snow 已提交
783
    const size_t buffsize = 512;
784 785 786

    g_assert(ahci != NULL);

J
John Snow 已提交
787 788 789 790 791 792
    /**
     * This serves as a bit of a tutorial on AHCI device programming:
     *
     * (1) Create a data buffer for the IDENTIFY response to be sent to
     * (2) Create a Command Table buffer, where we will store the
     *     command and PRDT (Physical Region Descriptor Table)
793
     * (3) Construct an FIS host-to-device command structure, and write it to
J
John Snow 已提交
794 795 796 797 798 799 800 801 802 803 804 805
     *     the top of the Command Table buffer.
     * (4) Create one or more Physical Region Descriptors (PRDs) that describe
     *     a location in memory where data may be stored/retrieved.
     * (5) Write these PRDTs to the bottom (offset 0x80) of the Command Table.
     * (6) Each AHCI port has up to 32 command slots. Each slot contains a
     *     header that points to a Command Table buffer. Pick an unused slot
     *     and update it to point to the Command Table we have built.
     * (7) Now: Command #n points to our Command Table, and our Command Table
     *     contains the FIS (that describes our command) and the PRDTL, which
     *     describes our buffer.
     * (8) We inform the HBA via PxCI (Command Issue) that the command in slot
     *     #n is ready for processing.
806 807 808
     */

    /* Pick the first implemented and running port */
J
John Snow 已提交
809 810
    px = ahci_port_select(ahci);
    g_test_message("Selected port %u for test", px);
811

812
    /* Clear out the FIS Receive area and any pending interrupts. */
J
John Snow 已提交
813
    ahci_port_clear(ahci, px);
814

J
John Snow 已提交
815
    /* "Read" 512 bytes using CMD_IDENTIFY into the host buffer. */
816
    ahci_io(ahci, px, CMD_IDENTIFY, &buff, buffsize, 0);
817 818 819 820 821 822 823 824 825 826 827 828 829

    /* Check serial number/version in the buffer */
    /* NB: IDENTIFY strings are packed in 16bit little endian chunks.
     * Since we copy byte-for-byte in ahci-test, on both LE and BE, we need to
     * unchunk this data. By contrast, ide-test copies 2 bytes at a time, and
     * as a consequence, only needs to unchunk the data on LE machines. */
    string_bswap16(&buff[10], 20);
    rc = memcmp(&buff[10], "testdisk            ", 20);
    g_assert_cmphex(rc, ==, 0);

    string_bswap16(&buff[23], 8);
    rc = memcmp(&buff[23], "version ", 8);
    g_assert_cmphex(rc, ==, 0);
830 831

    sect_size = le16_to_cpu(*((uint16_t *)(&buff[5])));
832
    g_assert_cmphex(sect_size, ==, AHCI_SECTOR_SIZE);
833 834
}

J
John Snow 已提交
835
static void ahci_test_io_rw_simple(AHCIQState *ahci, unsigned bufsize,
836 837
                                   uint64_t sector, uint8_t read_cmd,
                                   uint8_t write_cmd)
838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854
{
    uint64_t ptr;
    uint8_t port;
    unsigned char *tx = g_malloc(bufsize);
    unsigned char *rx = g_malloc0(bufsize);

    g_assert(ahci != NULL);

    /* Pick the first running port and clear it. */
    port = ahci_port_select(ahci);
    ahci_port_clear(ahci, port);

    /*** Create pattern and transfer to guest ***/
    /* Data buffer in the guest */
    ptr = ahci_alloc(ahci, bufsize);
    g_assert(ptr);

J
John Snow 已提交
855
    /* Write some indicative pattern to our buffer. */
856
    generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE);
857
    bufwrite(ptr, tx, bufsize);
858 859

    /* Write this buffer to disk, then read it back to the DMA buffer. */
860
    ahci_guest_io(ahci, port, write_cmd, ptr, bufsize, sector);
861
    qmemset(ptr, 0x00, bufsize);
862
    ahci_guest_io(ahci, port, read_cmd, ptr, bufsize, sector);
863 864

    /*** Read back the Data ***/
865
    bufread(ptr, rx, bufsize);
866 867 868 869 870 871 872
    g_assert_cmphex(memcmp(tx, rx, bufsize), ==, 0);

    ahci_free(ahci, ptr);
    g_free(tx);
    g_free(rx);
}

J
John Snow 已提交
873
static uint8_t ahci_test_nondata(AHCIQState *ahci, uint8_t ide_cmd)
J
John Snow 已提交
874
{
J
John Snow 已提交
875
    uint8_t port;
J
John Snow 已提交
876 877 878
    AHCICommand *cmd;

    /* Sanitize */
J
John Snow 已提交
879 880
    port = ahci_port_select(ahci);
    ahci_port_clear(ahci, port);
J
John Snow 已提交
881 882 883

    /* Issue Command */
    cmd = ahci_command_create(ide_cmd);
J
John Snow 已提交
884
    ahci_command_commit(ahci, cmd, port);
J
John Snow 已提交
885 886 887
    ahci_command_issue(ahci, cmd);
    ahci_command_verify(ahci, cmd);
    ahci_command_free(cmd);
J
John Snow 已提交
888 889

    return port;
J
John Snow 已提交
890 891 892 893 894 895 896
}

static void ahci_test_flush(AHCIQState *ahci)
{
    ahci_test_nondata(ahci, CMD_FLUSH_CACHE);
}

J
John Snow 已提交
897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923
static void ahci_test_max(AHCIQState *ahci)
{
    RegD2HFIS *d2h = g_malloc0(0x20);
    uint64_t nsect;
    uint8_t port;
    uint8_t cmd;
    uint64_t config_sect = TEST_IMAGE_SECTORS - 1;

    if (config_sect > 0xFFFFFF) {
        cmd = CMD_READ_MAX_EXT;
    } else {
        cmd = CMD_READ_MAX;
    }

    port = ahci_test_nondata(ahci, cmd);
    memread(ahci->port[port].fb + 0x40, d2h, 0x20);
    nsect = (uint64_t)d2h->lba_hi[2] << 40 |
        (uint64_t)d2h->lba_hi[1] << 32 |
        (uint64_t)d2h->lba_hi[0] << 24 |
        (uint64_t)d2h->lba_lo[2] << 16 |
        (uint64_t)d2h->lba_lo[1] << 8 |
        (uint64_t)d2h->lba_lo[0];

    g_assert_cmphex(nsect, ==, config_sect);
    g_free(d2h);
}

J
John Snow 已提交
924

925 926 927 928 929 930 931 932 933
/******************************************************************************/
/* Test Interfaces                                                            */
/******************************************************************************/

/**
 * Basic sanity test to boot a machine, find an AHCI device, and shutdown.
 */
static void test_sanity(void)
{
J
John Snow 已提交
934
    AHCIQState *ahci;
935
    ahci = ahci_boot(NULL);
936 937 938
    ahci_shutdown(ahci);
}

939 940 941 942 943 944
/**
 * Ensure that the PCI configuration space for the AHCI device is in-line with
 * the AHCI 1.3 specification for initial values.
 */
static void test_pci_spec(void)
{
J
John Snow 已提交
945
    AHCIQState *ahci;
946
    ahci = ahci_boot(NULL);
947
    ahci_test_pci_spec(ahci);
948 949 950
    ahci_shutdown(ahci);
}

951 952 953 954 955 956
/**
 * Engage the PCI AHCI device and sanity check the response.
 * Perform additional PCI config space bringup for the HBA.
 */
static void test_pci_enable(void)
{
J
John Snow 已提交
957
    AHCIQState *ahci;
958
    ahci = ahci_boot(NULL);
959
    ahci_pci_enable(ahci);
960 961 962
    ahci_shutdown(ahci);
}

963 964 965 966 967 968
/**
 * Investigate the memory mapped regions of the HBA,
 * and test them for AHCI specification adherence.
 */
static void test_hba_spec(void)
{
J
John Snow 已提交
969
    AHCIQState *ahci;
970

971
    ahci = ahci_boot(NULL);
972 973
    ahci_pci_enable(ahci);
    ahci_test_hba_spec(ahci);
974 975 976
    ahci_shutdown(ahci);
}

977 978 979 980 981 982
/**
 * Engage the HBA functionality of the AHCI PCI device,
 * and bring it into a functional idle state.
 */
static void test_hba_enable(void)
{
J
John Snow 已提交
983
    AHCIQState *ahci;
984

985
    ahci = ahci_boot(NULL);
986 987
    ahci_pci_enable(ahci);
    ahci_hba_enable(ahci);
988 989 990
    ahci_shutdown(ahci);
}

991 992 993 994 995 996
/**
 * Bring up the device and issue an IDENTIFY command.
 * Inspect the state of the HBA device and the data returned.
 */
static void test_identify(void)
{
J
John Snow 已提交
997
    AHCIQState *ahci;
998

999
    ahci = ahci_boot_and_enable(NULL);
1000
    ahci_test_identify(ahci);
1001 1002 1003
    ahci_shutdown(ahci);
}

J
John Snow 已提交
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
/**
 * Fragmented DMA test: Perform a standard 4K DMA read/write
 * test, but make sure the physical regions are fragmented to
 * be very small, each just 32 bytes, to see how AHCI performs
 * with chunks defined to be much less than a sector.
 */
static void test_dma_fragmented(void)
{
    AHCIQState *ahci;
    AHCICommand *cmd;
    uint8_t px;
    size_t bufsize = 4096;
    unsigned char *tx = g_malloc(bufsize);
    unsigned char *rx = g_malloc0(bufsize);
    uint64_t ptr;

1020
    ahci = ahci_boot_and_enable(NULL);
J
John Snow 已提交
1021 1022 1023 1024
    px = ahci_port_select(ahci);
    ahci_port_clear(ahci, px);

    /* create pattern */
1025
    generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE);
J
John Snow 已提交
1026 1027 1028 1029

    /* Create a DMA buffer in guest memory, and write our pattern to it. */
    ptr = guest_alloc(ahci->parent->alloc, bufsize);
    g_assert(ptr);
1030
    bufwrite(ptr, tx, bufsize);
J
John Snow 已提交
1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046

    cmd = ahci_command_create(CMD_WRITE_DMA);
    ahci_command_adjust(cmd, 0, ptr, bufsize, 32);
    ahci_command_commit(ahci, cmd, px);
    ahci_command_issue(ahci, cmd);
    ahci_command_verify(ahci, cmd);
    g_free(cmd);

    cmd = ahci_command_create(CMD_READ_DMA);
    ahci_command_adjust(cmd, 0, ptr, bufsize, 32);
    ahci_command_commit(ahci, cmd, px);
    ahci_command_issue(ahci, cmd);
    ahci_command_verify(ahci, cmd);
    g_free(cmd);

    /* Read back the guest's receive buffer into local memory */
1047
    bufread(ptr, rx, bufsize);
J
John Snow 已提交
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057
    guest_free(ahci->parent->alloc, ptr);

    g_assert_cmphex(memcmp(tx, rx, bufsize), ==, 0);

    ahci_shutdown(ahci);

    g_free(rx);
    g_free(tx);
}

J
John Snow 已提交
1058 1059 1060 1061
static void test_flush(void)
{
    AHCIQState *ahci;

1062
    ahci = ahci_boot_and_enable(NULL);
J
John Snow 已提交
1063 1064 1065 1066
    ahci_test_flush(ahci);
    ahci_shutdown(ahci);
}

J
John Snow 已提交
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
static void test_flush_retry(void)
{
    AHCIQState *ahci;
    AHCICommand *cmd;
    uint8_t port;
    const char *s;

    prepare_blkdebug_script(debug_path, "flush_to_disk");
    ahci = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0,"
                                "format=qcow2,cache=writeback,"
                                "rerror=stop,werror=stop "
                                "-M q35 "
                                "-device ide-hd,drive=drive0 ",
                                debug_path,
                                tmp_path);

J
John Snow 已提交
1083
    /* Issue Flush Command and wait for error */
J
John Snow 已提交
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101
    port = ahci_port_select(ahci);
    ahci_port_clear(ahci, port);
    cmd = ahci_command_create(CMD_FLUSH_CACHE);
    ahci_command_commit(ahci, cmd, port);
    ahci_command_issue_async(ahci, cmd);
    qmp_eventwait("STOP");

    /* Complete the command */
    s = "{'execute':'cont' }";
    qmp_async(s);
    qmp_eventwait("RESUME");
    ahci_command_wait(ahci, cmd);
    ahci_command_verify(ahci, cmd);

    ahci_command_free(cmd);
    ahci_shutdown(ahci);
}

J
John Snow 已提交
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
/**
 * Basic sanity test to boot a machine, find an AHCI device, and shutdown.
 */
static void test_migrate_sanity(void)
{
    AHCIQState *src, *dst;
    const char *uri = "tcp:127.0.0.1:1234";

    src = ahci_boot("-m 1024 -M q35 "
                    "-hda %s ", tmp_path);
    dst = ahci_boot("-m 1024 -M q35 "
                    "-hda %s "
                    "-incoming %s", tmp_path, uri);

    ahci_migrate(src, dst, uri);

    ahci_shutdown(src);
    ahci_shutdown(dst);
}

J
John Snow 已提交
1122
/**
J
John Snow 已提交
1123
 * Simple migration test: Write a pattern, migrate, then read.
J
John Snow 已提交
1124
 */
J
John Snow 已提交
1125
static void ahci_migrate_simple(uint8_t cmd_read, uint8_t cmd_write)
J
John Snow 已提交
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
{
    AHCIQState *src, *dst;
    uint8_t px;
    size_t bufsize = 4096;
    unsigned char *tx = g_malloc(bufsize);
    unsigned char *rx = g_malloc0(bufsize);
    const char *uri = "tcp:127.0.0.1:1234";

    src = ahci_boot_and_enable("-m 1024 -M q35 "
                               "-hda %s ", tmp_path);
    dst = ahci_boot("-m 1024 -M q35 "
                    "-hda %s "
                    "-incoming %s", tmp_path, uri);

    set_context(src->parent);

    /* initialize */
    px = ahci_port_select(src);
    ahci_port_clear(src, px);

    /* create pattern */
1147
    generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE);
J
John Snow 已提交
1148 1149

    /* Write, migrate, then read. */
J
John Snow 已提交
1150
    ahci_io(src, px, cmd_write, tx, bufsize, 0);
J
John Snow 已提交
1151
    ahci_migrate(src, dst, uri);
J
John Snow 已提交
1152
    ahci_io(dst, px, cmd_read, rx, bufsize, 0);
J
John Snow 已提交
1153 1154 1155 1156 1157 1158 1159 1160 1161 1162

    /* Verify pattern */
    g_assert_cmphex(memcmp(tx, rx, bufsize), ==, 0);

    ahci_shutdown(src);
    ahci_shutdown(dst);
    g_free(rx);
    g_free(tx);
}

J
John Snow 已提交
1163 1164 1165 1166 1167 1168 1169 1170 1171 1172
static void test_migrate_dma(void)
{
    ahci_migrate_simple(CMD_READ_DMA, CMD_WRITE_DMA);
}

static void test_migrate_ncq(void)
{
    ahci_migrate_simple(READ_FPDMA_QUEUED, WRITE_FPDMA_QUEUED);
}

J
John Snow 已提交
1173
/**
J
John Snow 已提交
1174
 * Halted IO Error Test
J
John Snow 已提交
1175 1176 1177 1178 1179
 *
 * Simulate an error on first write, Try to write a pattern,
 * Confirm the VM has stopped, resume the VM, verify command
 * has completed, then read back the data and verify.
 */
J
John Snow 已提交
1180
static void ahci_halted_io_test(uint8_t cmd_read, uint8_t cmd_write)
J
John Snow 已提交
1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204
{
    AHCIQState *ahci;
    uint8_t port;
    size_t bufsize = 4096;
    unsigned char *tx = g_malloc(bufsize);
    unsigned char *rx = g_malloc0(bufsize);
    uint64_t ptr;
    AHCICommand *cmd;

    prepare_blkdebug_script(debug_path, "write_aio");

    ahci = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0,"
                                "format=qcow2,cache=writeback,"
                                "rerror=stop,werror=stop "
                                "-M q35 "
                                "-device ide-hd,drive=drive0 ",
                                debug_path,
                                tmp_path);

    /* Initialize and prepare */
    port = ahci_port_select(ahci);
    ahci_port_clear(ahci, port);

    /* create DMA source buffer and write pattern */
1205
    generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE);
J
John Snow 已提交
1206 1207 1208 1209 1210
    ptr = ahci_alloc(ahci, bufsize);
    g_assert(ptr);
    memwrite(ptr, tx, bufsize);

    /* Attempt to write (and fail) */
J
John Snow 已提交
1211
    cmd = ahci_guest_io_halt(ahci, port, cmd_write,
J
John Snow 已提交
1212 1213 1214 1215 1216 1217 1218
                             ptr, bufsize, 0);

    /* Attempt to resume the command */
    ahci_guest_io_resume(ahci, cmd);
    ahci_free(ahci, ptr);

    /* Read back and verify */
J
John Snow 已提交
1219
    ahci_io(ahci, port, cmd_read, rx, bufsize, 0);
J
John Snow 已提交
1220 1221 1222 1223 1224 1225 1226 1227
    g_assert_cmphex(memcmp(tx, rx, bufsize), ==, 0);

    /* Cleanup and go home */
    ahci_shutdown(ahci);
    g_free(rx);
    g_free(tx);
}

J
John Snow 已提交
1228 1229 1230 1231 1232 1233 1234 1235 1236 1237
static void test_halted_dma(void)
{
    ahci_halted_io_test(CMD_READ_DMA, CMD_WRITE_DMA);
}

static void test_halted_ncq(void)
{
    ahci_halted_io_test(READ_FPDMA_QUEUED, WRITE_FPDMA_QUEUED);
}

1238
/**
1239
 * IO Error Migration Test
1240 1241 1242 1243 1244
 *
 * Simulate an error on first write, Try to write a pattern,
 * Confirm the VM has stopped, migrate, resume the VM,
 * verify command has completed, then read back the data and verify.
 */
1245
static void ahci_migrate_halted_io(uint8_t cmd_read, uint8_t cmd_write)
1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278
{
    AHCIQState *src, *dst;
    uint8_t port;
    size_t bufsize = 4096;
    unsigned char *tx = g_malloc(bufsize);
    unsigned char *rx = g_malloc0(bufsize);
    uint64_t ptr;
    AHCICommand *cmd;
    const char *uri = "tcp:127.0.0.1:1234";

    prepare_blkdebug_script(debug_path, "write_aio");

    src = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0,"
                               "format=qcow2,cache=writeback,"
                               "rerror=stop,werror=stop "
                               "-M q35 "
                               "-device ide-hd,drive=drive0 ",
                               debug_path,
                               tmp_path);

    dst = ahci_boot("-drive file=%s,if=none,id=drive0,"
                    "format=qcow2,cache=writeback,"
                    "rerror=stop,werror=stop "
                    "-M q35 "
                    "-device ide-hd,drive=drive0 "
                    "-incoming %s",
                    tmp_path, uri);

    set_context(src->parent);

    /* Initialize and prepare */
    port = ahci_port_select(src);
    ahci_port_clear(src, port);
1279
    generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE);
1280 1281 1282 1283 1284 1285 1286

    /* create DMA source buffer and write pattern */
    ptr = ahci_alloc(src, bufsize);
    g_assert(ptr);
    memwrite(ptr, tx, bufsize);

    /* Write, trigger the VM to stop, migrate, then resume. */
1287
    cmd = ahci_guest_io_halt(src, port, cmd_write,
1288 1289 1290 1291 1292 1293
                             ptr, bufsize, 0);
    ahci_migrate(src, dst, uri);
    ahci_guest_io_resume(dst, cmd);
    ahci_free(dst, ptr);

    /* Read back */
1294
    ahci_io(dst, port, cmd_read, rx, bufsize, 0);
1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305

    /* Verify TX and RX are identical */
    g_assert_cmphex(memcmp(tx, rx, bufsize), ==, 0);

    /* Cleanup and go home. */
    ahci_shutdown(src);
    ahci_shutdown(dst);
    g_free(rx);
    g_free(tx);
}

1306 1307 1308 1309 1310 1311 1312 1313 1314 1315
static void test_migrate_halted_dma(void)
{
    ahci_migrate_halted_io(CMD_READ_DMA, CMD_WRITE_DMA);
}

static void test_migrate_halted_ncq(void)
{
    ahci_migrate_halted_io(READ_FPDMA_QUEUED, WRITE_FPDMA_QUEUED);
}

J
John Snow 已提交
1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364
/**
 * Migration test: Try to flush, migrate, then resume.
 */
static void test_flush_migrate(void)
{
    AHCIQState *src, *dst;
    AHCICommand *cmd;
    uint8_t px;
    const char *s;
    const char *uri = "tcp:127.0.0.1:1234";

    prepare_blkdebug_script(debug_path, "flush_to_disk");

    src = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0,"
                               "cache=writeback,rerror=stop,werror=stop "
                               "-M q35 "
                               "-device ide-hd,drive=drive0 ",
                               debug_path, tmp_path);
    dst = ahci_boot("-drive file=%s,if=none,id=drive0,"
                    "cache=writeback,rerror=stop,werror=stop "
                    "-M q35 "
                    "-device ide-hd,drive=drive0 "
                    "-incoming %s", tmp_path, uri);

    set_context(src->parent);

    /* Issue Flush Command */
    px = ahci_port_select(src);
    ahci_port_clear(src, px);
    cmd = ahci_command_create(CMD_FLUSH_CACHE);
    ahci_command_commit(src, cmd, px);
    ahci_command_issue_async(src, cmd);
    qmp_eventwait("STOP");

    /* Migrate over */
    ahci_migrate(src, dst, uri);

    /* Complete the command */
    s = "{'execute':'cont' }";
    qmp_async(s);
    qmp_eventwait("RESUME");
    ahci_command_wait(dst, cmd);
    ahci_command_verify(dst, cmd);

    ahci_command_free(cmd);
    ahci_shutdown(src);
    ahci_shutdown(dst);
}

J
John Snow 已提交
1365 1366 1367 1368 1369 1370 1371 1372 1373
static void test_max(void)
{
    AHCIQState *ahci;

    ahci = ahci_boot_and_enable(NULL);
    ahci_test_max(ahci);
    ahci_shutdown(ahci);
}

J
John Snow 已提交
1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396
static void test_reset(void)
{
    AHCIQState *ahci;
    int i;

    ahci = ahci_boot(NULL);
    ahci_test_pci_spec(ahci);
    ahci_pci_enable(ahci);

    for (i = 0; i < 2; i++) {
        ahci_test_hba_spec(ahci);
        ahci_hba_enable(ahci);
        ahci_test_identify(ahci);
        ahci_test_io_rw_simple(ahci, 4096, 0,
                               CMD_READ_DMA_EXT,
                               CMD_WRITE_DMA_EXT);
        ahci_set(ahci, AHCI_GHC, AHCI_GHC_HR);
        ahci_clean_mem(ahci);
    }

    ahci_shutdown(ahci);
}

J
John Snow 已提交
1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407
static void test_ncq_simple(void)
{
    AHCIQState *ahci;

    ahci = ahci_boot_and_enable(NULL);
    ahci_test_io_rw_simple(ahci, 4096, 0,
                           READ_FPDMA_QUEUED,
                           WRITE_FPDMA_QUEUED);
    ahci_shutdown(ahci);
}

J
John Snow 已提交
1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447
/******************************************************************************/
/* AHCI I/O Test Matrix Definitions                                           */

enum BuffLen {
    LEN_BEGIN = 0,
    LEN_SIMPLE = LEN_BEGIN,
    LEN_DOUBLE,
    LEN_LONG,
    LEN_SHORT,
    NUM_LENGTHS
};

static const char *buff_len_str[NUM_LENGTHS] = { "simple", "double",
                                                 "long", "short" };

enum AddrMode {
    ADDR_MODE_BEGIN = 0,
    ADDR_MODE_LBA28 = ADDR_MODE_BEGIN,
    ADDR_MODE_LBA48,
    NUM_ADDR_MODES
};

static const char *addr_mode_str[NUM_ADDR_MODES] = { "lba28", "lba48" };

enum IOMode {
    MODE_BEGIN = 0,
    MODE_PIO = MODE_BEGIN,
    MODE_DMA,
    NUM_MODES
};

static const char *io_mode_str[NUM_MODES] = { "pio", "dma" };

enum IOOps {
    IO_BEGIN = 0,
    IO_READ = IO_BEGIN,
    IO_WRITE,
    NUM_IO_OPS
};

1448 1449 1450 1451 1452 1453 1454 1455 1456 1457
enum OffsetType {
    OFFSET_BEGIN = 0,
    OFFSET_ZERO = OFFSET_BEGIN,
    OFFSET_LOW,
    OFFSET_HIGH,
    NUM_OFFSETS
};

static const char *offset_str[NUM_OFFSETS] = { "zero", "low", "high" };

J
John Snow 已提交
1458 1459 1460 1461
typedef struct AHCIIOTestOptions {
    enum BuffLen length;
    enum AddrMode address_type;
    enum IOMode io_type;
1462
    enum OffsetType offset;
J
John Snow 已提交
1463 1464
} AHCIIOTestOptions;

1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486
static uint64_t offset_sector(enum OffsetType ofst,
                              enum AddrMode addr_type,
                              uint64_t buffsize)
{
    uint64_t ceil;
    uint64_t nsectors;

    switch (ofst) {
    case OFFSET_ZERO:
        return 0;
    case OFFSET_LOW:
        return 1;
    case OFFSET_HIGH:
        ceil = (addr_type == ADDR_MODE_LBA28) ? 0xfffffff : 0xffffffffffff;
        ceil = MIN(ceil, TEST_IMAGE_SECTORS - 1);
        nsectors = buffsize / AHCI_SECTOR_SIZE;
        return ceil - nsectors + 1;
    default:
        g_assert_not_reached();
    }
}

1487
/**
J
John Snow 已提交
1488
 * Table of possible I/O ATA commands given a set of enumerations.
1489
 */
J
John Snow 已提交
1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513
static const uint8_t io_cmds[NUM_MODES][NUM_ADDR_MODES][NUM_IO_OPS] = {
    [MODE_PIO] = {
        [ADDR_MODE_LBA28] = {
            [IO_READ] = CMD_READ_PIO,
            [IO_WRITE] = CMD_WRITE_PIO },
        [ADDR_MODE_LBA48] = {
            [IO_READ] = CMD_READ_PIO_EXT,
            [IO_WRITE] = CMD_WRITE_PIO_EXT }
    },
    [MODE_DMA] = {
        [ADDR_MODE_LBA28] = {
            [IO_READ] = CMD_READ_DMA,
            [IO_WRITE] = CMD_WRITE_DMA },
        [ADDR_MODE_LBA48] = {
            [IO_READ] = CMD_READ_DMA_EXT,
            [IO_WRITE] = CMD_WRITE_DMA_EXT }
    }
};

/**
 * Test a Read/Write pattern using various commands, addressing modes,
 * transfer modes, and buffer sizes.
 */
static void test_io_rw_interface(enum AddrMode lba48, enum IOMode dma,
1514
                                 unsigned bufsize, uint64_t sector)
1515 1516 1517
{
    AHCIQState *ahci;

1518
    ahci = ahci_boot_and_enable(NULL);
1519
    ahci_test_io_rw_simple(ahci, bufsize, sector,
J
John Snow 已提交
1520 1521
                           io_cmds[dma][lba48][IO_READ],
                           io_cmds[dma][lba48][IO_WRITE]);
1522 1523 1524
    ahci_shutdown(ahci);
}

J
John Snow 已提交
1525 1526 1527 1528
/**
 * Demultiplex the test data and invoke the actual test routine.
 */
static void test_io_interface(gconstpointer opaque)
J
John Snow 已提交
1529
{
J
John Snow 已提交
1530 1531
    AHCIIOTestOptions *opts = (AHCIIOTestOptions *)opaque;
    unsigned bufsize;
1532
    uint64_t sector;
J
John Snow 已提交
1533

J
John Snow 已提交
1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549
    switch (opts->length) {
    case LEN_SIMPLE:
        bufsize = 4096;
        break;
    case LEN_DOUBLE:
        bufsize = 8192;
        break;
    case LEN_LONG:
        bufsize = 4096 * 64;
        break;
    case LEN_SHORT:
        bufsize = 512;
        break;
    default:
        g_assert_not_reached();
    }
J
John Snow 已提交
1550

1551 1552
    sector = offset_sector(opts->offset, opts->address_type, bufsize);
    test_io_rw_interface(opts->address_type, opts->io_type, bufsize, sector);
J
John Snow 已提交
1553 1554
    g_free(opts);
    return;
J
John Snow 已提交
1555 1556
}

J
John Snow 已提交
1557
static void create_ahci_io_test(enum IOMode type, enum AddrMode addr,
1558
                                enum BuffLen len, enum OffsetType offset)
J
John Snow 已提交
1559
{
J
John Snow 已提交
1560 1561 1562 1563 1564 1565
    char *name;
    AHCIIOTestOptions *opts = g_malloc(sizeof(AHCIIOTestOptions));

    opts->length = len;
    opts->address_type = addr;
    opts->io_type = type;
1566
    opts->offset = offset;
J
John Snow 已提交
1567

1568
    name = g_strdup_printf("ahci/io/%s/%s/%s/%s",
J
John Snow 已提交
1569 1570
                           io_mode_str[type],
                           addr_mode_str[addr],
1571 1572
                           buff_len_str[len],
                           offset_str[offset]);
J
John Snow 已提交
1573

1574
    qtest_add_data_func(name, opts, test_io_interface);
J
John Snow 已提交
1575
    g_free(name);
J
John Snow 已提交
1576 1577
}

1578 1579 1580 1581 1582 1583
/******************************************************************************/

int main(int argc, char **argv)
{
    const char *arch;
    int ret;
J
John Snow 已提交
1584
    int fd;
1585
    int c;
1586
    int i, j, k, m;
1587 1588 1589 1590 1591

    static struct option long_options[] = {
        {"pedantic", no_argument, 0, 'p' },
        {0, 0, 0, 0},
    };
1592 1593 1594 1595

    /* Should be first to utilize g_test functionality, So we can see errors. */
    g_test_init(&argc, &argv, NULL);

1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612
    while (1) {
        c = getopt_long(argc, argv, "", long_options, NULL);
        if (c == -1) {
            break;
        }
        switch (c) {
        case -1:
            break;
        case 'p':
            ahci_pedantic = 1;
            break;
        default:
            fprintf(stderr, "Unrecognized ahci_test option.\n");
            g_assert_not_reached();
        }
    }

1613 1614 1615 1616 1617 1618 1619
    /* Check architecture */
    arch = qtest_get_arch();
    if (strcmp(arch, "i386") && strcmp(arch, "x86_64")) {
        g_test_message("Skipping test for non-x86");
        return 0;
    }

1620 1621 1622
    /* Create a temporary qcow2 image */
    close(mkstemp(tmp_path));
    mkqcow2(tmp_path, TEST_IMAGE_SIZE_MB);
1623

J
John Snow 已提交
1624 1625 1626 1627 1628
    /* Create temporary blkdebug instructions */
    fd = mkstemp(debug_path);
    g_assert(fd >= 0);
    close(fd);

1629 1630
    /* Run the tests */
    qtest_add_func("/ahci/sanity",     test_sanity);
1631
    qtest_add_func("/ahci/pci_spec",   test_pci_spec);
1632
    qtest_add_func("/ahci/pci_enable", test_pci_enable);
1633
    qtest_add_func("/ahci/hba_spec",   test_hba_spec);
1634
    qtest_add_func("/ahci/hba_enable", test_hba_enable);
1635
    qtest_add_func("/ahci/identify",   test_identify);
J
John Snow 已提交
1636 1637 1638 1639

    for (i = MODE_BEGIN; i < NUM_MODES; i++) {
        for (j = ADDR_MODE_BEGIN; j < NUM_ADDR_MODES; j++) {
            for (k = LEN_BEGIN; k < NUM_LENGTHS; k++) {
1640 1641 1642
                for (m = OFFSET_BEGIN; m < NUM_OFFSETS; m++) {
                    create_ahci_io_test(i, j, k, m);
                }
J
John Snow 已提交
1643 1644 1645
            }
        }
    }
1646

J
John Snow 已提交
1647 1648
    qtest_add_func("/ahci/io/dma/lba28/fragmented", test_dma_fragmented);

J
John Snow 已提交
1649
    qtest_add_func("/ahci/flush/simple", test_flush);
J
John Snow 已提交
1650
    qtest_add_func("/ahci/flush/retry", test_flush_retry);
J
John Snow 已提交
1651
    qtest_add_func("/ahci/flush/migrate", test_flush_migrate);
J
John Snow 已提交
1652

J
John Snow 已提交
1653
    qtest_add_func("/ahci/migrate/sanity", test_migrate_sanity);
1654
    qtest_add_func("/ahci/migrate/dma/simple", test_migrate_dma);
J
John Snow 已提交
1655
    qtest_add_func("/ahci/io/dma/lba28/retry", test_halted_dma);
1656
    qtest_add_func("/ahci/migrate/dma/halted", test_migrate_halted_dma);
J
John Snow 已提交
1657

J
John Snow 已提交
1658
    qtest_add_func("/ahci/max", test_max);
J
John Snow 已提交
1659
    qtest_add_func("/ahci/reset", test_reset);
J
John Snow 已提交
1660

J
John Snow 已提交
1661
    qtest_add_func("/ahci/io/ncq/simple", test_ncq_simple);
J
John Snow 已提交
1662
    qtest_add_func("/ahci/migrate/ncq/simple", test_migrate_ncq);
J
John Snow 已提交
1663
    qtest_add_func("/ahci/io/ncq/retry", test_halted_ncq);
1664
    qtest_add_func("/ahci/migrate/ncq/halted", test_migrate_halted_ncq);
J
John Snow 已提交
1665

1666 1667 1668 1669
    ret = g_test_run();

    /* Cleanup */
    unlink(tmp_path);
J
John Snow 已提交
1670
    unlink(debug_path);
1671 1672 1673

    return ret;
}