44 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2021, Google LLC.4 */5 6#include "apic.h"7 8void apic_disable(void)9{10 wrmsr(MSR_IA32_APICBASE,11 rdmsr(MSR_IA32_APICBASE) &12 ~(MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD));13}14 15void xapic_enable(void)16{17 uint64_t val = rdmsr(MSR_IA32_APICBASE);18 19 /* Per SDM: to enable xAPIC when in x2APIC must first disable APIC */20 if (val & MSR_IA32_APICBASE_EXTD) {21 apic_disable();22 wrmsr(MSR_IA32_APICBASE,23 rdmsr(MSR_IA32_APICBASE) | MSR_IA32_APICBASE_ENABLE);24 } else if (!(val & MSR_IA32_APICBASE_ENABLE)) {25 wrmsr(MSR_IA32_APICBASE, val | MSR_IA32_APICBASE_ENABLE);26 }27 28 /*29 * Per SDM: reset value of spurious interrupt vector register has the30 * APIC software enabled bit=0. It must be enabled in addition to the31 * enable bit in the MSR.32 */33 val = xapic_read_reg(APIC_SPIV) | APIC_SPIV_APIC_ENABLED;34 xapic_write_reg(APIC_SPIV, val);35}36 37void x2apic_enable(void)38{39 wrmsr(MSR_IA32_APICBASE, rdmsr(MSR_IA32_APICBASE) |40 MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD);41 x2apic_write_reg(APIC_SPIV,42 x2apic_read_reg(APIC_SPIV) | APIC_SPIV_APIC_ENABLED);43}44