diff --git a/kernel/src/cpu/x86/apic.rs b/kernel/src/cpu/x86/apic.rs new file mode 100644 index 000000000..68156629d --- /dev/null +++ b/kernel/src/cpu/x86/apic.rs @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) Microsoft Corporation +// +// Author: Jon Lange + +pub const APIC_MSR_EOI: u32 = 0x80B; +pub const APIC_MSR_ISR: u32 = 0x810; +pub const APIC_MSR_ICR: u32 = 0x830; + +// Returns the MSR offset and bitmask to identify a specific vector in an +// APIC register (IRR, ISR, or TMR). +pub fn apic_register_bit(vector: usize) -> (u32, u32) { + let index: u8 = (vector & 0xFF) as u8; + ((index >> 5) as u32, 1 << (index & 0x1F)) +} diff --git a/kernel/src/cpu/x86/mod.rs b/kernel/src/cpu/x86/mod.rs index 7f7ba665a..d888b5830 100644 --- a/kernel/src/cpu/x86/mod.rs +++ b/kernel/src/cpu/x86/mod.rs @@ -4,4 +4,5 @@ // // Authors: Thomas Leroy +pub mod apic; pub mod smap; diff --git a/kernel/src/platform/native.rs b/kernel/src/platform/native.rs index 003196a76..99125ee38 100644 --- a/kernel/src/platform/native.rs +++ b/kernel/src/platform/native.rs @@ -12,6 +12,7 @@ use crate::cpu::cpuid::CpuidResult; use crate::cpu::msr::{read_msr, write_msr}; use crate::cpu::percpu::PerCpu; use crate::cpu::smp::create_ap_start_context; +use crate::cpu::x86::apic::{APIC_MSR_EOI, APIC_MSR_ICR}; use crate::error::SvsmError; use crate::hyperv; use crate::hyperv::{hyperv_setup_hypercalls, hyperv_start_cpu, is_hyperv_hypervisor}; @@ -33,9 +34,6 @@ use bootlib::platform::SvsmPlatformType; const MSR_APIC_BASE: u32 = 0x1B; const APIC_X2_ENABLE_MASK: u64 = 0xC00; -const APIC_MSR_EOI: u32 = 0x80B; -const APIC_MSR_ICR: u32 = 0x830; - #[derive(Clone, Copy, Debug)] pub struct NativePlatform { is_hyperv: bool, diff --git a/kernel/src/platform/tdp.rs b/kernel/src/platform/tdp.rs index c14710762..e4d428aff 100644 --- a/kernel/src/platform/tdp.rs +++ b/kernel/src/platform/tdp.rs @@ -7,7 +7,9 @@ use crate::address::{Address, PhysAddr, VirtAddr}; use crate::console::init_svsm_console; use crate::cpu::cpuid::CpuidResult; +use crate::cpu::msr::read_msr; use crate::cpu::percpu::PerCpu; +use crate::cpu::x86::apic::{apic_register_bit, APIC_MSR_ISR}; use crate::error::SvsmError; use crate::hyperv; use crate::io::IOPort; @@ -171,11 +173,11 @@ impl SvsmPlatform for TdpPlatform { fn eoi(&self) {} - fn is_external_interrupt(&self, _vector: usize) -> bool { + fn is_external_interrupt(&self, vector: usize) -> bool { // Examine the APIC ISR to determine whether this interrupt vector is // active. If so, it is assumed to be an external interrupt. - // TODO - add code to read the APIC ISR. - todo!(); + let (msr, mask) = apic_register_bit(vector); + (read_msr(APIC_MSR_ISR + msr) & mask as u64) != 0 } fn start_cpu(