Date: Mon, 28 Apr 2014 18:41:26 +0000 (UTC) From: Peter Grehan <grehan@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r265058 - head/usr.sbin/bhyve Message-ID: <201404281841.s3SIfQ4F080289@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: grehan Date: Mon Apr 28 18:41:25 2014 New Revision: 265058 URL: http://svnweb.freebsd.org/changeset/base/265058 Log: Implement legacy interrupts for the AHCI device emulation according to the method outlined in the AHCI spec. Tested with FreeBSD 9/10/11 with MSI disabled, and also NetBSD/amd64 (lightly). Reviewed by: neel, tychon MFC after: 3 weeks Modified: head/usr.sbin/bhyve/pci_ahci.c Modified: head/usr.sbin/bhyve/pci_ahci.c ============================================================================== --- head/usr.sbin/bhyve/pci_ahci.c Mon Apr 28 18:25:21 2014 (r265057) +++ head/usr.sbin/bhyve/pci_ahci.c Mon Apr 28 18:41:25 2014 (r265058) @@ -192,6 +192,7 @@ struct pci_ahci_softc { uint32_t em_ctl; uint32_t cap2; uint32_t bohc; + uint32_t lintr; struct ahci_port port[MAX_PORTS]; }; #define ahci_ctx(sc) ((sc)->asc_pi->pi_vmctx) @@ -211,8 +212,11 @@ static inline void lba_to_msf(uint8_t *b static void ahci_generate_intr(struct pci_ahci_softc *sc) { + struct pci_devinst *pi; int i; + pi = sc->asc_pi; + for (i = 0; i < sc->ports; i++) { struct ahci_port *pr; pr = &sc->port[i]; @@ -222,8 +226,28 @@ ahci_generate_intr(struct pci_ahci_softc DPRINTF("%s %x\n", __func__, sc->is); - if (sc->is && (sc->ghc & AHCI_GHC_IE)) - pci_generate_msi(sc->asc_pi, 0); + if (sc->is && (sc->ghc & AHCI_GHC_IE)) { + if (pci_msi_enabled(pi)) { + /* + * Generate an MSI interrupt on every edge + */ + pci_generate_msi(pi, 0); + } else if (!sc->lintr) { + /* + * Only generate a pin-based interrupt if one wasn't + * in progress + */ + sc->lintr = 1; + pci_lintr_assert(pi); + } + } else if (sc->lintr) { + /* + * No interrupts: deassert pin-based signal if it had + * been asserted + */ + pci_lintr_deassert(pi); + sc->lintr = 0; + } } static void @@ -367,6 +391,12 @@ ahci_reset(struct pci_ahci_softc *sc) sc->ghc = AHCI_GHC_AE; sc->is = 0; + + if (sc->lintr) { + pci_lintr_deassert(sc->asc_pi); + sc->lintr = 0; + } + for (i = 0; i < sc->ports; i++) { sc->port[i].ie = 0; sc->port[i].is = 0; @@ -1814,6 +1844,8 @@ pci_ahci_init(struct vmctx *ctx, struct pci_emul_alloc_bar(pi, 5, PCIBAR_MEM32, AHCI_OFFSET + sc->ports * AHCI_STEP); + pci_lintr_request(pi); + open_fail: if (ret) { blockif_close(sc->port[0].bctx);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201404281841.s3SIfQ4F080289>