From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:42568) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T9WHC-0004wJ-8D for qemu-devel@nongnu.org; Thu, 06 Sep 2012 03:13:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T9WGv-0006TY-PC for qemu-devel@nongnu.org; Thu, 06 Sep 2012 03:13:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:22615) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T9WGv-0006T7-Gi for qemu-devel@nongnu.org; Thu, 06 Sep 2012 03:13:05 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q867D5a0013904 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 6 Sep 2012 03:13:05 -0400 From: Gerd Hoffmann Date: Thu, 6 Sep 2012 09:12:48 +0200 Message-Id: <1346915575-12369-48-git-send-email-kraxel@redhat.com> In-Reply-To: <1346915575-12369-1-git-send-email-kraxel@redhat.com> References: <1346915575-12369-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH 47/54] xhci: add msix support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann --- hw/usb/hcd-xhci.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- trace-events | 3 +++ 2 files changed, 49 insertions(+), 1 deletions(-) diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 5eae32e..3bac99a 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -23,6 +23,7 @@ #include "hw/usb.h" #include "hw/pci.h" #include "hw/msi.h" +#include "hw/msix.h" #include "trace.h" //#define DEBUG_XHCI @@ -59,6 +60,8 @@ #define OFF_OPER LEN_CAP #define OFF_RUNTIME 0x1000 #define OFF_DOORBELL 0x2000 +#define OFF_MSIX_TABLE 0x3000 +#define OFF_MSIX_PBA 0x3800 /* must be power of 2 */ #define LEN_REGS 0x4000 @@ -411,6 +414,7 @@ struct XHCIState { uint32_t erstba_high; uint32_t erdp_low; uint32_t erdp_high; + bool msix_used; int64_t mfindex_start; QEMUTimer *mfwrap_timer; @@ -437,6 +441,7 @@ typedef struct XHCIEvRingSeg { enum xhci_flags { XHCI_FLAG_USE_MSI = 1, + XHCI_FLAG_USE_MSI_X, }; static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, @@ -616,7 +621,8 @@ static void xhci_intx_update(XHCIState *xhci) { int level = 0; - if (msi_enabled(&xhci->pci_dev)) { + if (msix_enabled(&xhci->pci_dev) || + msi_enabled(&xhci->pci_dev)) { return; } @@ -630,6 +636,30 @@ static void xhci_intx_update(XHCIState *xhci) qemu_set_irq(xhci->irq, level); } +static void xhci_msix_update(XHCIState *xhci) +{ + bool enabled; + + if (!msix_enabled(&xhci->pci_dev)) { + return; + } + + enabled = xhci->iman & IMAN_IE; + if (enabled == xhci->msix_used) { + return; + } + + if (enabled) { + trace_usb_xhci_irq_msix_use(0); + msix_vector_use(&xhci->pci_dev, 0); + xhci->msix_used = true; + } else { + trace_usb_xhci_irq_msix_unuse(0); + msix_vector_unuse(&xhci->pci_dev, 0); + xhci->msix_used = false; + } +} + static void xhci_intr_raise(XHCIState *xhci) { if (!(xhci->iman & IMAN_IP) || @@ -641,6 +671,12 @@ static void xhci_intr_raise(XHCIState *xhci) return; } + if (msix_enabled(&xhci->pci_dev)) { + trace_usb_xhci_irq_msix(0); + msix_notify(&xhci->pci_dev, 0); + return; + } + if (msi_enabled(&xhci->pci_dev)) { trace_usb_xhci_irq_msi(0); msi_notify(&xhci->pci_dev, 0); @@ -2284,6 +2320,7 @@ static void xhci_reset(DeviceState *dev) xhci->erstba_high = 0; xhci->erdp_low = 0; xhci->erdp_high = 0; + xhci->msix_used = 0; xhci->er_ep_idx = 0; xhci->er_pcs = 1; @@ -2592,6 +2629,7 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) xhci->iman &= ~IMAN_IE; xhci->iman |= val & IMAN_IE; xhci_intx_update(xhci); + xhci_msix_update(xhci); break; case 0x24: /* IMOD */ xhci->imod = val; @@ -2885,6 +2923,12 @@ static int usb_xhci_initfn(struct PCIDevice *dev) if (xhci->flags & (1 << XHCI_FLAG_USE_MSI)) { msi_init(&xhci->pci_dev, 0x70, MAXINTRS, true, false); } + if (xhci->flags & (1 << XHCI_FLAG_USE_MSI_X)) { + msix_init(&xhci->pci_dev, MAXINTRS, + &xhci->mem, 0, OFF_MSIX_TABLE, + &xhci->mem, 0, OFF_MSIX_PBA, + 0x90); + } return 0; } @@ -2896,6 +2940,7 @@ static const VMStateDescription vmstate_xhci = { static Property xhci_properties[] = { DEFINE_PROP_BIT("msi", XHCIState, flags, XHCI_FLAG_USE_MSI, true), + DEFINE_PROP_BIT("msix", XHCIState, flags, XHCI_FLAG_USE_MSI_X, true), DEFINE_PROP_UINT32("p2", XHCIState, numports_2, 4), DEFINE_PROP_UINT32("p3", XHCIState, numports_3, 4), DEFINE_PROP_END_OF_LIST(), diff --git a/trace-events b/trace-events index 09972ad..f03745c 100644 --- a/trace-events +++ b/trace-events @@ -313,6 +313,9 @@ usb_xhci_runtime_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x" usb_xhci_doorbell_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x" usb_xhci_irq_intx(uint32_t level) "level %d" usb_xhci_irq_msi(uint32_t nr) "nr %d" +usb_xhci_irq_msix(uint32_t nr) "nr %d" +usb_xhci_irq_msix_use(uint32_t nr) "nr %d" +usb_xhci_irq_msix_unuse(uint32_t nr) "nr %d" usb_xhci_queue_event(uint32_t idx, const char *trb, const char *evt, uint64_t param, uint32_t status, uint32_t control) "idx %d, %s, %s, p %016" PRIx64 ", s %08x, c 0x%08x" usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x" usb_xhci_slot_enable(uint32_t slotid) "slotid %d" -- 1.7.1