// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause // // Copyright © 2025, Microsoft Corporation // use std::any::Any; use serde::{Deserialize, Serialize}; use crate::arch::aarch64::gic::{GicState, Result, Vgic, VgicConfig}; use crate::{CpuState, Vm}; pub struct MshvGicV2M { /// GIC distributor address pub dist_addr: u64, /// GIC distributor size pub dist_size: u64, /// GIC re-distributors address pub redists_addr: u64, /// GIC re-distributors size pub redists_size: u64, /// GITS translator address pub gits_addr: u64, /// GITS translator size pub gits_size: u64, /// Number of CPUs handled by the device pub vcpu_count: u64, } pub const BASE_SPI_IRQ: u32 = 32; #[derive(Clone, Default, Serialize, Deserialize)] pub struct MshvGicV2MState {} impl From for MshvGicV2MState { fn from(state: GicState) -> Self { match state { GicState::MshvGicV2M(state) => state, /* Needed in case other hypervisors are enabled */ #[allow(unreachable_patterns)] _ => panic!("GicState is not valid"), } } } impl From for GicState { fn from(state: MshvGicV2MState) -> Self { GicState::MshvGicV2M(state) } } impl MshvGicV2M { /// Create a new GICv2m device pub fn new(_vm: &dyn Vm, config: &VgicConfig) -> Result { let gic_device = MshvGicV2M { dist_addr: config.dist_addr, dist_size: config.dist_size, redists_addr: config.redists_addr, redists_size: config.redists_size, gits_addr: config.msi_addr, gits_size: config.msi_size, vcpu_count: config.vcpu_count, }; Ok(gic_device) } } impl Vgic for MshvGicV2M { fn fdt_compatibility(&self) -> &str { "arm,gic-v3" } fn msi_compatible(&self) -> bool { true } fn msi_compatibility(&self) -> &str { "arm,gic-v2m-frame" } fn fdt_maint_irq(&self) -> u32 { 0 } fn vcpu_count(&self) -> u64 { self.vcpu_count } fn msi_properties(&self) -> [u64; 2] { [self.gits_addr, self.gits_size] } fn device_properties(&self) -> [u64; 4] { [ self.dist_addr, self.dist_size, self.redists_addr, self.redists_size, ] } fn set_gicr_typers(&mut self, _vcpu_states: &[CpuState]) { unimplemented!() } fn state(&self) -> Result { unimplemented!() } fn as_any_concrete_mut(&mut self) -> &mut dyn Any { self } fn set_state(&mut self, _state: &GicState) -> Result<()> { unimplemented!() } fn save_data_tables(&self) -> Result<()> { Ok(()) } }