xref: /aosp_15_r20/external/crosvm/hypervisor/src/riscv64.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
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