cpu/x86/lapic: Split virtual_wire_mode_init()

Only the enable_lapic() part is required while doing
SMP init. Also disable_lapic() must not be called if
we rely on LAPIC for timer source.

Change-Id: Ib5e37c1a0a91fa4e9542141aa74f1c1876fee94e
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/55261
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
Kyösti Mälkki 2021-06-06 22:56:41 +03:00
parent 05ae8f2ff3
commit ff556ca995
1 changed files with 11 additions and 17 deletions

View File

@ -10,12 +10,15 @@
void enable_lapic(void) void enable_lapic(void)
{ {
msr_t msr; msr_t msr;
msr = rdmsr(LAPIC_BASE_MSR); msr = rdmsr(LAPIC_BASE_MSR);
msr.hi &= 0xffffff00; msr.hi &= 0xffffff00;
msr.lo &= ~LAPIC_BASE_MSR_ADDR_MASK; msr.lo &= ~LAPIC_BASE_MSR_ADDR_MASK;
msr.lo |= LAPIC_DEFAULT_BASE; msr.lo |= LAPIC_DEFAULT_BASE;
msr.lo |= LAPIC_BASE_MSR_ENABLE; msr.lo |= LAPIC_BASE_MSR_ENABLE;
wrmsr(LAPIC_BASE_MSR, msr); wrmsr(LAPIC_BASE_MSR, msr);
printk(BIOS_INFO, "Setting up local APIC 0x%x\n", lapicid());
} }
void disable_lapic(void) void disable_lapic(void)
@ -39,19 +42,6 @@ static int need_lapic_init(void)
static void lapic_virtual_wire_mode_init(void) static void lapic_virtual_wire_mode_init(void)
{ {
/* this is so interrupts work. This is very limited scope --
* linux will do better later, we hope ...
*/
/* this is the first way we learned to do it. It fails on real SMP
* stuff. So we have to do things differently ...
* see the Intel mp1.4 spec, page A-3
*/
printk(BIOS_INFO, "Setting up local APIC...\n");
/* Enable the local APIC */
enable_lapic();
/* /*
* Set Task Priority to 'accept all'. * Set Task Priority to 'accept all'.
*/ */
@ -70,14 +60,18 @@ static void lapic_virtual_wire_mode_init(void)
lapic_update32(LAPIC_LVT1, ~mask, LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING | lapic_update32(LAPIC_LVT1, ~mask, LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING |
LAPIC_DELIVERY_MODE_NMI); LAPIC_DELIVERY_MODE_NMI);
printk(BIOS_DEBUG, " apic_id: 0x%x ", lapicid());
printk(BIOS_INFO, "done.\n");
} }
void setup_lapic(void) void setup_lapic(void)
{ {
/* Enable the local APIC */
if (need_lapic_init())
enable_lapic();
else if (!CONFIG(UDELAY_LAPIC))
disable_lapic();
/* This programming is for PIC mode i8259 interrupts to be delivered to CPU
while LAPIC is enabled. */
if (need_lapic_init()) if (need_lapic_init())
lapic_virtual_wire_mode_init(); lapic_virtual_wire_mode_init();
else
disable_lapic();
} }