cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

ahci.h (22404B)


      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.h"
     29#include "pci.h"
     30#include "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