qemu/tests/qtest/libqos/ahci.h
<<
>>
Prefs
   1#ifndef LIBQOS_AHCI_H
   2#define LIBQOS_AHCI_H
   3
   4/*
   5 * AHCI qtest library functions and definitions
   6 *
   7 * Copyright (c) 2014 John Snow <jsnow@redhat.com>
   8 *
   9 * Permission is hereby granted, free of charge, to any person obtaining a copy
  10 * of this software and associated documentation files (the "Software"), to deal
  11 * in the Software without restriction, including without limitation the rights
  12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13 * copies of the Software, and to permit persons to whom the Software is
  14 * furnished to do so, subject to the following conditions:
  15 *
  16 * The above copyright notice and this permission notice shall be included in
  17 * all copies or substantial portions of the Software.
  18 *
  19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25 * THE SOFTWARE.
  26 */
  27
  28#include "libqos/libqos.h"
  29#include "libqos/pci.h"
  30#include "libqos/malloc-pc.h"
  31
  32/*** Supplementary PCI Config Space IDs & Masks ***/
  33#define PCI_DEVICE_ID_INTEL_Q35_AHCI   (0x2922)
  34#define PCI_MSI_FLAGS_RESERVED         (0xFF00)
  35#define PCI_PM_CTRL_RESERVED             (0xFC)
  36#define PCI_BCC(REG32)          ((REG32) >> 24)
  37#define PCI_PI(REG32)   (((REG32) >> 8) & 0xFF)
  38#define PCI_SCC(REG32) (((REG32) >> 16) & 0xFF)
  39
  40/*** Recognized AHCI Device Types ***/
  41#define AHCI_INTEL_ICH9 (PCI_DEVICE_ID_INTEL_Q35_AHCI << 16 | \
  42                         PCI_VENDOR_ID_INTEL)
  43
  44/*** AHCI/HBA Register Offsets and Bitmasks ***/
  45#define AHCI_CAP                          (0)
  46#define AHCI_CAP_NP                    (0x1F)
  47#define AHCI_CAP_SXS                   (0x20)
  48#define AHCI_CAP_EMS                   (0x40)
  49#define AHCI_CAP_CCCS                  (0x80)
  50#define AHCI_CAP_NCS                 (0x1F00)
  51#define AHCI_CAP_PSC                 (0x2000)
  52#define AHCI_CAP_SSC                 (0x4000)
  53#define AHCI_CAP_PMD                 (0x8000)
  54#define AHCI_CAP_FBSS               (0x10000)
  55#define AHCI_CAP_SPM                (0x20000)
  56#define AHCI_CAP_SAM                (0x40000)
  57#define AHCI_CAP_RESERVED           (0x80000)
  58#define AHCI_CAP_ISS               (0xF00000)
  59#define AHCI_CAP_SCLO             (0x1000000)
  60#define AHCI_CAP_SAL              (0x2000000)
  61#define AHCI_CAP_SALP             (0x4000000)
  62#define AHCI_CAP_SSS              (0x8000000)
  63#define AHCI_CAP_SMPS            (0x10000000)
  64#define AHCI_CAP_SSNTF           (0x20000000)
  65#define AHCI_CAP_SNCQ            (0x40000000)
  66#define AHCI_CAP_S64A            (0x80000000)
  67
  68#define AHCI_GHC                          (1)
  69#define AHCI_GHC_HR                    (0x01)
  70#define AHCI_GHC_IE                    (0x02)
  71#define AHCI_GHC_MRSM                  (0x04)
  72#define AHCI_GHC_RESERVED        (0x7FFFFFF8)
  73#define AHCI_GHC_AE              (0x80000000)
  74
  75#define AHCI_IS                           (2)
  76#define AHCI_PI                           (3)
  77#define AHCI_VS                           (4)
  78
  79#define AHCI_CCCCTL                       (5)
  80#define AHCI_CCCCTL_EN                 (0x01)
  81#define AHCI_CCCCTL_RESERVED           (0x06)
  82#define AHCI_CCCCTL_CC               (0xFF00)
  83#define AHCI_CCCCTL_TV           (0xFFFF0000)
  84
  85#define AHCI_CCCPORTS                     (6)
  86#define AHCI_EMLOC                        (7)
  87
  88#define AHCI_EMCTL                        (8)
  89#define AHCI_EMCTL_STSMR               (0x01)
  90#define AHCI_EMCTL_CTLTM              (0x100)
  91#define AHCI_EMCTL_CTLRST             (0x200)
  92#define AHCI_EMCTL_RESERVED      (0xF0F0FCFE)
  93
  94#define AHCI_CAP2                         (9)
  95#define AHCI_CAP2_BOH                  (0x01)
  96#define AHCI_CAP2_NVMP                 (0x02)
  97#define AHCI_CAP2_APST                 (0x04)
  98#define AHCI_CAP2_RESERVED       (0xFFFFFFF8)
  99
 100#define AHCI_BOHC                        (10)
 101#define AHCI_RESERVED                    (11)
 102#define AHCI_NVMHCI                      (24)
 103#define AHCI_VENDOR                      (40)
 104#define AHCI_PORTS                       (64)
 105
 106/*** Port Memory Offsets & Bitmasks ***/
 107#define AHCI_PX_CLB                       (0)
 108#define AHCI_PX_CLB_RESERVED          (0x1FF)
 109
 110#define AHCI_PX_CLBU                      (1)
 111
 112#define AHCI_PX_FB                        (2)
 113#define AHCI_PX_FB_RESERVED            (0xFF)
 114
 115#define AHCI_PX_FBU                       (3)
 116
 117#define AHCI_PX_IS                        (4)
 118#define AHCI_PX_IS_DHRS                 (0x1)
 119#define AHCI_PX_IS_PSS                  (0x2)
 120#define AHCI_PX_IS_DSS                  (0x4)
 121#define AHCI_PX_IS_SDBS                 (0x8)
 122#define AHCI_PX_IS_UFS                 (0x10)
 123#define AHCI_PX_IS_DPS                 (0x20)
 124#define AHCI_PX_IS_PCS                 (0x40)
 125#define AHCI_PX_IS_DMPS                (0x80)
 126#define AHCI_PX_IS_RESERVED       (0x23FFF00)
 127#define AHCI_PX_IS_PRCS            (0x400000)
 128#define AHCI_PX_IS_IPMS            (0x800000)
 129#define AHCI_PX_IS_OFS            (0x1000000)
 130#define AHCI_PX_IS_INFS           (0x4000000)
 131#define AHCI_PX_IS_IFS            (0x8000000)
 132#define AHCI_PX_IS_HBDS          (0x10000000)
 133#define AHCI_PX_IS_HBFS          (0x20000000)
 134#define AHCI_PX_IS_TFES          (0x40000000)
 135#define AHCI_PX_IS_CPDS          (0x80000000)
 136
 137#define AHCI_PX_IE                        (5)
 138#define AHCI_PX_IE_DHRE                 (0x1)
 139#define AHCI_PX_IE_PSE                  (0x2)
 140#define AHCI_PX_IE_DSE                  (0x4)
 141#define AHCI_PX_IE_SDBE                 (0x8)
 142#define AHCI_PX_IE_UFE                 (0x10)
 143#define AHCI_PX_IE_DPE                 (0x20)
 144#define AHCI_PX_IE_PCE                 (0x40)
 145#define AHCI_PX_IE_DMPE                (0x80)
 146#define AHCI_PX_IE_RESERVED       (0x23FFF00)
 147#define AHCI_PX_IE_PRCE            (0x400000)
 148#define AHCI_PX_IE_IPME            (0x800000)
 149#define AHCI_PX_IE_OFE            (0x1000000)
 150#define AHCI_PX_IE_INFE           (0x4000000)
 151#define AHCI_PX_IE_IFE            (0x8000000)
 152#define AHCI_PX_IE_HBDE          (0x10000000)
 153#define AHCI_PX_IE_HBFE          (0x20000000)
 154#define AHCI_PX_IE_TFEE          (0x40000000)
 155#define AHCI_PX_IE_CPDE          (0x80000000)
 156
 157#define AHCI_PX_CMD                       (6)
 158#define AHCI_PX_CMD_ST                  (0x1)
 159#define AHCI_PX_CMD_SUD                 (0x2)
 160#define AHCI_PX_CMD_POD                 (0x4)
 161#define AHCI_PX_CMD_CLO                 (0x8)
 162#define AHCI_PX_CMD_FRE                (0x10)
 163#define AHCI_PX_CMD_RESERVED           (0xE0)
 164#define AHCI_PX_CMD_CCS              (0x1F00)
 165#define AHCI_PX_CMD_MPSS             (0x2000)
 166#define AHCI_PX_CMD_FR               (0x4000)
 167#define AHCI_PX_CMD_CR               (0x8000)
 168#define AHCI_PX_CMD_CPS             (0x10000)
 169#define AHCI_PX_CMD_PMA             (0x20000)
 170#define AHCI_PX_CMD_HPCP            (0x40000)
 171#define AHCI_PX_CMD_MPSP            (0x80000)
 172#define AHCI_PX_CMD_CPD            (0x100000)
 173#define AHCI_PX_CMD_ESP            (0x200000)
 174#define AHCI_PX_CMD_FBSCP          (0x400000)
 175#define AHCI_PX_CMD_APSTE          (0x800000)
 176#define AHCI_PX_CMD_ATAPI         (0x1000000)
 177#define AHCI_PX_CMD_DLAE          (0x2000000)
 178#define AHCI_PX_CMD_ALPE          (0x4000000)
 179#define AHCI_PX_CMD_ASP           (0x8000000)
 180#define AHCI_PX_CMD_ICC          (0xF0000000)
 181
 182#define AHCI_PX_RES1                      (7)
 183
 184#define AHCI_PX_TFD                       (8)
 185#define AHCI_PX_TFD_STS                (0xFF)
 186#define AHCI_PX_TFD_STS_ERR            (0x01)
 187#define AHCI_PX_TFD_STS_CS1            (0x06)
 188#define AHCI_PX_TFD_STS_DRQ            (0x08)
 189#define AHCI_PX_TFD_STS_CS2            (0x70)
 190#define AHCI_PX_TFD_STS_BSY            (0x80)
 191#define AHCI_PX_TFD_ERR              (0xFF00)
 192#define AHCI_PX_TFD_RESERVED     (0xFFFF0000)
 193
 194#define AHCI_PX_SIG                       (9)
 195#define AHCI_PX_SIG_SECTOR_COUNT       (0xFF)
 196#define AHCI_PX_SIG_LBA_LOW          (0xFF00)
 197#define AHCI_PX_SIG_LBA_MID        (0xFF0000)
 198#define AHCI_PX_SIG_LBA_HIGH     (0xFF000000)
 199
 200#define AHCI_PX_SSTS                     (10)
 201#define AHCI_PX_SSTS_DET               (0x0F)
 202#define AHCI_PX_SSTS_SPD               (0xF0)
 203#define AHCI_PX_SSTS_IPM              (0xF00)
 204#define AHCI_PX_SSTS_RESERVED    (0xFFFFF000)
 205#define SSTS_DET_NO_DEVICE             (0x00)
 206#define SSTS_DET_PRESENT               (0x01)
 207#define SSTS_DET_ESTABLISHED           (0x03)
 208#define SSTS_DET_OFFLINE               (0x04)
 209
 210#define AHCI_PX_SCTL                     (11)
 211
 212#define AHCI_PX_SERR                     (12)
 213#define AHCI_PX_SERR_ERR             (0xFFFF)
 214#define AHCI_PX_SERR_DIAG        (0xFFFF0000)
 215#define AHCI_PX_SERR_DIAG_X      (0x04000000)
 216
 217#define AHCI_PX_SACT                     (13)
 218#define AHCI_PX_CI                       (14)
 219#define AHCI_PX_SNTF                     (15)
 220
 221#define AHCI_PX_FBS                      (16)
 222#define AHCI_PX_FBS_EN                  (0x1)
 223#define AHCI_PX_FBS_DEC                 (0x2)
 224#define AHCI_PX_FBS_SDE                 (0x4)
 225#define AHCI_PX_FBS_DEV               (0xF00)
 226#define AHCI_PX_FBS_ADO              (0xF000)
 227#define AHCI_PX_FBS_DWE             (0xF0000)
 228#define AHCI_PX_FBS_RESERVED     (0xFFF000F8)
 229
 230#define AHCI_PX_RES2                     (17)
 231#define AHCI_PX_VS                       (28)
 232
 233#define HBA_DATA_REGION_SIZE            (256)
 234#define HBA_PORT_DATA_SIZE              (128)
 235#define HBA_PORT_NUM_REG (HBA_PORT_DATA_SIZE/4)
 236
 237#define AHCI_VERSION_0_95        (0x00000905)
 238#define AHCI_VERSION_1_0         (0x00010000)
 239#define AHCI_VERSION_1_1         (0x00010100)
 240#define AHCI_VERSION_1_2         (0x00010200)
 241#define AHCI_VERSION_1_3         (0x00010300)
 242
 243#define AHCI_SECTOR_SIZE                (512)
 244#define ATAPI_SECTOR_SIZE              (2048)
 245
 246#define AHCI_SIGNATURE_CDROM     (0xeb140101)
 247#define AHCI_SIGNATURE_DISK      (0x00000101)
 248
 249/* FIS types */
 250enum {
 251    REG_H2D_FIS = 0x27,
 252    REG_D2H_FIS = 0x34,
 253    DMA_ACTIVATE_FIS = 0x39,
 254    DMA_SETUP_FIS = 0x41,
 255    DATA_FIS = 0x46,
 256    BIST_ACTIVATE_FIS = 0x58,
 257    PIO_SETUP_FIS = 0x5F,
 258    SDB_FIS = 0xA1
 259};
 260
 261/* FIS flags */
 262#define REG_H2D_FIS_CMD  0x80
 263
 264/* ATA Commands */
 265enum {
 266    /* DMA */
 267    CMD_READ_DMA       = 0xC8,
 268    CMD_READ_DMA_EXT   = 0x25,
 269    CMD_WRITE_DMA      = 0xCA,
 270    CMD_WRITE_DMA_EXT  = 0x35,
 271    /* PIO */
 272    CMD_READ_PIO       = 0x20,
 273    CMD_READ_PIO_EXT   = 0x24,
 274    CMD_WRITE_PIO      = 0x30,
 275    CMD_WRITE_PIO_EXT  = 0x34,
 276    /* Misc */
 277    CMD_READ_MAX       = 0xF8,
 278    CMD_READ_MAX_EXT   = 0x27,
 279    CMD_FLUSH_CACHE    = 0xE7,
 280    CMD_IDENTIFY       = 0xEC,
 281    CMD_PACKET         = 0xA0,
 282    CMD_PACKET_ID      = 0xA1,
 283    /* NCQ */
 284    READ_FPDMA_QUEUED  = 0x60,
 285    WRITE_FPDMA_QUEUED = 0x61,
 286};
 287
 288/* ATAPI Commands */
 289enum {
 290    CMD_ATAPI_TEST_UNIT_READY = 0x00,
 291    CMD_ATAPI_REQUEST_SENSE   = 0x03,
 292    CMD_ATAPI_START_STOP_UNIT = 0x1b,
 293    CMD_ATAPI_READ_10         = 0x28,
 294    CMD_ATAPI_READ_CD         = 0xbe,
 295};
 296
 297enum {
 298    SENSE_NO_SENSE       = 0x00,
 299    SENSE_NOT_READY      = 0x02,
 300    SENSE_UNIT_ATTENTION = 0x06,
 301};
 302
 303enum {
 304    ASC_MEDIUM_MAY_HAVE_CHANGED = 0x28,
 305    ASC_MEDIUM_NOT_PRESENT      = 0x3a,
 306};
 307
 308/* AHCI Command Header Flags & Masks*/
 309#define CMDH_CFL        (0x1F)
 310#define CMDH_ATAPI      (0x20)
 311#define CMDH_WRITE      (0x40)
 312#define CMDH_PREFETCH   (0x80)
 313#define CMDH_RESET     (0x100)
 314#define CMDH_BIST      (0x200)
 315#define CMDH_CLR_BSY   (0x400)
 316#define CMDH_RES       (0x800)
 317#define CMDH_PMP      (0xF000)
 318
 319/* ATA device register masks */
 320#define ATA_DEVICE_MAGIC 0xA0 /* used in ata1-3 */
 321#define ATA_DEVICE_LBA   0x40
 322#define NCQ_DEVICE_MAGIC 0x40 /* for ncq device registers */
 323#define ATA_DEVICE_DRIVE 0x10
 324#define ATA_DEVICE_HEAD  0x0F
 325
 326/*** Structures ***/
 327
 328typedef struct AHCIPortQState {
 329    uint64_t fb;
 330    uint64_t clb;
 331    uint64_t ctba[32];
 332    uint16_t prdtl[32];
 333    uint8_t next; /** Next Command Slot to Use **/
 334} AHCIPortQState;
 335
 336typedef struct AHCIQState {
 337    QOSState *parent;
 338    QPCIDevice *dev;
 339    QPCIBar hba_bar;
 340    uint64_t barsize;
 341    uint32_t fingerprint;
 342    uint32_t cap;
 343    uint32_t cap2;
 344    AHCIPortQState port[32];
 345    bool enabled;
 346} AHCIQState;
 347
 348/**
 349 * Generic FIS structure.
 350 */
 351typedef struct FIS {
 352    uint8_t fis_type;
 353    uint8_t flags;
 354    char data[];
 355} __attribute__((__packed__)) FIS;
 356
 357/**
 358 * Register device-to-host FIS structure.
 359 */
 360typedef struct RegD2HFIS {
 361    /* DW0 */
 362    uint8_t fis_type;
 363    uint8_t flags;
 364    uint8_t status;
 365    uint8_t error;
 366    /* DW1 */
 367    uint8_t lba_lo[3];
 368    uint8_t device;
 369    /* DW2 */
 370    uint8_t lba_hi[3];
 371    uint8_t res0;
 372    /* DW3 */
 373    uint16_t count;
 374    uint16_t res1;
 375    /* DW4 */
 376    uint32_t res2;
 377} __attribute__((__packed__)) RegD2HFIS;
 378
 379/**
 380 * Register device-to-host FIS structure;
 381 * PIO Setup variety.
 382 */
 383typedef struct PIOSetupFIS {
 384    /* DW0 */
 385    uint8_t fis_type;
 386    uint8_t flags;
 387    uint8_t status;
 388    uint8_t error;
 389    /* DW1 */
 390    uint8_t lba_lo[3];
 391    uint8_t device;
 392    /* DW2 */
 393    uint8_t lba_hi[3];
 394    uint8_t res0;
 395    /* DW3 */
 396    uint16_t count;
 397    uint8_t res1;
 398    uint8_t e_status;
 399    /* DW4 */
 400    uint16_t tx_count;
 401    uint16_t res2;
 402} __attribute__((__packed__)) PIOSetupFIS;
 403
 404/**
 405 * Register host-to-device FIS structure.
 406 */
 407typedef struct RegH2DFIS {
 408    /* DW0 */
 409    uint8_t fis_type;
 410    uint8_t flags;
 411    uint8_t command;
 412    uint8_t feature_low;
 413    /* DW1 */
 414    uint8_t lba_lo[3];
 415    uint8_t device;
 416    /* DW2 */
 417    uint8_t lba_hi[3];
 418    uint8_t feature_high;
 419    /* DW3 */
 420    uint16_t count;
 421    uint8_t icc;
 422    uint8_t control;
 423    /* DW4 */
 424    uint8_t aux[4];
 425} __attribute__((__packed__)) RegH2DFIS;
 426
 427/**
 428 * Register host-to-device FIS structure, for NCQ commands.
 429 * Actually just a RegH2DFIS, but with fields repurposed.
 430 * Repurposed fields are annotated below.
 431 */
 432typedef struct NCQFIS {
 433    /* DW0 */
 434    uint8_t fis_type;
 435    uint8_t flags;
 436    uint8_t command;
 437    uint8_t sector_low; /* H2D: Feature 7:0 */
 438    /* DW1 */
 439    uint8_t lba_lo[3];
 440    uint8_t device;
 441    /* DW2 */
 442    uint8_t lba_hi[3];
 443    uint8_t sector_hi; /* H2D: Feature 15:8 */
 444    /* DW3 */
 445    uint8_t tag;       /* H2D: Count 0:7 */
 446    uint8_t prio;      /* H2D: Count 15:8 */
 447    uint8_t icc;
 448    uint8_t control;
 449    /* DW4 */
 450    uint8_t aux[4];
 451} __attribute__((__packed__)) NCQFIS;
 452
 453/**
 454 * Command List entry structure.
 455 * The command list contains between 1-32 of these structures.
 456 */
 457typedef struct AHCICommandHeader {
 458    uint16_t flags; /* Cmd-Fis-Len, PMP#, and flags. */
 459    uint16_t prdtl; /* Phys Region Desc. Table Length */
 460    uint32_t prdbc; /* Phys Region Desc. Byte Count */
 461    uint64_t ctba;  /* Command Table Descriptor Base Address */
 462    uint32_t res[4];
 463} __attribute__((__packed__)) AHCICommandHeader;
 464
 465/**
 466 * Physical Region Descriptor; pointed to by the Command List Header,
 467 * struct ahci_command.
 468 */
 469typedef struct PRD {
 470    uint64_t dba;  /* Data Base Address */
 471    uint32_t res;  /* Reserved */
 472    uint32_t dbc;  /* Data Byte Count (0-indexed) & Interrupt Flag (bit 2^31) */
 473} __attribute__((__packed__)) PRD;
 474
 475/* Opaque, defined within ahci.c */
 476typedef struct AHCICommand AHCICommand;
 477
 478/* Options to ahci_exec */
 479typedef struct AHCIOpts {
 480    size_t size;        /* Size of transfer */
 481    unsigned prd_size;  /* Size per-each PRD */
 482    bool set_bcl;       /* Override the default BCL of ATAPI_SECTOR_SIZE */
 483    unsigned bcl;       /* Byte Count Limit, for ATAPI PIO */
 484    uint64_t lba;       /* Starting LBA offset */
 485    uint64_t buffer;    /* Pointer to source or destination guest buffer */
 486    bool atapi;         /* ATAPI command? */
 487    bool atapi_dma;     /* Use DMA for ATAPI? */
 488    bool error;
 489    int (*pre_cb)(AHCIQState*, AHCICommand*, const struct AHCIOpts *);
 490    int (*mid_cb)(AHCIQState*, AHCICommand*, const struct AHCIOpts *);
 491    int (*post_cb)(AHCIQState*, AHCICommand*, const struct AHCIOpts *);
 492    void *opaque;
 493} AHCIOpts;
 494
 495/*** Macro Utilities ***/
 496#define BITANY(data, mask) (((data) & (mask)) != 0)
 497#define BITSET(data, mask) (((data) & (mask)) == (mask))
 498#define BITCLR(data, mask) (((data) & (mask)) == 0)
 499#define ASSERT_BIT_SET(data, mask) g_assert_cmphex((data) & (mask), ==, (mask))
 500#define ASSERT_BIT_CLEAR(data, mask) g_assert_cmphex((data) & (mask), ==, 0)
 501
 502/* For calculating how big the PRD table needs to be: */
 503#define CMD_TBL_SIZ(n) ((0x80 + ((n) * sizeof(PRD)) + 0x7F) & ~0x7F)
 504
 505/* Helpers for reading/writing AHCI HBA register values */
 506
 507static inline uint32_t ahci_mread(AHCIQState *ahci, size_t offset)
 508{
 509    return qpci_io_readl(ahci->dev, ahci->hba_bar, offset);
 510}
 511
 512static inline void ahci_mwrite(AHCIQState *ahci, size_t offset, uint32_t value)
 513{
 514    qpci_io_writel(ahci->dev, ahci->hba_bar, offset, value);
 515}
 516
 517static inline uint32_t ahci_rreg(AHCIQState *ahci, uint32_t reg_num)
 518{
 519    return ahci_mread(ahci, 4 * reg_num);
 520}
 521
 522static inline void ahci_wreg(AHCIQState *ahci, uint32_t reg_num, uint32_t value)
 523{
 524    ahci_mwrite(ahci, 4 * reg_num, value);
 525}
 526
 527static inline void ahci_set(AHCIQState *ahci, uint32_t reg_num, uint32_t mask)
 528{
 529    ahci_wreg(ahci, reg_num, ahci_rreg(ahci, reg_num) | mask);
 530}
 531
 532static inline void ahci_clr(AHCIQState *ahci, uint32_t reg_num, uint32_t mask)
 533{
 534    ahci_wreg(ahci, reg_num, ahci_rreg(ahci, reg_num) & ~mask);
 535}
 536
 537static inline size_t ahci_px_offset(uint8_t port, uint32_t reg_num)
 538{
 539    return AHCI_PORTS + (HBA_PORT_NUM_REG * port) + reg_num;
 540}
 541
 542static inline uint32_t ahci_px_rreg(AHCIQState *ahci, uint8_t port,
 543                                    uint32_t reg_num)
 544{
 545    return ahci_rreg(ahci, ahci_px_offset(port, reg_num));
 546}
 547
 548static inline void ahci_px_wreg(AHCIQState *ahci, uint8_t port,
 549                                uint32_t reg_num, uint32_t value)
 550{
 551    ahci_wreg(ahci, ahci_px_offset(port, reg_num), value);
 552}
 553
 554static inline void ahci_px_set(AHCIQState *ahci, uint8_t port,
 555                               uint32_t reg_num, uint32_t mask)
 556{
 557    ahci_px_wreg(ahci, port, reg_num,
 558                 ahci_px_rreg(ahci, port, reg_num) | mask);
 559}
 560
 561static inline void ahci_px_clr(AHCIQState *ahci, uint8_t port,
 562                               uint32_t reg_num, uint32_t mask)
 563{
 564    ahci_px_wreg(ahci, port, reg_num,
 565                 ahci_px_rreg(ahci, port, reg_num) & ~mask);
 566}
 567
 568/*** Prototypes ***/
 569uint64_t ahci_alloc(AHCIQState *ahci, size_t bytes);
 570void ahci_free(AHCIQState *ahci, uint64_t addr);
 571void ahci_clean_mem(AHCIQState *ahci);
 572
 573/* Device management */
 574QPCIDevice *get_ahci_device(QTestState *qts, uint32_t *fingerprint);
 575void free_ahci_device(QPCIDevice *dev);
 576void ahci_pci_enable(AHCIQState *ahci);
 577void start_ahci_device(AHCIQState *ahci);
 578void ahci_hba_enable(AHCIQState *ahci);
 579
 580/* Port Management */
 581unsigned ahci_port_select(AHCIQState *ahci);
 582void ahci_port_clear(AHCIQState *ahci, uint8_t port);
 583
 584/* Command header / table management */
 585unsigned ahci_pick_cmd(AHCIQState *ahci, uint8_t port);
 586void ahci_get_command_header(AHCIQState *ahci, uint8_t port,
 587                             uint8_t slot, AHCICommandHeader *cmd);
 588void ahci_set_command_header(AHCIQState *ahci, uint8_t port,
 589                             uint8_t slot, AHCICommandHeader *cmd);
 590void ahci_destroy_command(AHCIQState *ahci, uint8_t port, uint8_t slot);
 591
 592/* AHCI sanity check routines */
 593void ahci_port_check_error(AHCIQState *ahci, uint8_t port,
 594                           uint32_t imask, uint8_t emask);
 595void ahci_port_check_interrupts(AHCIQState *ahci, uint8_t port,
 596                                uint32_t intr_mask);
 597void ahci_port_check_nonbusy(AHCIQState *ahci, uint8_t port, uint8_t slot);
 598void ahci_port_check_d2h_sanity(AHCIQState *ahci, uint8_t port, uint8_t slot);
 599void ahci_port_check_pio_sanity(AHCIQState *ahci, AHCICommand *cmd);
 600void ahci_port_check_cmd_sanity(AHCIQState *ahci, AHCICommand *cmd);
 601
 602/* Misc */
 603bool is_atapi(AHCIQState *ahci, uint8_t port);
 604unsigned size_to_prdtl(unsigned bytes, unsigned bytes_per_prd);
 605
 606/* Command: Macro level execution */
 607void ahci_guest_io(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
 608                   uint64_t gbuffer, size_t size, uint64_t sector);
 609AHCICommand *ahci_guest_io_halt(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
 610                                uint64_t gbuffer, size_t size, uint64_t sector);
 611void ahci_guest_io_resume(AHCIQState *ahci, AHCICommand *cmd);
 612void ahci_io(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
 613             void *buffer, size_t bufsize, uint64_t sector);
 614void ahci_exec(AHCIQState *ahci, uint8_t port,
 615               uint8_t op, const AHCIOpts *opts);
 616void ahci_atapi_test_ready(AHCIQState *ahci, uint8_t port, bool ready,
 617                           uint8_t expected_sense);
 618void ahci_atapi_get_sense(AHCIQState *ahci, uint8_t port,
 619                          uint8_t *sense, uint8_t *asc);
 620void ahci_atapi_eject(AHCIQState *ahci, uint8_t port);
 621void ahci_atapi_load(AHCIQState *ahci, uint8_t port);
 622
 623/* Command: Fine-grained lifecycle */
 624AHCICommand *ahci_command_create(uint8_t command_name);
 625AHCICommand *ahci_atapi_command_create(uint8_t scsi_cmd, uint16_t bcl, bool dma);
 626void ahci_command_commit(AHCIQState *ahci, AHCICommand *cmd, uint8_t port);
 627void ahci_command_issue(AHCIQState *ahci, AHCICommand *cmd);
 628void ahci_command_issue_async(AHCIQState *ahci, AHCICommand *cmd);
 629void ahci_command_wait(AHCIQState *ahci, AHCICommand *cmd);
 630void ahci_command_verify(AHCIQState *ahci, AHCICommand *cmd);
 631void ahci_command_free(AHCICommand *cmd);
 632
 633/* Command: adjustments */
 634void ahci_command_set_flags(AHCICommand *cmd, uint16_t cmdh_flags);
 635void ahci_command_clr_flags(AHCICommand *cmd, uint16_t cmdh_flags);
 636void ahci_command_set_offset(AHCICommand *cmd, uint64_t lba_sect);
 637void ahci_command_set_buffer(AHCICommand *cmd, uint64_t buffer);
 638void ahci_command_set_size(AHCICommand *cmd, uint64_t xbytes);
 639void ahci_command_set_prd_size(AHCICommand *cmd, unsigned prd_size);
 640void ahci_command_set_sizes(AHCICommand *cmd, uint64_t xbytes,
 641                            unsigned prd_size);
 642void ahci_command_set_acmd(AHCICommand *cmd, void *acmd);
 643void ahci_command_enable_atapi_dma(AHCICommand *cmd);
 644void ahci_command_adjust(AHCICommand *cmd, uint64_t lba_sect, uint64_t gbuffer,
 645                         uint64_t xbytes, unsigned prd_size);
 646
 647/* Command: Misc */
 648uint8_t ahci_command_slot(AHCICommand *cmd);
 649void ahci_write_fis(AHCIQState *ahci, AHCICommand *cmd);
 650
 651#endif
 652