Skip to content

Commit

Permalink
[PATCH] x86-64: Insert Local and IO APIC(s) into resource map
Browse files Browse the repository at this point in the history
Insert the Local APIC and IO APIC(s) into the resource tree.  It allows the
APIC resources to be visible within /proc/iomem.  The patch also takes into
account IO APIC(s) mapped in the PCI space by deferring the insertion until
after PCI has allocated its necessary resources.

Signed-off-by: Aaron Durbin <adurbin@google.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Andi Kleen <ak@muc.de>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
  • Loading branch information
Aaron Durbin authored and Andi Kleen committed Dec 7, 2006
1 parent acc2076 commit 3992872
Showing 1 changed file with 78 additions and 0 deletions.
78 changes: 78 additions & 0 deletions arch/x86_64/kernel/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/kernel_stat.h>
#include <linux/sysdev.h>
#include <linux/module.h>
#include <linux/ioport.h>

#include <asm/atomic.h>
#include <asm/smp.h>
Expand All @@ -45,6 +46,12 @@ int apic_calibrate_pmtmr __initdata;

int disable_apic_timer __initdata;

static struct resource *ioapic_resources;
static struct resource lapic_resource = {
.name = "Local APIC",
.flags = IORESOURCE_MEM | IORESOURCE_BUSY,
};

/*
* cpu_mask that denotes the CPUs that needs timer interrupt coming in as
* IPIs in place of local APIC timers
Expand Down Expand Up @@ -585,6 +592,64 @@ static int __init detect_init_APIC (void)
return 0;
}

#ifdef CONFIG_X86_IO_APIC
static struct resource * __init ioapic_setup_resources(void)
{
#define IOAPIC_RESOURCE_NAME_SIZE 11
unsigned long n;
struct resource *res;
char *mem;
int i;

if (nr_ioapics <= 0)
return NULL;

n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
n *= nr_ioapics;

mem = alloc_bootmem(n);
res = (void *)mem;

if (mem != NULL) {
memset(mem, 0, n);
mem += sizeof(struct resource) * nr_ioapics;

for (i = 0; i < nr_ioapics; i++) {
res[i].name = mem;
res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
sprintf(mem, "IOAPIC %u", i);
mem += IOAPIC_RESOURCE_NAME_SIZE;
}
}

ioapic_resources = res;

return res;
}

static int __init ioapic_insert_resources(void)
{
int i;
struct resource *r = ioapic_resources;

if (!r) {
printk("IO APIC resources could be not be allocated.\n");
return -1;
}

for (i = 0; i < nr_ioapics; i++) {
insert_resource(&iomem_resource, r);
r++;
}

return 0;
}

/* Insert the IO APIC resources after PCI initialization has occured to handle
* IO APICS that are mapped in on a BAR in PCI space. */
late_initcall(ioapic_insert_resources);
#endif

void __init init_apic_mappings(void)
{
unsigned long apic_phys;
Expand All @@ -604,6 +669,11 @@ void __init init_apic_mappings(void)
apic_mapped = 1;
apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys);

/* Put local APIC into the resource map. */
lapic_resource.start = apic_phys;
lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
insert_resource(&iomem_resource, &lapic_resource);

/*
* Fetch the APIC ID of the BSP in case we have a
* default configuration (or the MP table is broken).
Expand All @@ -613,7 +683,9 @@ void __init init_apic_mappings(void)
{
unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
int i;
struct resource *ioapic_res;

ioapic_res = ioapic_setup_resources();
for (i = 0; i < nr_ioapics; i++) {
if (smp_found_config) {
ioapic_phys = mp_ioapics[i].mpc_apicaddr;
Expand All @@ -625,6 +697,12 @@ void __init init_apic_mappings(void)
apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n",
__fix_to_virt(idx), ioapic_phys);
idx++;

if (ioapic_res != NULL) {
ioapic_res->start = ioapic_phys;
ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
ioapic_res++;
}
}
}
}
Expand Down

0 comments on commit 3992872

Please sign in to comment.