Commit cbf9bd60 authored by Yinghai Lu's avatar Yinghai Lu Committed by Ingo Molnar

acpi: get boot_cpu_id as early for k8_scan_nodes

[mingo@elte.hu: split from "x86_64: get boot_cpu_id as early for k8_scan_nodes]
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 4cf19463
......@@ -771,6 +771,32 @@ static void __init acpi_register_lapic_address(unsigned long address)
boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id());
}
static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
{
int count;
if (!cpu_has_apic)
return -ENODEV;
/*
* Note that the LAPIC address is obtained from the MADT (32-bit value)
* and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
*/
count =
acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE,
acpi_parse_lapic_addr_ovr, 0);
if (count < 0) {
printk(KERN_ERR PREFIX
"Error parsing LAPIC address override entry\n");
return count;
}
acpi_register_lapic_address(acpi_lapic_addr);
return count;
}
static int __init acpi_parse_madt_lapic_entries(void)
{
int count;
......@@ -901,6 +927,33 @@ static inline int acpi_parse_madt_ioapic_entries(void)
}
#endif /* !CONFIG_X86_IO_APIC */
static void __init early_acpi_process_madt(void)
{
#ifdef CONFIG_X86_LOCAL_APIC
int error;
if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
/*
* Parse MADT LAPIC entries
*/
error = early_acpi_parse_madt_lapic_addr_ovr();
if (!error) {
acpi_lapic = 1;
smp_found_config = 1;
}
if (error == -EINVAL) {
/*
* Dell Precision Workstation 410, 610 come here.
*/
printk(KERN_ERR PREFIX
"Invalid BIOS MADT, disabling ACPI\n");
disable_acpi();
}
}
#endif
}
static void __init acpi_process_madt(void)
{
#ifdef CONFIG_X86_LOCAL_APIC
......@@ -1233,6 +1286,23 @@ int __init acpi_boot_table_init(void)
return 0;
}
int __init early_acpi_boot_init(void)
{
/*
* If acpi_disabled, bail out
* One exception: acpi=ht continues far enough to enumerate LAPICs
*/
if (acpi_disabled && !acpi_ht)
return 1;
/*
* Process the Multiple APIC Description Table (MADT), if present
*/
early_acpi_process_madt();
return 0;
}
int __init acpi_boot_init(void)
{
/*
......
......@@ -13,12 +13,15 @@
#include <linux/nodemask.h>
#include <asm/io.h>
#include <linux/pci_ids.h>
#include <linux/acpi.h>
#include <asm/types.h>
#include <asm/mmzone.h>
#include <asm/proto.h>
#include <asm/e820.h>
#include <asm/pci-direct.h>
#include <asm/numa.h>
#include <asm/mpspec.h>
#include <asm/apic.h>
static __init int find_northbridge(void)
{
......@@ -44,6 +47,30 @@ static __init int find_northbridge(void)
return -1;
}
static __init void early_get_boot_cpu_id(void)
{
/*
* need to get boot_cpu_id so can use that to create apicid_to_node
* in k8_scan_nodes()
*/
/*
* Find possible boot-time SMP configuration:
*/
early_find_smp_config();
#ifdef CONFIG_ACPI
/*
* Read APIC information from ACPI tables.
*/
early_acpi_boot_init();
#endif
/*
* get boot-time SMP configuration:
*/
if (smp_found_config)
early_get_smp_config();
early_init_lapic_mapping();
}
int __init k8_scan_nodes(unsigned long start, unsigned long end)
{
unsigned long prevbase;
......@@ -56,6 +83,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
unsigned cores;
unsigned bits;
int j;
unsigned apicid_base;
if (!early_pci_allowed())
return -1;
......@@ -174,11 +202,19 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
/* use the coreid bits from early_identify_cpu */
bits = boot_cpu_data.x86_coreid_bits;
cores = (1<<bits);
apicid_base = 0;
/* need to get boot_cpu_id early for system with apicid lifting */
early_get_boot_cpu_id();
if (boot_cpu_physical_apicid > 0) {
printk(KERN_INFO "BSP APIC ID: %02x\n",
boot_cpu_physical_apicid);
apicid_base = boot_cpu_physical_apicid;
}
for (i = 0; i < 8; i++) {
if (nodes[i].start != nodes[i].end) {
nodeid = nodeids[i];
for (j = 0; j < cores; j++)
for (j = apicid_base; j < cores + apicid_base; j++)
apicid_to_node[(nodeid << bits) + j] = i;
setup_node_bootmem(i, nodes[i].start, nodes[i].end);
}
......
......@@ -79,6 +79,7 @@ typedef int (*acpi_table_handler) (struct acpi_table_header *table);
typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
int early_acpi_boot_init(void);
int acpi_boot_init (void);
int acpi_boot_table_init (void);
int acpi_numa_init (void);
......@@ -235,6 +236,10 @@ int acpi_check_mem_region(resource_size_t start, resource_size_t n,
#else /* CONFIG_ACPI */
static inline int early_acpi_boot_init(void)
{
return 0;
}
static inline int acpi_boot_init(void)
{
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment