qemu/tests/ide-test.c
<<
>>
Prefs
   1/*
   2 * IDE test cases
   3 *
   4 * Copyright (c) 2013 Kevin Wolf <kwolf@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
  27
  28#include "libqtest.h"
  29#include "libqos/libqos.h"
  30#include "libqos/pci-pc.h"
  31#include "libqos/malloc-pc.h"
  32
  33#include "qemu-common.h"
  34#include "qemu/bswap.h"
  35#include "hw/pci/pci_ids.h"
  36#include "hw/pci/pci_regs.h"
  37
  38#define TEST_IMAGE_SIZE 64 * 1024 * 1024
  39
  40#define IDE_PCI_DEV     1
  41#define IDE_PCI_FUNC    1
  42
  43#define IDE_BASE 0x1f0
  44#define IDE_PRIMARY_IRQ 14
  45
  46#define ATAPI_BLOCK_SIZE 2048
  47
  48/* How many bytes to receive via ATAPI PIO at one time.
  49 * Must be less than 0xFFFF. */
  50#define BYTE_COUNT_LIMIT 5120
  51
  52enum {
  53    reg_data        = 0x0,
  54    reg_feature     = 0x1,
  55    reg_nsectors    = 0x2,
  56    reg_lba_low     = 0x3,
  57    reg_lba_middle  = 0x4,
  58    reg_lba_high    = 0x5,
  59    reg_device      = 0x6,
  60    reg_status      = 0x7,
  61    reg_command     = 0x7,
  62};
  63
  64enum {
  65    BSY     = 0x80,
  66    DRDY    = 0x40,
  67    DF      = 0x20,
  68    DRQ     = 0x08,
  69    ERR     = 0x01,
  70};
  71
  72enum {
  73    DEV     = 0x10,
  74    LBA     = 0x40,
  75};
  76
  77enum {
  78    bmreg_cmd       = 0x0,
  79    bmreg_status    = 0x2,
  80    bmreg_prdt      = 0x4,
  81};
  82
  83enum {
  84    CMD_READ_DMA    = 0xc8,
  85    CMD_WRITE_DMA   = 0xca,
  86    CMD_FLUSH_CACHE = 0xe7,
  87    CMD_IDENTIFY    = 0xec,
  88    CMD_PACKET      = 0xa0,
  89
  90    CMDF_ABORT      = 0x100,
  91    CMDF_NO_BM      = 0x200,
  92};
  93
  94enum {
  95    BM_CMD_START    =  0x1,
  96    BM_CMD_WRITE    =  0x8, /* write = from device to memory */
  97};
  98
  99enum {
 100    BM_STS_ACTIVE   =  0x1,
 101    BM_STS_ERROR    =  0x2,
 102    BM_STS_INTR     =  0x4,
 103};
 104
 105enum {
 106    PRDT_EOT        = 0x80000000,
 107};
 108
 109#define assert_bit_set(data, mask) g_assert_cmphex((data) & (mask), ==, (mask))
 110#define assert_bit_clear(data, mask) g_assert_cmphex((data) & (mask), ==, 0)
 111
 112static QPCIBus *pcibus = NULL;
 113static QGuestAllocator *guest_malloc;
 114
 115static char tmp_path[] = "/tmp/qtest.XXXXXX";
 116static char debug_path[] = "/tmp/qtest-blkdebug.XXXXXX";
 117
 118static void ide_test_start(const char *cmdline_fmt, ...)
 119{
 120    va_list ap;
 121    char *cmdline;
 122
 123    va_start(ap, cmdline_fmt);
 124    cmdline = g_strdup_vprintf(cmdline_fmt, ap);
 125    va_end(ap);
 126
 127    qtest_start(cmdline);
 128    guest_malloc = pc_alloc_init();
 129
 130    g_free(cmdline);
 131}
 132
 133static void ide_test_quit(void)
 134{
 135    pc_alloc_uninit(guest_malloc);
 136    guest_malloc = NULL;
 137    qtest_end();
 138}
 139
 140static QPCIDevice *get_pci_device(QPCIBar *bmdma_bar, QPCIBar *ide_bar)
 141{
 142    QPCIDevice *dev;
 143    uint16_t vendor_id, device_id;
 144
 145    if (!pcibus) {
 146        pcibus = qpci_init_pc(NULL);
 147    }
 148
 149    /* Find PCI device and verify it's the right one */
 150    dev = qpci_device_find(pcibus, QPCI_DEVFN(IDE_PCI_DEV, IDE_PCI_FUNC));
 151    g_assert(dev != NULL);
 152
 153    vendor_id = qpci_config_readw(dev, PCI_VENDOR_ID);
 154    device_id = qpci_config_readw(dev, PCI_DEVICE_ID);
 155    g_assert(vendor_id == PCI_VENDOR_ID_INTEL);
 156    g_assert(device_id == PCI_DEVICE_ID_INTEL_82371SB_1);
 157
 158    /* Map bmdma BAR */
 159    *bmdma_bar = qpci_iomap(dev, 4, NULL);
 160
 161    *ide_bar = qpci_legacy_iomap(dev, IDE_BASE);
 162
 163    qpci_device_enable(dev);
 164
 165    return dev;
 166}
 167
 168static void free_pci_device(QPCIDevice *dev)
 169{
 170    /* libqos doesn't have a function for this, so free it manually */
 171    g_free(dev);
 172}
 173
 174typedef struct PrdtEntry {
 175    uint32_t addr;
 176    uint32_t size;
 177} QEMU_PACKED PrdtEntry;
 178
 179#define assert_bit_set(data, mask) g_assert_cmphex((data) & (mask), ==, (mask))
 180#define assert_bit_clear(data, mask) g_assert_cmphex((data) & (mask), ==, 0)
 181
 182static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
 183                            PrdtEntry *prdt, int prdt_entries,
 184                            void(*post_exec)(QPCIDevice *dev, QPCIBar ide_bar,
 185                                             uint64_t sector, int nb_sectors))
 186{
 187    QPCIDevice *dev;
 188    QPCIBar bmdma_bar, ide_bar;
 189    uintptr_t guest_prdt;
 190    size_t len;
 191    bool from_dev;
 192    uint8_t status;
 193    int flags;
 194
 195    dev = get_pci_device(&bmdma_bar, &ide_bar);
 196
 197    flags = cmd & ~0xff;
 198    cmd &= 0xff;
 199
 200    switch (cmd) {
 201    case CMD_READ_DMA:
 202    case CMD_PACKET:
 203        /* Assuming we only test data reads w/ ATAPI, otherwise we need to know
 204         * the SCSI command being sent in the packet, too. */
 205        from_dev = true;
 206        break;
 207    case CMD_WRITE_DMA:
 208        from_dev = false;
 209        break;
 210    default:
 211        g_assert_not_reached();
 212    }
 213
 214    if (flags & CMDF_NO_BM) {
 215        qpci_config_writew(dev, PCI_COMMAND,
 216                           PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
 217    }
 218
 219    /* Select device 0 */
 220    qpci_io_writeb(dev, ide_bar, reg_device, 0 | LBA);
 221
 222    /* Stop any running transfer, clear any pending interrupt */
 223    qpci_io_writeb(dev, bmdma_bar, bmreg_cmd, 0);
 224    qpci_io_writeb(dev, bmdma_bar, bmreg_status, BM_STS_INTR);
 225
 226    /* Setup PRDT */
 227    len = sizeof(*prdt) * prdt_entries;
 228    guest_prdt = guest_alloc(guest_malloc, len);
 229    memwrite(guest_prdt, prdt, len);
 230    qpci_io_writel(dev, bmdma_bar, bmreg_prdt, guest_prdt);
 231
 232    /* ATA DMA command */
 233    if (cmd == CMD_PACKET) {
 234        /* Enables ATAPI DMA; otherwise PIO is attempted */
 235        qpci_io_writeb(dev, ide_bar, reg_feature, 0x01);
 236    } else {
 237        qpci_io_writeb(dev, ide_bar, reg_nsectors, nb_sectors);
 238        qpci_io_writeb(dev, ide_bar, reg_lba_low,    sector & 0xff);
 239        qpci_io_writeb(dev, ide_bar, reg_lba_middle, (sector >> 8) & 0xff);
 240        qpci_io_writeb(dev, ide_bar, reg_lba_high,   (sector >> 16) & 0xff);
 241    }
 242
 243    qpci_io_writeb(dev, ide_bar, reg_command, cmd);
 244
 245    if (post_exec) {
 246        post_exec(dev, ide_bar, sector, nb_sectors);
 247    }
 248
 249    /* Start DMA transfer */
 250    qpci_io_writeb(dev, bmdma_bar, bmreg_cmd,
 251                   BM_CMD_START | (from_dev ? BM_CMD_WRITE : 0));
 252
 253    if (flags & CMDF_ABORT) {
 254        qpci_io_writeb(dev, bmdma_bar, bmreg_cmd, 0);
 255    }
 256
 257    /* Wait for the DMA transfer to complete */
 258    do {
 259        status = qpci_io_readb(dev, bmdma_bar, bmreg_status);
 260    } while ((status & (BM_STS_ACTIVE | BM_STS_INTR)) == BM_STS_ACTIVE);
 261
 262    g_assert_cmpint(get_irq(IDE_PRIMARY_IRQ), ==, !!(status & BM_STS_INTR));
 263
 264    /* Check IDE status code */
 265    assert_bit_set(qpci_io_readb(dev, ide_bar, reg_status), DRDY);
 266    assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), BSY | DRQ);
 267
 268    /* Reading the status register clears the IRQ */
 269    g_assert(!get_irq(IDE_PRIMARY_IRQ));
 270
 271    /* Stop DMA transfer if still active */
 272    if (status & BM_STS_ACTIVE) {
 273        qpci_io_writeb(dev, bmdma_bar, bmreg_cmd, 0);
 274    }
 275
 276    free_pci_device(dev);
 277
 278    return status;
 279}
 280
 281static void test_bmdma_simple_rw(void)
 282{
 283    QPCIDevice *dev;
 284    QPCIBar bmdma_bar, ide_bar;
 285    uint8_t status;
 286    uint8_t *buf;
 287    uint8_t *cmpbuf;
 288    size_t len = 512;
 289    uintptr_t guest_buf = guest_alloc(guest_malloc, len);
 290
 291    PrdtEntry prdt[] = {
 292        {
 293            .addr = cpu_to_le32(guest_buf),
 294            .size = cpu_to_le32(len | PRDT_EOT),
 295        },
 296    };
 297
 298    dev = get_pci_device(&bmdma_bar, &ide_bar);
 299
 300    buf = g_malloc(len);
 301    cmpbuf = g_malloc(len);
 302
 303    /* Write 0x55 pattern to sector 0 */
 304    memset(buf, 0x55, len);
 305    memwrite(guest_buf, buf, len);
 306
 307    status = send_dma_request(CMD_WRITE_DMA, 0, 1, prdt,
 308                              ARRAY_SIZE(prdt), NULL);
 309    g_assert_cmphex(status, ==, BM_STS_INTR);
 310    assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
 311
 312    /* Write 0xaa pattern to sector 1 */
 313    memset(buf, 0xaa, len);
 314    memwrite(guest_buf, buf, len);
 315
 316    status = send_dma_request(CMD_WRITE_DMA, 1, 1, prdt,
 317                              ARRAY_SIZE(prdt), NULL);
 318    g_assert_cmphex(status, ==, BM_STS_INTR);
 319    assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
 320
 321    /* Read and verify 0x55 pattern in sector 0 */
 322    memset(cmpbuf, 0x55, len);
 323
 324    status = send_dma_request(CMD_READ_DMA, 0, 1, prdt, ARRAY_SIZE(prdt), NULL);
 325    g_assert_cmphex(status, ==, BM_STS_INTR);
 326    assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
 327
 328    memread(guest_buf, buf, len);
 329    g_assert(memcmp(buf, cmpbuf, len) == 0);
 330
 331    /* Read and verify 0xaa pattern in sector 1 */
 332    memset(cmpbuf, 0xaa, len);
 333
 334    status = send_dma_request(CMD_READ_DMA, 1, 1, prdt, ARRAY_SIZE(prdt), NULL);
 335    g_assert_cmphex(status, ==, BM_STS_INTR);
 336    assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
 337
 338    memread(guest_buf, buf, len);
 339    g_assert(memcmp(buf, cmpbuf, len) == 0);
 340
 341
 342    free_pci_device(dev);
 343    g_free(buf);
 344    g_free(cmpbuf);
 345}
 346
 347static void test_bmdma_short_prdt(void)
 348{
 349    QPCIDevice *dev;
 350    QPCIBar bmdma_bar, ide_bar;
 351    uint8_t status;
 352
 353    PrdtEntry prdt[] = {
 354        {
 355            .addr = 0,
 356            .size = cpu_to_le32(0x10 | PRDT_EOT),
 357        },
 358    };
 359
 360    dev = get_pci_device(&bmdma_bar, &ide_bar);
 361
 362    /* Normal request */
 363    status = send_dma_request(CMD_READ_DMA, 0, 1,
 364                              prdt, ARRAY_SIZE(prdt), NULL);
 365    g_assert_cmphex(status, ==, 0);
 366    assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
 367
 368    /* Abort the request before it completes */
 369    status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1,
 370                              prdt, ARRAY_SIZE(prdt), NULL);
 371    g_assert_cmphex(status, ==, 0);
 372    assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
 373    free_pci_device(dev);
 374}
 375
 376static void test_bmdma_one_sector_short_prdt(void)
 377{
 378    QPCIDevice *dev;
 379    QPCIBar bmdma_bar, ide_bar;
 380    uint8_t status;
 381
 382    /* Read 2 sectors but only give 1 sector in PRDT */
 383    PrdtEntry prdt[] = {
 384        {
 385            .addr = 0,
 386            .size = cpu_to_le32(0x200 | PRDT_EOT),
 387        },
 388    };
 389
 390    dev = get_pci_device(&bmdma_bar, &ide_bar);
 391
 392    /* Normal request */
 393    status = send_dma_request(CMD_READ_DMA, 0, 2,
 394                              prdt, ARRAY_SIZE(prdt), NULL);
 395    g_assert_cmphex(status, ==, 0);
 396    assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
 397
 398    /* Abort the request before it completes */
 399    status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 2,
 400                              prdt, ARRAY_SIZE(prdt), NULL);
 401    g_assert_cmphex(status, ==, 0);
 402    assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
 403    free_pci_device(dev);
 404}
 405
 406static void test_bmdma_long_prdt(void)
 407{
 408    QPCIDevice *dev;
 409    QPCIBar bmdma_bar, ide_bar;
 410    uint8_t status;
 411
 412    PrdtEntry prdt[] = {
 413        {
 414            .addr = 0,
 415            .size = cpu_to_le32(0x1000 | PRDT_EOT),
 416        },
 417    };
 418
 419    dev = get_pci_device(&bmdma_bar, &ide_bar);
 420
 421    /* Normal request */
 422    status = send_dma_request(CMD_READ_DMA, 0, 1,
 423                              prdt, ARRAY_SIZE(prdt), NULL);
 424    g_assert_cmphex(status, ==, BM_STS_ACTIVE | BM_STS_INTR);
 425    assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
 426
 427    /* Abort the request before it completes */
 428    status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1,
 429                              prdt, ARRAY_SIZE(prdt), NULL);
 430    g_assert_cmphex(status, ==, BM_STS_INTR);
 431    assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
 432    free_pci_device(dev);
 433}
 434
 435static void test_bmdma_no_busmaster(void)
 436{
 437    QPCIDevice *dev;
 438    QPCIBar bmdma_bar, ide_bar;
 439    uint8_t status;
 440
 441    dev = get_pci_device(&bmdma_bar, &ide_bar);
 442
 443    /* No PRDT_EOT, each entry addr 0/size 64k, and in theory qemu shouldn't be
 444     * able to access it anyway because the Bus Master bit in the PCI command
 445     * register isn't set. This is complete nonsense, but it used to be pretty
 446     * good at confusing and occasionally crashing qemu. */
 447    PrdtEntry prdt[4096] = { };
 448
 449    status = send_dma_request(CMD_READ_DMA | CMDF_NO_BM, 0, 512,
 450                              prdt, ARRAY_SIZE(prdt), NULL);
 451
 452    /* Not entirely clear what the expected result is, but this is what we get
 453     * in practice. At least we want to be aware of any changes. */
 454    g_assert_cmphex(status, ==, BM_STS_ACTIVE | BM_STS_INTR);
 455    assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
 456    free_pci_device(dev);
 457}
 458
 459static void test_bmdma_setup(void)
 460{
 461    ide_test_start(
 462        "-drive file=%s,if=ide,serial=%s,cache=writeback,format=raw "
 463        "-global ide-hd.ver=%s",
 464        tmp_path, "testdisk", "version");
 465    qtest_irq_intercept_in(global_qtest, "ioapic");
 466}
 467
 468static void test_bmdma_teardown(void)
 469{
 470    ide_test_quit();
 471}
 472
 473static void string_cpu_to_be16(uint16_t *s, size_t bytes)
 474{
 475    g_assert((bytes & 1) == 0);
 476    bytes /= 2;
 477
 478    while (bytes--) {
 479        *s = cpu_to_be16(*s);
 480        s++;
 481    }
 482}
 483
 484static void test_identify(void)
 485{
 486    QPCIDevice *dev;
 487    QPCIBar bmdma_bar, ide_bar;
 488    uint8_t data;
 489    uint16_t buf[256];
 490    int i;
 491    int ret;
 492
 493    ide_test_start(
 494        "-drive file=%s,if=ide,serial=%s,cache=writeback,format=raw "
 495        "-global ide-hd.ver=%s",
 496        tmp_path, "testdisk", "version");
 497
 498    dev = get_pci_device(&bmdma_bar, &ide_bar);
 499
 500    /* IDENTIFY command on device 0*/
 501    qpci_io_writeb(dev, ide_bar, reg_device, 0);
 502    qpci_io_writeb(dev, ide_bar, reg_command, CMD_IDENTIFY);
 503
 504    /* Read in the IDENTIFY buffer and check registers */
 505    data = qpci_io_readb(dev, ide_bar, reg_device);
 506    g_assert_cmpint(data & DEV, ==, 0);
 507
 508    for (i = 0; i < 256; i++) {
 509        data = qpci_io_readb(dev, ide_bar, reg_status);
 510        assert_bit_set(data, DRDY | DRQ);
 511        assert_bit_clear(data, BSY | DF | ERR);
 512
 513        buf[i] = qpci_io_readw(dev, ide_bar, reg_data);
 514    }
 515
 516    data = qpci_io_readb(dev, ide_bar, reg_status);
 517    assert_bit_set(data, DRDY);
 518    assert_bit_clear(data, BSY | DF | ERR | DRQ);
 519
 520    /* Check serial number/version in the buffer */
 521    string_cpu_to_be16(&buf[10], 20);
 522    ret = memcmp(&buf[10], "testdisk            ", 20);
 523    g_assert(ret == 0);
 524
 525    string_cpu_to_be16(&buf[23], 8);
 526    ret = memcmp(&buf[23], "version ", 8);
 527    g_assert(ret == 0);
 528
 529    /* Write cache enabled bit */
 530    assert_bit_set(buf[85], 0x20);
 531
 532    ide_test_quit();
 533    free_pci_device(dev);
 534}
 535
 536/*
 537 * Write sector 1 with random data to make IDE storage dirty
 538 * Needed for flush tests so that flushes actually go though the block layer
 539 */
 540static void make_dirty(uint8_t device)
 541{
 542    QPCIDevice *dev;
 543    QPCIBar bmdma_bar, ide_bar;
 544    uint8_t status;
 545    size_t len = 512;
 546    uintptr_t guest_buf;
 547    void* buf;
 548
 549    dev = get_pci_device(&bmdma_bar, &ide_bar);
 550
 551    guest_buf = guest_alloc(guest_malloc, len);
 552    buf = g_malloc(len);
 553    memset(buf, rand() % 255 + 1, len);
 554    g_assert(guest_buf);
 555    g_assert(buf);
 556
 557    memwrite(guest_buf, buf, len);
 558
 559    PrdtEntry prdt[] = {
 560        {
 561            .addr = cpu_to_le32(guest_buf),
 562            .size = cpu_to_le32(len | PRDT_EOT),
 563        },
 564    };
 565
 566    status = send_dma_request(CMD_WRITE_DMA, 1, 1, prdt,
 567                              ARRAY_SIZE(prdt), NULL);
 568    g_assert_cmphex(status, ==, BM_STS_INTR);
 569    assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
 570
 571    g_free(buf);
 572    free_pci_device(dev);
 573}
 574
 575static void test_flush(void)
 576{
 577    QPCIDevice *dev;
 578    QPCIBar bmdma_bar, ide_bar;
 579    uint8_t data;
 580
 581    ide_test_start(
 582        "-drive file=blkdebug::%s,if=ide,cache=writeback,format=raw",
 583        tmp_path);
 584
 585    dev = get_pci_device(&bmdma_bar, &ide_bar);
 586
 587    qtest_irq_intercept_in(global_qtest, "ioapic");
 588
 589    /* Dirty media so that CMD_FLUSH_CACHE will actually go to disk */
 590    make_dirty(0);
 591
 592    /* Delay the completion of the flush request until we explicitly do it */
 593    g_free(hmp("qemu-io ide0-hd0 \"break flush_to_os A\""));
 594
 595    /* FLUSH CACHE command on device 0*/
 596    qpci_io_writeb(dev, ide_bar, reg_device, 0);
 597    qpci_io_writeb(dev, ide_bar, reg_command, CMD_FLUSH_CACHE);
 598
 599    /* Check status while request is in flight*/
 600    data = qpci_io_readb(dev, ide_bar, reg_status);
 601    assert_bit_set(data, BSY | DRDY);
 602    assert_bit_clear(data, DF | ERR | DRQ);
 603
 604    /* Complete the command */
 605    g_free(hmp("qemu-io ide0-hd0 \"resume A\""));
 606
 607    /* Check registers */
 608    data = qpci_io_readb(dev, ide_bar, reg_device);
 609    g_assert_cmpint(data & DEV, ==, 0);
 610
 611    do {
 612        data = qpci_io_readb(dev, ide_bar, reg_status);
 613    } while (data & BSY);
 614
 615    assert_bit_set(data, DRDY);
 616    assert_bit_clear(data, BSY | DF | ERR | DRQ);
 617
 618    ide_test_quit();
 619    free_pci_device(dev);
 620}
 621
 622static void test_retry_flush(const char *machine)
 623{
 624    QPCIDevice *dev;
 625    QPCIBar bmdma_bar, ide_bar;
 626    uint8_t data;
 627    const char *s;
 628
 629    prepare_blkdebug_script(debug_path, "flush_to_disk");
 630
 631    ide_test_start(
 632        "-drive file=blkdebug:%s:%s,if=ide,cache=writeback,format=raw,"
 633        "rerror=stop,werror=stop",
 634        debug_path, tmp_path);
 635
 636    dev = get_pci_device(&bmdma_bar, &ide_bar);
 637
 638    qtest_irq_intercept_in(global_qtest, "ioapic");
 639
 640    /* Dirty media so that CMD_FLUSH_CACHE will actually go to disk */
 641    make_dirty(0);
 642
 643    /* FLUSH CACHE command on device 0*/
 644    qpci_io_writeb(dev, ide_bar, reg_device, 0);
 645    qpci_io_writeb(dev, ide_bar, reg_command, CMD_FLUSH_CACHE);
 646
 647    /* Check status while request is in flight*/
 648    data = qpci_io_readb(dev, ide_bar, reg_status);
 649    assert_bit_set(data, BSY | DRDY);
 650    assert_bit_clear(data, DF | ERR | DRQ);
 651
 652    qmp_eventwait("STOP");
 653
 654    /* Complete the command */
 655    s = "{'execute':'cont' }";
 656    qmp_discard_response(s);
 657
 658    /* Check registers */
 659    data = qpci_io_readb(dev, ide_bar, reg_device);
 660    g_assert_cmpint(data & DEV, ==, 0);
 661
 662    do {
 663        data = qpci_io_readb(dev, ide_bar, reg_status);
 664    } while (data & BSY);
 665
 666    assert_bit_set(data, DRDY);
 667    assert_bit_clear(data, BSY | DF | ERR | DRQ);
 668
 669    ide_test_quit();
 670    free_pci_device(dev);
 671}
 672
 673static void test_flush_nodev(void)
 674{
 675    QPCIDevice *dev;
 676    QPCIBar bmdma_bar, ide_bar;
 677
 678    ide_test_start("");
 679
 680    dev = get_pci_device(&bmdma_bar, &ide_bar);
 681
 682    /* FLUSH CACHE command on device 0*/
 683    qpci_io_writeb(dev, ide_bar, reg_device, 0);
 684    qpci_io_writeb(dev, ide_bar, reg_command, CMD_FLUSH_CACHE);
 685
 686    /* Just testing that qemu doesn't crash... */
 687
 688    free_pci_device(dev);
 689    ide_test_quit();
 690}
 691
 692static void test_flush_empty_drive(void)
 693{
 694    QPCIDevice *dev;
 695    QPCIBar bmdma_bar, ide_bar;
 696
 697    ide_test_start("-device ide-cd,bus=ide.0");
 698    dev = get_pci_device(&bmdma_bar, &ide_bar);
 699
 700    /* FLUSH CACHE command on device 0 */
 701    qpci_io_writeb(dev, ide_bar, reg_device, 0);
 702    qpci_io_writeb(dev, ide_bar, reg_command, CMD_FLUSH_CACHE);
 703
 704    /* Just testing that qemu doesn't crash... */
 705
 706    free_pci_device(dev);
 707    ide_test_quit();
 708}
 709
 710static void test_pci_retry_flush(void)
 711{
 712    test_retry_flush("pc");
 713}
 714
 715static void test_isa_retry_flush(void)
 716{
 717    test_retry_flush("isapc");
 718}
 719
 720typedef struct Read10CDB {
 721    uint8_t opcode;
 722    uint8_t flags;
 723    uint32_t lba;
 724    uint8_t reserved;
 725    uint16_t nblocks;
 726    uint8_t control;
 727    uint16_t padding;
 728} __attribute__((__packed__)) Read10CDB;
 729
 730static void send_scsi_cdb_read10(QPCIDevice *dev, QPCIBar ide_bar,
 731                                 uint64_t lba, int nblocks)
 732{
 733    Read10CDB pkt = { .padding = 0 };
 734    int i;
 735
 736    g_assert_cmpint(lba, <=, UINT32_MAX);
 737    g_assert_cmpint(nblocks, <=, UINT16_MAX);
 738    g_assert_cmpint(nblocks, >=, 0);
 739
 740    /* Construct SCSI CDB packet */
 741    pkt.opcode = 0x28;
 742    pkt.lba = cpu_to_be32(lba);
 743    pkt.nblocks = cpu_to_be16(nblocks);
 744
 745    /* Send Packet */
 746    for (i = 0; i < sizeof(Read10CDB)/2; i++) {
 747        qpci_io_writew(dev, ide_bar, reg_data,
 748                       le16_to_cpu(((uint16_t *)&pkt)[i]));
 749    }
 750}
 751
 752static void nsleep(int64_t nsecs)
 753{
 754    const struct timespec val = { .tv_nsec = nsecs };
 755    nanosleep(&val, NULL);
 756    clock_set(nsecs);
 757}
 758
 759static uint8_t ide_wait_clear(uint8_t flag)
 760{
 761    QPCIDevice *dev;
 762    QPCIBar bmdma_bar, ide_bar;
 763    uint8_t data;
 764    time_t st;
 765
 766    dev = get_pci_device(&bmdma_bar, &ide_bar);
 767
 768    /* Wait with a 5 second timeout */
 769    time(&st);
 770    while (true) {
 771        data = qpci_io_readb(dev, ide_bar, reg_status);
 772        if (!(data & flag)) {
 773            free_pci_device(dev);
 774            return data;
 775        }
 776        if (difftime(time(NULL), st) > 5.0) {
 777            break;
 778        }
 779        nsleep(400);
 780    }
 781    g_assert_not_reached();
 782}
 783
 784static void ide_wait_intr(int irq)
 785{
 786    time_t st;
 787    bool intr;
 788
 789    time(&st);
 790    while (true) {
 791        intr = get_irq(irq);
 792        if (intr) {
 793            return;
 794        }
 795        if (difftime(time(NULL), st) > 5.0) {
 796            break;
 797        }
 798        nsleep(400);
 799    }
 800
 801    g_assert_not_reached();
 802}
 803
 804static void cdrom_pio_impl(int nblocks)
 805{
 806    QPCIDevice *dev;
 807    QPCIBar bmdma_bar, ide_bar;
 808    FILE *fh;
 809    int patt_blocks = MAX(16, nblocks);
 810    size_t patt_len = ATAPI_BLOCK_SIZE * patt_blocks;
 811    char *pattern = g_malloc(patt_len);
 812    size_t rxsize = ATAPI_BLOCK_SIZE * nblocks;
 813    uint16_t *rx = g_malloc0(rxsize);
 814    int i, j;
 815    uint8_t data;
 816    uint16_t limit;
 817    size_t ret;
 818
 819    /* Prepopulate the CDROM with an interesting pattern */
 820    generate_pattern(pattern, patt_len, ATAPI_BLOCK_SIZE);
 821    fh = fopen(tmp_path, "w+");
 822    ret = fwrite(pattern, ATAPI_BLOCK_SIZE, patt_blocks, fh);
 823    g_assert_cmpint(ret, ==, patt_blocks);
 824    fclose(fh);
 825
 826    ide_test_start("-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
 827                   "-device ide-cd,drive=sr0,bus=ide.0", tmp_path);
 828    dev = get_pci_device(&bmdma_bar, &ide_bar);
 829    qtest_irq_intercept_in(global_qtest, "ioapic");
 830
 831    /* PACKET command on device 0 */
 832    qpci_io_writeb(dev, ide_bar, reg_device, 0);
 833    qpci_io_writeb(dev, ide_bar, reg_lba_middle, BYTE_COUNT_LIMIT & 0xFF);
 834    qpci_io_writeb(dev, ide_bar, reg_lba_high, (BYTE_COUNT_LIMIT >> 8 & 0xFF));
 835    qpci_io_writeb(dev, ide_bar, reg_command, CMD_PACKET);
 836    /* HP0: Check_Status_A State */
 837    nsleep(400);
 838    data = ide_wait_clear(BSY);
 839    /* HP1: Send_Packet State */
 840    assert_bit_set(data, DRQ | DRDY);
 841    assert_bit_clear(data, ERR | DF | BSY);
 842
 843    /* SCSI CDB (READ10) -- read n*2048 bytes from block 0 */
 844    send_scsi_cdb_read10(dev, ide_bar, 0, nblocks);
 845
 846    /* Read data back: occurs in bursts of 'BYTE_COUNT_LIMIT' bytes.
 847     * If BYTE_COUNT_LIMIT is odd, we transfer BYTE_COUNT_LIMIT - 1 bytes.
 848     * We allow an odd limit only when the remaining transfer size is
 849     * less than BYTE_COUNT_LIMIT. However, SCSI's read10 command can only
 850     * request n blocks, so our request size is always even.
 851     * For this reason, we assume there is never a hanging byte to fetch. */
 852    g_assert(!(rxsize & 1));
 853    limit = BYTE_COUNT_LIMIT & ~1;
 854    for (i = 0; i < DIV_ROUND_UP(rxsize, limit); i++) {
 855        size_t offset = i * (limit / 2);
 856        size_t rem = (rxsize / 2) - offset;
 857
 858        /* HP3: INTRQ_Wait */
 859        ide_wait_intr(IDE_PRIMARY_IRQ);
 860
 861        /* HP2: Check_Status_B (and clear IRQ) */
 862        data = ide_wait_clear(BSY);
 863        assert_bit_set(data, DRQ | DRDY);
 864        assert_bit_clear(data, ERR | DF | BSY);
 865
 866        /* HP4: Transfer_Data */
 867        for (j = 0; j < MIN((limit / 2), rem); j++) {
 868            rx[offset + j] = cpu_to_le16(qpci_io_readw(dev, ide_bar,
 869                                                       reg_data));
 870        }
 871    }
 872
 873    /* Check for final completion IRQ */
 874    ide_wait_intr(IDE_PRIMARY_IRQ);
 875
 876    /* Sanity check final state */
 877    data = ide_wait_clear(DRQ);
 878    assert_bit_set(data, DRDY);
 879    assert_bit_clear(data, DRQ | ERR | DF | BSY);
 880
 881    g_assert_cmpint(memcmp(pattern, rx, rxsize), ==, 0);
 882    g_free(pattern);
 883    g_free(rx);
 884    test_bmdma_teardown();
 885    free_pci_device(dev);
 886}
 887
 888static void test_cdrom_pio(void)
 889{
 890    cdrom_pio_impl(1);
 891}
 892
 893static void test_cdrom_pio_large(void)
 894{
 895    /* Test a few loops of the PIO DRQ mechanism. */
 896    cdrom_pio_impl(BYTE_COUNT_LIMIT * 4 / ATAPI_BLOCK_SIZE);
 897}
 898
 899
 900static void test_cdrom_dma(void)
 901{
 902    static const size_t len = ATAPI_BLOCK_SIZE;
 903    size_t ret;
 904    char *pattern = g_malloc(ATAPI_BLOCK_SIZE * 16);
 905    char *rx = g_malloc0(len);
 906    uintptr_t guest_buf;
 907    PrdtEntry prdt[1];
 908    FILE *fh;
 909
 910    ide_test_start("-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
 911                   "-device ide-cd,drive=sr0,bus=ide.0", tmp_path);
 912    qtest_irq_intercept_in(global_qtest, "ioapic");
 913
 914    guest_buf = guest_alloc(guest_malloc, len);
 915    prdt[0].addr = cpu_to_le32(guest_buf);
 916    prdt[0].size = cpu_to_le32(len | PRDT_EOT);
 917
 918    generate_pattern(pattern, ATAPI_BLOCK_SIZE * 16, ATAPI_BLOCK_SIZE);
 919    fh = fopen(tmp_path, "w+");
 920    ret = fwrite(pattern, ATAPI_BLOCK_SIZE, 16, fh);
 921    g_assert_cmpint(ret, ==, 16);
 922    fclose(fh);
 923
 924    send_dma_request(CMD_PACKET, 0, 1, prdt, 1, send_scsi_cdb_read10);
 925
 926    /* Read back data from guest memory into local qtest memory */
 927    memread(guest_buf, rx, len);
 928    g_assert_cmpint(memcmp(pattern, rx, len), ==, 0);
 929
 930    g_free(pattern);
 931    g_free(rx);
 932    test_bmdma_teardown();
 933}
 934
 935int main(int argc, char **argv)
 936{
 937    const char *arch = qtest_get_arch();
 938    int fd;
 939    int ret;
 940
 941    /* Check architecture */
 942    if (strcmp(arch, "i386") && strcmp(arch, "x86_64")) {
 943        g_test_message("Skipping test for non-x86\n");
 944        return 0;
 945    }
 946
 947    /* Create temporary blkdebug instructions */
 948    fd = mkstemp(debug_path);
 949    g_assert(fd >= 0);
 950    close(fd);
 951
 952    /* Create a temporary raw image */
 953    fd = mkstemp(tmp_path);
 954    g_assert(fd >= 0);
 955    ret = ftruncate(fd, TEST_IMAGE_SIZE);
 956    g_assert(ret == 0);
 957    close(fd);
 958
 959    /* Run the tests */
 960    g_test_init(&argc, &argv, NULL);
 961
 962    qtest_add_func("/ide/identify", test_identify);
 963
 964    qtest_add_func("/ide/bmdma/setup", test_bmdma_setup);
 965    qtest_add_func("/ide/bmdma/simple_rw", test_bmdma_simple_rw);
 966    qtest_add_func("/ide/bmdma/short_prdt", test_bmdma_short_prdt);
 967    qtest_add_func("/ide/bmdma/one_sector_short_prdt",
 968                   test_bmdma_one_sector_short_prdt);
 969    qtest_add_func("/ide/bmdma/long_prdt", test_bmdma_long_prdt);
 970    qtest_add_func("/ide/bmdma/no_busmaster", test_bmdma_no_busmaster);
 971    qtest_add_func("/ide/bmdma/teardown", test_bmdma_teardown);
 972
 973    qtest_add_func("/ide/flush", test_flush);
 974    qtest_add_func("/ide/flush/nodev", test_flush_nodev);
 975    qtest_add_func("/ide/flush/empty_drive", test_flush_empty_drive);
 976    qtest_add_func("/ide/flush/retry_pci", test_pci_retry_flush);
 977    qtest_add_func("/ide/flush/retry_isa", test_isa_retry_flush);
 978
 979    qtest_add_func("/ide/cdrom/pio", test_cdrom_pio);
 980    qtest_add_func("/ide/cdrom/pio_large", test_cdrom_pio_large);
 981    qtest_add_func("/ide/cdrom/dma", test_cdrom_dma);
 982
 983    ret = g_test_run();
 984
 985    /* Cleanup */
 986    unlink(tmp_path);
 987    unlink(debug_path);
 988
 989    return ret;
 990}
 991