From patchwork Tue Sep 25 03:38:46 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hao, Xudong" X-Patchwork-Id: 186753 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B5CBC2C008F for ; Tue, 25 Sep 2012 20:19:35 +1000 (EST) Received: from localhost ([::1]:36917 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TGSEn-0006F5-Ht for incoming@patchwork.ozlabs.org; Tue, 25 Sep 2012 06:19:33 -0400 Received: from eggs.gnu.org ([208.118.235.92]:36274) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TGLvi-0007xK-0r for qemu-devel@nongnu.org; Mon, 24 Sep 2012 23:35:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TGLvg-0004pm-6E for qemu-devel@nongnu.org; Mon, 24 Sep 2012 23:35:25 -0400 Received: from mga02.intel.com ([134.134.136.20]:64426) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TGLvf-0004na-Tu for qemu-devel@nongnu.org; Mon, 24 Sep 2012 23:35:24 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 24 Sep 2012 20:35:15 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.80,478,1344236400"; d="scan'208";a="197250370" Received: from xhao-dev.sh.intel.com (HELO localhost.localdomain) ([10.239.48.48]) by orsmga001.jf.intel.com with ESMTP; 24 Sep 2012 20:35:13 -0700 From: Xudong Hao To: stefano.stabellini@eu.citrix.com Date: Tue, 25 Sep 2012 11:38:46 +0800 Message-Id: <1348544326-31334-1-git-send-email-xudong.hao@intel.com> X-Mailer: git-send-email 1.5.5 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 134.134.136.20 X-Mailman-Approved-At: Tue, 25 Sep 2012 06:19:24 -0400 Cc: Xudong Hao , qemu-devel@nongnu.org, xen-devel@lists.xen.org Subject: [Qemu-devel] [PATCH v2] qemu/xen: Add 64 bits big bar support on qemu X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Changes from v1: - Rebase to qemu upstream from qemu-xen Currently it is assumed PCI device BAR access < 4G memory. If there is such a device whose BAR size is larger than 4G, it must access > 4G memory address. This patch enable the 64bits big BAR support on qemu. Signed-off-by: Xudong Hao Signed-off-by: Xiantao Zhang --- hw/xen_pt.c | 16 ++++++++-------- hw/xen_pt_config_init.c | 42 +++++++++++++++++++++++++++++------------- diff --git a/hw/xen_pt.c b/hw/xen_pt.c index 307119a..2a8bcf3 100644 --- a/hw/xen_pt.c +++ b/hw/xen_pt.c @@ -403,21 +403,21 @@ static int xen_pt_register_regions(XenPCIPassthroughState *s) s->bases[i].access.u = r->base_addr; - if (r->type & XEN_HOST_PCI_REGION_TYPE_IO) { + if (r->type & XEN_HOST_PCI_REGION_TYPE_IO) type = PCI_BASE_ADDRESS_SPACE_IO; - } else { + else if (r->type & XEN_HOST_PCI_REGION_TYPE_MEM_64) + type = PCI_BASE_ADDRESS_MEM_TYPE_64; + else if (r->type & XEN_HOST_PCI_REGION_TYPE_PREFETCH) + type |= PCI_BASE_ADDRESS_MEM_PREFETCH; + else type = PCI_BASE_ADDRESS_SPACE_MEMORY; - if (r->type & XEN_HOST_PCI_REGION_TYPE_PREFETCH) { - type |= PCI_BASE_ADDRESS_MEM_PREFETCH; - } - } memory_region_init_io(&s->bar[i], &ops, &s->dev, "xen-pci-pt-bar", r->size); pci_register_bar(&s->dev, i, type, &s->bar[i]); - XEN_PT_LOG(&s->dev, "IO region %i registered (size=0x%08"PRIx64 - " base_addr=0x%08"PRIx64" type: %#x)\n", + XEN_PT_LOG(&s->dev, "IO region %i registered (size=0x%lx"PRIx64 + " base_addr=0x%lx"PRIx64" type: %#x)\n", i, r->size, r->base_addr, type); } diff --git a/hw/xen_pt_config_init.c b/hw/xen_pt_config_init.c index e524a40..5e7ca22 100644 --- a/hw/xen_pt_config_init.c +++ b/hw/xen_pt_config_init.c @@ -342,6 +342,7 @@ static int xen_pt_cmd_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry, #define XEN_PT_BAR_IO_RO_MASK 0x00000003 /* BAR ReadOnly mask(I/O) */ #define XEN_PT_BAR_IO_EMU_MASK 0xFFFFFFFC /* BAR emul mask(I/O) */ +static uint64_t xen_pt_get_bar_size(PCIIORegion *r); static XenPTBarFlag xen_pt_bar_reg_parse(XenPCIPassthroughState *s, XenPTRegInfo *reg) { @@ -366,7 +367,7 @@ static XenPTBarFlag xen_pt_bar_reg_parse(XenPCIPassthroughState *s, /* check unused BAR */ r = &d->io_regions[index]; - if (r->size == 0) { + if (!xen_pt_get_bar_size(r)) { return XEN_PT_BAR_FLAG_UNUSED; } @@ -383,6 +384,24 @@ static XenPTBarFlag xen_pt_bar_reg_parse(XenPCIPassthroughState *s, } } +static bool is_64bit_bar(PCIIORegion *r) +{ + return !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64); +} + +static uint64_t xen_pt_get_bar_size(PCIIORegion *r) +{ + if (is_64bit_bar(r)) + { + uint64_t size64; + size64 = (r + 1)->size; + size64 <<= 32; + size64 += r->size; + return size64; + } + return r->size; +} + static inline uint32_t base_address_with_flags(XenHostPCIIORegion *hr) { if (hr->type & XEN_HOST_PCI_REGION_TYPE_IO) { @@ -481,7 +500,10 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry, switch (s->bases[index].bar_flag) { case XEN_PT_BAR_FLAG_MEM: bar_emu_mask = XEN_PT_BAR_MEM_EMU_MASK; - bar_ro_mask = XEN_PT_BAR_MEM_RO_MASK | (r_size - 1); + if (!r_size) + bar_ro_mask = XEN_PT_BAR_ALLF; + else + bar_ro_mask = XEN_PT_BAR_MEM_RO_MASK | (r_size - 1); break; case XEN_PT_BAR_FLAG_IO: bar_emu_mask = XEN_PT_BAR_IO_EMU_MASK; @@ -489,7 +511,10 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry, break; case XEN_PT_BAR_FLAG_UPPER: bar_emu_mask = XEN_PT_BAR_ALLF; - bar_ro_mask = 0; /* all upper 32bit are R/W */ + if (!r_size) + bar_ro_mask = 0; + else + bar_ro_mask = r_size - 1; break; default: break; @@ -501,22 +526,13 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry, /* check whether we need to update the virtual region address or not */ switch (s->bases[index].bar_flag) { + case XEN_PT_BAR_FLAG_UPPER: case XEN_PT_BAR_FLAG_MEM: /* nothing to do */ break; case XEN_PT_BAR_FLAG_IO: /* nothing to do */ break; - case XEN_PT_BAR_FLAG_UPPER: - if (cfg_entry->data) { - if (cfg_entry->data != (XEN_PT_BAR_ALLF & ~bar_ro_mask)) { - XEN_PT_WARN(d, "Guest attempt to set high MMIO Base Address. " - "Ignore mapping. " - "(offset: 0x%02x, high address: 0x%08x)\n", - reg->offset, cfg_entry->data); - } - } - break; default: break; }