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