1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2023 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 anyhow::anyhow; 6*bb4ee6a4SAndroid Build Coastguard Worker use base::Result; 7*bb4ee6a4SAndroid Build Coastguard Worker use downcast_rs::impl_downcast; 8*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize; 9*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize; 10*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::GuestAddress; 11*bb4ee6a4SAndroid Build Coastguard Worker 12*bb4ee6a4SAndroid Build Coastguard Worker use crate::Hypervisor; 13*bb4ee6a4SAndroid Build Coastguard Worker use crate::IrqRoute; 14*bb4ee6a4SAndroid Build Coastguard Worker use crate::IrqSource; 15*bb4ee6a4SAndroid Build Coastguard Worker use crate::IrqSourceChip; 16*bb4ee6a4SAndroid Build Coastguard Worker use crate::Vcpu; 17*bb4ee6a4SAndroid Build Coastguard Worker use crate::Vm; 18*bb4ee6a4SAndroid Build Coastguard Worker 19*bb4ee6a4SAndroid Build Coastguard Worker /// A wrapper for using a VM on riscv64 and getting/setting its state. 20*bb4ee6a4SAndroid Build Coastguard Worker pub trait VmRiscv64: Vm { 21*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the `Hypervisor` that created this VM. get_hypervisor(&self) -> &dyn Hypervisor22*bb4ee6a4SAndroid Build Coastguard Worker fn get_hypervisor(&self) -> &dyn Hypervisor; 23*bb4ee6a4SAndroid Build Coastguard Worker 24*bb4ee6a4SAndroid Build Coastguard Worker /// Create a Vcpu with the specified Vcpu ID. create_vcpu(&self, id: usize) -> Result<Box<dyn VcpuRiscv64>>25*bb4ee6a4SAndroid Build Coastguard Worker fn create_vcpu(&self, id: usize) -> Result<Box<dyn VcpuRiscv64>>; 26*bb4ee6a4SAndroid Build Coastguard Worker } 27*bb4ee6a4SAndroid Build Coastguard Worker 28*bb4ee6a4SAndroid Build Coastguard Worker /// A wrapper around creating and using a VCPU on riscv64. 29*bb4ee6a4SAndroid Build Coastguard Worker pub trait VcpuRiscv64: Vcpu { 30*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the value of a register on this VCPU. set_one_reg(&self, reg_id: VcpuRegister, data: u64) -> Result<()>31*bb4ee6a4SAndroid Build Coastguard Worker fn set_one_reg(&self, reg_id: VcpuRegister, data: u64) -> Result<()>; 32*bb4ee6a4SAndroid Build Coastguard Worker 33*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the value of a register on this VCPU. get_one_reg(&self, reg_id: VcpuRegister) -> Result<u64>34*bb4ee6a4SAndroid Build Coastguard Worker fn get_one_reg(&self, reg_id: VcpuRegister) -> Result<u64>; 35*bb4ee6a4SAndroid Build Coastguard Worker 36*bb4ee6a4SAndroid Build Coastguard Worker /// Snapshot VCPU snapshot(&self) -> anyhow::Result<VcpuSnapshot>37*bb4ee6a4SAndroid Build Coastguard Worker fn snapshot(&self) -> anyhow::Result<VcpuSnapshot> { 38*bb4ee6a4SAndroid Build Coastguard Worker Err(anyhow!("not yet implemented")) 39*bb4ee6a4SAndroid Build Coastguard Worker } 40*bb4ee6a4SAndroid Build Coastguard Worker 41*bb4ee6a4SAndroid Build Coastguard Worker /// Restore VCPU restore(&self, _snapshot: &VcpuSnapshot) -> anyhow::Result<()>42*bb4ee6a4SAndroid Build Coastguard Worker fn restore(&self, _snapshot: &VcpuSnapshot) -> anyhow::Result<()> { 43*bb4ee6a4SAndroid Build Coastguard Worker Err(anyhow!("not yet implemented")) 44*bb4ee6a4SAndroid Build Coastguard Worker } 45*bb4ee6a4SAndroid Build Coastguard Worker } 46*bb4ee6a4SAndroid Build Coastguard Worker 47*bb4ee6a4SAndroid Build Coastguard Worker /// Riscv64 specific vCPU snapshot. 48*bb4ee6a4SAndroid Build Coastguard Worker /// 49*bb4ee6a4SAndroid Build Coastguard Worker /// Not implemented yet. 50*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Debug, Serialize, Deserialize)] 51*bb4ee6a4SAndroid Build Coastguard Worker pub struct VcpuSnapshot { 52*bb4ee6a4SAndroid Build Coastguard Worker pub vcpu_id: usize, 53*bb4ee6a4SAndroid Build Coastguard Worker } 54*bb4ee6a4SAndroid Build Coastguard Worker 55*bb4ee6a4SAndroid Build Coastguard Worker impl_downcast!(VcpuRiscv64); 56*bb4ee6a4SAndroid Build Coastguard Worker 57*bb4ee6a4SAndroid Build Coastguard Worker /// Initial state for Riscv64 VCPUs. 58*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone)] 59*bb4ee6a4SAndroid Build Coastguard Worker pub struct VcpuInitRiscv64 { 60*bb4ee6a4SAndroid Build Coastguard Worker /// The address of the FDT 61*bb4ee6a4SAndroid Build Coastguard Worker pub fdt_address: GuestAddress, 62*bb4ee6a4SAndroid Build Coastguard Worker } 63*bb4ee6a4SAndroid Build Coastguard Worker 64*bb4ee6a4SAndroid Build Coastguard Worker impl VcpuInitRiscv64 { new(fdt_address: GuestAddress) -> Self65*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(fdt_address: GuestAddress) -> Self { 66*bb4ee6a4SAndroid Build Coastguard Worker Self { fdt_address } 67*bb4ee6a4SAndroid Build Coastguard Worker } 68*bb4ee6a4SAndroid Build Coastguard Worker } 69*bb4ee6a4SAndroid Build Coastguard Worker 70*bb4ee6a4SAndroid Build Coastguard Worker /// Hold the CPU feature configurations that are needed to setup a vCPU. 71*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Debug, PartialEq, Eq)] 72*bb4ee6a4SAndroid Build Coastguard Worker pub struct CpuConfigRiscv64 { 73*bb4ee6a4SAndroid Build Coastguard Worker /// The address of the FDT 74*bb4ee6a4SAndroid Build Coastguard Worker pub fdt_address: GuestAddress, 75*bb4ee6a4SAndroid Build Coastguard Worker } 76*bb4ee6a4SAndroid Build Coastguard Worker 77*bb4ee6a4SAndroid Build Coastguard Worker impl CpuConfigRiscv64 { new(fdt_address: GuestAddress) -> Self78*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(fdt_address: GuestAddress) -> Self { 79*bb4ee6a4SAndroid Build Coastguard Worker Self { fdt_address } 80*bb4ee6a4SAndroid Build Coastguard Worker } 81*bb4ee6a4SAndroid Build Coastguard Worker } 82*bb4ee6a4SAndroid Build Coastguard Worker 83*bb4ee6a4SAndroid Build Coastguard Worker /// Config registers exposed by kvm. 84*bb4ee6a4SAndroid Build Coastguard Worker #[repr(u64)] 85*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone)] 86*bb4ee6a4SAndroid Build Coastguard Worker pub enum ConfigRegister { 87*bb4ee6a4SAndroid Build Coastguard Worker Isa = 0, 88*bb4ee6a4SAndroid Build Coastguard Worker } 89*bb4ee6a4SAndroid Build Coastguard Worker 90*bb4ee6a4SAndroid Build Coastguard Worker /// Timer registers exposed by kvm. 91*bb4ee6a4SAndroid Build Coastguard Worker #[repr(u64)] 92*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone)] 93*bb4ee6a4SAndroid Build Coastguard Worker pub enum TimerRegister { 94*bb4ee6a4SAndroid Build Coastguard Worker TimebaseFrequency = 0, 95*bb4ee6a4SAndroid Build Coastguard Worker } 96*bb4ee6a4SAndroid Build Coastguard Worker 97*bb4ee6a4SAndroid Build Coastguard Worker /// Core registers exposed by kvm. 98*bb4ee6a4SAndroid Build Coastguard Worker #[repr(u64)] 99*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone)] 100*bb4ee6a4SAndroid Build Coastguard Worker pub enum CoreRegister { 101*bb4ee6a4SAndroid Build Coastguard Worker Pc = 0x00, // Program counter 102*bb4ee6a4SAndroid Build Coastguard Worker Ra = 0x01, // Return address 103*bb4ee6a4SAndroid Build Coastguard Worker Sp = 0x02, // Stack pointer 104*bb4ee6a4SAndroid Build Coastguard Worker Gp = 0x03, // Global pointer 105*bb4ee6a4SAndroid Build Coastguard Worker Tp = 0x04, // Task pointer 106*bb4ee6a4SAndroid Build Coastguard Worker T0 = 0x05, // Caller saved register 0 107*bb4ee6a4SAndroid Build Coastguard Worker T1 = 0x06, // Caller saved register 1 108*bb4ee6a4SAndroid Build Coastguard Worker T2 = 0x07, // Caller saved register 2 109*bb4ee6a4SAndroid Build Coastguard Worker S0 = 0x08, // Callee saved register 0 110*bb4ee6a4SAndroid Build Coastguard Worker S1 = 0x09, // Callee saved register 1 111*bb4ee6a4SAndroid Build Coastguard Worker A0 = 0x0a, // Function argument (or return value) 0 112*bb4ee6a4SAndroid Build Coastguard Worker A1 = 0x0b, // Function argument (or return value) 1 113*bb4ee6a4SAndroid Build Coastguard Worker A2 = 0x0c, // Function argument 2 114*bb4ee6a4SAndroid Build Coastguard Worker A3 = 0x0d, // Function argument 3 115*bb4ee6a4SAndroid Build Coastguard Worker A4 = 0x0e, // Function argument 4 116*bb4ee6a4SAndroid Build Coastguard Worker A5 = 0x0f, // Function argument 5 117*bb4ee6a4SAndroid Build Coastguard Worker A6 = 0x10, // Function argument 6 118*bb4ee6a4SAndroid Build Coastguard Worker A7 = 0x11, // Function argument 7 119*bb4ee6a4SAndroid Build Coastguard Worker S2 = 0x12, // Callee saved register 2 120*bb4ee6a4SAndroid Build Coastguard Worker S3 = 0x13, // Callee saved register 3 121*bb4ee6a4SAndroid Build Coastguard Worker S4 = 0x14, // Callee saved register 4 122*bb4ee6a4SAndroid Build Coastguard Worker S5 = 0x15, // Callee saved register 5 123*bb4ee6a4SAndroid Build Coastguard Worker S6 = 0x16, // Callee saved register 6 124*bb4ee6a4SAndroid Build Coastguard Worker S7 = 0x17, // Callee saved register 7 125*bb4ee6a4SAndroid Build Coastguard Worker S8 = 0x18, // Callee saved register 8 126*bb4ee6a4SAndroid Build Coastguard Worker S9 = 0x19, // Callee saved register 9 127*bb4ee6a4SAndroid Build Coastguard Worker S10 = 0x1a, // Callee saved register 10 128*bb4ee6a4SAndroid Build Coastguard Worker S11 = 0x1b, // Callee saved register 11 129*bb4ee6a4SAndroid Build Coastguard Worker T3 = 0x1c, // Caller saved register 3 130*bb4ee6a4SAndroid Build Coastguard Worker T4 = 0x1d, // Caller saved register 4 131*bb4ee6a4SAndroid Build Coastguard Worker T5 = 0x1e, // Caller saved register 5 132*bb4ee6a4SAndroid Build Coastguard Worker T6 = 0x1f, // Caller saved register 6 133*bb4ee6a4SAndroid Build Coastguard Worker Mode = 0x20, // Privilege mode (1 = S-mode or 0 = U-mode) 134*bb4ee6a4SAndroid Build Coastguard Worker } 135*bb4ee6a4SAndroid Build Coastguard Worker 136*bb4ee6a4SAndroid Build Coastguard Worker /// Registers exposed through `KVM_[GET|SET]_ONE_REG` API. 137*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone)] 138*bb4ee6a4SAndroid Build Coastguard Worker pub enum VcpuRegister { 139*bb4ee6a4SAndroid Build Coastguard Worker Config(ConfigRegister), 140*bb4ee6a4SAndroid Build Coastguard Worker Core(CoreRegister), 141*bb4ee6a4SAndroid Build Coastguard Worker Timer(TimerRegister), 142*bb4ee6a4SAndroid Build Coastguard Worker } 143*bb4ee6a4SAndroid Build Coastguard Worker 144*bb4ee6a4SAndroid Build Coastguard Worker // Convenience constructors for IrqRoutes 145*bb4ee6a4SAndroid Build Coastguard Worker impl IrqRoute { aia_irq_route(irq_num: u32) -> IrqRoute146*bb4ee6a4SAndroid Build Coastguard Worker pub fn aia_irq_route(irq_num: u32) -> IrqRoute { 147*bb4ee6a4SAndroid Build Coastguard Worker IrqRoute { 148*bb4ee6a4SAndroid Build Coastguard Worker gsi: irq_num, 149*bb4ee6a4SAndroid Build Coastguard Worker source: IrqSource::Irqchip { 150*bb4ee6a4SAndroid Build Coastguard Worker chip: IrqSourceChip::Aia, 151*bb4ee6a4SAndroid Build Coastguard Worker pin: irq_num, 152*bb4ee6a4SAndroid Build Coastguard Worker }, 153*bb4ee6a4SAndroid Build Coastguard Worker } 154*bb4ee6a4SAndroid Build Coastguard Worker } 155*bb4ee6a4SAndroid Build Coastguard Worker } 156