提交 a5444d15 编写于 作者: I Ingo Molnar 提交者: H. Peter Anvin

x86: split e820 reserved entries record to late v4

this one replaces:

| commit a2bd7274
| Author: Yinghai Lu <yhlu.kernel@gmail.com>
| Date:   Mon Aug 25 00:56:08 2008 -0700
|
|    x86: fix HPET regression in 2.6.26 versus 2.6.25, check hpet against BAR, v3

v2: insert e820 reserve resources before pnp_system_init
v3: fix merging problem in tip/x86/core
v4: address Linus's review about comments and condition in _late()
Signed-off-by: NYinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: NIngo Molnar <mingo@elte.hu>
上级 58f7c988
......@@ -1271,12 +1271,12 @@ static inline const char *e820_type_to_string(int e820_type)
/*
* Mark e820 reserved areas as busy for the resource manager.
*/
struct resource __initdata *e820_res;
static struct resource __initdata *e820_res;
void __init e820_reserve_resources(void)
{
int i;
u64 end;
struct resource *res;
u64 end;
res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map);
e820_res = res;
......@@ -1293,6 +1293,12 @@ void __init e820_reserve_resources(void)
res->end = end;
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
/*
* don't register the region that could be conflicted with
* pci device BAR resource and insert them later in
* pcibios_resource_survey()
*/
if (e820.map[i].type != E820_RESERVED || res->start < (1ULL<<20))
insert_resource(&iomem_resource, res);
res++;
......@@ -1313,7 +1319,7 @@ void __init e820_reserve_resources_late(void)
res = e820_res;
for (i = 0; i < e820.nr_map; i++) {
if (e820.map[i].type == E820_RESERVED && res->start >= (1ULL<<20))
if (!res->parent && res->end)
insert_resource(&iomem_resource, res);
res++;
}
......
......@@ -31,11 +31,8 @@
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/bootmem.h>
#include <linux/acpi.h>
#include <asm/pat.h>
#include <asm/hpet.h>
#include <asm/io_apic.h>
#include <asm/e820.h>
#include "pci.h"
......@@ -81,77 +78,6 @@ pcibios_align_resource(void *data, struct resource *res,
}
EXPORT_SYMBOL(pcibios_align_resource);
static int check_res_with_valid(struct pci_dev *dev, struct resource *res)
{
unsigned long base;
unsigned long size;
int i;
base = res->start;
size = (res->start == 0 && res->end == res->start) ? 0 :
(res->end - res->start + 1);
if (!base || !size)
return 0;
#ifdef CONFIG_HPET_TIMER
/* for hpet */
if (base == hpet_address && (res->flags & IORESOURCE_MEM)) {
dev_info(&dev->dev, "BAR has HPET at %08lx-%08lx\n",
base, base + size - 1);
return 1;
}
#endif
#ifdef CONFIG_X86_IO_APIC
for (i = 0; i < nr_ioapics; i++) {
unsigned long ioapic_phys = mp_ioapics[i].mp_apicaddr;
if (base == ioapic_phys && (res->flags & IORESOURCE_MEM)) {
dev_info(&dev->dev, "BAR has ioapic at %08lx-%08lx\n",
base, base + size - 1);
return 1;
}
}
#endif
#ifdef CONFIG_PCI_MMCONFIG
for (i = 0; i < pci_mmcfg_config_num; i++) {
unsigned long addr;
addr = pci_mmcfg_config[i].address;
if (base == addr && (res->flags & IORESOURCE_MEM)) {
dev_info(&dev->dev, "BAR has MMCONFIG at %08lx-%08lx\n",
base, base + size - 1);
return 1;
}
}
#endif
return 0;
}
static int check_platform(struct pci_dev *dev, struct resource *res)
{
struct resource *root = NULL;
/*
* forcibly insert it into the
* resource tree
*/
if (res->flags & IORESOURCE_MEM)
root = &iomem_resource;
else if (res->flags & IORESOURCE_IO)
root = &ioport_resource;
if (root && check_res_with_valid(dev, res)) {
insert_resource(root, res);
return 1;
}
return 0;
}
/*
* Handle resources of PCI devices. If the world were perfect, we could
* just allocate all the resource regions and do nothing more. It isn't.
......@@ -203,8 +129,6 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
pr = pci_find_parent_resource(dev, r);
if (!r->start || !pr ||
request_resource(pr, r) < 0) {
if (check_platform(dev, r))
continue;
dev_err(&dev->dev, "BAR %d: can't allocate resource\n", idx);
/*
* Something is wrong with the region.
......@@ -246,8 +170,6 @@ static void __init pcibios_allocate_resources(int pass)
r->flags, disabled, pass);
pr = pci_find_parent_resource(dev, r);
if (!pr || request_resource(pr, r) < 0) {
if (check_platform(dev, r))
continue;
dev_err(&dev->dev, "BAR %d: can't allocate resource\n", idx);
/* We'll assign a new address later */
r->end -= r->start;
......@@ -306,6 +228,8 @@ void __init pcibios_resource_survey(void)
pcibios_allocate_bus_resources(&pci_root_buses);
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
e820_reserve_resources_late();
}
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册