aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/acpi/boot.c70
-rw-r--r--arch/x86/mm/k8topology_64.c38
-rw-r--r--include/linux/acpi.h5
3 files changed, 112 insertions, 1 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 977ed5cdeaa3..c49ebcc6c41e 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -771,6 +771,32 @@ static void __init acpi_register_lapic_address(unsigned long address)
771 boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id()); 771 boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id());
772} 772}
773 773
774static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
775{
776 int count;
777
778 if (!cpu_has_apic)
779 return -ENODEV;
780
781 /*
782 * Note that the LAPIC address is obtained from the MADT (32-bit value)
783 * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
784 */
785
786 count =
787 acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE,
788 acpi_parse_lapic_addr_ovr, 0);
789 if (count < 0) {
790 printk(KERN_ERR PREFIX
791 "Error parsing LAPIC address override entry\n");
792 return count;
793 }
794
795 acpi_register_lapic_address(acpi_lapic_addr);
796
797 return count;
798}
799
774static int __init acpi_parse_madt_lapic_entries(void) 800static int __init acpi_parse_madt_lapic_entries(void)
775{ 801{
776 int count; 802 int count;
@@ -901,6 +927,33 @@ static inline int acpi_parse_madt_ioapic_entries(void)
901} 927}
902#endif /* !CONFIG_X86_IO_APIC */ 928#endif /* !CONFIG_X86_IO_APIC */
903 929
930static void __init early_acpi_process_madt(void)
931{
932#ifdef CONFIG_X86_LOCAL_APIC
933 int error;
934
935 if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
936
937 /*
938 * Parse MADT LAPIC entries
939 */
940 error = early_acpi_parse_madt_lapic_addr_ovr();
941 if (!error) {
942 acpi_lapic = 1;
943 smp_found_config = 1;
944 }
945 if (error == -EINVAL) {
946 /*
947 * Dell Precision Workstation 410, 610 come here.
948 */
949 printk(KERN_ERR PREFIX
950 "Invalid BIOS MADT, disabling ACPI\n");
951 disable_acpi();
952 }
953 }
954#endif
955}
956
904static void __init acpi_process_madt(void) 957static void __init acpi_process_madt(void)
905{ 958{
906#ifdef CONFIG_X86_LOCAL_APIC 959#ifdef CONFIG_X86_LOCAL_APIC
@@ -1233,6 +1286,23 @@ int __init acpi_boot_table_init(void)
1233 return 0; 1286 return 0;
1234} 1287}
1235 1288
1289int __init early_acpi_boot_init(void)
1290{
1291 /*
1292 * If acpi_disabled, bail out
1293 * One exception: acpi=ht continues far enough to enumerate LAPICs
1294 */
1295 if (acpi_disabled && !acpi_ht)
1296 return 1;
1297
1298 /*
1299 * Process the Multiple APIC Description Table (MADT), if present
1300 */
1301 early_acpi_process_madt();
1302
1303 return 0;
1304}
1305
1236int __init acpi_boot_init(void) 1306int __init acpi_boot_init(void)
1237{ 1307{
1238 /* 1308 /*
diff --git a/arch/x86/mm/k8topology_64.c b/arch/x86/mm/k8topology_64.c
index 86808e666f9c..1f476e477844 100644
--- a/arch/x86/mm/k8topology_64.c
+++ b/arch/x86/mm/k8topology_64.c
@@ -13,12 +13,15 @@
13#include <linux/nodemask.h> 13#include <linux/nodemask.h>
14#include <asm/io.h> 14#include <asm/io.h>
15#include <linux/pci_ids.h> 15#include <linux/pci_ids.h>
16#include <linux/acpi.h>
16#include <asm/types.h> 17#include <asm/types.h>
17#include <asm/mmzone.h> 18#include <asm/mmzone.h>
18#include <asm/proto.h> 19#include <asm/proto.h>
19#include <asm/e820.h> 20#include <asm/e820.h>
20#include <asm/pci-direct.h> 21#include <asm/pci-direct.h>
21#include <asm/numa.h> 22#include <asm/numa.h>
23#include <asm/mpspec.h>
24#include <asm/apic.h>
22 25
23static __init int find_northbridge(void) 26static __init int find_northbridge(void)
24{ 27{
@@ -44,6 +47,30 @@ static __init int find_northbridge(void)
44 return -1; 47 return -1;
45} 48}
46 49
50static __init void early_get_boot_cpu_id(void)
51{
52 /*
53 * need to get boot_cpu_id so can use that to create apicid_to_node
54 * in k8_scan_nodes()
55 */
56 /*
57 * Find possible boot-time SMP configuration:
58 */
59 early_find_smp_config();
60#ifdef CONFIG_ACPI
61 /*
62 * Read APIC information from ACPI tables.
63 */
64 early_acpi_boot_init();
65#endif
66 /*
67 * get boot-time SMP configuration:
68 */
69 if (smp_found_config)
70 early_get_smp_config();
71 early_init_lapic_mapping();
72}
73
47int __init k8_scan_nodes(unsigned long start, unsigned long end) 74int __init k8_scan_nodes(unsigned long start, unsigned long end)
48{ 75{
49 unsigned long prevbase; 76 unsigned long prevbase;
@@ -56,6 +83,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
56 unsigned cores; 83 unsigned cores;
57 unsigned bits; 84 unsigned bits;
58 int j; 85 int j;
86 unsigned apicid_base;
59 87
60 if (!early_pci_allowed()) 88 if (!early_pci_allowed())
61 return -1; 89 return -1;
@@ -174,11 +202,19 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
174 /* use the coreid bits from early_identify_cpu */ 202 /* use the coreid bits from early_identify_cpu */
175 bits = boot_cpu_data.x86_coreid_bits; 203 bits = boot_cpu_data.x86_coreid_bits;
176 cores = (1<<bits); 204 cores = (1<<bits);
205 apicid_base = 0;
206 /* need to get boot_cpu_id early for system with apicid lifting */
207 early_get_boot_cpu_id();
208 if (boot_cpu_physical_apicid > 0) {
209 printk(KERN_INFO "BSP APIC ID: %02x\n",
210 boot_cpu_physical_apicid);
211 apicid_base = boot_cpu_physical_apicid;
212 }
177 213
178 for (i = 0; i < 8; i++) { 214 for (i = 0; i < 8; i++) {
179 if (nodes[i].start != nodes[i].end) { 215 if (nodes[i].start != nodes[i].end) {
180 nodeid = nodeids[i]; 216 nodeid = nodeids[i];
181 for (j = 0; j < cores; j++) 217 for (j = apicid_base; j < cores + apicid_base; j++)
182 apicid_to_node[(nodeid << bits) + j] = i; 218 apicid_to_node[(nodeid << bits) + j] = i;
183 setup_node_bootmem(i, nodes[i].start, nodes[i].end); 219 setup_node_bootmem(i, nodes[i].start, nodes[i].end);
184 } 220 }
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 2c7e003356ac..41f7ce7edd7a 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -79,6 +79,7 @@ typedef int (*acpi_table_handler) (struct acpi_table_header *table);
79typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end); 79typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
80 80
81char * __acpi_map_table (unsigned long phys_addr, unsigned long size); 81char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
82int early_acpi_boot_init(void);
82int acpi_boot_init (void); 83int acpi_boot_init (void);
83int acpi_boot_table_init (void); 84int acpi_boot_table_init (void);
84int acpi_numa_init (void); 85int acpi_numa_init (void);
@@ -235,6 +236,10 @@ int acpi_check_mem_region(resource_size_t start, resource_size_t n,
235 236
236#else /* CONFIG_ACPI */ 237#else /* CONFIG_ACPI */
237 238
239static inline int early_acpi_boot_init(void)
240{
241 return 0;
242}
238static inline int acpi_boot_init(void) 243static inline int acpi_boot_init(void)
239{ 244{
240 return 0; 245 return 0;