Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58f7c988 authored by Yinghai Lu's avatar Yinghai Lu Committed by H. Peter Anvin
Browse files

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: default avatarYinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 0ccd8c39
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -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.
 */
struct resource __initdata *e820_res;
void __init e820_reserve_resources(void)
{
	int i;
	struct resource *res;
	u64 end;
	struct resource *res;

	res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map);
	e820_res = res;
	for (i = 0; i < e820.nr_map; i++) {
		end = e820.map[i].addr + e820.map[i].size - 1;
#ifndef CONFIG_RESOURCES_64BIT
@@ -1291,6 +1293,7 @@ void __init e820_reserve_resources(void)
		res->end = end;

		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
		if (e820.map[i].type != E820_RESERVED || res->start < (1ULL<<20))
			insert_resource(&iomem_resource, 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 *who = "BIOS-e820";
+79 −0
Original line number Diff line number Diff line
@@ -31,8 +31,12 @@
#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"

@@ -77,6 +81,77 @@ 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.
@@ -128,6 +203,8 @@ 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.
@@ -169,6 +246,8 @@ 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;
+1 −0
Original line number Diff line number Diff line
@@ -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 void finish_e820_parsing(void);
extern void e820_reserve_resources(void);
extern void e820_reserve_resources_late(void);
extern void setup_memory_map(void);
extern char *default_machine_specific_memory_setup(void);
extern char *machine_specific_memory_setup(void);