x86: split e820 reserved entries record to late v2
so could let BAR res register at first, or even pnp. v2: insert e820 reserve resources before pnp_system_init Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
committed by
H. Peter Anvin
parent
0ccd8c39bc
commit
58f7c98850
@@ -1271,13 +1271,15 @@ static inline const char *e820_type_to_string(int e820_type)
|
|||||||
/*
|
/*
|
||||||
* Mark e820 reserved areas as busy for the resource manager.
|
* Mark e820 reserved areas as busy for the resource manager.
|
||||||
*/
|
*/
|
||||||
|
struct resource __initdata *e820_res;
|
||||||
void __init e820_reserve_resources(void)
|
void __init e820_reserve_resources(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct resource *res;
|
|
||||||
u64 end;
|
u64 end;
|
||||||
|
struct resource *res;
|
||||||
|
|
||||||
res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map);
|
res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map);
|
||||||
|
e820_res = res;
|
||||||
for (i = 0; i < e820.nr_map; i++) {
|
for (i = 0; i < e820.nr_map; i++) {
|
||||||
end = e820.map[i].addr + e820.map[i].size - 1;
|
end = e820.map[i].addr + e820.map[i].size - 1;
|
||||||
#ifndef CONFIG_RESOURCES_64BIT
|
#ifndef CONFIG_RESOURCES_64BIT
|
||||||
@@ -1291,7 +1293,8 @@ void __init e820_reserve_resources(void)
|
|||||||
res->end = end;
|
res->end = end;
|
||||||
|
|
||||||
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
|
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
|
||||||
insert_resource(&iomem_resource, res);
|
if (e820.map[i].type != E820_RESERVED || res->start < (1ULL<<20))
|
||||||
|
insert_resource(&iomem_resource, res);
|
||||||
res++;
|
res++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1303,6 +1306,19 @@ void __init e820_reserve_resources(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __init e820_reserve_resources_late(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct resource *res;
|
||||||
|
|
||||||
|
res = e820_res;
|
||||||
|
for (i = 0; i < e820.nr_map; i++) {
|
||||||
|
if (e820.map[i].type == E820_RESERVED && res->start >= (1ULL<<20))
|
||||||
|
insert_resource(&iomem_resource, res);
|
||||||
|
res++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char *__init default_machine_specific_memory_setup(void)
|
char *__init default_machine_specific_memory_setup(void)
|
||||||
{
|
{
|
||||||
char *who = "BIOS-e820";
|
char *who = "BIOS-e820";
|
||||||
|
@@ -31,8 +31,12 @@
|
|||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
|
#include <linux/acpi.h>
|
||||||
|
|
||||||
#include <asm/pat.h>
|
#include <asm/pat.h>
|
||||||
|
#include <asm/hpet.h>
|
||||||
|
#include <asm/io_apic.h>
|
||||||
|
#include <asm/e820.h>
|
||||||
|
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
|
|
||||||
@@ -77,6 +81,77 @@ pcibios_align_resource(void *data, struct resource *res,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pcibios_align_resource);
|
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
|
* 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.
|
* just allocate all the resource regions and do nothing more. It isn't.
|
||||||
@@ -128,6 +203,8 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
|
|||||||
pr = pci_find_parent_resource(dev, r);
|
pr = pci_find_parent_resource(dev, r);
|
||||||
if (!r->start || !pr ||
|
if (!r->start || !pr ||
|
||||||
request_resource(pr, r) < 0) {
|
request_resource(pr, r) < 0) {
|
||||||
|
if (check_platform(dev, r))
|
||||||
|
continue;
|
||||||
dev_err(&dev->dev, "BAR %d: can't allocate resource\n", idx);
|
dev_err(&dev->dev, "BAR %d: can't allocate resource\n", idx);
|
||||||
/*
|
/*
|
||||||
* Something is wrong with the region.
|
* Something is wrong with the region.
|
||||||
@@ -169,6 +246,8 @@ static void __init pcibios_allocate_resources(int pass)
|
|||||||
r->flags, disabled, pass);
|
r->flags, disabled, pass);
|
||||||
pr = pci_find_parent_resource(dev, r);
|
pr = pci_find_parent_resource(dev, r);
|
||||||
if (!pr || request_resource(pr, r) < 0) {
|
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);
|
dev_err(&dev->dev, "BAR %d: can't allocate resource\n", idx);
|
||||||
/* We'll assign a new address later */
|
/* We'll assign a new address later */
|
||||||
r->end -= r->start;
|
r->end -= r->start;
|
||||||
|
@@ -122,6 +122,7 @@ extern void e820_register_active_regions(int nid, unsigned long start_pfn,
|
|||||||
extern u64 e820_hole_size(u64 start, u64 end);
|
extern u64 e820_hole_size(u64 start, u64 end);
|
||||||
extern void finish_e820_parsing(void);
|
extern void finish_e820_parsing(void);
|
||||||
extern void e820_reserve_resources(void);
|
extern void e820_reserve_resources(void);
|
||||||
|
extern void e820_reserve_resources_late(void);
|
||||||
extern void setup_memory_map(void);
|
extern void setup_memory_map(void);
|
||||||
extern char *default_machine_specific_memory_setup(void);
|
extern char *default_machine_specific_memory_setup(void);
|
||||||
extern char *machine_specific_memory_setup(void);
|
extern char *machine_specific_memory_setup(void);
|
||||||
|
Reference in New Issue
Block a user