qemu/tests/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_READ_10 = 0x28,
 291};
 292
 293/* AHCI Command Header Flags & Masks*/
 294#define CMDH_CFL        (0x1F)
 295#define CMDH_ATAPI      (0x20)
 296#define CMDH_WRITE      (0x40)
 297#define CMDH_PREFETCH   (0x80)
 298#define CMDH_RESET     (0x100)
 299#define CMDH_BIST      (0x200)
 300#define CMDH_CLR_BSY   (0x400)
 301#define CMDH_RES       (0x800)
 302#define CMDH_PMP      (0xF000)
 303
 304/* ATA device register masks */
 305#define ATA_DEVICE_MAGIC 0xA0 /* used in ata1-3 */
 306#define ATA_DEVICE_LBA   0x40
 307#define NCQ_DEVICE_MAGIC 0x40 /* for ncq device registers */
 308#define ATA_DEVICE_DRIVE 0x10
 309#define ATA_DEVICE_HEAD  0x0F
 310
 311/*** Structures ***/
 312
 313typedef struct AHCIPortQState {
 314    uint64_t fb;
 315    uint64_t clb;
 316    uint64_t ctba[32];
 317    uint16_t prdtl[32];
 318    uint8_t next; /** Next Command Slot to Use **/
 319} AHCIPortQState;
 320
 321typedef struct AHCIQState {
 322    QOSState *parent;
 323    QPCIDevice *dev;
 324    void *hba_base;
 325    uint64_t barsize;
 326    uint32_t fingerprint;
 327    uint32_t cap;
 328    uint32_t cap2;
 329    AHCIPortQState port[32];
 330} AHCIQState;
 331
 332/**
 333 * Generic FIS structure.
 334 */
 335typedef struct FIS {
 336    uint8_t fis_type;
 337    uint8_t flags;
 338    char data[0];
 339} __attribute__((__packed__)) FIS;
 340
 341/**
 342 * Register device-to-host FIS structure.
 343 */
 344typedef struct RegD2HFIS {
 345    /* DW0 */
 346    uint8_t fis_type;
 347    uint8_t flags;
 348    uint8_t status;
 349    uint8_t error;
 350    /* DW1 */
 351    uint8_t lba_lo[3];
 352    uint8_t device;
 353    /* DW2 */
 354    uint8_t lba_hi[3];
 355    uint8_t res0;
 356    /* DW3 */
 357    uint16_t count;
 358    uint16_t res1;
 359    /* DW4 */
 360    uint32_t res2;
 361} __attribute__((__packed__)) RegD2HFIS;
 362
 363/**
 364 * Register device-to-host FIS structure;
 365 * PIO Setup variety.
 366 */
 367typedef struct PIOSetupFIS {
 368    /* DW0 */
 369    uint8_t fis_type;
 370    uint8_t flags;
 371    uint8_t status;
 372    uint8_t error;
 373    /* DW1 */
 374    uint8_t lba_lo[3];
 375    uint8_t device;
 376    /* DW2 */
 377    uint8_t lba_hi[3];
 378    uint8_t res0;
 379    /* DW3 */
 380    uint16_t count;
 381    uint8_t res1;
 382    uint8_t e_status;
 383    /* DW4 */
 384    uint16_t tx_count;
 385    uint16_t res2;
 386} __attribute__((__packed__)) PIOSetupFIS;
 387
 388/**
 389 * Register host-to-device FIS structure.
 390 */
 391typedef struct RegH2DFIS {
 392    /* DW0 */
 393    uint8_t fis_type;
 394    uint8_t flags;
 395    uint8_t command;
 396    uint8_t feature_low;
 397    /* DW1 */
 398    uint8_t lba_lo[3];
 399    uint8_t device;
 400    /* DW2 */
 401    uint8_t lba_hi[3];
 402    uint8_t feature_high;
 403    /* DW3 */
 404    uint16_t count;
 405    uint8_t icc;
 406    uint8_t control;
 407    /* DW4 */
 408    uint8_t aux[4];
 409} __attribute__((__packed__)) RegH2DFIS;
 410
 411/**
 412 * Register host-to-device FIS structure, for NCQ commands.
 413 * Actually just a RegH2DFIS, but with fields repurposed.
 414 * Repurposed fields are annotated below.
 415 */
 416typedef struct NCQFIS {
 417    /* DW0 */
 418    uint8_t fis_type;
 419    uint8_t flags;
 420    uint8_t command;
 421    uint8_t sector_low; /* H2D: Feature 7:0 */
 422    /* DW1 */
 423    uint8_t lba_lo[3];
 424    uint8_t device;
 425    /* DW2 */
 426    uint8_t lba_hi[3];
 427    uint8_t sector_hi; /* H2D: Feature 15:8 */
 428    /* DW3 */
 429    uint8_t tag;       /* H2D: Count 0:7 */
 430    uint8_t prio;      /* H2D: Count 15:8 */
 431    uint8_t icc;
 432    uint8_t control;
 433    /* DW4 */
 434    uint8_t aux[4];
 435} __attribute__((__packed__)) NCQFIS;
 436
 437/**
 438 * Command List entry structure.
 439 * The command list contains between 1-32 of these structures.
 440 */
 441typedef struct AHCICommandHeader {
 442    uint16_t flags; /* Cmd-Fis-Len, PMP#, and flags. */
 443    uint16_t prdtl; /* Phys Region Desc. Table Length */
 444    uint32_t prdbc; /* Phys Region Desc. Byte Count */
 445    uint64_t ctba;  /* Command Table Descriptor Base Address */
 446    uint32_t res[4];
 447} __attribute__((__packed__)) AHCICommandHeader;
 448
 449/**
 450 * Physical Region Descriptor; pointed to by the Command List Header,
 451 * struct ahci_command.
 452 */
 453typedef struct PRD {
 454    uint64_t dba;  /* Data Base Address */
 455    uint32_t res;  /* Reserved */
 456    uint32_t dbc;  /* Data Byte Count (0-indexed) & Interrupt Flag (bit 2^31) */
 457} __attribute__((__packed__)) PRD;
 458
 459/* Opaque, defined within ahci.c */
 460typedef struct AHCICommand AHCICommand;
 461
 462/* Options to ahci_exec */
 463typedef struct AHCIOpts {
 464    size_t size;
 465    unsigned prd_size;
 466    uint64_t lba;
 467    uint64_t buffer;
 468    bool atapi;
 469    bool atapi_dma;
 470    bool error;
 471    int (*pre_cb)(AHCIQState*, AHCICommand*, const struct AHCIOpts *);
 472    int (*mid_cb)(AHCIQState*, AHCICommand*, const struct AHCIOpts *);
 473    int (*post_cb)(AHCIQState*, AHCICommand*, const struct AHCIOpts *);
 474    void *opaque;
 475} AHCIOpts;
 476
 477/*** Macro Utilities ***/
 478#define BITANY(data, mask) (((data) & (mask)) != 0)
 479#define BITSET(data, mask) (((data) & (mask)) == (mask))
 480#define BITCLR(data, mask) (((data) & (mask)) == 0)
 481#define ASSERT_BIT_SET(data, mask) g_assert_cmphex((data) & (mask), ==, (mask))
 482#define ASSERT_BIT_CLEAR(data, mask) g_assert_cmphex((data) & (mask), ==, 0)
 483
 484/* For calculating how big the PRD table needs to be: */
 485#define CMD_TBL_SIZ(n) ((0x80 + ((n) * sizeof(PRD)) + 0x7F) & ~0x7F)
 486
 487/* Helpers for reading/writing AHCI HBA register values */
 488
 489static inline uint32_t ahci_mread(AHCIQState *ahci, size_t offset)
 490{
 491    return qpci_io_readl(ahci->dev, ahci->hba_base + offset);
 492}
 493
 494static inline void ahci_mwrite(AHCIQState *ahci, size_t offset, uint32_t value)
 495{
 496    qpci_io_writel(ahci->dev, ahci->hba_base + offset, value);
 497}
 498
 499static inline uint32_t ahci_rreg(AHCIQState *ahci, uint32_t reg_num)
 500{
 501    return ahci_mread(ahci, 4 * reg_num);
 502}
 503
 504static inline void ahci_wreg(AHCIQState *ahci, uint32_t reg_num, uint32_t value)
 505{
 506    ahci_mwrite(ahci, 4 * reg_num, value);
 507}
 508
 509static inline void ahci_set(AHCIQState *ahci, uint32_t reg_num, uint32_t mask)
 510{
 511    ahci_wreg(ahci, reg_num, ahci_rreg(ahci, reg_num) | mask);
 512}
 513
 514static inline void ahci_clr(AHCIQState *ahci, uint32_t reg_num, uint32_t mask)
 515{
 516    ahci_wreg(ahci, reg_num, ahci_rreg(ahci, reg_num) & ~mask);
 517}
 518
 519static inline size_t ahci_px_offset(uint8_t port, uint32_t reg_num)
 520{
 521    return AHCI_PORTS + (HBA_PORT_NUM_REG * port) + reg_num;
 522}
 523
 524static inline uint32_t ahci_px_rreg(AHCIQState *ahci, uint8_t port,
 525                                    uint32_t reg_num)
 526{
 527    return ahci_rreg(ahci, ahci_px_offset(port, reg_num));
 528}
 529
 530static inline void ahci_px_wreg(AHCIQState *ahci, uint8_t port,
 531                                uint32_t reg_num, uint32_t value)
 532{
 533    ahci_wreg(ahci, ahci_px_offset(port, reg_num), value);
 534}
 535
 536static inline void ahci_px_set(AHCIQState *ahci, uint8_t port,
 537                               uint32_t reg_num, uint32_t mask)
 538{
 539    ahci_px_wreg(ahci, port, reg_num,
 540                 ahci_px_rreg(ahci, port, reg_num) | mask);
 541}
 542
 543static inline void ahci_px_clr(AHCIQState *ahci, uint8_t port,
 544                               uint32_t reg_num, uint32_t mask)
 545{
 546    ahci_px_wreg(ahci, port, reg_num,
 547                 ahci_px_rreg(ahci, port, reg_num) & ~mask);
 548}
 549
 550/*** Prototypes ***/
 551uint64_t ahci_alloc(AHCIQState *ahci, size_t bytes);
 552void ahci_free(AHCIQState *ahci, uint64_t addr);
 553void ahci_clean_mem(AHCIQState *ahci);
 554
 555/* Device management */
 556QPCIDevice *get_ahci_device(uint32_t *fingerprint);
 557void free_ahci_device(QPCIDevice *dev);
 558void ahci_pci_enable(AHCIQState *ahci);
 559void start_ahci_device(AHCIQState *ahci);
 560void ahci_hba_enable(AHCIQState *ahci);
 561
 562/* Port Management */
 563unsigned ahci_port_select(AHCIQState *ahci);
 564void ahci_port_clear(AHCIQState *ahci, uint8_t port);
 565
 566/* Command header / table management */
 567unsigned ahci_pick_cmd(AHCIQState *ahci, uint8_t port);
 568void ahci_get_command_header(AHCIQState *ahci, uint8_t port,
 569                             uint8_t slot, AHCICommandHeader *cmd);
 570void ahci_set_command_header(AHCIQState *ahci, uint8_t port,
 571                             uint8_t slot, AHCICommandHeader *cmd);
 572void ahci_destroy_command(AHCIQState *ahci, uint8_t port, uint8_t slot);
 573
 574/* AHCI sanity check routines */
 575void ahci_port_check_error(AHCIQState *ahci, uint8_t port);
 576void ahci_port_check_interrupts(AHCIQState *ahci, uint8_t port,
 577                                uint32_t intr_mask);
 578void ahci_port_check_nonbusy(AHCIQState *ahci, uint8_t port, uint8_t slot);
 579void ahci_port_check_d2h_sanity(AHCIQState *ahci, uint8_t port, uint8_t slot);
 580void ahci_port_check_pio_sanity(AHCIQState *ahci, uint8_t port,
 581                                uint8_t slot, size_t buffsize);
 582void ahci_port_check_cmd_sanity(AHCIQState *ahci, AHCICommand *cmd);
 583
 584/* Misc */
 585bool is_atapi(AHCIQState *ahci, uint8_t port);
 586unsigned size_to_prdtl(unsigned bytes, unsigned bytes_per_prd);
 587
 588/* Command: Macro level execution */
 589void ahci_guest_io(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
 590                   uint64_t gbuffer, size_t size, uint64_t sector);
 591AHCICommand *ahci_guest_io_halt(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
 592                                uint64_t gbuffer, size_t size, uint64_t sector);
 593void ahci_guest_io_resume(AHCIQState *ahci, AHCICommand *cmd);
 594void ahci_io(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
 595             void *buffer, size_t bufsize, uint64_t sector);
 596void ahci_exec(AHCIQState *ahci, uint8_t port,
 597               uint8_t op, const AHCIOpts *opts);
 598
 599/* Command: Fine-grained lifecycle */
 600AHCICommand *ahci_command_create(uint8_t command_name);
 601AHCICommand *ahci_atapi_command_create(uint8_t scsi_cmd);
 602void ahci_command_commit(AHCIQState *ahci, AHCICommand *cmd, uint8_t port);
 603void ahci_command_issue(AHCIQState *ahci, AHCICommand *cmd);
 604void ahci_command_issue_async(AHCIQState *ahci, AHCICommand *cmd);
 605void ahci_command_wait(AHCIQState *ahci, AHCICommand *cmd);
 606void ahci_command_verify(AHCIQState *ahci, AHCICommand *cmd);
 607void ahci_command_free(AHCICommand *cmd);
 608
 609/* Command: adjustments */
 610void ahci_command_set_flags(AHCICommand *cmd, uint16_t cmdh_flags);
 611void ahci_command_clr_flags(AHCICommand *cmd, uint16_t cmdh_flags);
 612void ahci_command_set_offset(AHCICommand *cmd, uint64_t lba_sect);
 613void ahci_command_set_buffer(AHCICommand *cmd, uint64_t buffer);
 614void ahci_command_set_size(AHCICommand *cmd, uint64_t xbytes);
 615void ahci_command_set_prd_size(AHCICommand *cmd, unsigned prd_size);
 616void ahci_command_set_sizes(AHCICommand *cmd, uint64_t xbytes,
 617                            unsigned prd_size);
 618void ahci_command_set_acmd(AHCICommand *cmd, void *acmd);
 619void ahci_command_enable_atapi_dma(AHCICommand *cmd);
 620void ahci_command_adjust(AHCICommand *cmd, uint64_t lba_sect, uint64_t gbuffer,
 621                         uint64_t xbytes, unsigned prd_size);
 622
 623/* Command: Misc */
 624uint8_t ahci_command_slot(AHCICommand *cmd);
 625void ahci_write_fis(AHCIQState *ahci, AHCICommand *cmd);
 626
 627#endif
 628