Lines Matching +full:hba +full:- +full:cap
28 #include "hw/qdev-properties.h"
31 #include "qemu/error-report.h"
33 #include "qemu/main-loop.h"
35 #include "sysemu/block-backend.h"
38 #include "hw/ide/ahci-pci.h"
39 #include "hw/ide/ahci-sysbus.h"
40 #include "ahci-internal.h"
41 #include "ide-internal.h"
58 [AHCI_HOST_REG_CAP] = "CAP",
120 AHCIPortRegs *pr = &s->dev[port].port_regs; in ahci_port_read()
126 val = pr->lst_addr; in ahci_port_read()
129 val = pr->lst_addr_hi; in ahci_port_read()
132 val = pr->fis_addr; in ahci_port_read()
135 val = pr->fis_addr_hi; in ahci_port_read()
138 val = pr->irq_stat; in ahci_port_read()
141 val = pr->irq_mask; in ahci_port_read()
144 val = pr->cmd; in ahci_port_read()
147 val = pr->tfdata; in ahci_port_read()
150 val = pr->sig; in ahci_port_read()
153 if (s->dev[port].port.ifs[0].blk) { in ahci_port_read()
161 val = pr->scr_ctl; in ahci_port_read()
164 val = pr->scr_err; in ahci_port_read()
167 val = pr->scr_act; in ahci_port_read()
170 val = pr->cmd_issue; in ahci_port_read()
184 DeviceState *dev_state = s->container; in ahci_irq_raise()
193 qemu_irq_raise(s->irq); in ahci_irq_raise()
199 DeviceState *dev_state = s->container; in ahci_irq_lower()
206 qemu_irq_lower(s->irq); in ahci_irq_lower()
213 uint32_t old_irq = s->control_regs.irqstatus; in ahci_check_irq()
215 s->control_regs.irqstatus = 0; in ahci_check_irq()
216 for (i = 0; i < s->ports; i++) { in ahci_check_irq()
217 AHCIPortRegs *pr = &s->dev[i].port_regs; in ahci_check_irq()
218 if (pr->irq_stat & pr->irq_mask) { in ahci_check_irq()
219 s->control_regs.irqstatus |= (1 << i); in ahci_check_irq()
222 trace_ahci_check_irq(s, old_irq, s->control_regs.irqstatus); in ahci_check_irq()
223 if (s->control_regs.irqstatus && in ahci_check_irq()
224 (s->control_regs.ghc & HOST_CTL_IRQ_EN)) { in ahci_check_irq()
236 uint32_t irqstat = d->port_regs.irq_stat | irq; in ahci_trigger_irq()
238 trace_ahci_trigger_irq(s, d->port_no, in ahci_trigger_irq()
240 d->port_regs.irq_stat, irqstat, in ahci_trigger_irq()
241 irqstat & d->port_regs.irq_mask); in ahci_trigger_irq()
243 d->port_regs.irq_stat = irqstat; in ahci_trigger_irq()
270 * @return 0 on success, -1 on error.
274 AHCIPortRegs *pr = &ad->port_regs; in ahci_cond_start_engines()
275 bool cmd_start = pr->cmd & PORT_CMD_START; in ahci_cond_start_engines()
276 bool cmd_on = pr->cmd & PORT_CMD_LIST_ON; in ahci_cond_start_engines()
277 bool fis_start = pr->cmd & PORT_CMD_FIS_RX; in ahci_cond_start_engines()
278 bool fis_on = pr->cmd & PORT_CMD_FIS_ON; in ahci_cond_start_engines()
282 pr->cmd &= ~PORT_CMD_START; in ahci_cond_start_engines()
285 return -1; in ahci_cond_start_engines()
293 pr->cmd &= ~PORT_CMD_FIS_RX; in ahci_cond_start_engines()
296 return -1; in ahci_cond_start_engines()
307 AHCIPortRegs *pr = &s->dev[port].port_regs; in ahci_port_write()
314 pr->lst_addr = val; in ahci_port_write()
317 pr->lst_addr_hi = val; in ahci_port_write()
320 pr->fis_addr = val; in ahci_port_write()
323 pr->fis_addr_hi = val; in ahci_port_write()
326 pr->irq_stat &= ~val; in ahci_port_write()
330 pr->irq_mask = val & 0xfdc000ff; in ahci_port_write()
334 if ((pr->cmd & PORT_CMD_START) && !(val & PORT_CMD_START)) { in ahci_port_write()
335 pr->scr_act = 0; in ahci_port_write()
336 pr->cmd_issue = 0; in ahci_port_write()
339 /* Block any Read-only fields from being set; in ahci_port_write()
345 pr->cmd = (pr->cmd & PORT_CMD_RO_MASK) | in ahci_port_write()
349 ahci_cond_start_engines(&s->dev[port]); in ahci_port_write()
353 Instead, we only submit it once - which works in most in ahci_port_write()
355 if ((pr->cmd & PORT_CMD_FIS_ON) && in ahci_port_write()
356 !s->dev[port].init_d2h_sent) { in ahci_port_write()
357 ahci_init_d2h(&s->dev[port]); in ahci_port_write()
368 if (((pr->scr_ctl & AHCI_SCR_SCTL_DET) == 1) && in ahci_port_write()
372 pr->scr_ctl = val; in ahci_port_write()
375 pr->scr_err &= ~val; in ahci_port_write()
379 pr->scr_act |= val; in ahci_port_write()
382 pr->cmd_issue |= val; in ahci_port_write()
406 val = s->control_regs.cap; in ahci_mem_read_32()
409 val = s->control_regs.ghc; in ahci_mem_read_32()
412 val = s->control_regs.irqstatus; in ahci_mem_read_32()
415 val = s->control_regs.impl; in ahci_mem_read_32()
418 val = s->control_regs.version; in ahci_mem_read_32()
427 (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) { in ahci_mem_read_32()
428 val = ahci_port_read(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7, in ahci_mem_read_32()
440 * AHCI 1.3 section 3 ("HBA Memory Registers")
447 int ofst = addr - aligned; in ahci_mem_read()
479 "ahci: Mis-aligned write to addr 0x%03" HWADDR_PRIX "\n", in ahci_mem_write()
496 s->control_regs.ghc = (val & 0x3) | HOST_CTL_AHCI_EN; in ahci_mem_write()
501 s->control_regs.irqstatus &= ~val; in ahci_mem_write()
523 (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) { in ahci_mem_write()
524 ahci_port_write(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7, in ahci_mem_write()
545 if (addr == s->idp_offset) { in ahci_idp_read()
547 return s->idp_index; in ahci_idp_read()
548 } else if (addr == s->idp_offset + 4) { in ahci_idp_read()
549 /* data register - do memory read at location selected by index */ in ahci_idp_read()
550 return ahci_mem_read(opaque, s->idp_index, size); in ahci_idp_read()
561 if (addr == s->idp_offset) { in ahci_idp_write()
562 /* index register - mask off reserved bits */ in ahci_idp_write()
563 s->idp_index = (uint32_t)val & ((AHCI_MEM_BAR_SIZE - 1) & ~3); in ahci_idp_write()
564 } else if (addr == s->idp_offset + 4) { in ahci_idp_write()
565 /* data register - do memory write at location selected by index */ in ahci_idp_write()
566 ahci_mem_write(opaque, s->idp_index, val, size); in ahci_idp_write()
581 s->control_regs.cap = (s->ports - 1) | in ahci_reg_init()
586 s->control_regs.impl = (1 << s->ports) - 1; in ahci_reg_init()
588 s->control_regs.version = AHCI_VERSION_1_0; in ahci_reg_init()
590 for (i = 0; i < s->ports; i++) { in ahci_reg_init()
591 s->dev[i].port_state = STATE_RUN; in ahci_reg_init()
597 AHCIPortRegs *pr = &s->dev[port].port_regs; in check_cmd()
600 if ((pr->cmd & PORT_CMD_START) && pr->cmd_issue) { in check_cmd()
601 for (slot = 0; (slot < 32) && pr->cmd_issue; slot++) { in check_cmd()
602 if (pr->cmd_issue & (1U << slot)) { in check_cmd()
613 qemu_bh_delete(ad->check_bh); in ahci_check_cmd_bh()
614 ad->check_bh = NULL; in ahci_check_cmd_bh()
616 check_cmd(ad->hba, ad->port_no); in ahci_check_cmd_bh()
621 IDEState *ide_state = &ad->port.ifs[0]; in ahci_init_d2h()
622 AHCIPortRegs *pr = &ad->port_regs; in ahci_init_d2h()
624 if (ad->init_d2h_sent) { in ahci_init_d2h()
633 ad->init_d2h_sent = true; in ahci_init_d2h()
636 pr->sig = ((uint32_t)ide_state->hcyl << 24) | in ahci_init_d2h()
637 (ide_state->lcyl << 16) | in ahci_init_d2h()
638 (ide_state->sector << 8) | in ahci_init_d2h()
639 (ide_state->nsector & 0xFF); in ahci_init_d2h()
645 IDEState *s = &ad->port.ifs[0]; in ahci_set_signature()
646 s->hcyl = sig >> 24 & 0xFF; in ahci_set_signature()
647 s->lcyl = sig >> 16 & 0xFF; in ahci_set_signature()
648 s->sector = sig >> 8 & 0xFF; in ahci_set_signature()
649 s->nsector = sig & 0xFF; in ahci_set_signature()
651 trace_ahci_set_signature(ad->hba, ad->port_no, s->nsector, s->sector, in ahci_set_signature()
652 s->lcyl, s->hcyl, sig); in ahci_set_signature()
657 AHCIDevice *d = &s->dev[port]; in ahci_reset_port()
658 AHCIPortRegs *pr = &d->port_regs; in ahci_reset_port()
659 IDEState *ide_state = &d->port.ifs[0]; in ahci_reset_port()
664 ide_bus_reset(&d->port); in ahci_reset_port()
665 ide_state->ncq_queues = AHCI_MAX_CMDS; in ahci_reset_port()
667 pr->scr_stat = 0; in ahci_reset_port()
668 pr->scr_err = 0; in ahci_reset_port()
669 pr->scr_act = 0; in ahci_reset_port()
670 pr->tfdata = 0x7F; in ahci_reset_port()
671 pr->sig = 0xFFFFFFFF; in ahci_reset_port()
672 pr->cmd_issue = 0; in ahci_reset_port()
673 d->busy_slot = -1; in ahci_reset_port()
674 d->init_d2h_sent = false; in ahci_reset_port()
676 ide_state = &s->dev[port].port.ifs[0]; in ahci_reset_port()
677 if (!ide_state->blk) { in ahci_reset_port()
683 NCQTransferState *ncq_tfs = &s->dev[port].ncq_tfs[i]; in ahci_reset_port()
684 ncq_tfs->halt = false; in ahci_reset_port()
685 if (!ncq_tfs->used) { in ahci_reset_port()
689 if (ncq_tfs->aiocb) { in ahci_reset_port()
690 blk_aio_cancel(ncq_tfs->aiocb); in ahci_reset_port()
691 ncq_tfs->aiocb = NULL; in ahci_reset_port()
695 if (!ncq_tfs->used) { in ahci_reset_port()
699 qemu_sglist_destroy(&ncq_tfs->sglist); in ahci_reset_port()
700 ncq_tfs->used = 0; in ahci_reset_port()
703 s->dev[port].port_state = STATE_RUN; in ahci_reset_port()
704 if (ide_state->drive_kind == IDE_CD) { in ahci_reset_port()
706 ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT; in ahci_reset_port()
709 ide_state->status = SEEK_STAT | WRERR_STAT; in ahci_reset_port()
712 ide_state->error = 1; in ahci_reset_port()
735 AHCIPortRegs *pr = &ad->port_regs; in ahci_map_fis_address()
736 map_page(ad->hba->as, &ad->res_fis, in ahci_map_fis_address()
737 ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256); in ahci_map_fis_address()
738 if (ad->res_fis != NULL) { in ahci_map_fis_address()
739 pr->cmd |= PORT_CMD_FIS_ON; in ahci_map_fis_address()
743 pr->cmd &= ~PORT_CMD_FIS_ON; in ahci_map_fis_address()
749 if (ad->res_fis == NULL) { in ahci_unmap_fis_address()
750 trace_ahci_unmap_fis_address_null(ad->hba, ad->port_no); in ahci_unmap_fis_address()
753 ad->port_regs.cmd &= ~PORT_CMD_FIS_ON; in ahci_unmap_fis_address()
754 dma_memory_unmap(ad->hba->as, ad->res_fis, 256, in ahci_unmap_fis_address()
756 ad->res_fis = NULL; in ahci_unmap_fis_address()
761 AHCIPortRegs *pr = &ad->port_regs; in ahci_map_clb_address()
762 ad->cur_cmd = NULL; in ahci_map_clb_address()
763 map_page(ad->hba->as, &ad->lst, in ahci_map_clb_address()
764 ((uint64_t)pr->lst_addr_hi << 32) | pr->lst_addr, 1024); in ahci_map_clb_address()
765 if (ad->lst != NULL) { in ahci_map_clb_address()
766 pr->cmd |= PORT_CMD_LIST_ON; in ahci_map_clb_address()
770 pr->cmd &= ~PORT_CMD_LIST_ON; in ahci_map_clb_address()
776 if (ad->lst == NULL) { in ahci_unmap_clb_address()
777 trace_ahci_unmap_clb_address_null(ad->hba, ad->port_no); in ahci_unmap_clb_address()
780 ad->port_regs.cmd &= ~PORT_CMD_LIST_ON; in ahci_unmap_clb_address()
781 dma_memory_unmap(ad->hba->as, ad->lst, 1024, in ahci_unmap_clb_address()
783 ad->lst = NULL; in ahci_unmap_clb_address()
788 AHCIDevice *ad = ncq_tfs->drive; in ahci_write_fis_sdb()
789 AHCIPortRegs *pr = &ad->port_regs; in ahci_write_fis_sdb()
793 if (!ad->res_fis || in ahci_write_fis_sdb()
794 !(pr->cmd & PORT_CMD_FIS_RX)) { in ahci_write_fis_sdb()
798 sdb_fis = (SDBFIS *)&ad->res_fis[RES_FIS_SDBFIS]; in ahci_write_fis_sdb()
799 ide_state = &ad->port.ifs[0]; in ahci_write_fis_sdb()
801 sdb_fis->type = SATA_FIS_TYPE_SDB; in ahci_write_fis_sdb()
803 sdb_fis->flags = 0x40; /* Interrupt bit, always 1 for NCQ */ in ahci_write_fis_sdb()
804 sdb_fis->status = ide_state->status & 0x77; in ahci_write_fis_sdb()
805 sdb_fis->error = ide_state->error; in ahci_write_fis_sdb()
807 sdb_fis->payload = cpu_to_le32(ad->finished); in ahci_write_fis_sdb()
810 pr->tfdata = (ad->port.ifs[0].error << 8) | in ahci_write_fis_sdb()
811 (ad->port.ifs[0].status & 0x77) | in ahci_write_fis_sdb()
812 (pr->tfdata & 0x88); in ahci_write_fis_sdb()
813 pr->scr_act &= ~ad->finished; in ahci_write_fis_sdb()
814 ad->finished = 0; in ahci_write_fis_sdb()
821 if (sdb_fis->status & ERR_STAT) { in ahci_write_fis_sdb()
823 } else if (sdb_fis->flags & 0x40) { in ahci_write_fis_sdb()
830 AHCIPortRegs *pr = &ad->port_regs; in ahci_write_fis_pio()
832 IDEState *s = &ad->port.ifs[0]; in ahci_write_fis_pio()
834 if (!ad->res_fis || !(pr->cmd & PORT_CMD_FIS_RX)) { in ahci_write_fis_pio()
838 pio_fis = &ad->res_fis[RES_FIS_PSFIS]; in ahci_write_fis_pio()
842 pio_fis[2] = s->status; in ahci_write_fis_pio()
843 pio_fis[3] = s->error; in ahci_write_fis_pio()
845 pio_fis[4] = s->sector; in ahci_write_fis_pio()
846 pio_fis[5] = s->lcyl; in ahci_write_fis_pio()
847 pio_fis[6] = s->hcyl; in ahci_write_fis_pio()
848 pio_fis[7] = s->select; in ahci_write_fis_pio()
849 pio_fis[8] = s->hob_sector; in ahci_write_fis_pio()
850 pio_fis[9] = s->hob_lcyl; in ahci_write_fis_pio()
851 pio_fis[10] = s->hob_hcyl; in ahci_write_fis_pio()
853 pio_fis[12] = s->nsector & 0xFF; in ahci_write_fis_pio()
854 pio_fis[13] = (s->nsector >> 8) & 0xFF; in ahci_write_fis_pio()
856 pio_fis[15] = s->status; in ahci_write_fis_pio()
863 pr->tfdata = (ad->port.ifs[0].error << 8) | in ahci_write_fis_pio()
864 ad->port.ifs[0].status; in ahci_write_fis_pio()
867 ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES); in ahci_write_fis_pio()
873 AHCIPortRegs *pr = &ad->port_regs; in ahci_write_fis_d2h()
876 IDEState *s = &ad->port.ifs[0]; in ahci_write_fis_d2h()
878 if (!ad->res_fis || !(pr->cmd & PORT_CMD_FIS_RX)) { in ahci_write_fis_d2h()
882 d2h_fis = &ad->res_fis[RES_FIS_RFIS]; in ahci_write_fis_d2h()
886 d2h_fis[2] = s->status; in ahci_write_fis_d2h()
887 d2h_fis[3] = s->error; in ahci_write_fis_d2h()
889 d2h_fis[4] = s->sector; in ahci_write_fis_d2h()
890 d2h_fis[5] = s->lcyl; in ahci_write_fis_d2h()
891 d2h_fis[6] = s->hcyl; in ahci_write_fis_d2h()
892 d2h_fis[7] = s->select; in ahci_write_fis_d2h()
893 d2h_fis[8] = s->hob_sector; in ahci_write_fis_d2h()
894 d2h_fis[9] = s->hob_lcyl; in ahci_write_fis_d2h()
895 d2h_fis[10] = s->hob_hcyl; in ahci_write_fis_d2h()
897 d2h_fis[12] = s->nsector & 0xFF; in ahci_write_fis_d2h()
898 d2h_fis[13] = (s->nsector >> 8) & 0xFF; in ahci_write_fis_d2h()
904 pr->tfdata = (ad->port.ifs[0].error << 8) | in ahci_write_fis_d2h()
905 ad->port.ifs[0].status; in ahci_write_fis_d2h()
909 ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES); in ahci_write_fis_d2h()
911 ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_DHRS); in ahci_write_fis_d2h()
919 /* flags_size is zero-based */ in prdt_tbl_entry_size()
920 return (le32_to_cpu(tbl->flags_size) & AHCI_PRDT_SIZE_MASK) + 1; in prdt_tbl_entry_size()
924 * Fetch entries in a guest-provided PRDT and convert it into a QEMU SGlist.
932 * up to 32MiB as of ATA8-ACS3 rev 1b, assuming a 512 byte sector size. We stop
939 uint16_t opts = le16_to_cpu(cmd->opts); in ahci_populate_sglist()
940 uint16_t prdtl = le16_to_cpu(cmd->prdtl); in ahci_populate_sglist()
941 uint64_t cfis_addr = le64_to_cpu(cmd->tbl_addr); in ahci_populate_sglist()
949 int off_idx = -1; in ahci_populate_sglist()
950 int64_t off_pos = -1; in ahci_populate_sglist()
951 IDEBus *bus = &ad->port; in ahci_populate_sglist()
954 trace_ahci_populate_sglist(ad->hba, ad->port_no); in ahci_populate_sglist()
957 trace_ahci_populate_sglist_no_prdtl(ad->hba, ad->port_no, opts); in ahci_populate_sglist()
958 return -1; in ahci_populate_sglist()
962 if (!(prdt = dma_memory_map(ad->hba->as, prdt_addr, &prdt_len, in ahci_populate_sglist()
965 trace_ahci_populate_sglist_no_map(ad->hba, ad->port_no); in ahci_populate_sglist()
966 return -1; in ahci_populate_sglist()
970 trace_ahci_populate_sglist_short_map(ad->hba, ad->port_no); in ahci_populate_sglist()
971 r = -1; in ahci_populate_sglist()
985 off_pos = offset - sum; in ahci_populate_sglist()
990 if ((off_idx == -1) || (off_pos < 0) || (off_pos > tbl_entry_size)) { in ahci_populate_sglist()
991 trace_ahci_populate_sglist_bad_offset(ad->hba, ad->port_no, in ahci_populate_sglist()
993 r = -1; in ahci_populate_sglist()
997 qemu_sglist_init(sglist, qbus->parent, (prdtl - off_idx), in ahci_populate_sglist()
998 ad->hba->as); in ahci_populate_sglist()
1000 MIN(prdt_tbl_entry_size(&tbl[off_idx]) - off_pos, in ahci_populate_sglist()
1003 for (i = off_idx + 1; i < prdtl && sglist->size < limit; i++) { in ahci_populate_sglist()
1006 limit - sglist->size)); in ahci_populate_sglist()
1011 dma_memory_unmap(ad->hba->as, prdt, prdt_len, in ahci_populate_sglist()
1018 IDEState *ide_state = &ncq_tfs->drive->port.ifs[0]; in ncq_err()
1020 ide_state->error = ABRT_ERR; in ncq_err()
1021 ide_state->status = READY_STAT | ERR_STAT; in ncq_err()
1022 qemu_sglist_destroy(&ncq_tfs->sglist); in ncq_err()
1023 ncq_tfs->used = 0; in ncq_err()
1031 if (ncq_tfs->used) { in ncq_finish()
1032 ncq_tfs->drive->finished |= (1 << ncq_tfs->tag); in ncq_finish()
1035 ahci_write_fis_sdb(ncq_tfs->drive->hba, ncq_tfs); in ncq_finish()
1037 trace_ncq_finish(ncq_tfs->drive->hba, ncq_tfs->drive->port_no, in ncq_finish()
1038 ncq_tfs->tag); in ncq_finish()
1040 block_acct_done(blk_get_stats(ncq_tfs->drive->port.ifs[0].blk), in ncq_finish()
1041 &ncq_tfs->acct); in ncq_finish()
1042 qemu_sglist_destroy(&ncq_tfs->sglist); in ncq_finish()
1043 ncq_tfs->used = 0; in ncq_finish()
1049 IDEState *ide_state = &ncq_tfs->drive->port.ifs[0]; in ncq_cb()
1051 ncq_tfs->aiocb = NULL; in ncq_cb()
1054 bool is_read = ncq_tfs->cmd == READ_FPDMA_QUEUED; in ncq_cb()
1055 BlockErrorAction action = blk_get_error_action(ide_state->blk, in ncq_cb()
1056 is_read, -ret); in ncq_cb()
1058 ncq_tfs->halt = true; in ncq_cb()
1059 ide_state->bus->error_status = IDE_RETRY_HBA; in ncq_cb()
1063 blk_error_action(ide_state->blk, action, is_read, -ret); in ncq_cb()
1065 ide_state->status = READY_STAT | SEEK_STAT; in ncq_cb()
1068 if (!ncq_tfs->halt) { in ncq_cb()
1090 AHCIDevice *ad = ncq_tfs->drive; in execute_ncq_command()
1091 IDEState *ide_state = &ad->port.ifs[0]; in execute_ncq_command()
1092 int port = ad->port_no; in execute_ncq_command()
1094 g_assert(is_ncq(ncq_tfs->cmd)); in execute_ncq_command()
1095 ncq_tfs->halt = false; in execute_ncq_command()
1097 switch (ncq_tfs->cmd) { in execute_ncq_command()
1099 trace_execute_ncq_command_read(ad->hba, port, ncq_tfs->tag, in execute_ncq_command()
1100 ncq_tfs->sector_count, ncq_tfs->lba); in execute_ncq_command()
1101 dma_acct_start(ide_state->blk, &ncq_tfs->acct, in execute_ncq_command()
1102 &ncq_tfs->sglist, BLOCK_ACCT_READ); in execute_ncq_command()
1103 ncq_tfs->aiocb = dma_blk_read(ide_state->blk, &ncq_tfs->sglist, in execute_ncq_command()
1104 ncq_tfs->lba << BDRV_SECTOR_BITS, in execute_ncq_command()
1109 trace_execute_ncq_command_write(ad->hba, port, ncq_tfs->tag, in execute_ncq_command()
1110 ncq_tfs->sector_count, ncq_tfs->lba); in execute_ncq_command()
1111 dma_acct_start(ide_state->blk, &ncq_tfs->acct, in execute_ncq_command()
1112 &ncq_tfs->sglist, BLOCK_ACCT_WRITE); in execute_ncq_command()
1113 ncq_tfs->aiocb = dma_blk_write(ide_state->blk, &ncq_tfs->sglist, in execute_ncq_command()
1114 ncq_tfs->lba << BDRV_SECTOR_BITS, in execute_ncq_command()
1119 trace_execute_ncq_command_unsup(ad->hba, port, in execute_ncq_command()
1120 ncq_tfs->tag, ncq_tfs->cmd); in execute_ncq_command()
1129 AHCIDevice *ad = &s->dev[port]; in process_ncq_command()
1131 uint8_t tag = ncq_fis->tag >> 3; in process_ncq_command()
1132 NCQTransferState *ncq_tfs = &ad->ncq_tfs[tag]; in process_ncq_command()
1135 g_assert(is_ncq(ncq_fis->command)); in process_ncq_command()
1136 if (ncq_tfs->used) { in process_ncq_command()
1137 /* error - already in use */ in process_ncq_command()
1161 ncq_tfs->used = 1; in process_ncq_command()
1162 ncq_tfs->drive = ad; in process_ncq_command()
1163 ncq_tfs->slot = slot; in process_ncq_command()
1164 ncq_tfs->cmdh = &((AHCICmdHdr *)ad->lst)[slot]; in process_ncq_command()
1165 ncq_tfs->cmd = ncq_fis->command; in process_ncq_command()
1166 ncq_tfs->lba = ((uint64_t)ncq_fis->lba5 << 40) | in process_ncq_command()
1167 ((uint64_t)ncq_fis->lba4 << 32) | in process_ncq_command()
1168 ((uint64_t)ncq_fis->lba3 << 24) | in process_ncq_command()
1169 ((uint64_t)ncq_fis->lba2 << 16) | in process_ncq_command()
1170 ((uint64_t)ncq_fis->lba1 << 8) | in process_ncq_command()
1171 (uint64_t)ncq_fis->lba0; in process_ncq_command()
1172 ncq_tfs->tag = tag; in process_ncq_command()
1174 /* Sanity-check the NCQ packet */ in process_ncq_command()
1179 if (ncq_fis->aux0 || ncq_fis->aux1 || ncq_fis->aux2 || ncq_fis->aux3) { in process_ncq_command()
1182 if (ncq_fis->prio || ncq_fis->icc) { in process_ncq_command()
1185 if (ncq_fis->fua & NCQ_FIS_FUA_MASK) { in process_ncq_command()
1188 if (ncq_fis->tag & NCQ_FIS_RARC_MASK) { in process_ncq_command()
1192 ncq_tfs->sector_count = ((ncq_fis->sector_count_high << 8) | in process_ncq_command()
1193 ncq_fis->sector_count_low); in process_ncq_command()
1194 if (!ncq_tfs->sector_count) { in process_ncq_command()
1195 ncq_tfs->sector_count = 0x10000; in process_ncq_command()
1197 size = ncq_tfs->sector_count * BDRV_SECTOR_SIZE; in process_ncq_command()
1198 ahci_populate_sglist(ad, &ncq_tfs->sglist, ncq_tfs->cmdh, size, 0); in process_ncq_command()
1200 if (ncq_tfs->sglist.size < size) { in process_ncq_command()
1203 ncq_tfs->sglist.size, size); in process_ncq_command()
1205 ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_OFS); in process_ncq_command()
1207 } else if (ncq_tfs->sglist.size != size) { in process_ncq_command()
1209 ncq_tfs->sglist.size, size); in process_ncq_command()
1213 ncq_fis->command, in process_ncq_command()
1214 ncq_tfs->lba, in process_ncq_command()
1215 ncq_tfs->lba + ncq_tfs->sector_count - 1); in process_ncq_command()
1221 if (port >= s->ports || slot >= AHCI_MAX_CMDS) { in get_cmd_header()
1225 return s->dev[port].lst ? &((AHCICmdHdr *)s->dev[port].lst)[slot] : NULL; in get_cmd_header()
1231 IDEState *ide_state = &s->dev[port].port.ifs[0]; in handle_reg_h2d_fis()
1233 AHCIDevice *ad = &s->dev[port]; in handle_reg_h2d_fis()
1234 uint16_t opts = le16_to_cpu(cmd->opts); in handle_reg_h2d_fis()
1249 switch (s->dev[port].port_state) { in handle_reg_h2d_fis()
1252 s->dev[port].port_state = STATE_RESET; in handle_reg_h2d_fis()
1301 ide_state->feature = cmd_fis[3]; in handle_reg_h2d_fis()
1302 ide_state->sector = cmd_fis[4]; /* LBA 7:0 */ in handle_reg_h2d_fis()
1303 ide_state->lcyl = cmd_fis[5]; /* LBA 15:8 */ in handle_reg_h2d_fis()
1304 ide_state->hcyl = cmd_fis[6]; /* LBA 23:16 */ in handle_reg_h2d_fis()
1305 ide_state->select = cmd_fis[7]; /* LBA 27:24 (LBA28) */ in handle_reg_h2d_fis()
1306 ide_state->hob_sector = cmd_fis[8]; /* LBA 31:24 */ in handle_reg_h2d_fis()
1307 ide_state->hob_lcyl = cmd_fis[9]; /* LBA 39:32 */ in handle_reg_h2d_fis()
1308 ide_state->hob_hcyl = cmd_fis[10]; /* LBA 47:40 */ in handle_reg_h2d_fis()
1309 ide_state->hob_feature = cmd_fis[11]; in handle_reg_h2d_fis()
1310 ide_state->nsector = (int64_t)((cmd_fis[13] << 8) | cmd_fis[12]); in handle_reg_h2d_fis()
1315 * table to ide_state->io_buffer */ in handle_reg_h2d_fis()
1317 memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10); in handle_reg_h2d_fis()
1319 char *pretty_fis = ahci_pretty_buffer_fis(ide_state->io_buffer, 0x10); in handle_reg_h2d_fis()
1325 ide_state->error = 0; in handle_reg_h2d_fis()
1326 s->dev[port].done_first_drq = false; in handle_reg_h2d_fis()
1328 cmd->status = 0; in handle_reg_h2d_fis()
1331 * A non-NCQ command clears the bit in PxCI after the command has COMPLETED in handle_reg_h2d_fis()
1334 * For non-NCQ commands, PxCI will always be cleared by ahci_cmd_done(). in handle_reg_h2d_fis()
1336 ad->busy_slot = slot; in handle_reg_h2d_fis()
1339 ide_bus_exec_cmd(&s->dev[port].port, cmd_fis[2]); in handle_reg_h2d_fis()
1350 if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) { in handle_cmd()
1356 if (!s->dev[port].lst) { in handle_cmd()
1362 s->dev[port].cur_cmd = cmd; in handle_cmd()
1365 ide_state = &s->dev[port].port.ifs[0]; in handle_cmd()
1366 if (!ide_state->blk) { in handle_cmd()
1371 tbl_addr = le64_to_cpu(cmd->tbl_addr); in handle_cmd()
1373 cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len, in handle_cmd()
1379 ahci_trigger_irq(s, &s->dev[port], AHCI_PORT_IRQ_BIT_HBFS); in handle_cmd()
1399 dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_TO_DEVICE, in handle_cmd()
1407 IDEState *s = &ad->port.ifs[0]; in ahci_pio_transfer()
1408 uint32_t size = (uint32_t)(s->data_end - s->data_ptr); in ahci_pio_transfer()
1409 /* write == ram -> device */ in ahci_pio_transfer()
1410 uint16_t opts = le16_to_cpu(ad->cur_cmd->opts); in ahci_pio_transfer()
1419 * The device only sets the 'I' bit in the PIO Setup FIS for device->host in ahci_pio_transfer()
1420 * requests (see "DPIOI1" in the SATA spec), or for host->device DRQs after in ahci_pio_transfer()
1426 pio_fis_i = ad->done_first_drq || (!is_atapi && !is_write); in ahci_pio_transfer()
1429 if (is_atapi && !ad->done_first_drq) { in ahci_pio_transfer()
1438 trace_ahci_pio_transfer(ad->hba, ad->port_no, is_write ? "writ" : "read", in ahci_pio_transfer()
1446 dma_buf_write(s->data_ptr, size, NULL, &s->sg, attrs); in ahci_pio_transfer()
1448 dma_buf_read(s->data_ptr, size, NULL, &s->sg, attrs); in ahci_pio_transfer()
1457 s->data_ptr = s->data_end; in ahci_pio_transfer()
1459 ad->done_first_drq = true; in ahci_pio_transfer()
1461 ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_PSS); in ahci_pio_transfer()
1469 trace_ahci_start_dma(ad->hba, ad->port_no); in ahci_start_dma()
1470 s->io_buffer_offset = 0; in ahci_start_dma()
1476 /* Nothing to do, ahci_start_dma already resets s->io_buffer_offset. */ in ahci_restart_dma()
1481 * need an extra kick from the AHCI HBA.
1489 NCQTransferState *ncq_tfs = &ad->ncq_tfs[i]; in ahci_restart()
1490 if (ncq_tfs->halt) { in ahci_restart()
1503 IDEState *s = &ad->port.ifs[0]; in ahci_dma_prepare_buf()
1505 if (ahci_populate_sglist(ad, &s->sg, ad->cur_cmd, in ahci_dma_prepare_buf()
1506 limit, s->io_buffer_offset) == -1) { in ahci_dma_prepare_buf()
1507 trace_ahci_dma_prepare_buf_fail(ad->hba, ad->port_no); in ahci_dma_prepare_buf()
1508 return -1; in ahci_dma_prepare_buf()
1510 s->io_buffer_size = s->sg.size; in ahci_dma_prepare_buf()
1512 trace_ahci_dma_prepare_buf(ad->hba, ad->port_no, limit, s->io_buffer_size); in ahci_dma_prepare_buf()
1513 return s->io_buffer_size; in ahci_dma_prepare_buf()
1517 * Updates the command header with a bytes-read value.
1525 tx_bytes += le32_to_cpu(ad->cur_cmd->status); in ahci_commit_buf()
1526 ad->cur_cmd->status = cpu_to_le32(tx_bytes); in ahci_commit_buf()
1532 IDEState *s = &ad->port.ifs[0]; in ahci_dma_rw_buf()
1533 uint8_t *p = s->io_buffer + s->io_buffer_index; in ahci_dma_rw_buf()
1534 int l = s->io_buffer_size - s->io_buffer_index; in ahci_dma_rw_buf()
1536 if (ahci_populate_sglist(ad, &s->sg, ad->cur_cmd, l, s->io_buffer_offset)) { in ahci_dma_rw_buf()
1541 dma_buf_read(p, l, NULL, &s->sg, MEMTXATTRS_UNSPECIFIED); in ahci_dma_rw_buf()
1543 dma_buf_write(p, l, NULL, &s->sg, MEMTXATTRS_UNSPECIFIED); in ahci_dma_rw_buf()
1548 s->io_buffer_index += l; in ahci_dma_rw_buf()
1550 trace_ahci_dma_rw_buf(ad->hba, ad->port_no, l); in ahci_dma_rw_buf()
1556 IDEState *ide_state = &ad->port.ifs[0]; in ahci_clear_cmd_issue()
1558 if (!(ide_state->status & ERR_STAT) && in ahci_clear_cmd_issue()
1559 !(ide_state->status & (BUSY_STAT | DRQ_STAT))) { in ahci_clear_cmd_issue()
1560 ad->port_regs.cmd_issue &= ~(1 << slot); in ahci_clear_cmd_issue()
1564 /* Non-NCQ command is done - This function is never called for NCQ commands. */
1568 IDEState *ide_state = &ad->port.ifs[0]; in ahci_cmd_done()
1570 trace_ahci_cmd_done(ad->hba, ad->port_no); in ahci_cmd_done()
1573 if (ad->busy_slot != -1) { in ahci_cmd_done()
1574 ahci_clear_cmd_issue(ad, ad->busy_slot); in ahci_cmd_done()
1575 ad->busy_slot = -1; in ahci_cmd_done()
1579 * In reality, for non-NCQ commands, PxCI is cleared after receiving a D2H in ahci_cmd_done()
1585 if (!(ide_state->status & ERR_STAT) && in ahci_cmd_done()
1586 ad->port_regs.cmd_issue && !ad->check_bh) { in ahci_cmd_done()
1587 ad->check_bh = qemu_bh_new_guarded(ahci_check_cmd_bh, ad, in ahci_cmd_done()
1588 &ad->mem_reentrancy_guard); in ahci_cmd_done()
1589 qemu_bh_schedule(ad->check_bh); in ahci_cmd_done()
1611 s->container = qdev; in ahci_init()
1613 memory_region_init_io(&s->mem, OBJECT(qdev), &ahci_mem_ops, s, in ahci_init()
1615 memory_region_init_io(&s->idp, OBJECT(qdev), &ahci_idp_ops, s, in ahci_init()
1616 "ahci-idp", 32); in ahci_init()
1624 s->as = as; in ahci_realize()
1625 assert(s->ports > 0); in ahci_realize()
1626 s->dev = g_new0(AHCIDevice, s->ports); in ahci_realize()
1628 irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports); in ahci_realize()
1629 for (i = 0; i < s->ports; i++) { in ahci_realize()
1630 AHCIDevice *ad = &s->dev[i]; in ahci_realize()
1632 ide_bus_init(&ad->port, sizeof(ad->port), qdev, i, 1); in ahci_realize()
1633 ide_bus_init_output_irq(&ad->port, irqs[i]); in ahci_realize()
1635 ad->hba = s; in ahci_realize()
1636 ad->port_no = i; in ahci_realize()
1637 ad->port.dma = &ad->dma; in ahci_realize()
1638 ad->port.dma->ops = &ahci_dma_ops; in ahci_realize()
1639 ide_bus_register_restart_cb(&ad->port); in ahci_realize()
1648 for (i = 0; i < s->ports; i++) { in ahci_uninit()
1649 AHCIDevice *ad = &s->dev[i]; in ahci_uninit()
1652 ide_exit(&ad->port.ifs[j]); in ahci_uninit()
1654 object_unparent(OBJECT(&ad->port)); in ahci_uninit()
1657 g_free(s->dev); in ahci_uninit()
1667 s->control_regs.irqstatus = 0; in ahci_reset()
1670 * CAP.SAM bit. If CAP.SAM is '0', then GHC.AE shall be read-write and in ahci_reset()
1671 * shall have a reset value of '0'. If CAP.SAM is '1', then AE shall be in ahci_reset()
1672 * read-only and shall have a reset value of '1'. in ahci_reset()
1676 s->control_regs.ghc = HOST_CTL_AHCI_EN; in ahci_reset()
1678 for (i = 0; i < s->ports; i++) { in ahci_reset()
1679 pr = &s->dev[i].port_regs; in ahci_reset()
1680 pr->irq_stat = 0; in ahci_reset()
1681 pr->irq_mask = 0; in ahci_reset()
1682 pr->scr_ctl = 0; in ahci_reset()
1683 pr->cmd = PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON; in ahci_reset()
1742 for (i = 0; i < s->ports; i++) { in ahci_state_post_load()
1743 ad = &s->dev[i]; in ahci_state_post_load()
1744 pr = &ad->port_regs; in ahci_state_post_load()
1746 if (!(pr->cmd & PORT_CMD_START) && (pr->cmd & PORT_CMD_LIST_ON)) { in ahci_state_post_load()
1749 return -1; in ahci_state_post_load()
1751 if (!(pr->cmd & PORT_CMD_FIS_RX) && (pr->cmd & PORT_CMD_FIS_ON)) { in ahci_state_post_load()
1754 return -1; in ahci_state_post_load()
1759 pr->cmd &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON); in ahci_state_post_load()
1761 return -1; in ahci_state_post_load()
1765 ncq_tfs = &ad->ncq_tfs[j]; in ahci_state_post_load()
1766 ncq_tfs->drive = ad; in ahci_state_post_load()
1768 if (ncq_tfs->used != ncq_tfs->halt) { in ahci_state_post_load()
1769 return -1; in ahci_state_post_load()
1771 if (!ncq_tfs->halt) { in ahci_state_post_load()
1774 if (!is_ncq(ncq_tfs->cmd)) { in ahci_state_post_load()
1775 return -1; in ahci_state_post_load()
1777 if (ncq_tfs->slot != ncq_tfs->tag) { in ahci_state_post_load()
1778 return -1; in ahci_state_post_load()
1780 /* If ncq_tfs->halt is justly set, the engine should be engaged, in ahci_state_post_load()
1782 ncq_tfs->cmdh = get_cmd_header(s, i, ncq_tfs->slot); in ahci_state_post_load()
1783 if (!ncq_tfs->cmdh) { in ahci_state_post_load()
1784 return -1; in ahci_state_post_load()
1786 ahci_populate_sglist(ncq_tfs->drive, &ncq_tfs->sglist, in ahci_state_post_load()
1787 ncq_tfs->cmdh, in ahci_state_post_load()
1788 ncq_tfs->sector_count * BDRV_SECTOR_SIZE, in ahci_state_post_load()
1790 if (ncq_tfs->sector_count != ncq_tfs->sglist.size >> 9) { in ahci_state_post_load()
1791 return -1; in ahci_state_post_load()
1797 * If an error is present, ad->busy_slot will be valid and not -1. in ahci_state_post_load()
1798 * In this case, an operation is waiting to resume and will re-check in ahci_state_post_load()
1801 * In the case where no error was present, busy_slot will be -1, in ahci_state_post_load()
1804 if (ad->busy_slot == -1) { in ahci_state_post_load()
1809 if (ad->busy_slot < 0 || ad->busy_slot >= AHCI_MAX_CMDS) { in ahci_state_post_load()
1810 return -1; in ahci_state_post_load()
1812 ad->cur_cmd = get_cmd_header(s, i, ad->busy_slot); in ahci_state_post_load()
1826 VMSTATE_UINT32(control_regs.cap, AHCIState),
1838 .name = "sysbus-ahci",
1849 ahci_reset(&s->ahci); in sysbus_ahci_reset()
1857 ahci_init(&s->ahci, DEVICE(obj)); in sysbus_ahci_init()
1859 sysbus_init_mmio(sbd, &s->ahci.mem); in sysbus_ahci_init()
1860 sysbus_init_irq(sbd, &s->ahci.irq); in sysbus_ahci_init()
1867 ahci_realize(&s->ahci, dev, &address_space_memory); in sysbus_ahci_realize()
1871 DEFINE_PROP_UINT32("num-ports", SysbusAHCIState, ahci.ports, 1),
1879 dc->realize = sysbus_ahci_realize; in sysbus_ahci_class_init()
1880 dc->vmsd = &vmstate_sysbus_ahci; in sysbus_ahci_class_init()
1883 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); in sysbus_ahci_class_init()
1905 for (i = 0; i < ahci->ports; i++) { in type_init()
1909 ide_bus_create_drive(&ahci->dev[i].port, 0, hd[i]); in type_init()