socsvn commit: r255258 - soc2013/zcore/head/usr.sbin/bhyve
zcore at FreeBSD.org
zcore at FreeBSD.org
Sun Jul 28 09:08:31 UTC 2013
Author: zcore
Date: Sun Jul 28 09:08:31 2013
New Revision: 255258
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=255258
Log:
add reset and interrupt support
Modified:
soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c
Modified: soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c
==============================================================================
--- soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c Sun Jul 28 09:07:08 2013 (r255257)
+++ soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c Sun Jul 28 09:08:31 2013 (r255258)
@@ -127,6 +127,27 @@
};
/*
+ * generate HBA intr depending on whether or not ports within
+ * the controller have an interrupt pending.
+ */
+static void
+ahci_generate_intr(struct pci_ahci_softc *sc)
+{
+ int i;
+
+ for (i = 0; i < sc->ports; i++) {
+ struct ahci_port *pr;
+ pr = &sc->port[i];
+ if (pr->is & pr->ie)
+ sc->is |= (1 << i);
+ }
+
+ DPRINTF(("%s %x\n", __func__, sc->is));
+ if (sc->is && (sc->ghc & AHCI_GHC_IE))
+ pci_generate_msi(sc->asc_pi, 0);
+}
+
+/*
* blockif callback routine - this runs in the context of the blockif
* i/o thread, so the mutex needs to be acquired.
*/
@@ -146,6 +167,7 @@
/* TODO */
+ ahci_generate_intr(sc);
/*
* Move the blockif request back to the free list
*/
@@ -154,7 +176,6 @@
pthread_mutex_unlock(&sc->mtx);
DPRINTF(("%s exit\n", __func__));
-
}
static void
@@ -180,6 +201,30 @@
}
}
+static void
+ahci_port_reset(struct ahci_port *pr)
+{
+ memset(&pr->clb, 0, 17 * sizeof(uint32_t));
+ pr->sig = 0xFFFFFFFF;
+ pr->tfd = 0x7F;
+ if (pr->bctx)
+ pr->ssts = ATA_SS_DET_PHY_ONLINE | ATA_SS_SPD_GEN2 |
+ ATA_SS_IPM_ACTIVE;
+ else
+ pr->ssts = ATA_SS_DET_NO_DEVICE;
+}
+
+static void
+ahci_reset(struct pci_ahci_softc *sc)
+{
+ int i;
+
+ sc->ghc = AHCI_GHC_AE;
+ sc->is = 0;
+ for (i = 0; i < sc->ports; i++)
+ ahci_port_reset(&sc->port[i]);
+}
+
static int
pci_ahci_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
{
@@ -235,6 +280,7 @@
sc->pi = (1 << sc->ports) - 1;
sc->vs = 0x10300;
sc->cap2 = AHCI_CAP2_APST;
+ ahci_reset(sc);
pci_set_cfgdata16(pi, PCIR_DEVICE, 0x1c03);
pci_set_cfgdata16(pi, PCIR_VENDOR, 0x8086);
@@ -273,9 +319,11 @@
break;
case AHCI_P_IS:
p->is &= ~value;
+ ahci_generate_intr(sc);
break;
case AHCI_P_IE:
- p->ie = value & 0xfdc000ff;
+ p->ie = value & 0xFDC000FF;
+ ahci_generate_intr(sc);
break;
case AHCI_P_CMD:
/* TODO */
@@ -286,14 +334,20 @@
WPRINTF(("pci_ahci_port: read only registers 0x%lx\n", offset));
break;
case AHCI_P_SCTL:
- /* TODO */
+ if (!(p->cmd & AHCI_P_CMD_ST)) {
+ if (value & ATA_SC_DET_RESET)
+ ahci_port_reset(p);
+ p->sctl = value;
+ }
break;
case AHCI_P_SERR:
p->serr &= ~value;
break;
case AHCI_P_SACT:
+ p->sact |= value;
break;
case AHCI_P_CI:
+ p->ci |= value;
/* TODO */
break;
case AHCI_P_SNTF:
@@ -316,6 +370,18 @@
case AHCI_CAP2:
WPRINTF(("pci_ahci_host: read only registers 0x%lx\n", offset));
break;
+ case AHCI_GHC:
+ if (value & AHCI_GHC_HR)
+ ahci_reset(sc);
+ else if (value & AHCI_GHC_IE) {
+ sc->ghc |= AHCI_GHC_IE;
+ ahci_generate_intr(sc);
+ }
+ break;
+ case AHCI_IS:
+ sc->is &= ~value;
+ ahci_generate_intr(sc);
+ break;
default:
break;
}
@@ -396,6 +462,7 @@
case AHCI_P_SCTL:
case AHCI_P_SERR:
case AHCI_P_SACT:
+ /* TODO */
case AHCI_P_CI:
case AHCI_P_SNTF:
case AHCI_P_FBS:
More information about the svn-soc-all
mailing list