Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be7a656f authored by Yinghai Lu's avatar Yinghai Lu Committed by Ingo Molnar
Browse files

x86: copy detect_init_APIC to the other



Signed-off-by: default avatarYinghai Lu <yhlu.kernel@mgail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent fa2bd35a
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -1214,6 +1214,25 @@ void __cpuinit end_local_APIC_setup(void)
	apic_pm_activate();
}

#ifdef CONFIG_X86_64
/*
 * Detect and enable local APICs on non-SMP boards.
 * Original code written by Keir Fraser.
 * On AMD64 we trust the BIOS - if it says no APIC it is likely
 * not correctly set up (usually the APIC timer won't work etc.)
 */
static int __init detect_init_APIC(void)
{
	if (!cpu_has_apic) {
		printk(KERN_INFO "No local APIC present\n");
		return -1;
	}

	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
	boot_cpu_physical_apicid = 0;
	return 0;
}
#else
/*
 * Detect and initialize APIC
 */
@@ -1292,6 +1311,7 @@ static int __init detect_init_APIC(void)
	printk(KERN_INFO "No local APIC present or hardware disabled\n");
	return -1;
}
#endif

#ifdef CONFIG_X86_64
void __init early_init_lapic_mapping(void)
+81 −1
Original line number Diff line number Diff line
@@ -684,7 +684,6 @@ int setup_profiling_timer(unsigned int multiplier)
	return -EINVAL;
}


/*
 * Local APIC start and shutdown
 */
@@ -1264,6 +1263,7 @@ void enable_IR_x2apic(void)
}
#endif /* HAVE_X2APIC */

#ifdef CONFIG_X86_64
/*
 * Detect and enable local APICs on non-SMP boards.
 * Original code written by Keir Fraser.
@@ -1281,6 +1281,86 @@ static int __init detect_init_APIC(void)
	boot_cpu_physical_apicid = 0;
	return 0;
}
#else
/*
 * Detect and initialize APIC
 */
static int __init detect_init_APIC(void)
{
	u32 h, l, features;

	/* Disabled by kernel option? */
	if (disable_apic)
		return -1;

	switch (boot_cpu_data.x86_vendor) {
	case X86_VENDOR_AMD:
		if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) ||
		    (boot_cpu_data.x86 == 15))
			break;
		goto no_apic;
	case X86_VENDOR_INTEL:
		if (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15 ||
		    (boot_cpu_data.x86 == 5 && cpu_has_apic))
			break;
		goto no_apic;
	default:
		goto no_apic;
	}

	if (!cpu_has_apic) {
		/*
		 * Over-ride BIOS and try to enable the local APIC only if
		 * "lapic" specified.
		 */
		if (!force_enable_local_apic) {
			printk(KERN_INFO "Local APIC disabled by BIOS -- "
			       "you can enable it with \"lapic\"\n");
			return -1;
		}
		/*
		 * Some BIOSes disable the local APIC in the APIC_BASE
		 * MSR. This can only be done in software for Intel P6 or later
		 * and AMD K7 (Model > 1) or later.
		 */
		rdmsr(MSR_IA32_APICBASE, l, h);
		if (!(l & MSR_IA32_APICBASE_ENABLE)) {
			printk(KERN_INFO
			       "Local APIC disabled by BIOS -- reenabling.\n");
			l &= ~MSR_IA32_APICBASE_BASE;
			l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
			wrmsr(MSR_IA32_APICBASE, l, h);
			enabled_via_apicbase = 1;
		}
	}
	/*
	 * The APIC feature bit should now be enabled
	 * in `cpuid'
	 */
	features = cpuid_edx(1);
	if (!(features & (1 << X86_FEATURE_APIC))) {
		printk(KERN_WARNING "Could not enable APIC!\n");
		return -1;
	}
	set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;

	/* The BIOS may have set up the APIC at some other address */
	rdmsr(MSR_IA32_APICBASE, l, h);
	if (l & MSR_IA32_APICBASE_ENABLE)
		mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;

	printk(KERN_INFO "Found and enabled local APIC!\n");

	apic_pm_activate();

	return 0;

no_apic:
	printk(KERN_INFO "No local APIC present or hardware disabled\n");
	return -1;
}
#endif

#ifdef CONFIG_X86_64
void __init early_init_lapic_mapping(void)