|
@@ -134,9 +134,6 @@ static inline void imcr_apic_to_pic(void)
|
|
|
*/
|
|
|
static int force_enable_local_apic __initdata;
|
|
|
|
|
|
-/* Control whether x2APIC mode is enabled or not */
|
|
|
-static bool nox2apic __initdata;
|
|
|
-
|
|
|
/*
|
|
|
* APIC command line parameters
|
|
|
*/
|
|
@@ -161,33 +158,6 @@ static __init int setup_apicpmtimer(char *s)
|
|
|
__setup("apicpmtimer", setup_apicpmtimer);
|
|
|
#endif
|
|
|
|
|
|
-int x2apic_mode;
|
|
|
-#ifdef CONFIG_X86_X2APIC
|
|
|
-/* x2apic enabled before OS handover */
|
|
|
-int x2apic_preenabled;
|
|
|
-static int x2apic_disabled;
|
|
|
-static int __init setup_nox2apic(char *str)
|
|
|
-{
|
|
|
- if (x2apic_enabled()) {
|
|
|
- int apicid = native_apic_msr_read(APIC_ID);
|
|
|
-
|
|
|
- if (apicid >= 255) {
|
|
|
- pr_warning("Apicid: %08x, cannot enforce nox2apic\n",
|
|
|
- apicid);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- pr_warning("x2apic already enabled. will disable it\n");
|
|
|
- } else
|
|
|
- setup_clear_cpu_cap(X86_FEATURE_X2APIC);
|
|
|
-
|
|
|
- nox2apic = true;
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-early_param("nox2apic", setup_nox2apic);
|
|
|
-#endif
|
|
|
-
|
|
|
unsigned long mp_lapic_addr;
|
|
|
int disable_apic;
|
|
|
/* Disable local APIC timer from the kernel commandline or via dmi quirk */
|
|
@@ -1475,7 +1445,7 @@ void setup_local_APIC(void)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-void end_local_APIC_setup(void)
|
|
|
+static void end_local_APIC_setup(void)
|
|
|
{
|
|
|
lapic_setup_esr();
|
|
|
|
|
@@ -1492,116 +1462,184 @@ void end_local_APIC_setup(void)
|
|
|
apic_pm_activate();
|
|
|
}
|
|
|
|
|
|
-void __init bsp_end_local_APIC_setup(void)
|
|
|
+/*
|
|
|
+ * APIC setup function for application processors. Called from smpboot.c
|
|
|
+ */
|
|
|
+void apic_ap_setup(void)
|
|
|
{
|
|
|
+ setup_local_APIC();
|
|
|
end_local_APIC_setup();
|
|
|
-
|
|
|
- /*
|
|
|
- * Now that local APIC setup is completed for BP, configure the fault
|
|
|
- * handling for interrupt remapping.
|
|
|
- */
|
|
|
- irq_remap_enable_fault_handling();
|
|
|
-
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_X86_X2APIC
|
|
|
-/*
|
|
|
- * Need to disable xapic and x2apic at the same time and then enable xapic mode
|
|
|
- */
|
|
|
-static inline void __disable_x2apic(u64 msr)
|
|
|
-{
|
|
|
- wrmsrl(MSR_IA32_APICBASE,
|
|
|
- msr & ~(X2APIC_ENABLE | XAPIC_ENABLE));
|
|
|
- wrmsrl(MSR_IA32_APICBASE, msr & ~X2APIC_ENABLE);
|
|
|
-}
|
|
|
+int x2apic_mode;
|
|
|
|
|
|
-static __init void disable_x2apic(void)
|
|
|
+enum {
|
|
|
+ X2APIC_OFF,
|
|
|
+ X2APIC_ON,
|
|
|
+ X2APIC_DISABLED,
|
|
|
+};
|
|
|
+static int x2apic_state;
|
|
|
+
|
|
|
+static inline void __x2apic_disable(void)
|
|
|
{
|
|
|
u64 msr;
|
|
|
|
|
|
- if (!cpu_has_x2apic)
|
|
|
+ if (cpu_has_apic)
|
|
|
return;
|
|
|
|
|
|
rdmsrl(MSR_IA32_APICBASE, msr);
|
|
|
- if (msr & X2APIC_ENABLE) {
|
|
|
- u32 x2apic_id = read_apic_id();
|
|
|
-
|
|
|
- if (x2apic_id >= 255)
|
|
|
- panic("Cannot disable x2apic, id: %08x\n", x2apic_id);
|
|
|
+ if (!(msr & X2APIC_ENABLE))
|
|
|
+ return;
|
|
|
+ /* Disable xapic and x2apic first and then reenable xapic mode */
|
|
|
+ wrmsrl(MSR_IA32_APICBASE, msr & ~(X2APIC_ENABLE | XAPIC_ENABLE));
|
|
|
+ wrmsrl(MSR_IA32_APICBASE, msr & ~X2APIC_ENABLE);
|
|
|
+ printk_once(KERN_INFO "x2apic disabled\n");
|
|
|
+}
|
|
|
|
|
|
- pr_info("Disabling x2apic\n");
|
|
|
- __disable_x2apic(msr);
|
|
|
+static inline void __x2apic_enable(void)
|
|
|
+{
|
|
|
+ u64 msr;
|
|
|
|
|
|
- if (nox2apic) {
|
|
|
- clear_cpu_cap(&cpu_data(0), X86_FEATURE_X2APIC);
|
|
|
- setup_clear_cpu_cap(X86_FEATURE_X2APIC);
|
|
|
- }
|
|
|
+ rdmsrl(MSR_IA32_APICBASE, msr);
|
|
|
+ if (msr & X2APIC_ENABLE)
|
|
|
+ return;
|
|
|
+ wrmsrl(MSR_IA32_APICBASE, msr | X2APIC_ENABLE);
|
|
|
+ printk_once(KERN_INFO "x2apic enabled\n");
|
|
|
+}
|
|
|
|
|
|
- x2apic_disabled = 1;
|
|
|
- x2apic_mode = 0;
|
|
|
+static int __init setup_nox2apic(char *str)
|
|
|
+{
|
|
|
+ if (x2apic_enabled()) {
|
|
|
+ int apicid = native_apic_msr_read(APIC_ID);
|
|
|
|
|
|
- register_lapic_address(mp_lapic_addr);
|
|
|
+ if (apicid >= 255) {
|
|
|
+ pr_warning("Apicid: %08x, cannot enforce nox2apic\n",
|
|
|
+ apicid);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ pr_warning("x2apic already enabled.\n");
|
|
|
+ __x2apic_disable();
|
|
|
}
|
|
|
+ setup_clear_cpu_cap(X86_FEATURE_X2APIC);
|
|
|
+ x2apic_state = X2APIC_DISABLED;
|
|
|
+ x2apic_mode = 0;
|
|
|
+ return 0;
|
|
|
}
|
|
|
+early_param("nox2apic", setup_nox2apic);
|
|
|
|
|
|
-void check_x2apic(void)
|
|
|
+/* Called from cpu_init() to enable x2apic on (secondary) cpus */
|
|
|
+void x2apic_setup(void)
|
|
|
{
|
|
|
- if (x2apic_enabled()) {
|
|
|
- pr_info("x2apic enabled by BIOS, switching to x2apic ops\n");
|
|
|
- x2apic_preenabled = x2apic_mode = 1;
|
|
|
+ /*
|
|
|
+ * If x2apic is not in ON state, disable it if already enabled
|
|
|
+ * from BIOS.
|
|
|
+ */
|
|
|
+ if (x2apic_state != X2APIC_ON) {
|
|
|
+ __x2apic_disable();
|
|
|
+ return;
|
|
|
}
|
|
|
+ __x2apic_enable();
|
|
|
}
|
|
|
|
|
|
-void enable_x2apic(void)
|
|
|
+static __init void x2apic_disable(void)
|
|
|
{
|
|
|
- u64 msr;
|
|
|
+ u32 x2apic_id;
|
|
|
|
|
|
- rdmsrl(MSR_IA32_APICBASE, msr);
|
|
|
- if (x2apic_disabled) {
|
|
|
- __disable_x2apic(msr);
|
|
|
+ if (x2apic_state != X2APIC_ON)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ x2apic_id = read_apic_id();
|
|
|
+ if (x2apic_id >= 255)
|
|
|
+ panic("Cannot disable x2apic, id: %08x\n", x2apic_id);
|
|
|
+
|
|
|
+ __x2apic_disable();
|
|
|
+ register_lapic_address(mp_lapic_addr);
|
|
|
+out:
|
|
|
+ x2apic_state = X2APIC_DISABLED;
|
|
|
+ x2apic_mode = 0;
|
|
|
+}
|
|
|
+
|
|
|
+static __init void x2apic_enable(void)
|
|
|
+{
|
|
|
+ if (x2apic_state != X2APIC_OFF)
|
|
|
return;
|
|
|
- }
|
|
|
|
|
|
- if (!x2apic_mode)
|
|
|
+ x2apic_mode = 1;
|
|
|
+ x2apic_state = X2APIC_ON;
|
|
|
+ __x2apic_enable();
|
|
|
+}
|
|
|
+
|
|
|
+static __init void try_to_enable_x2apic(int remap_mode)
|
|
|
+{
|
|
|
+ if (x2apic_state == X2APIC_DISABLED)
|
|
|
return;
|
|
|
|
|
|
- if (!(msr & X2APIC_ENABLE)) {
|
|
|
- printk_once(KERN_INFO "Enabling x2apic\n");
|
|
|
- wrmsrl(MSR_IA32_APICBASE, msr | X2APIC_ENABLE);
|
|
|
+ if (remap_mode != IRQ_REMAP_X2APIC_MODE) {
|
|
|
+ /* IR is required if there is APIC ID > 255 even when running
|
|
|
+ * under KVM
|
|
|
+ */
|
|
|
+ if (max_physical_apicid > 255 ||
|
|
|
+ (IS_ENABLED(CONFIG_HYPERVISOR_GUEST) &&
|
|
|
+ !hypervisor_x2apic_available())) {
|
|
|
+ pr_info("x2apic: IRQ remapping doesn't support X2APIC mode\n");
|
|
|
+ x2apic_disable();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * without IR all CPUs can be addressed by IOAPIC/MSI
|
|
|
+ * only in physical mode
|
|
|
+ */
|
|
|
+ x2apic_phys = 1;
|
|
|
}
|
|
|
+ x2apic_enable();
|
|
|
}
|
|
|
-#endif /* CONFIG_X86_X2APIC */
|
|
|
|
|
|
-int __init enable_IR(void)
|
|
|
+void __init check_x2apic(void)
|
|
|
{
|
|
|
-#ifdef CONFIG_IRQ_REMAP
|
|
|
- if (!irq_remapping_supported()) {
|
|
|
- pr_debug("intr-remapping not supported\n");
|
|
|
- return -1;
|
|
|
+ if (x2apic_enabled()) {
|
|
|
+ pr_info("x2apic: enabled by BIOS, switching to x2apic ops\n");
|
|
|
+ x2apic_mode = 1;
|
|
|
+ x2apic_state = X2APIC_ON;
|
|
|
+ } else if (!cpu_has_x2apic) {
|
|
|
+ x2apic_state = X2APIC_DISABLED;
|
|
|
}
|
|
|
+}
|
|
|
+#else /* CONFIG_X86_X2APIC */
|
|
|
+static int __init validate_x2apic(void)
|
|
|
+{
|
|
|
+ if (!apic_is_x2apic_enabled())
|
|
|
+ return 0;
|
|
|
+ /*
|
|
|
+ * Checkme: Can we simply turn off x2apic here instead of panic?
|
|
|
+ */
|
|
|
+ panic("BIOS has enabled x2apic but kernel doesn't support x2apic, please disable x2apic in BIOS.\n");
|
|
|
+}
|
|
|
+early_initcall(validate_x2apic);
|
|
|
|
|
|
- if (!x2apic_preenabled && skip_ioapic_setup) {
|
|
|
- pr_info("Skipped enabling intr-remap because of skipping "
|
|
|
- "io-apic setup\n");
|
|
|
+static inline void try_to_enable_x2apic(int remap_mode) { }
|
|
|
+static inline void __x2apic_enable(void) { }
|
|
|
+#endif /* !CONFIG_X86_X2APIC */
|
|
|
+
|
|
|
+static int __init try_to_enable_IR(void)
|
|
|
+{
|
|
|
+#ifdef CONFIG_X86_IO_APIC
|
|
|
+ if (!x2apic_enabled() && skip_ioapic_setup) {
|
|
|
+ pr_info("Not enabling interrupt remapping due to skipped IO-APIC setup\n");
|
|
|
return -1;
|
|
|
}
|
|
|
-
|
|
|
- return irq_remapping_enable();
|
|
|
#endif
|
|
|
- return -1;
|
|
|
+ return irq_remapping_enable();
|
|
|
}
|
|
|
|
|
|
void __init enable_IR_x2apic(void)
|
|
|
{
|
|
|
unsigned long flags;
|
|
|
- int ret, x2apic_enabled = 0;
|
|
|
- int hardware_init_ret;
|
|
|
-
|
|
|
- /* Make sure irq_remap_ops are initialized */
|
|
|
- setup_irq_remapping_ops();
|
|
|
+ int ret, ir_stat;
|
|
|
|
|
|
- hardware_init_ret = irq_remapping_prepare();
|
|
|
- if (hardware_init_ret && !x2apic_supported())
|
|
|
+ ir_stat = irq_remapping_prepare();
|
|
|
+ if (ir_stat < 0 && !x2apic_supported())
|
|
|
return;
|
|
|
|
|
|
ret = save_ioapic_entries();
|
|
@@ -1614,49 +1652,13 @@ void __init enable_IR_x2apic(void)
|
|
|
legacy_pic->mask_all();
|
|
|
mask_ioapic_entries();
|
|
|
|
|
|
- if (x2apic_preenabled && nox2apic)
|
|
|
- disable_x2apic();
|
|
|
-
|
|
|
- if (hardware_init_ret)
|
|
|
- ret = -1;
|
|
|
- else
|
|
|
- ret = enable_IR();
|
|
|
-
|
|
|
- if (!x2apic_supported())
|
|
|
- goto skip_x2apic;
|
|
|
+ /* If irq_remapping_prepare() succeded, try to enable it */
|
|
|
+ if (ir_stat >= 0)
|
|
|
+ ir_stat = try_to_enable_IR();
|
|
|
+ /* ir_stat contains the remap mode or an error code */
|
|
|
+ try_to_enable_x2apic(ir_stat);
|
|
|
|
|
|
- if (ret < 0) {
|
|
|
- /* IR is required if there is APIC ID > 255 even when running
|
|
|
- * under KVM
|
|
|
- */
|
|
|
- if (max_physical_apicid > 255 ||
|
|
|
- !hypervisor_x2apic_available()) {
|
|
|
- if (x2apic_preenabled)
|
|
|
- disable_x2apic();
|
|
|
- goto skip_x2apic;
|
|
|
- }
|
|
|
- /*
|
|
|
- * without IR all CPUs can be addressed by IOAPIC/MSI
|
|
|
- * only in physical mode
|
|
|
- */
|
|
|
- x2apic_force_phys();
|
|
|
- }
|
|
|
-
|
|
|
- if (ret == IRQ_REMAP_XAPIC_MODE) {
|
|
|
- pr_info("x2apic not enabled, IRQ remapping is in xapic mode\n");
|
|
|
- goto skip_x2apic;
|
|
|
- }
|
|
|
-
|
|
|
- x2apic_enabled = 1;
|
|
|
-
|
|
|
- if (x2apic_supported() && !x2apic_mode) {
|
|
|
- x2apic_mode = 1;
|
|
|
- enable_x2apic();
|
|
|
- pr_info("Enabled x2apic\n");
|
|
|
- }
|
|
|
-
|
|
|
-skip_x2apic:
|
|
|
- if (ret < 0) /* IR enabling failed */
|
|
|
+ if (ir_stat < 0)
|
|
|
restore_ioapic_entries();
|
|
|
legacy_pic->restore_mask();
|
|
|
local_irq_restore(flags);
|
|
@@ -1847,82 +1849,8 @@ void __init register_lapic_address(unsigned long address)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * This initializes the IO-APIC and APIC hardware if this is
|
|
|
- * a UP kernel.
|
|
|
- */
|
|
|
int apic_version[MAX_LOCAL_APIC];
|
|
|
|
|
|
-int __init APIC_init_uniprocessor(void)
|
|
|
-{
|
|
|
- if (disable_apic) {
|
|
|
- pr_info("Apic disabled\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
-#ifdef CONFIG_X86_64
|
|
|
- if (!cpu_has_apic) {
|
|
|
- disable_apic = 1;
|
|
|
- pr_info("Apic disabled by BIOS\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
-#else
|
|
|
- if (!smp_found_config && !cpu_has_apic)
|
|
|
- return -1;
|
|
|
-
|
|
|
- /*
|
|
|
- * Complain if the BIOS pretends there is one.
|
|
|
- */
|
|
|
- if (!cpu_has_apic &&
|
|
|
- APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
|
|
|
- pr_err("BIOS bug, local APIC 0x%x not detected!...\n",
|
|
|
- boot_cpu_physical_apicid);
|
|
|
- return -1;
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
- default_setup_apic_routing();
|
|
|
-
|
|
|
- verify_local_APIC();
|
|
|
- connect_bsp_APIC();
|
|
|
-
|
|
|
-#ifdef CONFIG_X86_64
|
|
|
- apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid));
|
|
|
-#else
|
|
|
- /*
|
|
|
- * Hack: In case of kdump, after a crash, kernel might be booting
|
|
|
- * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid
|
|
|
- * might be zero if read from MP tables. Get it from LAPIC.
|
|
|
- */
|
|
|
-# ifdef CONFIG_CRASH_DUMP
|
|
|
- boot_cpu_physical_apicid = read_apic_id();
|
|
|
-# endif
|
|
|
-#endif
|
|
|
- physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
|
|
|
- setup_local_APIC();
|
|
|
-
|
|
|
-#ifdef CONFIG_X86_IO_APIC
|
|
|
- /*
|
|
|
- * Now enable IO-APICs, actually call clear_IO_APIC
|
|
|
- * We need clear_IO_APIC before enabling error vector
|
|
|
- */
|
|
|
- if (!skip_ioapic_setup && nr_ioapics)
|
|
|
- enable_IO_APIC();
|
|
|
-#endif
|
|
|
-
|
|
|
- bsp_end_local_APIC_setup();
|
|
|
-
|
|
|
-#ifdef CONFIG_X86_IO_APIC
|
|
|
- if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
|
|
|
- setup_IO_APIC();
|
|
|
- else {
|
|
|
- nr_ioapics = 0;
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
- x86_init.timers.setup_percpu_clockev();
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* Local APIC interrupts
|
|
|
*/
|
|
@@ -2027,7 +1955,7 @@ __visible void smp_trace_error_interrupt(struct pt_regs *regs)
|
|
|
/**
|
|
|
* connect_bsp_APIC - attach the APIC to the interrupt system
|
|
|
*/
|
|
|
-void __init connect_bsp_APIC(void)
|
|
|
+static void __init connect_bsp_APIC(void)
|
|
|
{
|
|
|
#ifdef CONFIG_X86_32
|
|
|
if (pic_mode) {
|
|
@@ -2274,6 +2202,100 @@ void __init apic_set_eoi_write(void (*eoi_write)(u32 reg, u32 v))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void __init apic_bsp_up_setup(void)
|
|
|
+{
|
|
|
+#ifdef CONFIG_X86_64
|
|
|
+ apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid));
|
|
|
+#else
|
|
|
+ /*
|
|
|
+ * Hack: In case of kdump, after a crash, kernel might be booting
|
|
|
+ * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid
|
|
|
+ * might be zero if read from MP tables. Get it from LAPIC.
|
|
|
+ */
|
|
|
+# ifdef CONFIG_CRASH_DUMP
|
|
|
+ boot_cpu_physical_apicid = read_apic_id();
|
|
|
+# endif
|
|
|
+#endif
|
|
|
+ physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * apic_bsp_setup - Setup function for local apic and io-apic
|
|
|
+ * @upmode: Force UP mode (for APIC_init_uniprocessor)
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * apic_id of BSP APIC
|
|
|
+ */
|
|
|
+int __init apic_bsp_setup(bool upmode)
|
|
|
+{
|
|
|
+ int id;
|
|
|
+
|
|
|
+ connect_bsp_APIC();
|
|
|
+ if (upmode)
|
|
|
+ apic_bsp_up_setup();
|
|
|
+ setup_local_APIC();
|
|
|
+
|
|
|
+ if (x2apic_mode)
|
|
|
+ id = apic_read(APIC_LDR);
|
|
|
+ else
|
|
|
+ id = GET_APIC_LOGICAL_ID(apic_read(APIC_LDR));
|
|
|
+
|
|
|
+ enable_IO_APIC();
|
|
|
+ end_local_APIC_setup();
|
|
|
+ irq_remap_enable_fault_handling();
|
|
|
+ setup_IO_APIC();
|
|
|
+ /* Setup local timer */
|
|
|
+ x86_init.timers.setup_percpu_clockev();
|
|
|
+ return id;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * This initializes the IO-APIC and APIC hardware if this is
|
|
|
+ * a UP kernel.
|
|
|
+ */
|
|
|
+int __init APIC_init_uniprocessor(void)
|
|
|
+{
|
|
|
+ if (disable_apic) {
|
|
|
+ pr_info("Apic disabled\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+#ifdef CONFIG_X86_64
|
|
|
+ if (!cpu_has_apic) {
|
|
|
+ disable_apic = 1;
|
|
|
+ pr_info("Apic disabled by BIOS\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+#else
|
|
|
+ if (!smp_found_config && !cpu_has_apic)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Complain if the BIOS pretends there is one.
|
|
|
+ */
|
|
|
+ if (!cpu_has_apic &&
|
|
|
+ APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
|
|
|
+ pr_err("BIOS bug, local APIC 0x%x not detected!...\n",
|
|
|
+ boot_cpu_physical_apicid);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ if (!smp_found_config)
|
|
|
+ disable_ioapic_support();
|
|
|
+
|
|
|
+ default_setup_apic_routing();
|
|
|
+ verify_local_APIC();
|
|
|
+ apic_bsp_setup(true);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+#ifdef CONFIG_UP_LATE_INIT
|
|
|
+void __init up_late_init(void)
|
|
|
+{
|
|
|
+ APIC_init_uniprocessor();
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
/*
|
|
|
* Power management
|
|
|
*/
|
|
@@ -2359,9 +2381,9 @@ static void lapic_resume(void)
|
|
|
mask_ioapic_entries();
|
|
|
legacy_pic->mask_all();
|
|
|
|
|
|
- if (x2apic_mode)
|
|
|
- enable_x2apic();
|
|
|
- else {
|
|
|
+ if (x2apic_mode) {
|
|
|
+ __x2apic_enable();
|
|
|
+ } else {
|
|
|
/*
|
|
|
* Make sure the APICBASE points to the right address
|
|
|
*
|