x86emu/
cpu.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Trait for asynchronous callouts from the emulator to the VM.
5
6use crate::registers::RegisterIndex;
7use crate::registers::Segment;
8use std::future::Future;
9use x86defs::RFlags;
10use x86defs::SegmentRegister;
11
12/// Trait for asynchronous callouts from the emulator to the VM.
13pub trait Cpu {
14    /// The error type for IO access failures.
15    type Error;
16
17    /// Performs a memory read of 1, 2, 4, or 8 bytes.
18    fn read_memory(
19        &mut self,
20        gva: u64,
21        bytes: &mut [u8],
22        is_user_mode: bool,
23    ) -> impl Future<Output = Result<(), Self::Error>>;
24
25    /// Performs a memory write of 1, 2, 4, or 8 bytes.
26    fn write_memory(
27        &mut self,
28        gva: u64,
29        bytes: &[u8],
30        is_user_mode: bool,
31    ) -> impl Future<Output = Result<(), Self::Error>>;
32
33    /// Performs an atomic, sequentially-consistent compare exchange on a memory
34    /// location.
35    ///
36    /// The caller has already fetched `current` via `read_memory`, so the
37    /// implementor only needs to perform an atomic compare+write if the memory
38    /// could have mutated concurrently and supports atomic operation. This
39    /// includes ordinary RAM, but does not include device registers.
40    ///
41    /// Returns `true` if the exchange succeeded, `false` otherwise.
42    fn compare_and_write_memory(
43        &mut self,
44        gva: u64,
45        current: &[u8],
46        new: &[u8],
47        is_user_mode: bool,
48    ) -> impl Future<Output = Result<bool, Self::Error>>;
49
50    /// Performs an io read of 1, 2, or 4 bytes.
51    fn read_io(
52        &mut self,
53        io_port: u16,
54        bytes: &mut [u8],
55    ) -> impl Future<Output = Result<(), Self::Error>>;
56    /// Performs an io write of 1, 2, or 4 bytes.
57    fn write_io(
58        &mut self,
59        io_port: u16,
60        bytes: &[u8],
61    ) -> impl Future<Output = Result<(), Self::Error>>;
62
63    fn gp(&mut self, reg: RegisterIndex) -> u64;
64    fn gp_sign_extend(&mut self, reg: RegisterIndex) -> i64;
65    fn set_gp(&mut self, reg: RegisterIndex, v: u64);
66    fn xmm(&mut self, index: usize) -> u128;
67    fn set_xmm(&mut self, index: usize, v: u128) -> Result<(), Self::Error>;
68    fn rip(&mut self) -> u64;
69    fn set_rip(&mut self, v: u64);
70    fn segment(&mut self, index: Segment) -> SegmentRegister;
71    fn efer(&mut self) -> u64;
72    fn cr0(&mut self) -> u64;
73    fn rflags(&mut self) -> RFlags;
74    fn set_rflags(&mut self, v: RFlags);
75}
76
77impl<T: Cpu + ?Sized> Cpu for &mut T {
78    type Error = T::Error;
79
80    fn read_memory(
81        &mut self,
82        gva: u64,
83        bytes: &mut [u8],
84        is_user_mode: bool,
85    ) -> impl Future<Output = Result<(), Self::Error>> {
86        (*self).read_memory(gva, bytes, is_user_mode)
87    }
88
89    fn write_memory(
90        &mut self,
91        gva: u64,
92        bytes: &[u8],
93        is_user_mode: bool,
94    ) -> impl Future<Output = Result<(), Self::Error>> {
95        (*self).write_memory(gva, bytes, is_user_mode)
96    }
97
98    fn compare_and_write_memory(
99        &mut self,
100        gva: u64,
101        current: &[u8],
102        new: &[u8],
103        is_user_mode: bool,
104    ) -> impl Future<Output = Result<bool, Self::Error>> {
105        (*self).compare_and_write_memory(gva, current, new, is_user_mode)
106    }
107
108    fn read_io(
109        &mut self,
110        io_port: u16,
111        bytes: &mut [u8],
112    ) -> impl Future<Output = Result<(), Self::Error>> {
113        (*self).read_io(io_port, bytes)
114    }
115
116    fn write_io(
117        &mut self,
118        io_port: u16,
119        bytes: &[u8],
120    ) -> impl Future<Output = Result<(), Self::Error>> {
121        (*self).write_io(io_port, bytes)
122    }
123
124    fn gp(&mut self, reg: RegisterIndex) -> u64 {
125        (*self).gp(reg)
126    }
127
128    fn gp_sign_extend(&mut self, reg: RegisterIndex) -> i64 {
129        (*self).gp_sign_extend(reg)
130    }
131
132    fn set_gp(&mut self, reg: RegisterIndex, v: u64) {
133        (*self).set_gp(reg, v)
134    }
135
136    fn xmm(&mut self, index: usize) -> u128 {
137        (*self).xmm(index)
138    }
139
140    fn set_xmm(&mut self, index: usize, v: u128) -> Result<(), Self::Error> {
141        (*self).set_xmm(index, v)
142    }
143
144    fn rip(&mut self) -> u64 {
145        (*self).rip()
146    }
147
148    fn set_rip(&mut self, v: u64) {
149        (*self).set_rip(v);
150    }
151
152    fn segment(&mut self, index: Segment) -> SegmentRegister {
153        (*self).segment(index)
154    }
155
156    fn efer(&mut self) -> u64 {
157        (*self).efer()
158    }
159
160    fn cr0(&mut self) -> u64 {
161        (*self).cr0()
162    }
163
164    fn rflags(&mut self) -> RFlags {
165        (*self).rflags()
166    }
167
168    fn set_rflags(&mut self, v: RFlags) {
169        (*self).set_rflags(v);
170    }
171}