aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/kernel/apic.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 6472e321cad7..135ff25e6b44 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -25,6 +25,7 @@
25#include <linux/kernel_stat.h> 25#include <linux/kernel_stat.h>
26#include <linux/sysdev.h> 26#include <linux/sysdev.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/ioport.h>
28 29
29#include <asm/atomic.h> 30#include <asm/atomic.h>
30#include <asm/smp.h> 31#include <asm/smp.h>
@@ -45,6 +46,11 @@ int apic_calibrate_pmtmr __initdata;
45 46
46int disable_apic_timer __initdata; 47int disable_apic_timer __initdata;
47 48
49static struct resource lapic_resource = {
50 .name = "Local APIC",
51 .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
52};
53
48/* 54/*
49 * cpu_mask that denotes the CPUs that needs timer interrupt coming in as 55 * cpu_mask that denotes the CPUs that needs timer interrupt coming in as
50 * IPIs in place of local APIC timers 56 * IPIs in place of local APIC timers
@@ -585,6 +591,40 @@ static int __init detect_init_APIC (void)
585 return 0; 591 return 0;
586} 592}
587 593
594#ifdef CONFIG_X86_IO_APIC
595static struct resource * __init ioapic_setup_resources(void)
596{
597#define IOAPIC_RESOURCE_NAME_SIZE 11
598 unsigned long n;
599 struct resource *res;
600 char *mem;
601 int i;
602
603 if (nr_ioapics <= 0)
604 return NULL;
605
606 n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
607 n *= nr_ioapics;
608
609 res = alloc_bootmem(n);
610
611 if (!res)
612 return NULL;
613
614 memset(res, 0, n);
615 mem = (void *)&res[nr_ioapics];
616
617 for (i = 0; i < nr_ioapics; i++) {
618 res[i].name = mem;
619 res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
620 snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i);
621 mem += IOAPIC_RESOURCE_NAME_SIZE;
622 }
623
624 return res;
625}
626#endif
627
588void __init init_apic_mappings(void) 628void __init init_apic_mappings(void)
589{ 629{
590 unsigned long apic_phys; 630 unsigned long apic_phys;
@@ -604,6 +644,11 @@ void __init init_apic_mappings(void)
604 apic_mapped = 1; 644 apic_mapped = 1;
605 apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys); 645 apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys);
606 646
647 /* Put local APIC into the resource map. */
648 lapic_resource.start = apic_phys;
649 lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
650 insert_resource(&iomem_resource, &lapic_resource);
651
607 /* 652 /*
608 * Fetch the APIC ID of the BSP in case we have a 653 * Fetch the APIC ID of the BSP in case we have a
609 * default configuration (or the MP table is broken). 654 * default configuration (or the MP table is broken).
@@ -613,7 +658,9 @@ void __init init_apic_mappings(void)
613 { 658 {
614 unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; 659 unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
615 int i; 660 int i;
661 struct resource *ioapic_res;
616 662
663 ioapic_res = ioapic_setup_resources();
617 for (i = 0; i < nr_ioapics; i++) { 664 for (i = 0; i < nr_ioapics; i++) {
618 if (smp_found_config) { 665 if (smp_found_config) {
619 ioapic_phys = mp_ioapics[i].mpc_apicaddr; 666 ioapic_phys = mp_ioapics[i].mpc_apicaddr;
@@ -625,6 +672,13 @@ void __init init_apic_mappings(void)
625 apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n", 672 apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n",
626 __fix_to_virt(idx), ioapic_phys); 673 __fix_to_virt(idx), ioapic_phys);
627 idx++; 674 idx++;
675
676 if (ioapic_res) {
677 ioapic_res->start = ioapic_phys;
678 ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
679 insert_resource(&iomem_resource, ioapic_res);
680 ioapic_res++;
681 }
628 } 682 }
629 } 683 }
630} 684}