Annotation of qemu/hw/ide/ahci.h, revision 1.1

1.1     ! root        1: /*
        !             2:  * QEMU AHCI Emulation
        !             3:  *
        !             4:  * Copyright (c) 2010 [email protected]
        !             5:  * Copyright (c) 2010 Roland Elek <[email protected]>
        !             6:  * Copyright (c) 2010 Sebastian Herbszt <[email protected]>
        !             7:  * Copyright (c) 2010 Alexander Graf <[email protected]>
        !             8:  *
        !             9:  * This library is free software; you can redistribute it and/or
        !            10:  * modify it under the terms of the GNU Lesser General Public
        !            11:  * License as published by the Free Software Foundation; either
        !            12:  * version 2 of the License, or (at your option) any later version.
        !            13:  *
        !            14:  * This library is distributed in the hope that it will be useful,
        !            15:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            16:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            17:  * Lesser General Public License for more details.
        !            18:  *
        !            19:  * You should have received a copy of the GNU Lesser General Public
        !            20:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
        !            21:  *
        !            22:  */
        !            23: 
        !            24: #ifndef HW_IDE_AHCI_H
        !            25: #define HW_IDE_AHCI_H
        !            26: 
        !            27: #define AHCI_PCI_BAR              5
        !            28: #define AHCI_MAX_PORTS            32
        !            29: #define AHCI_MAX_SG               168 /* hardware max is 64K */
        !            30: #define AHCI_DMA_BOUNDARY         0xffffffff
        !            31: #define AHCI_USE_CLUSTERING       0
        !            32: #define AHCI_MAX_CMDS             32
        !            33: #define AHCI_CMD_SZ               32
        !            34: #define AHCI_CMD_SLOT_SZ          (AHCI_MAX_CMDS * AHCI_CMD_SZ)
        !            35: #define AHCI_RX_FIS_SZ            256
        !            36: #define AHCI_CMD_TBL_CDB          0x40
        !            37: #define AHCI_CMD_TBL_HDR_SZ       0x80
        !            38: #define AHCI_CMD_TBL_SZ           (AHCI_CMD_TBL_HDR_SZ + (AHCI_MAX_SG * 16))
        !            39: #define AHCI_CMD_TBL_AR_SZ        (AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS)
        !            40: #define AHCI_PORT_PRIV_DMA_SZ     (AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + \
        !            41:                                    AHCI_RX_FIS_SZ)
        !            42: 
        !            43: #define AHCI_IRQ_ON_SG            (1 << 31)
        !            44: #define AHCI_CMD_ATAPI            (1 << 5)
        !            45: #define AHCI_CMD_WRITE            (1 << 6)
        !            46: #define AHCI_CMD_PREFETCH         (1 << 7)
        !            47: #define AHCI_CMD_RESET            (1 << 8)
        !            48: #define AHCI_CMD_CLR_BUSY         (1 << 10)
        !            49: 
        !            50: #define RX_FIS_D2H_REG            0x40 /* offset of D2H Register FIS data */
        !            51: #define RX_FIS_SDB                0x58 /* offset of SDB FIS data */
        !            52: #define RX_FIS_UNK                0x60 /* offset of Unknown FIS data */
        !            53: 
        !            54: /* global controller registers */
        !            55: #define HOST_CAP                  0x00 /* host capabilities */
        !            56: #define HOST_CTL                  0x04 /* global host control */
        !            57: #define HOST_IRQ_STAT             0x08 /* interrupt status */
        !            58: #define HOST_PORTS_IMPL           0x0c /* bitmap of implemented ports */
        !            59: #define HOST_VERSION              0x10 /* AHCI spec. version compliancy */
        !            60: 
        !            61: /* HOST_CTL bits */
        !            62: #define HOST_CTL_RESET            (1 << 0)  /* reset controller; self-clear */
        !            63: #define HOST_CTL_IRQ_EN           (1 << 1)  /* global IRQ enable */
        !            64: #define HOST_CTL_AHCI_EN          (1 << 31) /* AHCI enabled */
        !            65: 
        !            66: /* HOST_CAP bits */
        !            67: #define HOST_CAP_SSC              (1 << 14) /* Slumber capable */
        !            68: #define HOST_CAP_AHCI             (1 << 18) /* AHCI only */
        !            69: #define HOST_CAP_CLO              (1 << 24) /* Command List Override support */
        !            70: #define HOST_CAP_SSS              (1 << 27) /* Staggered Spin-up */
        !            71: #define HOST_CAP_NCQ              (1 << 30) /* Native Command Queueing */
        !            72: #define HOST_CAP_64               (1 << 31) /* PCI DAC (64-bit DMA) support */
        !            73: 
        !            74: /* registers for each SATA port */
        !            75: #define PORT_LST_ADDR             0x00 /* command list DMA addr */
        !            76: #define PORT_LST_ADDR_HI          0x04 /* command list DMA addr hi */
        !            77: #define PORT_FIS_ADDR             0x08 /* FIS rx buf addr */
        !            78: #define PORT_FIS_ADDR_HI          0x0c /* FIS rx buf addr hi */
        !            79: #define PORT_IRQ_STAT             0x10 /* interrupt status */
        !            80: #define PORT_IRQ_MASK             0x14 /* interrupt enable/disable mask */
        !            81: #define PORT_CMD                  0x18 /* port command */
        !            82: #define PORT_TFDATA               0x20 /* taskfile data */
        !            83: #define PORT_SIG                  0x24 /* device TF signature */
        !            84: #define PORT_SCR_STAT             0x28 /* SATA phy register: SStatus */
        !            85: #define PORT_SCR_CTL              0x2c /* SATA phy register: SControl */
        !            86: #define PORT_SCR_ERR              0x30 /* SATA phy register: SError */
        !            87: #define PORT_SCR_ACT              0x34 /* SATA phy register: SActive */
        !            88: #define PORT_CMD_ISSUE            0x38 /* command issue */
        !            89: #define PORT_RESERVED             0x3c /* reserved */
        !            90: 
        !            91: /* PORT_IRQ_{STAT,MASK} bits */
        !            92: #define PORT_IRQ_COLD_PRES        (1 << 31) /* cold presence detect */
        !            93: #define PORT_IRQ_TF_ERR           (1 << 30) /* task file error */
        !            94: #define PORT_IRQ_HBUS_ERR         (1 << 29) /* host bus fatal error */
        !            95: #define PORT_IRQ_HBUS_DATA_ERR    (1 << 28) /* host bus data error */
        !            96: #define PORT_IRQ_IF_ERR           (1 << 27) /* interface fatal error */
        !            97: #define PORT_IRQ_IF_NONFATAL      (1 << 26) /* interface non-fatal error */
        !            98: #define PORT_IRQ_OVERFLOW         (1 << 24) /* xfer exhausted available S/G */
        !            99: #define PORT_IRQ_BAD_PMP          (1 << 23) /* incorrect port multiplier */
        !           100: 
        !           101: #define PORT_IRQ_PHYRDY           (1 << 22) /* PhyRdy changed */
        !           102: #define PORT_IRQ_DEV_ILCK         (1 << 7) /* device interlock */
        !           103: #define PORT_IRQ_CONNECT          (1 << 6) /* port connect change status */
        !           104: #define PORT_IRQ_SG_DONE          (1 << 5) /* descriptor processed */
        !           105: #define PORT_IRQ_UNK_FIS          (1 << 4) /* unknown FIS rx'd */
        !           106: #define PORT_IRQ_SDB_FIS          (1 << 3) /* Set Device Bits FIS rx'd */
        !           107: #define PORT_IRQ_DMAS_FIS         (1 << 2) /* DMA Setup FIS rx'd */
        !           108: #define PORT_IRQ_PIOS_FIS         (1 << 1) /* PIO Setup FIS rx'd */
        !           109: #define PORT_IRQ_D2H_REG_FIS      (1 << 0) /* D2H Register FIS rx'd */
        !           110: 
        !           111: #define PORT_IRQ_FREEZE           (PORT_IRQ_HBUS_ERR | PORT_IRQ_IF_ERR |   \
        !           112:                                    PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY |    \
        !           113:                                    PORT_IRQ_UNK_FIS)
        !           114: #define PORT_IRQ_ERROR            (PORT_IRQ_FREEZE | PORT_IRQ_TF_ERR |     \
        !           115:                                    PORT_IRQ_HBUS_DATA_ERR)
        !           116: #define DEF_PORT_IRQ              (PORT_IRQ_ERROR | PORT_IRQ_SG_DONE |     \
        !           117:                                    PORT_IRQ_SDB_FIS | PORT_IRQ_DMAS_FIS |  \
        !           118:                                    PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS)
        !           119: 
        !           120: /* PORT_CMD bits */
        !           121: #define PORT_CMD_ATAPI            (1 << 24) /* Device is ATAPI */
        !           122: #define PORT_CMD_LIST_ON          (1 << 15) /* cmd list DMA engine running */
        !           123: #define PORT_CMD_FIS_ON           (1 << 14) /* FIS DMA engine running */
        !           124: #define PORT_CMD_FIS_RX           (1 << 4) /* Enable FIS receive DMA engine */
        !           125: #define PORT_CMD_CLO              (1 << 3) /* Command list override */
        !           126: #define PORT_CMD_POWER_ON         (1 << 2) /* Power up device */
        !           127: #define PORT_CMD_SPIN_UP          (1 << 1) /* Spin up device */
        !           128: #define PORT_CMD_START            (1 << 0) /* Enable port DMA engine */
        !           129: 
        !           130: #define PORT_CMD_ICC_MASK         (0xf << 28) /* i/f ICC state mask */
        !           131: #define PORT_CMD_ICC_ACTIVE       (0x1 << 28) /* Put i/f in active state */
        !           132: #define PORT_CMD_ICC_PARTIAL      (0x2 << 28) /* Put i/f in partial state */
        !           133: #define PORT_CMD_ICC_SLUMBER      (0x6 << 28) /* Put i/f in slumber state */
        !           134: 
        !           135: #define PORT_IRQ_STAT_DHRS        (1 << 0) /* Device to Host Register FIS */
        !           136: #define PORT_IRQ_STAT_PSS         (1 << 1) /* PIO Setup FIS */
        !           137: #define PORT_IRQ_STAT_DSS         (1 << 2) /* DMA Setup FIS */
        !           138: #define PORT_IRQ_STAT_SDBS        (1 << 3) /* Set Device Bits */
        !           139: #define PORT_IRQ_STAT_UFS         (1 << 4) /* Unknown FIS */
        !           140: #define PORT_IRQ_STAT_DPS         (1 << 5) /* Descriptor Processed */
        !           141: #define PORT_IRQ_STAT_PCS         (1 << 6) /* Port Connect Change Status */
        !           142: #define PORT_IRQ_STAT_DMPS        (1 << 7) /* Device Mechanical Presence
        !           143:                                               Status */
        !           144: #define PORT_IRQ_STAT_PRCS        (1 << 22) /* File Ready Status */
        !           145: #define PORT_IRQ_STAT_IPMS        (1 << 23) /* Incorrect Port Multiplier
        !           146:                                                Status */
        !           147: #define PORT_IRQ_STAT_OFS         (1 << 24) /* Overflow Status */
        !           148: #define PORT_IRQ_STAT_INFS        (1 << 26) /* Interface Non-Fatal Error
        !           149:                                                Status */
        !           150: #define PORT_IRQ_STAT_IFS         (1 << 27) /* Interface Fatal Error */
        !           151: #define PORT_IRQ_STAT_HBDS        (1 << 28) /* Host Bus Data Error Status */
        !           152: #define PORT_IRQ_STAT_HBFS        (1 << 29) /* Host Bus Fatal Error Status */
        !           153: #define PORT_IRQ_STAT_TFES        (1 << 30) /* Task File Error Status */
        !           154: #define PORT_IRQ_STAT_CPDS        (1 << 31) /* Code Port Detect Status */
        !           155: 
        !           156: /* ap->flags bits */
        !           157: #define AHCI_FLAG_NO_NCQ                  (1 << 24)
        !           158: #define AHCI_FLAG_IGN_IRQ_IF_ERR          (1 << 25) /* ignore IRQ_IF_ERR */
        !           159: #define AHCI_FLAG_HONOR_PI                (1 << 26) /* honor PORTS_IMPL */
        !           160: #define AHCI_FLAG_IGN_SERR_INTERNAL       (1 << 27) /* ignore SERR_INTERNAL */
        !           161: #define AHCI_FLAG_32BIT_ONLY              (1 << 28) /* force 32bit */
        !           162: 
        !           163: #define ATA_SRST                          (1 << 2)  /* software reset */
        !           164: 
        !           165: #define STATE_RUN                         0
        !           166: #define STATE_RESET                       1
        !           167: 
        !           168: #define SATA_SCR_SSTATUS_DET_NODEV        0x0
        !           169: #define SATA_SCR_SSTATUS_DET_DEV_PRESENT_PHY_UP 0x3
        !           170: 
        !           171: #define SATA_SCR_SSTATUS_SPD_NODEV        0x00
        !           172: #define SATA_SCR_SSTATUS_SPD_GEN1         0x10
        !           173: 
        !           174: #define SATA_SCR_SSTATUS_IPM_NODEV        0x000
        !           175: #define SATA_SCR_SSTATUS_IPM_ACTIVE       0X100
        !           176: 
        !           177: #define AHCI_SCR_SCTL_DET                 0xf
        !           178: 
        !           179: #define SATA_FIS_TYPE_REGISTER_H2D        0x27
        !           180: #define SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER 0x80
        !           181: 
        !           182: #define AHCI_CMD_HDR_CMD_FIS_LEN           0x1f
        !           183: #define AHCI_CMD_HDR_PRDT_LEN              16
        !           184: 
        !           185: #define SATA_SIGNATURE_CDROM               0xeb140000
        !           186: #define SATA_SIGNATURE_DISK                0x00000101
        !           187: 
        !           188: #define AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR 0x20
        !           189:                                             /* Shouldn't this be 0x2c? */
        !           190: 
        !           191: #define AHCI_PORT_REGS_START_ADDR          0x100
        !           192: #define AHCI_PORT_ADDR_OFFSET_MASK         0x7f
        !           193: #define AHCI_PORT_ADDR_OFFSET_LEN          0x80
        !           194: 
        !           195: #define AHCI_NUM_COMMAND_SLOTS             31
        !           196: #define AHCI_SUPPORTED_SPEED               20
        !           197: #define AHCI_SUPPORTED_SPEED_GEN1          1
        !           198: #define AHCI_VERSION_1_0                   0x10000
        !           199: 
        !           200: #define AHCI_PROGMODE_MAJOR_REV_1          1
        !           201: 
        !           202: #define AHCI_COMMAND_TABLE_ACMD            0x40
        !           203: 
        !           204: #define IDE_FEATURE_DMA                    1
        !           205: 
        !           206: #define READ_FPDMA_QUEUED                  0x60
        !           207: #define WRITE_FPDMA_QUEUED                 0x61
        !           208: 
        !           209: #define RES_FIS_DSFIS                      0x00
        !           210: #define RES_FIS_PSFIS                      0x20
        !           211: #define RES_FIS_RFIS                       0x40
        !           212: #define RES_FIS_SDBFIS                     0x58
        !           213: #define RES_FIS_UFIS                       0x60
        !           214: 
        !           215: typedef struct AHCIControlRegs {
        !           216:     uint32_t    cap;
        !           217:     uint32_t    ghc;
        !           218:     uint32_t    irqstatus;
        !           219:     uint32_t    impl;
        !           220:     uint32_t    version;
        !           221: } AHCIControlRegs;
        !           222: 
        !           223: typedef struct AHCIPortRegs {
        !           224:     uint32_t    lst_addr;
        !           225:     uint32_t    lst_addr_hi;
        !           226:     uint32_t    fis_addr;
        !           227:     uint32_t    fis_addr_hi;
        !           228:     uint32_t    irq_stat;
        !           229:     uint32_t    irq_mask;
        !           230:     uint32_t    cmd;
        !           231:     uint32_t    unused0;
        !           232:     uint32_t    tfdata;
        !           233:     uint32_t    sig;
        !           234:     uint32_t    scr_stat;
        !           235:     uint32_t    scr_ctl;
        !           236:     uint32_t    scr_err;
        !           237:     uint32_t    scr_act;
        !           238:     uint32_t    cmd_issue;
        !           239:     uint32_t    reserved;
        !           240: } AHCIPortRegs;
        !           241: 
        !           242: typedef struct AHCICmdHdr {
        !           243:     uint32_t    opts;
        !           244:     uint32_t    status;
        !           245:     uint64_t    tbl_addr;
        !           246:     uint32_t    reserved[4];
        !           247: } __attribute__ ((packed)) AHCICmdHdr;
        !           248: 
        !           249: typedef struct AHCI_SG {
        !           250:     uint64_t    addr;
        !           251:     uint32_t    reserved;
        !           252:     uint32_t    flags_size;
        !           253: } __attribute__ ((packed)) AHCI_SG;
        !           254: 
        !           255: typedef struct AHCIDevice AHCIDevice;
        !           256: 
        !           257: typedef struct NCQTransferState {
        !           258:     AHCIDevice *drive;
        !           259:     BlockDriverAIOCB *aiocb;
        !           260:     QEMUSGList sglist;
        !           261:     int is_read;
        !           262:     uint16_t sector_count;
        !           263:     uint64_t lba;
        !           264:     uint8_t tag;
        !           265:     int slot;
        !           266:     int used;
        !           267: } NCQTransferState;
        !           268: 
        !           269: struct AHCIDevice {
        !           270:     IDEDMA dma;
        !           271:     IDEBus port;
        !           272:     int port_no;
        !           273:     uint32_t port_state;
        !           274:     uint32_t finished;
        !           275:     AHCIPortRegs port_regs;
        !           276:     struct AHCIState *hba;
        !           277:     QEMUBH *check_bh;
        !           278:     uint8_t *lst;
        !           279:     uint8_t *res_fis;
        !           280:     int dma_status;
        !           281:     int done_atapi_packet;
        !           282:     int busy_slot;
        !           283:     int init_d2h_sent;
        !           284:     BlockDriverCompletionFunc *dma_cb;
        !           285:     AHCICmdHdr *cur_cmd;
        !           286:     NCQTransferState ncq_tfs[AHCI_MAX_CMDS];
        !           287: };
        !           288: 
        !           289: typedef struct AHCIState {
        !           290:     AHCIDevice *dev;
        !           291:     AHCIControlRegs control_regs;
        !           292:     int mem;
        !           293:     int ports;
        !           294:     qemu_irq irq;
        !           295: } AHCIState;
        !           296: 
        !           297: typedef struct AHCIPCIState {
        !           298:     PCIDevice card;
        !           299:     AHCIState ahci;
        !           300: } AHCIPCIState;
        !           301: 
        !           302: typedef struct NCQFrame {
        !           303:     uint8_t fis_type;
        !           304:     uint8_t c;
        !           305:     uint8_t command;
        !           306:     uint8_t sector_count_low;
        !           307:     uint8_t lba0;
        !           308:     uint8_t lba1;
        !           309:     uint8_t lba2;
        !           310:     uint8_t fua;
        !           311:     uint8_t lba3;
        !           312:     uint8_t lba4;
        !           313:     uint8_t lba5;
        !           314:     uint8_t sector_count_high;
        !           315:     uint8_t tag;
        !           316:     uint8_t reserved5;
        !           317:     uint8_t reserved6;
        !           318:     uint8_t control;
        !           319:     uint8_t reserved7;
        !           320:     uint8_t reserved8;
        !           321:     uint8_t reserved9;
        !           322:     uint8_t reserved10;
        !           323: } __attribute__ ((packed)) NCQFrame;
        !           324: 
        !           325: void ahci_init(AHCIState *s, DeviceState *qdev, int ports);
        !           326: void ahci_uninit(AHCIState *s);
        !           327: 
        !           328: void ahci_pci_map(PCIDevice *pci_dev, int region_num,
        !           329:         pcibus_t addr, pcibus_t size, int type);
        !           330: 
        !           331: void ahci_reset(void *opaque);
        !           332: 
        !           333: #endif /* HW_IDE_AHCI_H */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.