From patchwork Tue Feb 9 16:37:01 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 44922 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 6F4D3B7D16 for ; Wed, 10 Feb 2010 03:58:58 +1100 (EST) Received: from localhost ([127.0.0.1]:44244 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NetK6-0002CW-Pj for incoming@patchwork.ozlabs.org; Tue, 09 Feb 2010 11:52:26 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Net5h-0006Lt-Rn for qemu-devel@nongnu.org; Tue, 09 Feb 2010 11:37:34 -0500 Received: from [199.232.76.173] (port=50216 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Net5g-0006LP-IX for qemu-devel@nongnu.org; Tue, 09 Feb 2010 11:37:32 -0500 Received: from Debian-exim by monty-python.gnu.org with spam-scanned (Exim 4.60) (envelope-from ) id 1Net5Q-0007DM-NP for qemu-devel@nongnu.org; Tue, 09 Feb 2010 11:37:32 -0500 Received: from cantor2.suse.de ([195.135.220.15]:43968 helo=mx2.suse.de) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Net5M-0007CE-K4 for qemu-devel@nongnu.org; Tue, 09 Feb 2010 11:37:13 -0500 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id 227E68726A; Tue, 9 Feb 2010 17:37:11 +0100 (CET) From: Alexander Graf To: qemu-devel@nongnu.org Date: Tue, 9 Feb 2010 17:37:01 +0100 Message-Id: <1265733430-9656-2-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1265733430-9656-1-git-send-email-agraf@suse.de> References: <1265733430-9656-1-git-send-email-agraf@suse.de> X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.4-2.6 Cc: blauwirbel@gmail.com, aurelien@aurel32.net, mst@redhat.com Subject: [Qemu-devel] [PATCH 01/10] PPC: Uninorth config space accessor X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The Uninorth PCI bridge requires different layouts in its PCI config space accessors. This patch introduces a conversion function that makes it compatible with the way Linux accesses it. I also kept an OpenBIOS compatibility hack in. I think it'd be better to take small steps here and do the config space access rework in OpenBIOS later on. When that's done we can remove that hack. Signed-off-by: Alexander Graf --- hw/unin_pci.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 66 insertions(+), 1 deletions(-) diff --git a/hw/unin_pci.c b/hw/unin_pci.c index 19eb5e0..0fbef1e 100644 --- a/hw/unin_pci.c +++ b/hw/unin_pci.c @@ -39,6 +39,7 @@ typedef struct UNINState { SysBusDevice busdev; PCIHostState host_state; + ReadWriteHandler data_handler; } UNINState; /* Don't know if this matches real hardware, but it agrees with OHW. */ @@ -75,6 +76,68 @@ static void pci_unin_reset(void *opaque) { } +static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr) +{ + uint32_t retval; + + if (reg & (1u << 31)) { + /* XXX OpenBIOS compatibility hack */ + retval = reg | (addr & 3); + } else if (reg & 1) { + /* CFA1 style */ + retval = (reg & ~7u) | (addr & 7); + } else { + uint32_t slot, func; + + /* Grab CFA0 style values */ + slot = ffs(reg & 0xfffff800) - 1; + func = (reg >> 8) & 7; + + /* ... and then convert them to x86 format */ + /* config pointer */ + retval = (reg & (0xff - 7)) | (addr & 7); + /* slot */ + retval |= slot << 11; + /* fn */ + retval |= func << 8; + } + + + UNIN_DPRINTF("Converted config space accessor %08x/%08x -> %08x\n", + reg, addr, retval); + + return retval; +} + +static void unin_data_write(ReadWriteHandler *handler, + uint64_t addr, uint32_t val, int len) +{ + UNINState *s = container_of(handler, UNINState, data_handler); +#ifdef TARGET_WORDS_BIGENDIAN + val = qemu_bswap_len(val, len); +#endif + UNIN_DPRINTF("write addr %" PRIx64 " len %d val %x\n", addr, len, val); + pci_data_write(s->host_state.bus, + unin_get_config_reg(s->host_state.config_reg, addr), + val, len); +} + +static uint32_t unin_data_read(ReadWriteHandler *handler, + uint64_t addr, int len) +{ + UNINState *s = container_of(handler, UNINState, data_handler); + uint32_t val; + + val = pci_data_read(s->host_state.bus, + unin_get_config_reg(s->host_state.config_reg, addr), + len); + UNIN_DPRINTF("read addr %" PRIx64 " len %d val %x\n", addr, len, val); +#ifdef TARGET_WORDS_BIGENDIAN + val = qemu_bswap_len(val, len); +#endif + return val; +} + static int pci_unin_main_init_device(SysBusDevice *dev) { UNINState *s; @@ -85,7 +148,9 @@ static int pci_unin_main_init_device(SysBusDevice *dev) s = FROM_SYSBUS(UNINState, dev); pci_mem_config = pci_host_conf_register_mmio(&s->host_state); - pci_mem_data = pci_host_data_register_mmio(&s->host_state); + s->data_handler.read = unin_data_read; + s->data_handler.write = unin_data_write; + pci_mem_data = cpu_register_io_memory_simple(&s->data_handler); sysbus_init_mmio(dev, 0x1000, pci_mem_config); sysbus_init_mmio(dev, 0x1000, pci_mem_data);