Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 88768
b: refs/heads/master
c: 8643f9d
h: refs/heads/master
v: v3
  • Loading branch information
Yinghai Lu authored and Ingo Molnar committed Apr 17, 2008
1 parent 904af2f commit e182c60
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 24 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6079d2d5d11122eb52721f0f3c828952a490e6c1
refs/heads/master: 8643f9d02a7bb9db74634b4c062d8e70ce7c59b9
24 changes: 24 additions & 0 deletions trunk/arch/x86/kernel/apic_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,30 @@ static int __init detect_init_APIC(void)
return 0;
}

void __init early_init_lapic_mapping(void)
{
unsigned long apic_phys;

/*
* If no local APIC can be found then go out
* : it means there is no mpatable and MADT
*/
if (!smp_found_config)
return;

apic_phys = mp_lapic_addr;

set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
APIC_BASE, apic_phys);

/*
* Fetch the APIC ID of the BSP in case we have a
* default configuration (or the MP table is broken).
*/
boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID));
}

/**
* init_apic_mappings - initialize APIC mappings
*/
Expand Down
89 changes: 66 additions & 23 deletions trunk/arch/x86/kernel/mpparse_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,7 @@ static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
/*
* Read/parse the MPC
*/

static int __init smp_read_mpc(struct mp_config_table *mpc)
static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
{
char str[16];
int count=sizeof(*mpc);
Expand Down Expand Up @@ -266,6 +265,9 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
if (!acpi_lapic)
mp_lapic_addr = mpc->mpc_lapic;

if (early)
return 1;

/*
* Now process the configuration blocks.
*/
Expand Down Expand Up @@ -477,27 +479,38 @@ static struct intel_mp_floating *mpf_found;
/*
* Scan the memory blocks for an SMP configuration block.
*/
void __init get_smp_config (void)
static void __init __get_smp_config(unsigned early)
{
struct intel_mp_floating *mpf = mpf_found;

if (acpi_lapic && early)
return;
/*
* ACPI supports both logical (e.g. Hyper-Threading) and physical
* processors, where MPS only supports physical.
*/
if (acpi_lapic && acpi_ioapic) {
printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n");
return;
}
else if (acpi_lapic)
printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n");
* ACPI supports both logical (e.g. Hyper-Threading) and physical
* processors, where MPS only supports physical.
*/
if (acpi_lapic && acpi_ioapic) {
printk(KERN_INFO "Using ACPI (MADT) for SMP configuration "
"information\n");
return;
} else if (acpi_lapic)
printk(KERN_INFO "Using ACPI for processor (LAPIC) "
"configuration information\n");

printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n",
mpf->mpf_specification);

/*
* Now see if we need to read further.
*/
if (mpf->mpf_feature1 != 0) {
if (early) {
/*
* local APIC has default address
*/
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
return;
}

printk(KERN_INFO "Default MP configuration #%d\n", mpf->mpf_feature1);
construct_default_ISA_mptable(mpf->mpf_feature1);
Expand All @@ -508,12 +521,15 @@ void __init get_smp_config (void)
* Read the physical hardware table. Anything here will
* override the defaults.
*/
if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr))) {
if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr), early)) {
smp_found_config = 0;
printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
return;
}

if (early)
return;
/*
* If there are no explicit MP IRQ entries, then we are
* broken. We set up most of the low 16 IO-APIC pins to
Expand All @@ -535,13 +551,25 @@ void __init get_smp_config (void)
} else
BUG();

printk(KERN_INFO "Processors: %d\n", num_processors);
if (!early)
printk(KERN_INFO "Processors: %d\n", num_processors);
/*
* Only use the first configuration found.
*/
}

static int __init smp_scan_config (unsigned long base, unsigned long length)
void __init early_get_smp_config(void)
{
__get_smp_config(1);
}

void __init get_smp_config(void)
{
__get_smp_config(0);
}

static int __init smp_scan_config(unsigned long base, unsigned long length,
unsigned reserve)
{
extern void __bad_mpf_size(void);
unsigned int *bp = phys_to_virt(base);
Expand All @@ -560,10 +588,15 @@ static int __init smp_scan_config (unsigned long base, unsigned long length)
|| (mpf->mpf_specification == 4)) ) {

smp_found_config = 1;
mpf_found = mpf;

if (!reserve)
return 1;

reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE);
if (mpf->mpf_physptr)
reserve_bootmem_generic(mpf->mpf_physptr, PAGE_SIZE);
mpf_found = mpf;
reserve_bootmem_generic(mpf->mpf_physptr,
PAGE_SIZE);
return 1;
}
bp += 4;
Expand All @@ -572,7 +605,7 @@ static int __init smp_scan_config (unsigned long base, unsigned long length)
return 0;
}

void __init find_smp_config(void)
static void __init __find_smp_config(unsigned reserve)
{
unsigned int address;

Expand All @@ -584,9 +617,9 @@ void __init find_smp_config(void)
* 2) Scan the top 1K of base RAM
* 3) Scan the 64K of bios
*/
if (smp_scan_config(0x0,0x400) ||
smp_scan_config(639*0x400,0x400) ||
smp_scan_config(0xF0000,0x10000))
if (smp_scan_config(0x0, 0x400, reserve) ||
smp_scan_config(639*0x400, 0x400, reserve) ||
smp_scan_config(0xF0000, 0x10000, reserve))
return;
/*
* If it is an SMP machine we should know now.
Expand All @@ -603,13 +636,23 @@ void __init find_smp_config(void)

address = *(unsigned short *)phys_to_virt(0x40E);
address <<= 4;
if (smp_scan_config(address, 0x1000))
if (smp_scan_config(address, 0x1000, reserve))
return;

/* If we have come this far, we did not find an MP table */
printk(KERN_INFO "No mptable found.\n");
}

void __init early_find_smp_config(void)
{
__find_smp_config(0);
}

void __init find_smp_config(void)
{
__find_smp_config(1);
}

/* --------------------------------------------------------------------------
ACPI-based MP Configuration
-------------------------------------------------------------------------- */
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-x86/apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ extern void enable_NMI_through_LVT0(void);
*/
#ifdef CONFIG_X86_64
extern void setup_apic_routing(void);
extern void early_init_lapic_mapping(void);
#endif

extern u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask);
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/asm-x86/mpspec.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ extern int pic_mode;

extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);

extern void early_find_smp_config(void);
extern void early_get_smp_config(void);

#endif

extern int mp_bus_id_to_pci_bus[MAX_MP_BUSSES];
Expand Down

0 comments on commit e182c60

Please sign in to comment.