kernel/arch/riscv64/vcpu/
mod.rs1use crate::arch::Trapframe;
8
9use super::IntRegisters;
10use super::fpu::{FpuContext, VectorContext};
11
12use alloc::boxed::Box;
13
14#[derive(Debug, Clone, Copy, PartialEq)]
15pub enum Mode {
16 User,
17 Kernel,
18}
19
20#[derive(Debug, Clone)]
21pub struct Vcpu {
22 pub iregs: IntRegisters,
23 pub fpu: FpuContext,
25 pub fpu_used: bool,
27 pub vector: Option<Box<VectorContext>>,
29 pub vector_used: bool,
31 pc: u64,
32 asid: usize,
33 mode: Mode,
34}
35
36impl Vcpu {
37 pub fn new(mode: Mode) -> Self {
38 Vcpu {
39 iregs: IntRegisters::new(),
40 fpu: FpuContext::new(),
41 fpu_used: false,
42 vector: None,
43 vector_used: false,
44 pc: 0,
45 asid: 0,
46 mode,
47 }
48 }
49
50 pub fn set_asid(&mut self, asid: usize) {
51 self.asid = asid;
52 }
53
54 pub fn set_pc(&mut self, pc: u64) {
55 self.pc = pc;
56 }
57
58 pub fn get_pc(&self) -> u64 {
59 self.pc
60 }
61
62 pub fn set_sp(&mut self, sp: usize) {
63 self.iregs.reg[2] = sp;
64 }
65
66 pub fn get_mode(&self) -> Mode {
67 self.mode
68 }
69
70 pub fn reset_iregs(&mut self) {
71 self.iregs = IntRegisters::new();
72 }
73
74 pub fn copy_iregs_to(&self, iregs: &mut IntRegisters) {
75 *iregs = self.iregs;
76 }
77
78 pub fn copy_iregs_from(&mut self, iregs: &IntRegisters) {
79 self.iregs = *iregs;
80 }
81
82 pub fn clone_to(&self, other: &mut Vcpu) {
87 other.iregs = self.iregs;
88 other.fpu = self.fpu.clone();
89 other.fpu_used = self.fpu_used;
90 other.vector = self.vector.clone();
91 other.vector_used = self.vector_used;
92 other.pc = self.pc;
93 }
94
95 pub fn store(&mut self, trapframe: &Trapframe) {
96 self.iregs = trapframe.regs;
97 self.pc = trapframe.epc;
98 }
99
100 pub fn switch(&mut self, trapframe: &mut Trapframe) {
101 trapframe.regs = self.iregs;
102 trapframe.epc = self.pc;
103 }
104
105 #[inline]
109 pub fn get_tls_pointer(&self) -> usize {
110 self.iregs.get_tp()
111 }
112
113 #[inline]
117 pub fn set_tls_pointer(&mut self, ptr: usize) {
118 self.iregs.set_tp(ptr);
119 }
120}