Annotation of qemu/hw/ide/ahci.c, revision 1.1.1.3

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: #include <hw/hw.h>
                     25: #include <hw/msi.h>
                     26: #include <hw/pc.h>
                     27: #include <hw/pci.h>
                     28: 
                     29: #include "monitor.h"
                     30: #include "dma.h"
                     31: #include "cpu-common.h"
                     32: #include "internal.h"
                     33: #include <hw/ide/pci.h>
                     34: #include <hw/ide/ahci.h>
                     35: 
                     36: /* #define DEBUG_AHCI */
                     37: 
                     38: #ifdef DEBUG_AHCI
                     39: #define DPRINTF(port, fmt, ...) \
                     40: do { fprintf(stderr, "ahci: %s: [%d] ", __FUNCTION__, port); \
                     41:      fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
                     42: #else
                     43: #define DPRINTF(port, fmt, ...) do {} while(0)
                     44: #endif
                     45: 
                     46: static void check_cmd(AHCIState *s, int port);
                     47: static int handle_cmd(AHCIState *s,int port,int slot);
                     48: static void ahci_reset_port(AHCIState *s, int port);
                     49: static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis);
                     50: static void ahci_init_d2h(AHCIDevice *ad);
                     51: 
                     52: static uint32_t  ahci_port_read(AHCIState *s, int port, int offset)
                     53: {
                     54:     uint32_t val;
                     55:     AHCIPortRegs *pr;
                     56:     pr = &s->dev[port].port_regs;
                     57: 
                     58:     switch (offset) {
                     59:     case PORT_LST_ADDR:
                     60:         val = pr->lst_addr;
                     61:         break;
                     62:     case PORT_LST_ADDR_HI:
                     63:         val = pr->lst_addr_hi;
                     64:         break;
                     65:     case PORT_FIS_ADDR:
                     66:         val = pr->fis_addr;
                     67:         break;
                     68:     case PORT_FIS_ADDR_HI:
                     69:         val = pr->fis_addr_hi;
                     70:         break;
                     71:     case PORT_IRQ_STAT:
                     72:         val = pr->irq_stat;
                     73:         break;
                     74:     case PORT_IRQ_MASK:
                     75:         val = pr->irq_mask;
                     76:         break;
                     77:     case PORT_CMD:
                     78:         val = pr->cmd;
                     79:         break;
                     80:     case PORT_TFDATA:
                     81:         val = ((uint16_t)s->dev[port].port.ifs[0].error << 8) |
                     82:               s->dev[port].port.ifs[0].status;
                     83:         break;
                     84:     case PORT_SIG:
                     85:         val = pr->sig;
                     86:         break;
                     87:     case PORT_SCR_STAT:
                     88:         if (s->dev[port].port.ifs[0].bs) {
                     89:             val = SATA_SCR_SSTATUS_DET_DEV_PRESENT_PHY_UP |
                     90:                   SATA_SCR_SSTATUS_SPD_GEN1 | SATA_SCR_SSTATUS_IPM_ACTIVE;
                     91:         } else {
                     92:             val = SATA_SCR_SSTATUS_DET_NODEV;
                     93:         }
                     94:         break;
                     95:     case PORT_SCR_CTL:
                     96:         val = pr->scr_ctl;
                     97:         break;
                     98:     case PORT_SCR_ERR:
                     99:         val = pr->scr_err;
                    100:         break;
                    101:     case PORT_SCR_ACT:
                    102:         pr->scr_act &= ~s->dev[port].finished;
                    103:         s->dev[port].finished = 0;
                    104:         val = pr->scr_act;
                    105:         break;
                    106:     case PORT_CMD_ISSUE:
                    107:         val = pr->cmd_issue;
                    108:         break;
                    109:     case PORT_RESERVED:
                    110:     default:
                    111:         val = 0;
                    112:     }
                    113:     DPRINTF(port, "offset: 0x%x val: 0x%x\n", offset, val);
                    114:     return val;
                    115: 
                    116: }
                    117: 
                    118: static void ahci_irq_raise(AHCIState *s, AHCIDevice *dev)
                    119: {
                    120:     struct AHCIPCIState *d = container_of(s, AHCIPCIState, ahci);
                    121: 
                    122:     DPRINTF(0, "raise irq\n");
                    123: 
                    124:     if (msi_enabled(&d->card)) {
                    125:         msi_notify(&d->card, 0);
                    126:     } else {
                    127:         qemu_irq_raise(s->irq);
                    128:     }
                    129: }
                    130: 
                    131: static void ahci_irq_lower(AHCIState *s, AHCIDevice *dev)
                    132: {
                    133:     struct AHCIPCIState *d = container_of(s, AHCIPCIState, ahci);
                    134: 
                    135:     DPRINTF(0, "lower irq\n");
                    136: 
                    137:     if (!msi_enabled(&d->card)) {
                    138:         qemu_irq_lower(s->irq);
                    139:     }
                    140: }
                    141: 
                    142: static void ahci_check_irq(AHCIState *s)
                    143: {
                    144:     int i;
                    145: 
                    146:     DPRINTF(-1, "check irq %#x\n", s->control_regs.irqstatus);
                    147: 
                    148:     for (i = 0; i < s->ports; i++) {
                    149:         AHCIPortRegs *pr = &s->dev[i].port_regs;
                    150:         if (pr->irq_stat & pr->irq_mask) {
                    151:             s->control_regs.irqstatus |= (1 << i);
                    152:         }
                    153:     }
                    154: 
                    155:     if (s->control_regs.irqstatus &&
                    156:         (s->control_regs.ghc & HOST_CTL_IRQ_EN)) {
                    157:             ahci_irq_raise(s, NULL);
                    158:     } else {
                    159:         ahci_irq_lower(s, NULL);
                    160:     }
                    161: }
                    162: 
                    163: static void ahci_trigger_irq(AHCIState *s, AHCIDevice *d,
                    164:                              int irq_type)
                    165: {
                    166:     DPRINTF(d->port_no, "trigger irq %#x -> %x\n",
                    167:             irq_type, d->port_regs.irq_mask & irq_type);
                    168: 
                    169:     d->port_regs.irq_stat |= irq_type;
                    170:     ahci_check_irq(s);
                    171: }
                    172: 
                    173: static void map_page(uint8_t **ptr, uint64_t addr, uint32_t wanted)
                    174: {
                    175:     target_phys_addr_t len = wanted;
                    176: 
                    177:     if (*ptr) {
                    178:         cpu_physical_memory_unmap(*ptr, len, 1, len);
                    179:     }
                    180: 
                    181:     *ptr = cpu_physical_memory_map(addr, &len, 1);
                    182:     if (len < wanted) {
                    183:         cpu_physical_memory_unmap(*ptr, len, 1, len);
                    184:         *ptr = NULL;
                    185:     }
                    186: }
                    187: 
                    188: static void  ahci_port_write(AHCIState *s, int port, int offset, uint32_t val)
                    189: {
                    190:     AHCIPortRegs *pr = &s->dev[port].port_regs;
                    191: 
                    192:     DPRINTF(port, "offset: 0x%x val: 0x%x\n", offset, val);
                    193:     switch (offset) {
                    194:         case PORT_LST_ADDR:
                    195:             pr->lst_addr = val;
                    196:             map_page(&s->dev[port].lst,
                    197:                      ((uint64_t)pr->lst_addr_hi << 32) | pr->lst_addr, 1024);
                    198:             s->dev[port].cur_cmd = NULL;
                    199:             break;
                    200:         case PORT_LST_ADDR_HI:
                    201:             pr->lst_addr_hi = val;
                    202:             map_page(&s->dev[port].lst,
                    203:                      ((uint64_t)pr->lst_addr_hi << 32) | pr->lst_addr, 1024);
                    204:             s->dev[port].cur_cmd = NULL;
                    205:             break;
                    206:         case PORT_FIS_ADDR:
                    207:             pr->fis_addr = val;
                    208:             map_page(&s->dev[port].res_fis,
                    209:                      ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256);
                    210:             break;
                    211:         case PORT_FIS_ADDR_HI:
                    212:             pr->fis_addr_hi = val;
                    213:             map_page(&s->dev[port].res_fis,
                    214:                      ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256);
                    215:             break;
                    216:         case PORT_IRQ_STAT:
                    217:             pr->irq_stat &= ~val;
                    218:             break;
                    219:         case PORT_IRQ_MASK:
                    220:             pr->irq_mask = val & 0xfdc000ff;
                    221:             ahci_check_irq(s);
                    222:             break;
                    223:         case PORT_CMD:
                    224:             pr->cmd = val & ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON);
                    225: 
                    226:             if (pr->cmd & PORT_CMD_START) {
                    227:                 pr->cmd |= PORT_CMD_LIST_ON;
                    228:             }
                    229: 
                    230:             if (pr->cmd & PORT_CMD_FIS_RX) {
                    231:                 pr->cmd |= PORT_CMD_FIS_ON;
                    232:             }
                    233: 
                    234:             /* XXX usually the FIS would be pending on the bus here and
                    235:                    issuing deferred until the OS enables FIS receival.
                    236:                    Instead, we only submit it once - which works in most
                    237:                    cases, but is a hack. */
                    238:             if ((pr->cmd & PORT_CMD_FIS_ON) &&
                    239:                 !s->dev[port].init_d2h_sent) {
                    240:                 ahci_init_d2h(&s->dev[port]);
                    241:                 s->dev[port].init_d2h_sent = 1;
                    242:             }
                    243: 
                    244:             check_cmd(s, port);
                    245:             break;
                    246:         case PORT_TFDATA:
                    247:             s->dev[port].port.ifs[0].error = (val >> 8) & 0xff;
                    248:             s->dev[port].port.ifs[0].status = val & 0xff;
                    249:             break;
                    250:         case PORT_SIG:
                    251:             pr->sig = val;
                    252:             break;
                    253:         case PORT_SCR_STAT:
                    254:             pr->scr_stat = val;
                    255:             break;
                    256:         case PORT_SCR_CTL:
                    257:             if (((pr->scr_ctl & AHCI_SCR_SCTL_DET) == 1) &&
                    258:                 ((val & AHCI_SCR_SCTL_DET) == 0)) {
                    259:                 ahci_reset_port(s, port);
                    260:             }
                    261:             pr->scr_ctl = val;
                    262:             break;
                    263:         case PORT_SCR_ERR:
                    264:             pr->scr_err &= ~val;
                    265:             break;
                    266:         case PORT_SCR_ACT:
                    267:             /* RW1 */
                    268:             pr->scr_act |= val;
                    269:             break;
                    270:         case PORT_CMD_ISSUE:
                    271:             pr->cmd_issue |= val;
                    272:             check_cmd(s, port);
                    273:             break;
                    274:         default:
                    275:             break;
                    276:     }
                    277: }
                    278: 
1.1.1.3 ! root      279: static uint64_t ahci_mem_read(void *opaque, target_phys_addr_t addr,
        !           280:                               unsigned size)
1.1       root      281: {
1.1.1.3 ! root      282:     AHCIState *s = opaque;
1.1       root      283:     uint32_t val = 0;
                    284: 
                    285:     if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
                    286:         switch (addr) {
                    287:         case HOST_CAP:
                    288:             val = s->control_regs.cap;
                    289:             break;
                    290:         case HOST_CTL:
                    291:             val = s->control_regs.ghc;
                    292:             break;
                    293:         case HOST_IRQ_STAT:
                    294:             val = s->control_regs.irqstatus;
                    295:             break;
                    296:         case HOST_PORTS_IMPL:
                    297:             val = s->control_regs.impl;
                    298:             break;
                    299:         case HOST_VERSION:
                    300:             val = s->control_regs.version;
                    301:             break;
                    302:         }
                    303: 
                    304:         DPRINTF(-1, "(addr 0x%08X), val 0x%08X\n", (unsigned) addr, val);
                    305:     } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
                    306:                (addr < (AHCI_PORT_REGS_START_ADDR +
                    307:                 (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) {
                    308:         val = ahci_port_read(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7,
                    309:                              addr & AHCI_PORT_ADDR_OFFSET_MASK);
                    310:     }
                    311: 
                    312:     return val;
                    313: }
                    314: 
                    315: 
                    316: 
1.1.1.3 ! root      317: static void ahci_mem_write(void *opaque, target_phys_addr_t addr,
        !           318:                            uint64_t val, unsigned size)
1.1       root      319: {
1.1.1.3 ! root      320:     AHCIState *s = opaque;
1.1       root      321: 
                    322:     /* Only aligned reads are allowed on AHCI */
                    323:     if (addr & 3) {
                    324:         fprintf(stderr, "ahci: Mis-aligned write to addr 0x"
                    325:                 TARGET_FMT_plx "\n", addr);
                    326:         return;
                    327:     }
                    328: 
                    329:     if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
1.1.1.3 ! root      330:         DPRINTF(-1, "(addr 0x%08X), val 0x%08"PRIX64"\n", (unsigned) addr, val);
1.1       root      331: 
                    332:         switch (addr) {
                    333:             case HOST_CAP: /* R/WO, RO */
                    334:                 /* FIXME handle R/WO */
                    335:                 break;
                    336:             case HOST_CTL: /* R/W */
                    337:                 if (val & HOST_CTL_RESET) {
                    338:                     DPRINTF(-1, "HBA Reset\n");
                    339:                     ahci_reset(container_of(s, AHCIPCIState, ahci));
                    340:                 } else {
                    341:                     s->control_regs.ghc = (val & 0x3) | HOST_CTL_AHCI_EN;
                    342:                     ahci_check_irq(s);
                    343:                 }
                    344:                 break;
                    345:             case HOST_IRQ_STAT: /* R/WC, RO */
                    346:                 s->control_regs.irqstatus &= ~val;
                    347:                 ahci_check_irq(s);
                    348:                 break;
                    349:             case HOST_PORTS_IMPL: /* R/WO, RO */
                    350:                 /* FIXME handle R/WO */
                    351:                 break;
                    352:             case HOST_VERSION: /* RO */
                    353:                 /* FIXME report write? */
                    354:                 break;
                    355:             default:
                    356:                 DPRINTF(-1, "write to unknown register 0x%x\n", (unsigned)addr);
                    357:         }
                    358:     } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
                    359:                (addr < (AHCI_PORT_REGS_START_ADDR +
                    360:                 (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) {
                    361:         ahci_port_write(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7,
                    362:                         addr & AHCI_PORT_ADDR_OFFSET_MASK, val);
                    363:     }
                    364: 
                    365: }
                    366: 
1.1.1.3 ! root      367: static MemoryRegionOps ahci_mem_ops = {
        !           368:     .read = ahci_mem_read,
        !           369:     .write = ahci_mem_write,
        !           370:     .endianness = DEVICE_LITTLE_ENDIAN,
1.1       root      371: };
                    372: 
1.1.1.3 ! root      373: static uint64_t ahci_idp_read(void *opaque, target_phys_addr_t addr,
        !           374:                               unsigned size)
        !           375: {
        !           376:     AHCIState *s = opaque;
        !           377: 
        !           378:     if (addr == s->idp_offset) {
        !           379:         /* index register */
        !           380:         return s->idp_index;
        !           381:     } else if (addr == s->idp_offset + 4) {
        !           382:         /* data register - do memory read at location selected by index */
        !           383:         return ahci_mem_read(opaque, s->idp_index, size);
        !           384:     } else {
        !           385:         return 0;
        !           386:     }
        !           387: }
        !           388: 
        !           389: static void ahci_idp_write(void *opaque, target_phys_addr_t addr,
        !           390:                            uint64_t val, unsigned size)
        !           391: {
        !           392:     AHCIState *s = opaque;
        !           393: 
        !           394:     if (addr == s->idp_offset) {
        !           395:         /* index register - mask off reserved bits */
        !           396:         s->idp_index = (uint32_t)val & ((AHCI_MEM_BAR_SIZE - 1) & ~3);
        !           397:     } else if (addr == s->idp_offset + 4) {
        !           398:         /* data register - do memory write at location selected by index */
        !           399:         ahci_mem_write(opaque, s->idp_index, val, size);
        !           400:     }
        !           401: }
        !           402: 
        !           403: static MemoryRegionOps ahci_idp_ops = {
        !           404:     .read = ahci_idp_read,
        !           405:     .write = ahci_idp_write,
        !           406:     .endianness = DEVICE_LITTLE_ENDIAN,
1.1       root      407: };
                    408: 
1.1.1.3 ! root      409: 
1.1       root      410: static void ahci_reg_init(AHCIState *s)
                    411: {
                    412:     int i;
                    413: 
                    414:     s->control_regs.cap = (s->ports - 1) |
                    415:                           (AHCI_NUM_COMMAND_SLOTS << 8) |
                    416:                           (AHCI_SUPPORTED_SPEED_GEN1 << AHCI_SUPPORTED_SPEED) |
                    417:                           HOST_CAP_NCQ | HOST_CAP_AHCI;
                    418: 
                    419:     s->control_regs.impl = (1 << s->ports) - 1;
                    420: 
                    421:     s->control_regs.version = AHCI_VERSION_1_0;
                    422: 
                    423:     for (i = 0; i < s->ports; i++) {
                    424:         s->dev[i].port_state = STATE_RUN;
                    425:     }
                    426: }
                    427: 
                    428: static uint32_t read_from_sglist(uint8_t *buffer, uint32_t len,
                    429:                                  QEMUSGList *sglist)
                    430: {
                    431:     uint32_t i = 0;
                    432:     uint32_t total = 0, once;
                    433:     ScatterGatherEntry *cur_prd;
                    434:     uint32_t sgcount;
                    435: 
                    436:     cur_prd = sglist->sg;
                    437:     sgcount = sglist->nsg;
                    438:     for (i = 0; len && sgcount; i++) {
                    439:         once = MIN(cur_prd->len, len);
                    440:         cpu_physical_memory_read(cur_prd->base, buffer, once);
                    441:         cur_prd++;
                    442:         sgcount--;
                    443:         len -= once;
                    444:         buffer += once;
                    445:         total += once;
                    446:     }
                    447: 
                    448:     return total;
                    449: }
                    450: 
                    451: static uint32_t write_to_sglist(uint8_t *buffer, uint32_t len,
                    452:                                 QEMUSGList *sglist)
                    453: {
                    454:     uint32_t i = 0;
                    455:     uint32_t total = 0, once;
                    456:     ScatterGatherEntry *cur_prd;
                    457:     uint32_t sgcount;
                    458: 
                    459:     DPRINTF(-1, "total: 0x%x bytes\n", len);
                    460: 
                    461:     cur_prd = sglist->sg;
                    462:     sgcount = sglist->nsg;
                    463:     for (i = 0; len && sgcount; i++) {
                    464:         once = MIN(cur_prd->len, len);
                    465:         DPRINTF(-1, "write 0x%x bytes to 0x%lx\n", once, (long)cur_prd->base);
                    466:         cpu_physical_memory_write(cur_prd->base, buffer, once);
                    467:         cur_prd++;
                    468:         sgcount--;
                    469:         len -= once;
                    470:         buffer += once;
                    471:         total += once;
                    472:     }
                    473: 
                    474:     return total;
                    475: }
                    476: 
                    477: static void check_cmd(AHCIState *s, int port)
                    478: {
                    479:     AHCIPortRegs *pr = &s->dev[port].port_regs;
                    480:     int slot;
                    481: 
                    482:     if ((pr->cmd & PORT_CMD_START) && pr->cmd_issue) {
                    483:         for (slot = 0; (slot < 32) && pr->cmd_issue; slot++) {
                    484:             if ((pr->cmd_issue & (1 << slot)) &&
                    485:                 !handle_cmd(s, port, slot)) {
                    486:                 pr->cmd_issue &= ~(1 << slot);
                    487:             }
                    488:         }
                    489:     }
                    490: }
                    491: 
                    492: static void ahci_check_cmd_bh(void *opaque)
                    493: {
                    494:     AHCIDevice *ad = opaque;
                    495: 
                    496:     qemu_bh_delete(ad->check_bh);
                    497:     ad->check_bh = NULL;
                    498: 
                    499:     if ((ad->busy_slot != -1) &&
                    500:         !(ad->port.ifs[0].status & (BUSY_STAT|DRQ_STAT))) {
                    501:         /* no longer busy */
                    502:         ad->port_regs.cmd_issue &= ~(1 << ad->busy_slot);
                    503:         ad->busy_slot = -1;
                    504:     }
                    505: 
                    506:     check_cmd(ad->hba, ad->port_no);
                    507: }
                    508: 
                    509: static void ahci_init_d2h(AHCIDevice *ad)
                    510: {
                    511:     uint8_t init_fis[0x20];
                    512:     IDEState *ide_state = &ad->port.ifs[0];
                    513: 
                    514:     memset(init_fis, 0, sizeof(init_fis));
                    515: 
                    516:     init_fis[4] = 1;
                    517:     init_fis[12] = 1;
                    518: 
                    519:     if (ide_state->drive_kind == IDE_CD) {
                    520:         init_fis[5] = ide_state->lcyl;
                    521:         init_fis[6] = ide_state->hcyl;
                    522:     }
                    523: 
                    524:     ahci_write_fis_d2h(ad, init_fis);
                    525: }
                    526: 
                    527: static void ahci_reset_port(AHCIState *s, int port)
                    528: {
                    529:     AHCIDevice *d = &s->dev[port];
                    530:     AHCIPortRegs *pr = &d->port_regs;
                    531:     IDEState *ide_state = &d->port.ifs[0];
                    532:     int i;
                    533: 
                    534:     DPRINTF(port, "reset port\n");
                    535: 
                    536:     ide_bus_reset(&d->port);
                    537:     ide_state->ncq_queues = AHCI_MAX_CMDS;
                    538: 
                    539:     pr->scr_stat = 0;
                    540:     pr->scr_err = 0;
                    541:     pr->scr_act = 0;
                    542:     d->busy_slot = -1;
                    543:     d->init_d2h_sent = 0;
                    544: 
                    545:     ide_state = &s->dev[port].port.ifs[0];
                    546:     if (!ide_state->bs) {
                    547:         return;
                    548:     }
                    549: 
                    550:     /* reset ncq queue */
                    551:     for (i = 0; i < AHCI_MAX_CMDS; i++) {
                    552:         NCQTransferState *ncq_tfs = &s->dev[port].ncq_tfs[i];
                    553:         if (!ncq_tfs->used) {
                    554:             continue;
                    555:         }
                    556: 
                    557:         if (ncq_tfs->aiocb) {
                    558:             bdrv_aio_cancel(ncq_tfs->aiocb);
                    559:             ncq_tfs->aiocb = NULL;
                    560:         }
                    561: 
                    562:         qemu_sglist_destroy(&ncq_tfs->sglist);
                    563:         ncq_tfs->used = 0;
                    564:     }
                    565: 
                    566:     s->dev[port].port_state = STATE_RUN;
                    567:     if (!ide_state->bs) {
                    568:         s->dev[port].port_regs.sig = 0;
                    569:         ide_state->status = SEEK_STAT | WRERR_STAT;
                    570:     } else if (ide_state->drive_kind == IDE_CD) {
                    571:         s->dev[port].port_regs.sig = SATA_SIGNATURE_CDROM;
                    572:         ide_state->lcyl = 0x14;
                    573:         ide_state->hcyl = 0xeb;
                    574:         DPRINTF(port, "set lcyl = %d\n", ide_state->lcyl);
                    575:         ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT;
                    576:     } else {
                    577:         s->dev[port].port_regs.sig = SATA_SIGNATURE_DISK;
                    578:         ide_state->status = SEEK_STAT | WRERR_STAT;
                    579:     }
                    580: 
                    581:     ide_state->error = 1;
                    582:     ahci_init_d2h(d);
                    583: }
                    584: 
                    585: static void debug_print_fis(uint8_t *fis, int cmd_len)
                    586: {
                    587: #ifdef DEBUG_AHCI
                    588:     int i;
                    589: 
                    590:     fprintf(stderr, "fis:");
                    591:     for (i = 0; i < cmd_len; i++) {
                    592:         if ((i & 0xf) == 0) {
                    593:             fprintf(stderr, "\n%02x:",i);
                    594:         }
                    595:         fprintf(stderr, "%02x ",fis[i]);
                    596:     }
                    597:     fprintf(stderr, "\n");
                    598: #endif
                    599: }
                    600: 
                    601: static void ahci_write_fis_sdb(AHCIState *s, int port, uint32_t finished)
                    602: {
                    603:     AHCIPortRegs *pr = &s->dev[port].port_regs;
                    604:     IDEState *ide_state;
                    605:     uint8_t *sdb_fis;
                    606: 
                    607:     if (!s->dev[port].res_fis ||
                    608:         !(pr->cmd & PORT_CMD_FIS_RX)) {
                    609:         return;
                    610:     }
                    611: 
                    612:     sdb_fis = &s->dev[port].res_fis[RES_FIS_SDBFIS];
                    613:     ide_state = &s->dev[port].port.ifs[0];
                    614: 
                    615:     /* clear memory */
                    616:     *(uint32_t*)sdb_fis = 0;
                    617: 
                    618:     /* write values */
                    619:     sdb_fis[0] = ide_state->error;
                    620:     sdb_fis[2] = ide_state->status & 0x77;
                    621:     s->dev[port].finished |= finished;
                    622:     *(uint32_t*)(sdb_fis + 4) = cpu_to_le32(s->dev[port].finished);
                    623: 
                    624:     ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_STAT_SDBS);
                    625: }
                    626: 
                    627: static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis)
                    628: {
                    629:     AHCIPortRegs *pr = &ad->port_regs;
                    630:     uint8_t *d2h_fis;
                    631:     int i;
                    632:     target_phys_addr_t cmd_len = 0x80;
                    633:     int cmd_mapped = 0;
                    634: 
                    635:     if (!ad->res_fis || !(pr->cmd & PORT_CMD_FIS_RX)) {
                    636:         return;
                    637:     }
                    638: 
                    639:     if (!cmd_fis) {
                    640:         /* map cmd_fis */
                    641:         uint64_t tbl_addr = le64_to_cpu(ad->cur_cmd->tbl_addr);
                    642:         cmd_fis = cpu_physical_memory_map(tbl_addr, &cmd_len, 0);
                    643:         cmd_mapped = 1;
                    644:     }
                    645: 
                    646:     d2h_fis = &ad->res_fis[RES_FIS_RFIS];
                    647: 
                    648:     d2h_fis[0] = 0x34;
                    649:     d2h_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
                    650:     d2h_fis[2] = ad->port.ifs[0].status;
                    651:     d2h_fis[3] = ad->port.ifs[0].error;
                    652: 
                    653:     d2h_fis[4] = cmd_fis[4];
                    654:     d2h_fis[5] = cmd_fis[5];
                    655:     d2h_fis[6] = cmd_fis[6];
                    656:     d2h_fis[7] = cmd_fis[7];
                    657:     d2h_fis[8] = cmd_fis[8];
                    658:     d2h_fis[9] = cmd_fis[9];
                    659:     d2h_fis[10] = cmd_fis[10];
                    660:     d2h_fis[11] = cmd_fis[11];
                    661:     d2h_fis[12] = cmd_fis[12];
                    662:     d2h_fis[13] = cmd_fis[13];
                    663:     for (i = 14; i < 0x20; i++) {
                    664:         d2h_fis[i] = 0;
                    665:     }
                    666: 
                    667:     if (d2h_fis[2] & ERR_STAT) {
                    668:         ahci_trigger_irq(ad->hba, ad, PORT_IRQ_STAT_TFES);
                    669:     }
                    670: 
                    671:     ahci_trigger_irq(ad->hba, ad, PORT_IRQ_D2H_REG_FIS);
                    672: 
                    673:     if (cmd_mapped) {
                    674:         cpu_physical_memory_unmap(cmd_fis, cmd_len, 0, cmd_len);
                    675:     }
                    676: }
                    677: 
                    678: static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist)
                    679: {
                    680:     AHCICmdHdr *cmd = ad->cur_cmd;
                    681:     uint32_t opts = le32_to_cpu(cmd->opts);
                    682:     uint64_t prdt_addr = le64_to_cpu(cmd->tbl_addr) + 0x80;
                    683:     int sglist_alloc_hint = opts >> AHCI_CMD_HDR_PRDT_LEN;
                    684:     target_phys_addr_t prdt_len = (sglist_alloc_hint * sizeof(AHCI_SG));
                    685:     target_phys_addr_t real_prdt_len = prdt_len;
                    686:     uint8_t *prdt;
                    687:     int i;
                    688:     int r = 0;
                    689: 
                    690:     if (!sglist_alloc_hint) {
                    691:         DPRINTF(ad->port_no, "no sg list given by guest: 0x%08x\n", opts);
                    692:         return -1;
                    693:     }
                    694: 
                    695:     /* map PRDT */
                    696:     if (!(prdt = cpu_physical_memory_map(prdt_addr, &prdt_len, 0))){
                    697:         DPRINTF(ad->port_no, "map failed\n");
                    698:         return -1;
                    699:     }
                    700: 
                    701:     if (prdt_len < real_prdt_len) {
                    702:         DPRINTF(ad->port_no, "mapped less than expected\n");
                    703:         r = -1;
                    704:         goto out;
                    705:     }
                    706: 
                    707:     /* Get entries in the PRDT, init a qemu sglist accordingly */
                    708:     if (sglist_alloc_hint > 0) {
                    709:         AHCI_SG *tbl = (AHCI_SG *)prdt;
                    710: 
                    711:         qemu_sglist_init(sglist, sglist_alloc_hint);
                    712:         for (i = 0; i < sglist_alloc_hint; i++) {
                    713:             /* flags_size is zero-based */
                    714:             qemu_sglist_add(sglist, le64_to_cpu(tbl[i].addr),
                    715:                             le32_to_cpu(tbl[i].flags_size) + 1);
                    716:         }
                    717:     }
                    718: 
                    719: out:
                    720:     cpu_physical_memory_unmap(prdt, prdt_len, 0, prdt_len);
                    721:     return r;
                    722: }
                    723: 
                    724: static void ncq_cb(void *opaque, int ret)
                    725: {
                    726:     NCQTransferState *ncq_tfs = (NCQTransferState *)opaque;
                    727:     IDEState *ide_state = &ncq_tfs->drive->port.ifs[0];
                    728: 
                    729:     /* Clear bit for this tag in SActive */
                    730:     ncq_tfs->drive->port_regs.scr_act &= ~(1 << ncq_tfs->tag);
                    731: 
                    732:     if (ret < 0) {
                    733:         /* error */
                    734:         ide_state->error = ABRT_ERR;
                    735:         ide_state->status = READY_STAT | ERR_STAT;
                    736:         ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag);
                    737:     } else {
                    738:         ide_state->status = READY_STAT | SEEK_STAT;
                    739:     }
                    740: 
                    741:     ahci_write_fis_sdb(ncq_tfs->drive->hba, ncq_tfs->drive->port_no,
                    742:                        (1 << ncq_tfs->tag));
                    743: 
                    744:     DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n",
                    745:             ncq_tfs->tag);
                    746: 
1.1.1.3 ! root      747:     bdrv_acct_done(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct);
1.1       root      748:     qemu_sglist_destroy(&ncq_tfs->sglist);
                    749:     ncq_tfs->used = 0;
                    750: }
                    751: 
                    752: static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
                    753:                                 int slot)
                    754: {
                    755:     NCQFrame *ncq_fis = (NCQFrame*)cmd_fis;
                    756:     uint8_t tag = ncq_fis->tag >> 3;
                    757:     NCQTransferState *ncq_tfs = &s->dev[port].ncq_tfs[tag];
                    758: 
                    759:     if (ncq_tfs->used) {
                    760:         /* error - already in use */
                    761:         fprintf(stderr, "%s: tag %d already used\n", __FUNCTION__, tag);
                    762:         return;
                    763:     }
                    764: 
                    765:     ncq_tfs->used = 1;
                    766:     ncq_tfs->drive = &s->dev[port];
                    767:     ncq_tfs->slot = slot;
                    768:     ncq_tfs->lba = ((uint64_t)ncq_fis->lba5 << 40) |
                    769:                    ((uint64_t)ncq_fis->lba4 << 32) |
                    770:                    ((uint64_t)ncq_fis->lba3 << 24) |
                    771:                    ((uint64_t)ncq_fis->lba2 << 16) |
                    772:                    ((uint64_t)ncq_fis->lba1 << 8) |
                    773:                    (uint64_t)ncq_fis->lba0;
                    774: 
                    775:     /* Note: We calculate the sector count, but don't currently rely on it.
                    776:      * The total size of the DMA buffer tells us the transfer size instead. */
                    777:     ncq_tfs->sector_count = ((uint16_t)ncq_fis->sector_count_high << 8) |
                    778:                                 ncq_fis->sector_count_low;
                    779: 
1.1.1.3 ! root      780:     DPRINTF(port, "NCQ transfer LBA from %"PRId64" to %"PRId64", "
        !           781:             "drive max %"PRId64"\n",
1.1       root      782:             ncq_tfs->lba, ncq_tfs->lba + ncq_tfs->sector_count - 2,
                    783:             s->dev[port].port.ifs[0].nb_sectors - 1);
                    784: 
                    785:     ahci_populate_sglist(&s->dev[port], &ncq_tfs->sglist);
                    786:     ncq_tfs->tag = tag;
                    787: 
                    788:     switch(ncq_fis->command) {
                    789:         case READ_FPDMA_QUEUED:
1.1.1.3 ! root      790:             DPRINTF(port, "NCQ reading %d sectors from LBA %"PRId64", "
        !           791:                     "tag %d\n",
1.1       root      792:                     ncq_tfs->sector_count-1, ncq_tfs->lba, ncq_tfs->tag);
                    793: 
1.1.1.3 ! root      794:             DPRINTF(port, "tag %d aio read %"PRId64"\n",
        !           795:                     ncq_tfs->tag, ncq_tfs->lba);
        !           796: 
        !           797:             bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
        !           798:                             (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
        !           799:                             BDRV_ACCT_READ);
1.1       root      800:             ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs,
                    801:                                            &ncq_tfs->sglist, ncq_tfs->lba,
                    802:                                            ncq_cb, ncq_tfs);
                    803:             break;
                    804:         case WRITE_FPDMA_QUEUED:
1.1.1.3 ! root      805:             DPRINTF(port, "NCQ writing %d sectors to LBA %"PRId64", tag %d\n",
1.1       root      806:                     ncq_tfs->sector_count-1, ncq_tfs->lba, ncq_tfs->tag);
                    807: 
1.1.1.3 ! root      808:             DPRINTF(port, "tag %d aio write %"PRId64"\n",
        !           809:                     ncq_tfs->tag, ncq_tfs->lba);
        !           810: 
        !           811:             bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
        !           812:                             (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
        !           813:                             BDRV_ACCT_WRITE);
1.1       root      814:             ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs,
                    815:                                             &ncq_tfs->sglist, ncq_tfs->lba,
                    816:                                             ncq_cb, ncq_tfs);
                    817:             break;
                    818:         default:
                    819:             DPRINTF(port, "error: tried to process non-NCQ command as NCQ\n");
                    820:             qemu_sglist_destroy(&ncq_tfs->sglist);
                    821:             break;
                    822:     }
                    823: }
                    824: 
                    825: static int handle_cmd(AHCIState *s, int port, int slot)
                    826: {
                    827:     IDEState *ide_state;
                    828:     uint32_t opts;
                    829:     uint64_t tbl_addr;
                    830:     AHCICmdHdr *cmd;
                    831:     uint8_t *cmd_fis;
                    832:     target_phys_addr_t cmd_len;
                    833: 
                    834:     if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
                    835:         /* Engine currently busy, try again later */
                    836:         DPRINTF(port, "engine busy\n");
                    837:         return -1;
                    838:     }
                    839: 
                    840:     cmd = &((AHCICmdHdr *)s->dev[port].lst)[slot];
                    841: 
                    842:     if (!s->dev[port].lst) {
                    843:         DPRINTF(port, "error: lst not given but cmd handled");
                    844:         return -1;
                    845:     }
                    846: 
                    847:     /* remember current slot handle for later */
                    848:     s->dev[port].cur_cmd = cmd;
                    849: 
                    850:     opts = le32_to_cpu(cmd->opts);
                    851:     tbl_addr = le64_to_cpu(cmd->tbl_addr);
                    852: 
                    853:     cmd_len = 0x80;
                    854:     cmd_fis = cpu_physical_memory_map(tbl_addr, &cmd_len, 1);
                    855: 
                    856:     if (!cmd_fis) {
                    857:         DPRINTF(port, "error: guest passed us an invalid cmd fis\n");
                    858:         return -1;
                    859:     }
                    860: 
                    861:     /* The device we are working for */
                    862:     ide_state = &s->dev[port].port.ifs[0];
                    863: 
                    864:     if (!ide_state->bs) {
                    865:         DPRINTF(port, "error: guest accessed unused port");
                    866:         goto out;
                    867:     }
                    868: 
                    869:     debug_print_fis(cmd_fis, 0x90);
                    870:     //debug_print_fis(cmd_fis, (opts & AHCI_CMD_HDR_CMD_FIS_LEN) * 4);
                    871: 
                    872:     switch (cmd_fis[0]) {
                    873:         case SATA_FIS_TYPE_REGISTER_H2D:
                    874:             break;
                    875:         default:
                    876:             DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
                    877:                           "cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
                    878:                           cmd_fis[2]);
                    879:             goto out;
                    880:             break;
                    881:     }
                    882: 
                    883:     switch (cmd_fis[1]) {
                    884:         case SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER:
                    885:             break;
                    886:         case 0:
                    887:             break;
                    888:         default:
                    889:             DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
                    890:                           "cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
                    891:                           cmd_fis[2]);
                    892:             goto out;
                    893:             break;
                    894:     }
                    895: 
                    896:     switch (s->dev[port].port_state) {
                    897:         case STATE_RUN:
                    898:             if (cmd_fis[15] & ATA_SRST) {
                    899:                 s->dev[port].port_state = STATE_RESET;
                    900:             }
                    901:             break;
                    902:         case STATE_RESET:
                    903:             if (!(cmd_fis[15] & ATA_SRST)) {
                    904:                 ahci_reset_port(s, port);
                    905:             }
                    906:             break;
                    907:     }
                    908: 
                    909:     if (cmd_fis[1] == SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER) {
                    910: 
                    911:         /* Check for NCQ command */
                    912:         if ((cmd_fis[2] == READ_FPDMA_QUEUED) ||
                    913:             (cmd_fis[2] == WRITE_FPDMA_QUEUED)) {
                    914:             process_ncq_command(s, port, cmd_fis, slot);
                    915:             goto out;
                    916:         }
                    917: 
                    918:         /* Decompose the FIS  */
                    919:         ide_state->nsector = (int64_t)((cmd_fis[13] << 8) | cmd_fis[12]);
                    920:         ide_state->feature = cmd_fis[3];
                    921:         if (!ide_state->nsector) {
                    922:             ide_state->nsector = 256;
                    923:         }
                    924: 
                    925:         if (ide_state->drive_kind != IDE_CD) {
1.1.1.2   root      926:             /*
                    927:              * We set the sector depending on the sector defined in the FIS.
                    928:              * Unfortunately, the spec isn't exactly obvious on this one.
                    929:              *
                    930:              * Apparently LBA48 commands set fis bytes 10,9,8,6,5,4 to the
                    931:              * 48 bit sector number. ATA_CMD_READ_DMA_EXT is an example for
                    932:              * such a command.
                    933:              *
                    934:              * Non-LBA48 commands however use 7[lower 4 bits],6,5,4 to define a
                    935:              * 28-bit sector number. ATA_CMD_READ_DMA is an example for such
                    936:              * a command.
                    937:              *
                    938:              * Since the spec doesn't explicitly state what each field should
                    939:              * do, I simply assume non-used fields as reserved and OR everything
                    940:              * together, independent of the command.
                    941:              */
                    942:             ide_set_sector(ide_state, ((uint64_t)cmd_fis[10] << 40)
                    943:                                     | ((uint64_t)cmd_fis[9] << 32)
                    944:                                     /* This is used for LBA48 commands */
                    945:                                     | ((uint64_t)cmd_fis[8] << 24)
                    946:                                     /* This is used for non-LBA48 commands */
                    947:                                     | ((uint64_t)(cmd_fis[7] & 0xf) << 24)
                    948:                                     | ((uint64_t)cmd_fis[6] << 16)
                    949:                                     | ((uint64_t)cmd_fis[5] << 8)
                    950:                                     | cmd_fis[4]);
1.1       root      951:         }
                    952: 
                    953:         /* Copy the ACMD field (ATAPI packet, if any) from the AHCI command
                    954:          * table to ide_state->io_buffer
                    955:          */
                    956:         if (opts & AHCI_CMD_ATAPI) {
                    957:             memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10);
                    958:             ide_state->lcyl = 0x14;
                    959:             ide_state->hcyl = 0xeb;
                    960:             debug_print_fis(ide_state->io_buffer, 0x10);
                    961:             ide_state->feature = IDE_FEATURE_DMA;
                    962:             s->dev[port].done_atapi_packet = 0;
                    963:             /* XXX send PIO setup FIS */
                    964:         }
                    965: 
                    966:         ide_state->error = 0;
                    967: 
                    968:         /* Reset transferred byte counter */
                    969:         cmd->status = 0;
                    970: 
                    971:         /* We're ready to process the command in FIS byte 2. */
                    972:         ide_exec_cmd(&s->dev[port].port, cmd_fis[2]);
                    973: 
                    974:         if (s->dev[port].port.ifs[0].status & READY_STAT) {
                    975:             ahci_write_fis_d2h(&s->dev[port], cmd_fis);
                    976:         }
                    977:     }
                    978: 
                    979: out:
                    980:     cpu_physical_memory_unmap(cmd_fis, cmd_len, 1, cmd_len);
                    981: 
                    982:     if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
                    983:         /* async command, complete later */
                    984:         s->dev[port].busy_slot = slot;
                    985:         return -1;
                    986:     }
                    987: 
                    988:     /* done handling the command */
                    989:     return 0;
                    990: }
                    991: 
                    992: /* DMA dev <-> ram */
                    993: static int ahci_start_transfer(IDEDMA *dma)
                    994: {
                    995:     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
                    996:     IDEState *s = &ad->port.ifs[0];
                    997:     uint32_t size = (uint32_t)(s->data_end - s->data_ptr);
                    998:     /* write == ram -> device */
                    999:     uint32_t opts = le32_to_cpu(ad->cur_cmd->opts);
                   1000:     int is_write = opts & AHCI_CMD_WRITE;
                   1001:     int is_atapi = opts & AHCI_CMD_ATAPI;
                   1002:     int has_sglist = 0;
                   1003: 
                   1004:     if (is_atapi && !ad->done_atapi_packet) {
                   1005:         /* already prepopulated iobuffer */
                   1006:         ad->done_atapi_packet = 1;
                   1007:         goto out;
                   1008:     }
                   1009: 
                   1010:     if (!ahci_populate_sglist(ad, &s->sg)) {
                   1011:         has_sglist = 1;
                   1012:     }
                   1013: 
                   1014:     DPRINTF(ad->port_no, "%sing %d bytes on %s w/%s sglist\n",
                   1015:             is_write ? "writ" : "read", size, is_atapi ? "atapi" : "ata",
                   1016:             has_sglist ? "" : "o");
                   1017: 
                   1018:     if (is_write && has_sglist && (s->data_ptr < s->data_end)) {
                   1019:         read_from_sglist(s->data_ptr, size, &s->sg);
                   1020:     }
                   1021: 
                   1022:     if (!is_write && has_sglist && (s->data_ptr < s->data_end)) {
                   1023:         write_to_sglist(s->data_ptr, size, &s->sg);
                   1024:     }
                   1025: 
                   1026:     /* update number of transferred bytes */
                   1027:     ad->cur_cmd->status = cpu_to_le32(le32_to_cpu(ad->cur_cmd->status) + size);
                   1028: 
                   1029: out:
                   1030:     /* declare that we processed everything */
                   1031:     s->data_ptr = s->data_end;
                   1032: 
                   1033:     if (has_sglist) {
                   1034:         qemu_sglist_destroy(&s->sg);
                   1035:     }
                   1036: 
                   1037:     s->end_transfer_func(s);
                   1038: 
                   1039:     if (!(s->status & DRQ_STAT)) {
                   1040:         /* done with DMA */
                   1041:         ahci_trigger_irq(ad->hba, ad, PORT_IRQ_STAT_DSS);
                   1042:     }
                   1043: 
                   1044:     return 0;
                   1045: }
                   1046: 
                   1047: static void ahci_start_dma(IDEDMA *dma, IDEState *s,
                   1048:                            BlockDriverCompletionFunc *dma_cb)
                   1049: {
                   1050:     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
                   1051: 
                   1052:     DPRINTF(ad->port_no, "\n");
                   1053:     ad->dma_cb = dma_cb;
                   1054:     ad->dma_status |= BM_STATUS_DMAING;
                   1055:     dma_cb(s, 0);
                   1056: }
                   1057: 
                   1058: static int ahci_dma_prepare_buf(IDEDMA *dma, int is_write)
                   1059: {
                   1060:     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
                   1061:     IDEState *s = &ad->port.ifs[0];
                   1062:     int i;
                   1063: 
                   1064:     ahci_populate_sglist(ad, &s->sg);
                   1065: 
                   1066:     s->io_buffer_size = 0;
                   1067:     for (i = 0; i < s->sg.nsg; i++) {
                   1068:         s->io_buffer_size += s->sg.sg[i].len;
                   1069:     }
                   1070: 
                   1071:     DPRINTF(ad->port_no, "len=%#x\n", s->io_buffer_size);
                   1072:     return s->io_buffer_size != 0;
                   1073: }
                   1074: 
                   1075: static int ahci_dma_rw_buf(IDEDMA *dma, int is_write)
                   1076: {
                   1077:     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
                   1078:     IDEState *s = &ad->port.ifs[0];
                   1079:     uint8_t *p = s->io_buffer + s->io_buffer_index;
                   1080:     int l = s->io_buffer_size - s->io_buffer_index;
                   1081: 
                   1082:     if (ahci_populate_sglist(ad, &s->sg)) {
                   1083:         return 0;
                   1084:     }
                   1085: 
                   1086:     if (is_write) {
                   1087:         write_to_sglist(p, l, &s->sg);
                   1088:     } else {
                   1089:         read_from_sglist(p, l, &s->sg);
                   1090:     }
                   1091: 
                   1092:     /* update number of transferred bytes */
                   1093:     ad->cur_cmd->status = cpu_to_le32(le32_to_cpu(ad->cur_cmd->status) + l);
                   1094:     s->io_buffer_index += l;
                   1095: 
                   1096:     DPRINTF(ad->port_no, "len=%#x\n", l);
                   1097: 
                   1098:     return 1;
                   1099: }
                   1100: 
                   1101: static int ahci_dma_set_unit(IDEDMA *dma, int unit)
                   1102: {
                   1103:     /* only a single unit per link */
                   1104:     return 0;
                   1105: }
                   1106: 
                   1107: static int ahci_dma_add_status(IDEDMA *dma, int status)
                   1108: {
                   1109:     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
                   1110:     ad->dma_status |= status;
                   1111:     DPRINTF(ad->port_no, "set status: %x\n", status);
                   1112: 
                   1113:     if (status & BM_STATUS_INT) {
                   1114:         ahci_trigger_irq(ad->hba, ad, PORT_IRQ_STAT_DSS);
                   1115:     }
                   1116: 
                   1117:     return 0;
                   1118: }
                   1119: 
                   1120: static int ahci_dma_set_inactive(IDEDMA *dma)
                   1121: {
                   1122:     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
                   1123: 
                   1124:     DPRINTF(ad->port_no, "dma done\n");
                   1125: 
                   1126:     /* update d2h status */
                   1127:     ahci_write_fis_d2h(ad, NULL);
                   1128: 
                   1129:     ad->dma_cb = NULL;
                   1130: 
1.1.1.2   root     1131:     if (!ad->check_bh) {
                   1132:         /* maybe we still have something to process, check later */
                   1133:         ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
                   1134:         qemu_bh_schedule(ad->check_bh);
                   1135:     }
1.1       root     1136: 
                   1137:     return 0;
                   1138: }
                   1139: 
                   1140: static void ahci_irq_set(void *opaque, int n, int level)
                   1141: {
                   1142: }
                   1143: 
1.1.1.3 ! root     1144: static void ahci_dma_restart_cb(void *opaque, int running, RunState state)
1.1       root     1145: {
                   1146: }
                   1147: 
                   1148: static int ahci_dma_reset(IDEDMA *dma)
                   1149: {
                   1150:     return 0;
                   1151: }
                   1152: 
                   1153: static const IDEDMAOps ahci_dma_ops = {
                   1154:     .start_dma = ahci_start_dma,
                   1155:     .start_transfer = ahci_start_transfer,
                   1156:     .prepare_buf = ahci_dma_prepare_buf,
                   1157:     .rw_buf = ahci_dma_rw_buf,
                   1158:     .set_unit = ahci_dma_set_unit,
                   1159:     .add_status = ahci_dma_add_status,
                   1160:     .set_inactive = ahci_dma_set_inactive,
                   1161:     .restart_cb = ahci_dma_restart_cb,
                   1162:     .reset = ahci_dma_reset,
                   1163: };
                   1164: 
                   1165: void ahci_init(AHCIState *s, DeviceState *qdev, int ports)
                   1166: {
                   1167:     qemu_irq *irqs;
                   1168:     int i;
                   1169: 
                   1170:     s->ports = ports;
1.1.1.3 ! root     1171:     s->dev = g_malloc0(sizeof(AHCIDevice) * ports);
1.1       root     1172:     ahci_reg_init(s);
1.1.1.3 ! root     1173:     /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
        !          1174:     memory_region_init_io(&s->mem, &ahci_mem_ops, s, "ahci", AHCI_MEM_BAR_SIZE);
        !          1175:     memory_region_init_io(&s->idp, &ahci_idp_ops, s, "ahci-idp", 32);
        !          1176: 
1.1       root     1177:     irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports);
                   1178: 
                   1179:     for (i = 0; i < s->ports; i++) {
                   1180:         AHCIDevice *ad = &s->dev[i];
                   1181: 
                   1182:         ide_bus_new(&ad->port, qdev, i);
                   1183:         ide_init2(&ad->port, irqs[i]);
                   1184: 
                   1185:         ad->hba = s;
                   1186:         ad->port_no = i;
                   1187:         ad->port.dma = &ad->dma;
                   1188:         ad->port.dma->ops = &ahci_dma_ops;
                   1189:         ad->port_regs.cmd = PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON;
                   1190:     }
                   1191: }
                   1192: 
                   1193: void ahci_uninit(AHCIState *s)
                   1194: {
1.1.1.3 ! root     1195:     memory_region_destroy(&s->mem);
        !          1196:     memory_region_destroy(&s->idp);
        !          1197:     g_free(s->dev);
1.1       root     1198: }
                   1199: 
                   1200: void ahci_reset(void *opaque)
                   1201: {
                   1202:     struct AHCIPCIState *d = opaque;
1.1.1.3 ! root     1203:     AHCIPortRegs *pr;
1.1       root     1204:     int i;
                   1205: 
                   1206:     d->ahci.control_regs.irqstatus = 0;
                   1207:     d->ahci.control_regs.ghc = 0;
                   1208: 
                   1209:     for (i = 0; i < d->ahci.ports; i++) {
1.1.1.3 ! root     1210:         pr = &d->ahci.dev[i].port_regs;
        !          1211:         pr->irq_stat = 0;
        !          1212:         pr->irq_mask = 0;
        !          1213:         pr->scr_ctl = 0;
1.1       root     1214:         ahci_reset_port(&d->ahci, i);
                   1215:     }
                   1216: }

unix.superglobalmegacorp.com

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