From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Mv6Rr-0007Ui-MK for qemu-devel@nongnu.org; Tue, 06 Oct 2009 05:35:11 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Mv6Rm-0007Sj-Ng for qemu-devel@nongnu.org; Tue, 06 Oct 2009 05:35:11 -0400 Received: from [199.232.76.173] (port=43266 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Mv6Rm-0007Sd-Eo for qemu-devel@nongnu.org; Tue, 06 Oct 2009 05:35:06 -0400 Received: from mx1.redhat.com ([209.132.183.28]:4739) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Mv6Rl-0007kj-Uv for qemu-devel@nongnu.org; Tue, 06 Oct 2009 05:35:06 -0400 Date: Tue, 6 Oct 2009 11:33:03 +0200 From: "Michael S. Tsirkin" Subject: Re: [Qemu-devel] [PATCH 5/9] pci: 64bit bar support. Message-ID: <20091006093302.GB8854@redhat.com> References: <1247656509-32227-1-git-send-email-yamahata@valinux.co.jp> <1247656509-32227-6-git-send-email-yamahata@valinux.co.jp> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1247656509-32227-6-git-send-email-yamahata@valinux.co.jp> List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Isaku Yamahata Cc: qemu-devel@nongnu.org On Wed, Jul 15, 2009 at 08:15:05PM +0900, Isaku Yamahata wrote: > implemented pci 64bit bar support. > > Signed-off-by: Isaku Yamahata > --- > hw/pci.c | 46 ++++++++++++++++++++++++++++++++++++++++------ > hw/pci.h | 9 +++++++++ > 2 files changed, 49 insertions(+), 6 deletions(-) > > diff --git a/hw/pci.c b/hw/pci.c > index 2d985f0..9639a32 100644 > --- a/hw/pci.c > +++ b/hw/pci.c > @@ -429,9 +429,15 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, > } else { > addr = 0x10 + region_num * 4; > } > + > *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type); > - *(uint32_t *)(pci_dev->wmask + addr) = cpu_to_le32(wmask & 0xffffffff); > - *(uint32_t *)(pci_dev->cmask + addr) = 0xffffffff; > + if (pci_bar_is_64bit(r)) { > + *(uint64_t *)(pci_dev->wmask + addr) = cpu_to_le64(wmask); > + *(uint64_t *)(pci_dev->cmask + addr) = ~0ULL; > + } else { > + *(uint32_t *)(pci_dev->wmask + addr) = cpu_to_le32(wmask & 0xffffffff); > + *(uint32_t *)(pci_dev->cmask + addr) = 0xffffffff; > + } > } > > static void pci_update_mappings(PCIDevice *d) > @@ -466,8 +472,14 @@ static void pci_update_mappings(PCIDevice *d) > } > } else { > if (cmd & PCI_COMMAND_MEMORY) { > - new_addr = le32_to_cpu(*(uint32_t *)(d->config + > - config_ofs)); > + > + if (pci_bar_is_64bit(r)) { > + new_addr = le64_to_cpu(*(uint64_t *)(d->config + > + config_ofs)); > + } else { > + new_addr = le32_to_cpu(*(uint32_t *)(d->config + > + config_ofs)); > + } shouldn't new_addr be uint64_t then? > /* the ROM slot has a specific enable bit */ > if (i == PCI_ROM_SLOT && !(new_addr & 1)) > goto no_mem_map; > @@ -482,7 +494,7 @@ static void pci_update_mappings(PCIDevice *d) > > /* keep old behaviour > * without this, PC ide doesn't work well. */ > - last_addr >= UINT32_MAX) { > + (!pci_bar_is_64bit(r) && last_addr >= UINT32_MAX)) { > new_addr = PCI_BAR_UNMAPPED; > } > } else { > @@ -741,7 +753,29 @@ static void pci_info_device(PCIDevice *d) > monitor_printf(mon, "I/O at 0x%04"PRIx64" [0x%04"PRIx64"].\n", > r->addr, r->addr + r->size - 1); > } else { > - monitor_printf(mon, "32 bit memory at 0x%08"PRIx64" [0x%08"PRIx64"].\n", > + const char *type; > + const char* prefetch; > + > + switch (r->type & PCI_ADDRESS_SPACE_MEM_TYPE_MASK) { > + case PCI_ADDRESS_SPACE_MEM: > + type = "32 bit"; > + break; > + case PCI_ADDRESS_SPACE_MEM_64: > + type = "64 bit"; > + break; > + default: > + type = "unknown"; > + break; > + } > + > + prefetch = ""; > + if (r->type & PCI_ADDRESS_SPACE_MEM_PREFETCH) { > + prefetch = " prefetchable"; > + } > + > + monitor_printf(mon, "%s%s memory at " > + "0x%08"PRIx64" [0x%08"PRIx64"].\n", > + type, prefetch, > r->addr, r->addr + r->size - 1); > } > } > diff --git a/hw/pci.h b/hw/pci.h > index fee9ed6..33e2ef2 100644 > --- a/hw/pci.h > +++ b/hw/pci.h > @@ -80,6 +80,8 @@ typedef int PCIUnregisterFunc(PCIDevice *pci_dev); > > #define PCI_ADDRESS_SPACE_MEM 0x00 > #define PCI_ADDRESS_SPACE_IO 0x01 > +#define PCI_ADDRESS_SPACE_MEM_64 0x04 /* 64 bit address */ > +#define PCI_ADDRESS_SPACE_MEM_TYPE_MASK 0x06 > #define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08 > > typedef struct PCIIORegion { > @@ -90,6 +92,13 @@ typedef struct PCIIORegion { > PCIMapIORegionFunc *map_func; > } PCIIORegion; > > +static inline int pci_bar_is_64bit(const PCIIORegion *r) > +{ > + return !(r->type & PCI_ADDRESS_SPACE_IO) && > + ((r->type & PCI_ADDRESS_SPACE_MEM_TYPE_MASK) == > + PCI_ADDRESS_SPACE_MEM_64); > +} > + > #define PCI_ROM_SLOT 6 > #define PCI_NUM_REGIONS 7 > > -- > 1.6.0.2 > >