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

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

unix.superglobalmegacorp.com

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