diff options
| -rw-r--r-- | arch/x86/kernel/acpi/boot.c | 70 | ||||
| -rw-r--r-- | arch/x86/mm/k8topology_64.c | 38 | ||||
| -rw-r--r-- | include/linux/acpi.h | 5 |
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 | ||
| 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 | } |
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); | |||
| 79 | typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end); | 79 | typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end); |
| 80 | 80 | ||
| 81 | char * __acpi_map_table (unsigned long phys_addr, unsigned long size); | 81 | char * __acpi_map_table (unsigned long phys_addr, unsigned long size); |
| 82 | int early_acpi_boot_init(void); | ||
| 82 | int acpi_boot_init (void); | 83 | int acpi_boot_init (void); |
| 83 | int acpi_boot_table_init (void); | 84 | int acpi_boot_table_init (void); |
| 84 | int acpi_numa_init (void); | 85 | int 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 | ||
| 239 | static inline int early_acpi_boot_init(void) | ||
| 240 | { | ||
| 241 | return 0; | ||
| 242 | } | ||
| 238 | static inline int acpi_boot_init(void) | 243 | static inline int acpi_boot_init(void) |
| 239 | { | 244 | { |
| 240 | return 0; | 245 | return 0; |
