diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 70 | ||||
-rw-r--r-- | arch/x86/mm/k8topology_64.c | 38 |
2 files changed, 107 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 | ||
774 | static 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 | |||
774 | static int __init acpi_parse_madt_lapic_entries(void) | 800 | static 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 | ||
930 | static 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 | |||
904 | static void __init acpi_process_madt(void) | 957 | static 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 | ||
1289 | int __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 | |||
1236 | int __init acpi_boot_init(void) | 1306 | int __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 | ||
23 | static __init int find_northbridge(void) | 26 | static __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 | ||
50 | static __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 | |||
47 | int __init k8_scan_nodes(unsigned long start, unsigned long end) | 74 | int __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 | } |