1 // Copyright 2020 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use base::Result; 6 use downcast_rs::impl_downcast; 7 use vm_memory::GuestAddress; 8 9 use crate::{Hypervisor, IrqRoute, IrqSource, IrqSourceChip, Vcpu, Vm}; 10 11 /// Represents a version of Power State Coordination Interface (PSCI). 12 pub struct PsciVersion { 13 pub major: u32, 14 pub minor: u32, 15 } 16 17 /// A wrapper for using a VM on aarch64 and getting/setting its state. 18 pub trait VmAArch64: Vm { 19 /// Gets the `Hypervisor` that created this VM. get_hypervisor(&self) -> &dyn Hypervisor20 fn get_hypervisor(&self) -> &dyn Hypervisor; 21 22 /// Enables protected mode for the VM, creating a memslot for the firmware as needed. 23 /// Only works on VMs that support `VmCap::Protected`. enable_protected_vm(&mut self, fw_addr: GuestAddress, fw_max_size: u64) -> Result<()>24 fn enable_protected_vm(&mut self, fw_addr: GuestAddress, fw_max_size: u64) -> Result<()>; 25 26 /// Create a Vcpu with the specified Vcpu ID. create_vcpu(&self, id: usize) -> Result<Box<dyn VcpuAArch64>>27 fn create_vcpu(&self, id: usize) -> Result<Box<dyn VcpuAArch64>>; 28 } 29 30 /// A wrapper around creating and using a VCPU on aarch64. 31 pub trait VcpuAArch64: Vcpu { 32 /// Does ARM-specific initialization of this VCPU. Inits the VCPU with the preferred target 33 /// VCPU type and the specified `features`, and resets the value of all registers to defaults. 34 /// All VCPUs should be created before calling this function. init(&self, features: &[VcpuFeature]) -> Result<()>35 fn init(&self, features: &[VcpuFeature]) -> Result<()>; 36 37 /// Initializes the ARM Performance Monitor Unit v3 on this VCPU, with overflow interrupt number 38 /// `irq`. init_pmu(&self, irq: u64) -> Result<()>39 fn init_pmu(&self, irq: u64) -> Result<()>; 40 41 /// Sets the value of a register on this VCPU. `reg_id` is the register ID, as specified in the 42 /// KVM API documentation for KVM_SET_ONE_REG. set_one_reg(&self, reg_id: u64, data: u64) -> Result<()>43 fn set_one_reg(&self, reg_id: u64, data: u64) -> Result<()>; 44 45 /// Gets the value of a register on this VCPU. `reg_id` is the register ID, as specified in the 46 /// KVM API documentation for KVM_GET_ONE_REG. get_one_reg(&self, reg_id: u64) -> Result<u64>47 fn get_one_reg(&self, reg_id: u64) -> Result<u64>; 48 49 /// Gets the current PSCI version. get_psci_version(&self) -> Result<PsciVersion>50 fn get_psci_version(&self) -> Result<PsciVersion>; 51 } 52 53 impl_downcast!(VcpuAArch64); 54 55 // Convenience constructors for IrqRoutes 56 impl IrqRoute { gic_irq_route(irq_num: u32) -> IrqRoute57 pub fn gic_irq_route(irq_num: u32) -> IrqRoute { 58 IrqRoute { 59 gsi: irq_num, 60 source: IrqSource::Irqchip { 61 chip: IrqSourceChip::Gic, 62 pin: irq_num, 63 }, 64 } 65 } 66 } 67 68 /// A feature that can be enabled on a VCPU with `VcpuAArch64::init`. 69 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 70 pub enum VcpuFeature { 71 /// Emulate PSCI v0.2 (or a future revision backward compatible with v0.2) for the VCPU. 72 PsciV0_2, 73 /// Emulate Performance Monitor Unit v3 for the VCPU. 74 PmuV3, 75 /// Starts the VCPU in a power-off state. 76 PowerOff, 77 } 78