From patchwork Tue Jun 22 08:57:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaku Yamahata X-Patchwork-Id: 56439 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 E63F5B6EF1 for ; Tue, 22 Jun 2010 19:15:25 +1000 (EST) Received: from localhost ([127.0.0.1]:33998 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OQzZi-0003lh-M9 for incoming@patchwork.ozlabs.org; Tue, 22 Jun 2010 05:15:22 -0400 Received: from [140.186.70.92] (port=35007 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OQzPg-0007d3-42 for qemu-devel@nongnu.org; Tue, 22 Jun 2010 05:05:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OQzMR-0002rz-ST for qemu-devel@nongnu.org; Tue, 22 Jun 2010 05:01:42 -0400 Received: from mail.valinux.co.jp ([210.128.90.3]:55534) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OQzMR-0002rU-EF for qemu-devel@nongnu.org; Tue, 22 Jun 2010 05:01:39 -0400 Received: from ps.local.valinux.co.jp (vagw.valinux.co.jp [210.128.90.14]) by mail.valinux.co.jp (Postfix) with SMTP id 42B2D107419; Tue, 22 Jun 2010 18:01:38 +0900 (JST) Received: (nullmailer pid 28818 invoked by uid 1000); Tue, 22 Jun 2010 08:57:53 -0000 From: Isaku Yamahata To: seabios@seabios.org Date: Tue, 22 Jun 2010 17:57:49 +0900 Message-Id: X-Mailer: git-send-email 1.6.6.1 In-Reply-To: References: In-Reply-To: References: X-Virus-Scanned: clamav-milter 0.95.2 at va-mail.local.valinux.co.jp X-Virus-Status: Clean X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: stefano.stabellini@eu.citrix.com, jan.kiszka@siemens.com, mst@redhat.com, allen.m.kay@intel.com, qemu-devel@nongnu.org, yamahata@valinux.co.jp, jean.guyader@gmail.com Subject: [Qemu-devel] [PATCH v2 4/8] seabios: pciinit: make pci bar assigner preferchable memory aware. 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 Make pci bar assigner preferchable memory aware. This is needed for PCI bridge support because memory space and prefetchable memory space is filtered independently based on memory base/limit and prefetchable memory base/limit of pci bridge. On bus 0, such a distinction isn't necessary so keep existing behavior by checking bus=0. With this patch, pci mem assignment area has been decreased. To make seabios behave as before for compatible reason, define CONFIG_OLD_PCIMEM_ASSIGNMENT. Signed-off-by: Isaku Yamahata --- changes v1 -> v2. - introduced BUILD_PCI{MEM, PERFMEM}_{START, SIZE, END} - added range overlap check of pci mem/perfmem area. --- src/config.h | 17 +++++++++++++++++ src/pciinit.c | 49 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/config.h b/src/config.h index ad569c6..b1e17de 100644 --- a/src/config.h +++ b/src/config.h @@ -151,7 +151,24 @@ // 32KB for shadow ram copying (works around emulator deficiencies) #define BUILD_BIOS_TMP_ADDR 0x30000 #define BUILD_MAX_HIGHMEM 0xe0000000 + +// Support old pci mem assignment behaviour +//#define CONFIG_OLD_PCIMEM_ASSIGNMENT 1 +#if CONFIG_OLD_PCIMEM_ASSIGNMENT +#define BUILD_PCIMEM_START 0xf0000000 +#define BUILD_PCIMEM_SIZE (BUILD_PCIMEM_END - BUILD_PCIMEM_START) +#define BUILD_PCIMEM_END 0xfec00000 /* IOAPIC is mapped at */ +#define BUILD_PCIPREFMEM_START 0 +#define BUILD_PCIPREFMEM_SIZE 0 +#define BUILD_PCIPREFMEM_END 0 +#else #define BUILD_PCIMEM_START 0xf0000000 +#define BUILD_PCIMEM_SIZE 0x08000000 /* half- of pci window */ +#define BUILD_PCIMEM_END (BUILD_PCIMEM_START + BUILD_PCIMEM_SIZE) +#define BUILD_PCIPREFMEM_START BUILD_PCIMEM_END +#define BUILD_PCIPREFMEM_SIZE (BUILD_PCIPREFMEM_END - BUILD_PCIPREFMEM_START) +#define BUILD_PCIPREFMEM_END 0xfec00000 /* IOAPIC is mapped at */ +#endif #define BUILD_APIC_ADDR 0xfee00000 #define BUILD_IOAPIC_ADDR 0xfec00000 diff --git a/src/pciinit.c b/src/pciinit.c index b635e44..a65c58d 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -16,6 +16,7 @@ static u32 pci_bios_io_addr; static u32 pci_bios_mem_addr; +static u32 pci_bios_prefmem_addr; /* host irqs corresponding to PCI irqs A-D */ static u8 pci_irqs[4] = { 10, 10, 11, 11 @@ -66,21 +67,54 @@ static int pci_bios_allocate_region(u16 bdf, int region_num) u32 val = pci_config_readl(bdf, ofs); pci_config_writel(bdf, ofs, old); + u32 size = (~(val & mask)) + 1; if (val != 0) { - u32 size = (~(val & mask)) + 1; - if (val & PCI_BASE_ADDRESS_SPACE_IO) + if (val & PCI_BASE_ADDRESS_SPACE_IO) { paddr = &pci_bios_io_addr; - else + if (ALIGN(*paddr, size) + size >= 64 * 1024) { + dprintf(1, + "io region of (bdf 0x%x bar %d) can't be mapped.\n", + bdf, region_num); + size = 0; + } + } else if ((val & PCI_BASE_ADDRESS_MEM_PREFETCH) && + /* keep behaviour on bus = 0 */ + pci_bdf_to_bus(bdf) != 0 && + /* If pci_bios_prefmem_addr == 0, keep old behaviour */ + pci_bios_prefmem_addr != 0) { + paddr = &pci_bios_prefmem_addr; + if (ALIGN(*paddr, size) + size >= BUILD_PCIPREFMEM_END) { + dprintf(1, + "prefmem region of (bdf 0x%x bar %d) can't be mapped. " + "decrease BUILD_PCIMEM_SIZE and recompile. size %x\n", + bdf, region_num, BUILD_PCIPREFMEM_SIZE); + size = 0; + } + } else { paddr = &pci_bios_mem_addr; - *paddr = ALIGN(*paddr, size); - pci_set_io_region_addr(bdf, region_num, *paddr); - *paddr += size; + if (ALIGN(*paddr, size) + size >= BUILD_PCIMEM_END) { + dprintf(1, + "mem region of (bdf 0x%x bar %d) can't be mapped. " + "increase BUILD_PCIMEM_SIZE and recompile. size %x\n", + bdf, region_num, BUILD_PCIMEM_SIZE); + size = 0; + } + } + if (size > 0) { + *paddr = ALIGN(*paddr, size); + pci_set_io_region_addr(bdf, region_num, *paddr); + *paddr += size; + } } int is_64bit = !(val & PCI_BASE_ADDRESS_SPACE_IO) && (val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64; if (is_64bit) { - pci_config_writel(bdf, ofs + 4, 0); + if (size > 0) { + pci_config_writel(bdf, ofs + 4, 0); + } else { + pci_config_writel(bdf, ofs + 4, ~0); + } } return is_64bit; } @@ -220,6 +254,7 @@ pci_setup(void) pci_bios_io_addr = 0xc000; pci_bios_mem_addr = BUILD_PCIMEM_START; + pci_bios_prefmem_addr = BUILD_PCIPREFMEM_START; int bdf, max; foreachpci(bdf, max) {