1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2020 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::BTreeMap; 6*bb4ee6a4SAndroid Build Coastguard Worker use std::convert::TryFrom; 7*bb4ee6a4SAndroid Build Coastguard Worker use std::fmt::Debug; 8*bb4ee6a4SAndroid Build Coastguard Worker 9*bb4ee6a4SAndroid Build Coastguard Worker use base::Error; 10*bb4ee6a4SAndroid Build Coastguard Worker use base::Result; 11*bb4ee6a4SAndroid Build Coastguard Worker use cros_fdt::Fdt; 12*bb4ee6a4SAndroid Build Coastguard Worker use downcast_rs::impl_downcast; 13*bb4ee6a4SAndroid Build Coastguard Worker use libc::EINVAL; 14*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize; 15*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize; 16*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::GuestAddress; 17*bb4ee6a4SAndroid Build Coastguard Worker 18*bb4ee6a4SAndroid Build Coastguard Worker use crate::Hypervisor; 19*bb4ee6a4SAndroid Build Coastguard Worker use crate::IrqRoute; 20*bb4ee6a4SAndroid Build Coastguard Worker use crate::IrqSource; 21*bb4ee6a4SAndroid Build Coastguard Worker use crate::IrqSourceChip; 22*bb4ee6a4SAndroid Build Coastguard Worker use crate::Vcpu; 23*bb4ee6a4SAndroid Build Coastguard Worker use crate::Vm; 24*bb4ee6a4SAndroid Build Coastguard Worker 25*bb4ee6a4SAndroid Build Coastguard Worker /// Represents a version of Power State Coordination Interface (PSCI). 26*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Eq, Ord, PartialEq, PartialOrd)] 27*bb4ee6a4SAndroid Build Coastguard Worker pub struct PsciVersion { 28*bb4ee6a4SAndroid Build Coastguard Worker pub major: u16, 29*bb4ee6a4SAndroid Build Coastguard Worker pub minor: u16, 30*bb4ee6a4SAndroid Build Coastguard Worker } 31*bb4ee6a4SAndroid Build Coastguard Worker 32*bb4ee6a4SAndroid Build Coastguard Worker impl PsciVersion { new(major: u16, minor: u16) -> Result<Self>33*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(major: u16, minor: u16) -> Result<Self> { 34*bb4ee6a4SAndroid Build Coastguard Worker if (major as i16) < 0 { 35*bb4ee6a4SAndroid Build Coastguard Worker Err(Error::new(EINVAL)) 36*bb4ee6a4SAndroid Build Coastguard Worker } else { 37*bb4ee6a4SAndroid Build Coastguard Worker Ok(Self { major, minor }) 38*bb4ee6a4SAndroid Build Coastguard Worker } 39*bb4ee6a4SAndroid Build Coastguard Worker } 40*bb4ee6a4SAndroid Build Coastguard Worker } 41*bb4ee6a4SAndroid Build Coastguard Worker 42*bb4ee6a4SAndroid Build Coastguard Worker impl TryFrom<u32> for PsciVersion { 43*bb4ee6a4SAndroid Build Coastguard Worker type Error = base::Error; 44*bb4ee6a4SAndroid Build Coastguard Worker try_from(item: u32) -> Result<Self>45*bb4ee6a4SAndroid Build Coastguard Worker fn try_from(item: u32) -> Result<Self> { 46*bb4ee6a4SAndroid Build Coastguard Worker Self::new((item >> 16) as u16, item as u16) 47*bb4ee6a4SAndroid Build Coastguard Worker } 48*bb4ee6a4SAndroid Build Coastguard Worker } 49*bb4ee6a4SAndroid Build Coastguard Worker 50*bb4ee6a4SAndroid Build Coastguard Worker // Aarch64 does not provide a concrete number as to how many registers exist. 51*bb4ee6a4SAndroid Build Coastguard Worker // The list of registers available exceeds 600 registers 52*bb4ee6a4SAndroid Build Coastguard Worker pub const AARCH64_MAX_REG_COUNT: usize = 1024; 53*bb4ee6a4SAndroid Build Coastguard Worker 54*bb4ee6a4SAndroid Build Coastguard Worker pub const PSCI_0_2: PsciVersion = PsciVersion { major: 0, minor: 2 }; 55*bb4ee6a4SAndroid Build Coastguard Worker pub const PSCI_1_0: PsciVersion = PsciVersion { major: 1, minor: 0 }; 56*bb4ee6a4SAndroid Build Coastguard Worker 57*bb4ee6a4SAndroid Build Coastguard Worker /// AArch64 system register as used in MSR/MRS instructions. 58*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize)] 59*bb4ee6a4SAndroid Build Coastguard Worker #[serde(transparent)] 60*bb4ee6a4SAndroid Build Coastguard Worker pub struct AArch64SysRegId(u16); 61*bb4ee6a4SAndroid Build Coastguard Worker 62*bb4ee6a4SAndroid Build Coastguard Worker impl AArch64SysRegId { 63*bb4ee6a4SAndroid Build Coastguard Worker /// Construct a system register ID from Op0, Op1, CRn, CRm, Op2. 64*bb4ee6a4SAndroid Build Coastguard Worker /// 65*bb4ee6a4SAndroid Build Coastguard Worker /// The meanings of the arguments are described in the ARMv8 Architecture Reference Manual 66*bb4ee6a4SAndroid Build Coastguard Worker /// "System instruction class encoding overview" section. new(op0: u8, op1: u8, crn: u8, crm: u8, op2: u8) -> Result<Self>67*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(op0: u8, op1: u8, crn: u8, crm: u8, op2: u8) -> Result<Self> { 68*bb4ee6a4SAndroid Build Coastguard Worker if op0 > 0b11 || op1 > 0b111 || crn > 0b1111 || crm > 0b1111 || op2 > 0b111 { 69*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::new(EINVAL)); 70*bb4ee6a4SAndroid Build Coastguard Worker } 71*bb4ee6a4SAndroid Build Coastguard Worker 72*bb4ee6a4SAndroid Build Coastguard Worker Ok(Self::new_unchecked(op0, op1, crn, crm, op2)) 73*bb4ee6a4SAndroid Build Coastguard Worker } 74*bb4ee6a4SAndroid Build Coastguard Worker 75*bb4ee6a4SAndroid Build Coastguard Worker /// Construct a system register ID from Op0, Op1, CRn, CRm, Op2. 76*bb4ee6a4SAndroid Build Coastguard Worker /// 77*bb4ee6a4SAndroid Build Coastguard Worker /// Out-of-range values will be silently truncated. new_unchecked(op0: u8, op1: u8, crn: u8, crm: u8, op2: u8) -> Self78*bb4ee6a4SAndroid Build Coastguard Worker pub const fn new_unchecked(op0: u8, op1: u8, crn: u8, crm: u8, op2: u8) -> Self { 79*bb4ee6a4SAndroid Build Coastguard Worker let op0 = (op0 as u16 & 0b11) << 14; 80*bb4ee6a4SAndroid Build Coastguard Worker let op1 = (op1 as u16 & 0b111) << 11; 81*bb4ee6a4SAndroid Build Coastguard Worker let crn = (crn as u16 & 0b1111) << 7; 82*bb4ee6a4SAndroid Build Coastguard Worker let crm = (crm as u16 & 0b1111) << 3; 83*bb4ee6a4SAndroid Build Coastguard Worker let op2 = op2 as u16 & 0b111; 84*bb4ee6a4SAndroid Build Coastguard Worker Self(op0 | op1 | crn | crm | op2) 85*bb4ee6a4SAndroid Build Coastguard Worker } 86*bb4ee6a4SAndroid Build Coastguard Worker from_encoded(v: u16) -> Self87*bb4ee6a4SAndroid Build Coastguard Worker pub fn from_encoded(v: u16) -> Self { 88*bb4ee6a4SAndroid Build Coastguard Worker Self(v) 89*bb4ee6a4SAndroid Build Coastguard Worker } 90*bb4ee6a4SAndroid Build Coastguard Worker 91*bb4ee6a4SAndroid Build Coastguard Worker #[inline] op0(&self) -> u892*bb4ee6a4SAndroid Build Coastguard Worker pub const fn op0(&self) -> u8 { 93*bb4ee6a4SAndroid Build Coastguard Worker ((self.0 >> 14) & 0b11) as u8 94*bb4ee6a4SAndroid Build Coastguard Worker } 95*bb4ee6a4SAndroid Build Coastguard Worker 96*bb4ee6a4SAndroid Build Coastguard Worker #[inline] op1(&self) -> u897*bb4ee6a4SAndroid Build Coastguard Worker pub const fn op1(&self) -> u8 { 98*bb4ee6a4SAndroid Build Coastguard Worker ((self.0 >> 11) & 0b111) as u8 99*bb4ee6a4SAndroid Build Coastguard Worker } 100*bb4ee6a4SAndroid Build Coastguard Worker 101*bb4ee6a4SAndroid Build Coastguard Worker #[inline] crn(&self) -> u8102*bb4ee6a4SAndroid Build Coastguard Worker pub const fn crn(&self) -> u8 { 103*bb4ee6a4SAndroid Build Coastguard Worker ((self.0 >> 7) & 0b1111) as u8 104*bb4ee6a4SAndroid Build Coastguard Worker } 105*bb4ee6a4SAndroid Build Coastguard Worker 106*bb4ee6a4SAndroid Build Coastguard Worker #[inline] crm(&self) -> u8107*bb4ee6a4SAndroid Build Coastguard Worker pub const fn crm(&self) -> u8 { 108*bb4ee6a4SAndroid Build Coastguard Worker ((self.0 >> 3) & 0b1111) as u8 109*bb4ee6a4SAndroid Build Coastguard Worker } 110*bb4ee6a4SAndroid Build Coastguard Worker 111*bb4ee6a4SAndroid Build Coastguard Worker #[inline] op2(&self) -> u8112*bb4ee6a4SAndroid Build Coastguard Worker pub const fn op2(&self) -> u8 { 113*bb4ee6a4SAndroid Build Coastguard Worker (self.0 & 0b111) as u8 114*bb4ee6a4SAndroid Build Coastguard Worker } 115*bb4ee6a4SAndroid Build Coastguard Worker 116*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the system register as encoded in bits 5-20 of MRS and MSR instructions. encoded(&self) -> u16117*bb4ee6a4SAndroid Build Coastguard Worker pub const fn encoded(&self) -> u16 { 118*bb4ee6a4SAndroid Build Coastguard Worker self.0 119*bb4ee6a4SAndroid Build Coastguard Worker } 120*bb4ee6a4SAndroid Build Coastguard Worker } 121*bb4ee6a4SAndroid Build Coastguard Worker 122*bb4ee6a4SAndroid Build Coastguard Worker impl Debug for AArch64SysRegId { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result123*bb4ee6a4SAndroid Build Coastguard Worker fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 124*bb4ee6a4SAndroid Build Coastguard Worker f.debug_struct("AArch64SysRegId") 125*bb4ee6a4SAndroid Build Coastguard Worker .field("Op0", &self.op0()) 126*bb4ee6a4SAndroid Build Coastguard Worker .field("Op1", &self.op1()) 127*bb4ee6a4SAndroid Build Coastguard Worker .field("CRn", &self.crn()) 128*bb4ee6a4SAndroid Build Coastguard Worker .field("CRm", &self.crm()) 129*bb4ee6a4SAndroid Build Coastguard Worker .field("Op2", &self.op2()) 130*bb4ee6a4SAndroid Build Coastguard Worker .finish() 131*bb4ee6a4SAndroid Build Coastguard Worker } 132*bb4ee6a4SAndroid Build Coastguard Worker } 133*bb4ee6a4SAndroid Build Coastguard Worker 134*bb4ee6a4SAndroid Build Coastguard Worker #[rustfmt::skip] 135*bb4ee6a4SAndroid Build Coastguard Worker #[allow(non_upper_case_globals)] 136*bb4ee6a4SAndroid Build Coastguard Worker impl AArch64SysRegId { 137*bb4ee6a4SAndroid Build Coastguard Worker // Op0 Op1 CRn CRm Op2 138*bb4ee6a4SAndroid Build Coastguard Worker pub const MPIDR_EL1: Self = Self::new_unchecked(0b11, 0b000, 0b0000, 0b0000, 0b101); 139*bb4ee6a4SAndroid Build Coastguard Worker pub const CCSIDR_EL1: Self = Self::new_unchecked(0b11, 0b001, 0b0000, 0b0000, 0b000); 140*bb4ee6a4SAndroid Build Coastguard Worker pub const CSSELR_EL1: Self = Self::new_unchecked(0b11, 0b010, 0b0000, 0b0000, 0b000); 141*bb4ee6a4SAndroid Build Coastguard Worker pub const FPCR: Self = Self::new_unchecked(0b11, 0b011, 0b0100, 0b0100, 0b000); 142*bb4ee6a4SAndroid Build Coastguard Worker pub const FPSR: Self = Self::new_unchecked(0b11, 0b011, 0b0100, 0b0100, 0b001); 143*bb4ee6a4SAndroid Build Coastguard Worker pub const SPSR_EL1: Self = Self::new_unchecked(0b11, 0b000, 0b0100, 0b0000, 0b000); 144*bb4ee6a4SAndroid Build Coastguard Worker pub const SPSR_irq: Self = Self::new_unchecked(0b11, 0b100, 0b0100, 0b0011, 0b000); 145*bb4ee6a4SAndroid Build Coastguard Worker pub const SPSR_abt: Self = Self::new_unchecked(0b11, 0b100, 0b0100, 0b0011, 0b001); 146*bb4ee6a4SAndroid Build Coastguard Worker pub const SPSR_und: Self = Self::new_unchecked(0b11, 0b100, 0b0100, 0b0011, 0b010); 147*bb4ee6a4SAndroid Build Coastguard Worker pub const SPSR_fiq: Self = Self::new_unchecked(0b11, 0b100, 0b0100, 0b0011, 0b011); 148*bb4ee6a4SAndroid Build Coastguard Worker pub const ELR_EL1: Self = Self::new_unchecked(0b11, 0b000, 0b0100, 0b0000, 0b001); 149*bb4ee6a4SAndroid Build Coastguard Worker pub const SP_EL1: Self = Self::new_unchecked(0b11, 0b100, 0b0100, 0b0001, 0b000); 150*bb4ee6a4SAndroid Build Coastguard Worker pub const CNTVCT_EL0: Self = Self::new_unchecked(0b11, 0b011, 0b1110, 0b0000, 0b010); 151*bb4ee6a4SAndroid Build Coastguard Worker pub const CNTV_CVAL_EL0: Self = Self::new_unchecked(0b11, 0b011, 0b1110, 0b0011, 0b010); 152*bb4ee6a4SAndroid Build Coastguard Worker } 153*bb4ee6a4SAndroid Build Coastguard Worker 154*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] 155*bb4ee6a4SAndroid Build Coastguard Worker pub enum VcpuRegAArch64 { 156*bb4ee6a4SAndroid Build Coastguard Worker X(u8), 157*bb4ee6a4SAndroid Build Coastguard Worker Sp, 158*bb4ee6a4SAndroid Build Coastguard Worker Pc, 159*bb4ee6a4SAndroid Build Coastguard Worker Pstate, 160*bb4ee6a4SAndroid Build Coastguard Worker System(AArch64SysRegId), 161*bb4ee6a4SAndroid Build Coastguard Worker } 162*bb4ee6a4SAndroid Build Coastguard Worker 163*bb4ee6a4SAndroid Build Coastguard Worker /// A wrapper for using a VM on aarch64 and getting/setting its state. 164*bb4ee6a4SAndroid Build Coastguard Worker pub trait VmAArch64: Vm { 165*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the `Hypervisor` that created this VM. get_hypervisor(&self) -> &dyn Hypervisor166*bb4ee6a4SAndroid Build Coastguard Worker fn get_hypervisor(&self) -> &dyn Hypervisor; 167*bb4ee6a4SAndroid Build Coastguard Worker 168*bb4ee6a4SAndroid Build Coastguard Worker /// Load pVM firmware for the VM, creating a memslot for it as needed. 169*bb4ee6a4SAndroid Build Coastguard Worker /// 170*bb4ee6a4SAndroid Build Coastguard Worker /// Only works on protected VMs (i.e. those that support `VmCap::Protected`). load_protected_vm_firmware(&mut self, fw_addr: GuestAddress, fw_max_size: u64) -> Result<()>171*bb4ee6a4SAndroid Build Coastguard Worker fn load_protected_vm_firmware(&mut self, fw_addr: GuestAddress, fw_max_size: u64) 172*bb4ee6a4SAndroid Build Coastguard Worker -> Result<()>; 173*bb4ee6a4SAndroid Build Coastguard Worker 174*bb4ee6a4SAndroid Build Coastguard Worker /// Create a Vcpu with the specified Vcpu ID. create_vcpu(&self, id: usize) -> Result<Box<dyn VcpuAArch64>>175*bb4ee6a4SAndroid Build Coastguard Worker fn create_vcpu(&self, id: usize) -> Result<Box<dyn VcpuAArch64>>; 176*bb4ee6a4SAndroid Build Coastguard Worker 177*bb4ee6a4SAndroid Build Coastguard Worker /// Create DT configuration node for the hypervisor. 178*bb4ee6a4SAndroid Build Coastguard Worker /// `fdt` - Fdt initialized at the root node. 179*bb4ee6a4SAndroid Build Coastguard Worker /// `phandles` - Map of strings to a phandle. create_fdt(&self, fdt: &mut Fdt, phandles: &BTreeMap<&str, u32>) -> cros_fdt::Result<()>180*bb4ee6a4SAndroid Build Coastguard Worker fn create_fdt(&self, fdt: &mut Fdt, phandles: &BTreeMap<&str, u32>) -> cros_fdt::Result<()>; 181*bb4ee6a4SAndroid Build Coastguard Worker 182*bb4ee6a4SAndroid Build Coastguard Worker // Initialize a VM. Called after building the VM. Presently called before vCPUs are initialized. init_arch( &self, payload_entry_address: GuestAddress, fdt_address: GuestAddress, fdt_size: usize, ) -> Result<()>183*bb4ee6a4SAndroid Build Coastguard Worker fn init_arch( 184*bb4ee6a4SAndroid Build Coastguard Worker &self, 185*bb4ee6a4SAndroid Build Coastguard Worker payload_entry_address: GuestAddress, 186*bb4ee6a4SAndroid Build Coastguard Worker fdt_address: GuestAddress, 187*bb4ee6a4SAndroid Build Coastguard Worker fdt_size: usize, 188*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()>; 189*bb4ee6a4SAndroid Build Coastguard Worker 190*bb4ee6a4SAndroid Build Coastguard Worker /// Set an offset that describes a number of counter cycles that are subtracted from both 191*bb4ee6a4SAndroid Build Coastguard Worker /// virtual and physical counter views. set_counter_offset(&self, _offset: u64) -> Result<()>192*bb4ee6a4SAndroid Build Coastguard Worker fn set_counter_offset(&self, _offset: u64) -> Result<()> { 193*bb4ee6a4SAndroid Build Coastguard Worker Err(Error::new(libc::ENOSYS)) 194*bb4ee6a4SAndroid Build Coastguard Worker } 195*bb4ee6a4SAndroid Build Coastguard Worker } 196*bb4ee6a4SAndroid Build Coastguard Worker 197*bb4ee6a4SAndroid Build Coastguard Worker /// A wrapper around creating and using a VCPU on aarch64. 198*bb4ee6a4SAndroid Build Coastguard Worker pub trait VcpuAArch64: Vcpu { 199*bb4ee6a4SAndroid Build Coastguard Worker /// Does ARM-specific initialization of this VCPU. Inits the VCPU with the preferred target 200*bb4ee6a4SAndroid Build Coastguard Worker /// VCPU type and the specified `features`, and resets the value of all registers to defaults. 201*bb4ee6a4SAndroid Build Coastguard Worker /// All VCPUs should be created before calling this function. init(&self, features: &[VcpuFeature]) -> Result<()>202*bb4ee6a4SAndroid Build Coastguard Worker fn init(&self, features: &[VcpuFeature]) -> Result<()>; 203*bb4ee6a4SAndroid Build Coastguard Worker 204*bb4ee6a4SAndroid Build Coastguard Worker /// Initializes the ARM Performance Monitor Unit v3 on this VCPU, with overflow interrupt number 205*bb4ee6a4SAndroid Build Coastguard Worker /// `irq`. init_pmu(&self, irq: u64) -> Result<()>206*bb4ee6a4SAndroid Build Coastguard Worker fn init_pmu(&self, irq: u64) -> Result<()>; 207*bb4ee6a4SAndroid Build Coastguard Worker 208*bb4ee6a4SAndroid Build Coastguard Worker /// Checks if ARM ParaVirtualized Time is supported on this VCPU has_pvtime_support(&self) -> bool209*bb4ee6a4SAndroid Build Coastguard Worker fn has_pvtime_support(&self) -> bool; 210*bb4ee6a4SAndroid Build Coastguard Worker 211*bb4ee6a4SAndroid Build Coastguard Worker /// Initializes the ARM ParaVirtualized Time on this VCPU, with base address of the stolen time 212*bb4ee6a4SAndroid Build Coastguard Worker /// structure as `pvtime_ipa`. init_pvtime(&self, pvtime_ipa: u64) -> Result<()>213*bb4ee6a4SAndroid Build Coastguard Worker fn init_pvtime(&self, pvtime_ipa: u64) -> Result<()>; 214*bb4ee6a4SAndroid Build Coastguard Worker 215*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the value of a register on this VCPU. set_one_reg(&self, reg_id: VcpuRegAArch64, data: u64) -> Result<()>216*bb4ee6a4SAndroid Build Coastguard Worker fn set_one_reg(&self, reg_id: VcpuRegAArch64, data: u64) -> Result<()>; 217*bb4ee6a4SAndroid Build Coastguard Worker 218*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the value of a register on this VCPU. get_one_reg(&self, reg_id: VcpuRegAArch64) -> Result<u64>219*bb4ee6a4SAndroid Build Coastguard Worker fn get_one_reg(&self, reg_id: VcpuRegAArch64) -> Result<u64>; 220*bb4ee6a4SAndroid Build Coastguard Worker 221*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the value of a Neon vector register (V0-V31) on this VCPU. set_vector_reg(&self, reg_num: u8, data: u128) -> Result<()>222*bb4ee6a4SAndroid Build Coastguard Worker fn set_vector_reg(&self, reg_num: u8, data: u128) -> Result<()>; 223*bb4ee6a4SAndroid Build Coastguard Worker 224*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the value of a Neon vector register (V0-V31) on this VCPU. get_vector_reg(&self, reg_num: u8) -> Result<u128>225*bb4ee6a4SAndroid Build Coastguard Worker fn get_vector_reg(&self, reg_num: u8) -> Result<u128>; 226*bb4ee6a4SAndroid Build Coastguard Worker 227*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the set of system registers accessible by the hypervisor get_system_regs(&self) -> Result<BTreeMap<AArch64SysRegId, u64>>228*bb4ee6a4SAndroid Build Coastguard Worker fn get_system_regs(&self) -> Result<BTreeMap<AArch64SysRegId, u64>>; 229*bb4ee6a4SAndroid Build Coastguard Worker 230*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the hypervisor specific data for snapshot hypervisor_specific_snapshot(&self) -> anyhow::Result<serde_json::Value>231*bb4ee6a4SAndroid Build Coastguard Worker fn hypervisor_specific_snapshot(&self) -> anyhow::Result<serde_json::Value>; 232*bb4ee6a4SAndroid Build Coastguard Worker 233*bb4ee6a4SAndroid Build Coastguard Worker /// Restores the hypervisor specific data hypervisor_specific_restore(&self, _data: serde_json::Value) -> anyhow::Result<()>234*bb4ee6a4SAndroid Build Coastguard Worker fn hypervisor_specific_restore(&self, _data: serde_json::Value) -> anyhow::Result<()>; 235*bb4ee6a4SAndroid Build Coastguard Worker 236*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the value of MPIDR_EL1 on this VCPU. get_mpidr(&self) -> Result<u64>237*bb4ee6a4SAndroid Build Coastguard Worker fn get_mpidr(&self) -> Result<u64> { 238*bb4ee6a4SAndroid Build Coastguard Worker const RES1: u64 = 1 << 31; 239*bb4ee6a4SAndroid Build Coastguard Worker 240*bb4ee6a4SAndroid Build Coastguard Worker // Assume that MPIDR_EL1.{U,MT} = {0,0}. 241*bb4ee6a4SAndroid Build Coastguard Worker 242*bb4ee6a4SAndroid Build Coastguard Worker let aff = u64::try_from(self.id()).unwrap(); 243*bb4ee6a4SAndroid Build Coastguard Worker 244*bb4ee6a4SAndroid Build Coastguard Worker Ok(RES1 | aff) 245*bb4ee6a4SAndroid Build Coastguard Worker } 246*bb4ee6a4SAndroid Build Coastguard Worker 247*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the current PSCI version. get_psci_version(&self) -> Result<PsciVersion>248*bb4ee6a4SAndroid Build Coastguard Worker fn get_psci_version(&self) -> Result<PsciVersion>; 249*bb4ee6a4SAndroid Build Coastguard Worker 250*bb4ee6a4SAndroid Build Coastguard Worker /// Sets up debug registers and configure vcpu for handling guest debug events. set_guest_debug(&self, addrs: &[GuestAddress], enable_singlestep: bool) -> Result<()>251*bb4ee6a4SAndroid Build Coastguard Worker fn set_guest_debug(&self, addrs: &[GuestAddress], enable_singlestep: bool) -> Result<()>; 252*bb4ee6a4SAndroid Build Coastguard Worker 253*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the max number of hardware breakpoints. get_max_hw_bps(&self) -> Result<usize>254*bb4ee6a4SAndroid Build Coastguard Worker fn get_max_hw_bps(&self) -> Result<usize>; 255*bb4ee6a4SAndroid Build Coastguard Worker 256*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the cache architecture information for all cache levels. 257*bb4ee6a4SAndroid Build Coastguard Worker /// The keys of the map are the lower 4 lower significant bits of CSSELR_EL1, which represents 258*bb4ee6a4SAndroid Build Coastguard Worker /// the cache level. cache level is actually located in bits [3:1], but the value saves also 259*bb4ee6a4SAndroid Build Coastguard Worker /// if the cache is an instruction or data. 260*bb4ee6a4SAndroid Build Coastguard Worker /// The values of the map are CCSIDR_EL1, which is the configuration of the cache. get_cache_info(&self) -> Result<BTreeMap<u8, u64>>261*bb4ee6a4SAndroid Build Coastguard Worker fn get_cache_info(&self) -> Result<BTreeMap<u8, u64>>; 262*bb4ee6a4SAndroid Build Coastguard Worker 263*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the cache architecture information for all cache levels. set_cache_info(&self, cache_info: BTreeMap<u8, u64>) -> Result<()>264*bb4ee6a4SAndroid Build Coastguard Worker fn set_cache_info(&self, cache_info: BTreeMap<u8, u64>) -> Result<()>; 265*bb4ee6a4SAndroid Build Coastguard Worker snapshot(&self) -> anyhow::Result<VcpuSnapshot>266*bb4ee6a4SAndroid Build Coastguard Worker fn snapshot(&self) -> anyhow::Result<VcpuSnapshot> { 267*bb4ee6a4SAndroid Build Coastguard Worker let mut snap = VcpuSnapshot { 268*bb4ee6a4SAndroid Build Coastguard Worker vcpu_id: self.id(), 269*bb4ee6a4SAndroid Build Coastguard Worker sp: self.get_one_reg(VcpuRegAArch64::Sp)?, 270*bb4ee6a4SAndroid Build Coastguard Worker pc: self.get_one_reg(VcpuRegAArch64::Pc)?, 271*bb4ee6a4SAndroid Build Coastguard Worker pstate: self.get_one_reg(VcpuRegAArch64::Pstate)?, 272*bb4ee6a4SAndroid Build Coastguard Worker hypervisor_data: self.hypervisor_specific_snapshot()?, 273*bb4ee6a4SAndroid Build Coastguard Worker sys: self.get_system_regs()?, 274*bb4ee6a4SAndroid Build Coastguard Worker cache_arch_info: self.get_cache_info()?, 275*bb4ee6a4SAndroid Build Coastguard Worker ..Default::default() 276*bb4ee6a4SAndroid Build Coastguard Worker }; 277*bb4ee6a4SAndroid Build Coastguard Worker 278*bb4ee6a4SAndroid Build Coastguard Worker for (n, xn) in snap.x.iter_mut().enumerate() { 279*bb4ee6a4SAndroid Build Coastguard Worker *xn = self.get_one_reg(VcpuRegAArch64::X(n as u8))?; 280*bb4ee6a4SAndroid Build Coastguard Worker } 281*bb4ee6a4SAndroid Build Coastguard Worker 282*bb4ee6a4SAndroid Build Coastguard Worker for (n, vn) in snap.v.iter_mut().enumerate() { 283*bb4ee6a4SAndroid Build Coastguard Worker *vn = self.get_vector_reg(n as u8)?; 284*bb4ee6a4SAndroid Build Coastguard Worker } 285*bb4ee6a4SAndroid Build Coastguard Worker 286*bb4ee6a4SAndroid Build Coastguard Worker Ok(snap) 287*bb4ee6a4SAndroid Build Coastguard Worker } 288*bb4ee6a4SAndroid Build Coastguard Worker 289*bb4ee6a4SAndroid Build Coastguard Worker /// Restore VCPU restore(&self, snapshot: &VcpuSnapshot) -> anyhow::Result<()>290*bb4ee6a4SAndroid Build Coastguard Worker fn restore(&self, snapshot: &VcpuSnapshot) -> anyhow::Result<()> { 291*bb4ee6a4SAndroid Build Coastguard Worker self.set_one_reg(VcpuRegAArch64::Sp, snapshot.sp)?; 292*bb4ee6a4SAndroid Build Coastguard Worker self.set_one_reg(VcpuRegAArch64::Pc, snapshot.pc)?; 293*bb4ee6a4SAndroid Build Coastguard Worker self.set_one_reg(VcpuRegAArch64::Pstate, snapshot.pstate)?; 294*bb4ee6a4SAndroid Build Coastguard Worker 295*bb4ee6a4SAndroid Build Coastguard Worker for (n, xn) in snapshot.x.iter().enumerate() { 296*bb4ee6a4SAndroid Build Coastguard Worker self.set_one_reg(VcpuRegAArch64::X(n as u8), *xn)?; 297*bb4ee6a4SAndroid Build Coastguard Worker } 298*bb4ee6a4SAndroid Build Coastguard Worker for (n, vn) in snapshot.v.iter().enumerate() { 299*bb4ee6a4SAndroid Build Coastguard Worker self.set_vector_reg(n as u8, *vn)?; 300*bb4ee6a4SAndroid Build Coastguard Worker } 301*bb4ee6a4SAndroid Build Coastguard Worker for (id, val) in &snapshot.sys { 302*bb4ee6a4SAndroid Build Coastguard Worker self.set_one_reg(VcpuRegAArch64::System(*id), *val)?; 303*bb4ee6a4SAndroid Build Coastguard Worker } 304*bb4ee6a4SAndroid Build Coastguard Worker self.set_cache_info(snapshot.cache_arch_info.clone())?; 305*bb4ee6a4SAndroid Build Coastguard Worker self.hypervisor_specific_restore(snapshot.hypervisor_data.clone())?; 306*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 307*bb4ee6a4SAndroid Build Coastguard Worker } 308*bb4ee6a4SAndroid Build Coastguard Worker } 309*bb4ee6a4SAndroid Build Coastguard Worker 310*bb4ee6a4SAndroid Build Coastguard Worker /// Aarch64 specific vCPU snapshot. 311*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Debug, Default, Serialize, Deserialize)] 312*bb4ee6a4SAndroid Build Coastguard Worker pub struct VcpuSnapshot { 313*bb4ee6a4SAndroid Build Coastguard Worker pub vcpu_id: usize, 314*bb4ee6a4SAndroid Build Coastguard Worker pub sp: u64, 315*bb4ee6a4SAndroid Build Coastguard Worker pub pc: u64, 316*bb4ee6a4SAndroid Build Coastguard Worker pub pstate: u64, 317*bb4ee6a4SAndroid Build Coastguard Worker pub x: [u64; 31], 318*bb4ee6a4SAndroid Build Coastguard Worker pub v: [u128; 32], 319*bb4ee6a4SAndroid Build Coastguard Worker pub sys: BTreeMap<AArch64SysRegId, u64>, 320*bb4ee6a4SAndroid Build Coastguard Worker pub cache_arch_info: BTreeMap<u8, u64>, 321*bb4ee6a4SAndroid Build Coastguard Worker pub hypervisor_data: serde_json::Value, 322*bb4ee6a4SAndroid Build Coastguard Worker } 323*bb4ee6a4SAndroid Build Coastguard Worker 324*bb4ee6a4SAndroid Build Coastguard Worker impl_downcast!(VcpuAArch64); 325*bb4ee6a4SAndroid Build Coastguard Worker 326*bb4ee6a4SAndroid Build Coastguard Worker /// Initial register state for AArch64 VCPUs. 327*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Default)] 328*bb4ee6a4SAndroid Build Coastguard Worker pub struct VcpuInitAArch64 { 329*bb4ee6a4SAndroid Build Coastguard Worker /// Initial register state as a map of register name to value pairs. Registers that do not have 330*bb4ee6a4SAndroid Build Coastguard Worker /// a value specified in this map will retain the original value provided by the hypervisor. 331*bb4ee6a4SAndroid Build Coastguard Worker pub regs: BTreeMap<VcpuRegAArch64, u64>, 332*bb4ee6a4SAndroid Build Coastguard Worker } 333*bb4ee6a4SAndroid Build Coastguard Worker 334*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Debug, PartialEq, Eq)] 335*bb4ee6a4SAndroid Build Coastguard Worker pub struct CpuConfigAArch64 {} 336*bb4ee6a4SAndroid Build Coastguard Worker 337*bb4ee6a4SAndroid Build Coastguard Worker // Convenience constructors for IrqRoutes 338*bb4ee6a4SAndroid Build Coastguard Worker impl IrqRoute { gic_irq_route(irq_num: u32) -> IrqRoute339*bb4ee6a4SAndroid Build Coastguard Worker pub fn gic_irq_route(irq_num: u32) -> IrqRoute { 340*bb4ee6a4SAndroid Build Coastguard Worker IrqRoute { 341*bb4ee6a4SAndroid Build Coastguard Worker gsi: irq_num, 342*bb4ee6a4SAndroid Build Coastguard Worker source: IrqSource::Irqchip { 343*bb4ee6a4SAndroid Build Coastguard Worker chip: IrqSourceChip::Gic, 344*bb4ee6a4SAndroid Build Coastguard Worker pin: irq_num, 345*bb4ee6a4SAndroid Build Coastguard Worker }, 346*bb4ee6a4SAndroid Build Coastguard Worker } 347*bb4ee6a4SAndroid Build Coastguard Worker } 348*bb4ee6a4SAndroid Build Coastguard Worker } 349*bb4ee6a4SAndroid Build Coastguard Worker 350*bb4ee6a4SAndroid Build Coastguard Worker /// A feature that can be enabled on a VCPU with `VcpuAArch64::init`. 351*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq)] 352*bb4ee6a4SAndroid Build Coastguard Worker pub enum VcpuFeature { 353*bb4ee6a4SAndroid Build Coastguard Worker /// Emulate PSCI v0.2 (or a future revision backward compatible with v0.2) for the VCPU. 354*bb4ee6a4SAndroid Build Coastguard Worker PsciV0_2, 355*bb4ee6a4SAndroid Build Coastguard Worker /// Emulate Performance Monitor Unit v3 for the VCPU. 356*bb4ee6a4SAndroid Build Coastguard Worker PmuV3, 357*bb4ee6a4SAndroid Build Coastguard Worker /// Starts the VCPU in a power-off state. 358*bb4ee6a4SAndroid Build Coastguard Worker PowerOff, 359*bb4ee6a4SAndroid Build Coastguard Worker /// Scalable Vector Extension support 360*bb4ee6a4SAndroid Build Coastguard Worker Sve, 361*bb4ee6a4SAndroid Build Coastguard Worker } 362*bb4ee6a4SAndroid Build Coastguard Worker 363*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)] 364*bb4ee6a4SAndroid Build Coastguard Worker mod tests { 365*bb4ee6a4SAndroid Build Coastguard Worker use super::*; 366*bb4ee6a4SAndroid Build Coastguard Worker 367*bb4ee6a4SAndroid Build Coastguard Worker #[test] sysreg_new()368*bb4ee6a4SAndroid Build Coastguard Worker fn sysreg_new() { 369*bb4ee6a4SAndroid Build Coastguard Worker let sysreg = AArch64SysRegId::new(1, 2, 3, 4, 5).unwrap(); 370*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(sysreg.op0(), 1); 371*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(sysreg.op1(), 2); 372*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(sysreg.crn(), 3); 373*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(sysreg.crm(), 4); 374*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(sysreg.op2(), 5); 375*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(sysreg.encoded(), 0x51A5); 376*bb4ee6a4SAndroid Build Coastguard Worker } 377*bb4ee6a4SAndroid Build Coastguard Worker 378*bb4ee6a4SAndroid Build Coastguard Worker #[test] sysreg_new_max()379*bb4ee6a4SAndroid Build Coastguard Worker fn sysreg_new_max() { 380*bb4ee6a4SAndroid Build Coastguard Worker let sysreg = AArch64SysRegId::new(0b11, 0b111, 0b1111, 0b1111, 0b111).unwrap(); 381*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(sysreg.op0(), 3); 382*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(sysreg.op1(), 7); 383*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(sysreg.crn(), 15); 384*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(sysreg.crm(), 15); 385*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(sysreg.op2(), 7); 386*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(sysreg.encoded(), 0xFFFF); 387*bb4ee6a4SAndroid Build Coastguard Worker } 388*bb4ee6a4SAndroid Build Coastguard Worker 389*bb4ee6a4SAndroid Build Coastguard Worker #[test] sysreg_new_out_of_range()390*bb4ee6a4SAndroid Build Coastguard Worker fn sysreg_new_out_of_range() { 391*bb4ee6a4SAndroid Build Coastguard Worker AArch64SysRegId::new(4, 0, 0, 0, 0).expect_err("invalid Op0"); 392*bb4ee6a4SAndroid Build Coastguard Worker AArch64SysRegId::new(0, 8, 0, 0, 0).expect_err("invalid Op1"); 393*bb4ee6a4SAndroid Build Coastguard Worker AArch64SysRegId::new(0, 0, 16, 0, 0).expect_err("invalid CRn"); 394*bb4ee6a4SAndroid Build Coastguard Worker AArch64SysRegId::new(0, 0, 0, 16, 0).expect_err("invalid CRm"); 395*bb4ee6a4SAndroid Build Coastguard Worker AArch64SysRegId::new(0, 0, 0, 0, 8).expect_err("invalid Op2"); 396*bb4ee6a4SAndroid Build Coastguard Worker } 397*bb4ee6a4SAndroid Build Coastguard Worker 398*bb4ee6a4SAndroid Build Coastguard Worker #[test] sysreg_encoding_mpidr_el1()399*bb4ee6a4SAndroid Build Coastguard Worker fn sysreg_encoding_mpidr_el1() { 400*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::MPIDR_EL1.op0(), 3); 401*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::MPIDR_EL1.op1(), 0); 402*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::MPIDR_EL1.crn(), 0); 403*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::MPIDR_EL1.crm(), 0); 404*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::MPIDR_EL1.op2(), 5); 405*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::MPIDR_EL1.encoded(), 0xC005); 406*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 407*bb4ee6a4SAndroid Build Coastguard Worker AArch64SysRegId::MPIDR_EL1, 408*bb4ee6a4SAndroid Build Coastguard Worker AArch64SysRegId::new(3, 0, 0, 0, 5).unwrap() 409*bb4ee6a4SAndroid Build Coastguard Worker ); 410*bb4ee6a4SAndroid Build Coastguard Worker } 411*bb4ee6a4SAndroid Build Coastguard Worker 412*bb4ee6a4SAndroid Build Coastguard Worker #[test] sysreg_encoding_cntvct_el0()413*bb4ee6a4SAndroid Build Coastguard Worker fn sysreg_encoding_cntvct_el0() { 414*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::CNTVCT_EL0.op0(), 3); 415*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::CNTVCT_EL0.op1(), 3); 416*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::CNTVCT_EL0.crn(), 14); 417*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::CNTVCT_EL0.crm(), 0); 418*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::CNTVCT_EL0.op2(), 2); 419*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::CNTVCT_EL0.encoded(), 0xDF02); 420*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 421*bb4ee6a4SAndroid Build Coastguard Worker AArch64SysRegId::CNTVCT_EL0, 422*bb4ee6a4SAndroid Build Coastguard Worker AArch64SysRegId::new(3, 3, 14, 0, 2).unwrap() 423*bb4ee6a4SAndroid Build Coastguard Worker ); 424*bb4ee6a4SAndroid Build Coastguard Worker } 425*bb4ee6a4SAndroid Build Coastguard Worker 426*bb4ee6a4SAndroid Build Coastguard Worker #[test] sysreg_encoding_cntv_cval_el0()427*bb4ee6a4SAndroid Build Coastguard Worker fn sysreg_encoding_cntv_cval_el0() { 428*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::CNTV_CVAL_EL0.op0(), 3); 429*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::CNTV_CVAL_EL0.op1(), 3); 430*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::CNTV_CVAL_EL0.crn(), 14); 431*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::CNTV_CVAL_EL0.crm(), 3); 432*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::CNTV_CVAL_EL0.op2(), 2); 433*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AArch64SysRegId::CNTV_CVAL_EL0.encoded(), 0xDF1A); 434*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 435*bb4ee6a4SAndroid Build Coastguard Worker AArch64SysRegId::CNTV_CVAL_EL0, 436*bb4ee6a4SAndroid Build Coastguard Worker AArch64SysRegId::new(3, 3, 14, 3, 2).unwrap() 437*bb4ee6a4SAndroid Build Coastguard Worker ); 438*bb4ee6a4SAndroid Build Coastguard Worker } 439*bb4ee6a4SAndroid Build Coastguard Worker 440*bb4ee6a4SAndroid Build Coastguard Worker #[test] sysreg_debug()441*bb4ee6a4SAndroid Build Coastguard Worker fn sysreg_debug() { 442*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 443*bb4ee6a4SAndroid Build Coastguard Worker format!("{:?}", AArch64SysRegId::MPIDR_EL1), 444*bb4ee6a4SAndroid Build Coastguard Worker "AArch64SysRegId { Op0: 3, Op1: 0, CRn: 0, CRm: 0, Op2: 5 }" 445*bb4ee6a4SAndroid Build Coastguard Worker ); 446*bb4ee6a4SAndroid Build Coastguard Worker } 447*bb4ee6a4SAndroid Build Coastguard Worker } 448