1use core::fmt::{Debug, LowerHex, UpperHex};
4
5use ax_memory_addr::AddrRange;
6use axvm_types::GuestPhysAddr;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
12pub enum AccessWidth {
13 Byte,
15 Word,
17 Dword,
19 Qword,
21}
22
23impl TryFrom<usize> for AccessWidth {
24 type Error = ();
25
26 fn try_from(value: usize) -> Result<Self, Self::Error> {
27 match value {
28 1 => Ok(Self::Byte),
29 2 => Ok(Self::Word),
30 4 => Ok(Self::Dword),
31 8 => Ok(Self::Qword),
32 _ => Err(()),
33 }
34 }
35}
36
37impl From<AccessWidth> for usize {
38 fn from(width: AccessWidth) -> usize {
39 match width {
40 AccessWidth::Byte => 1,
41 AccessWidth::Word => 2,
42 AccessWidth::Dword => 4,
43 AccessWidth::Qword => 8,
44 }
45 }
46}
47
48impl AccessWidth {
49 pub fn size(&self) -> usize {
51 (*self).into()
52 }
53
54 pub fn bits_range(&self) -> core::ops::Range<usize> {
56 match self {
57 AccessWidth::Byte => 0..8,
58 AccessWidth::Word => 0..16,
59 AccessWidth::Dword => 0..32,
60 AccessWidth::Qword => 0..64,
61 }
62 }
63}
64
65#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
67pub struct Port(pub u16);
68
69impl Port {
70 pub fn new(port: u16) -> Self {
72 Self(port)
73 }
74
75 pub fn number(&self) -> u16 {
77 self.0
78 }
79}
80
81impl LowerHex for Port {
82 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
83 write!(f, "Port({:#x})", self.0)
84 }
85}
86
87impl UpperHex for Port {
88 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
89 write!(f, "Port({:#X})", self.0)
90 }
91}
92
93impl Debug for Port {
94 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
95 write!(f, "Port({})", self.0)
96 }
97}
98
99#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
101pub struct SysRegAddr(pub usize);
102
103impl SysRegAddr {
104 pub const fn new(addr: usize) -> Self {
106 Self(addr)
107 }
108
109 pub const fn addr(&self) -> usize {
111 self.0
112 }
113}
114
115impl LowerHex for SysRegAddr {
116 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
117 write!(f, "SysRegAddr({:#x})", self.0)
118 }
119}
120
121impl UpperHex for SysRegAddr {
122 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
123 write!(f, "SysRegAddr({:#X})", self.0)
124 }
125}
126
127impl Debug for SysRegAddr {
128 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
129 write!(f, "SysRegAddr({})", self.0)
130 }
131}
132
133pub trait DeviceAddr: Copy + Eq + Ord + core::fmt::Debug {}
135
136pub trait DeviceAddrRange {
138 type Addr: DeviceAddr;
140
141 fn contains(&self, addr: Self::Addr) -> bool;
143}
144
145impl DeviceAddr for GuestPhysAddr {}
146
147impl DeviceAddrRange for AddrRange<GuestPhysAddr> {
148 type Addr = GuestPhysAddr;
149
150 fn contains(&self, addr: Self::Addr) -> bool {
151 Self::contains(*self, addr)
152 }
153}
154
155impl DeviceAddr for SysRegAddr {}
156
157#[derive(Copy, Clone, Eq, PartialEq, Debug)]
161pub struct SysRegAddrRange {
162 pub start: SysRegAddr,
164 pub end: SysRegAddr,
166}
167
168impl SysRegAddrRange {
169 pub fn new(start: SysRegAddr, end: SysRegAddr) -> Self {
171 Self { start, end }
172 }
173}
174
175impl DeviceAddrRange for SysRegAddrRange {
176 type Addr = SysRegAddr;
177
178 fn contains(&self, addr: Self::Addr) -> bool {
179 addr.0 >= self.start.0 && addr.0 <= self.end.0
180 }
181}
182
183impl LowerHex for SysRegAddrRange {
184 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
185 write!(f, "{:#x}..={:#x}", self.start.0, self.end.0)
186 }
187}
188
189impl DeviceAddr for Port {}
190
191#[derive(Copy, Clone, Eq, PartialEq, Debug)]
195pub struct PortRange {
196 pub start: Port,
198 pub end: Port,
200}
201
202impl PortRange {
203 pub fn new(start: Port, end: Port) -> Self {
205 Self { start, end }
206 }
207}
208
209impl DeviceAddrRange for PortRange {
210 type Addr = Port;
211
212 fn contains(&self, addr: Self::Addr) -> bool {
213 addr.0 >= self.start.0 && addr.0 <= self.end.0
214 }
215}
216
217impl LowerHex for PortRange {
218 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
219 write!(f, "{:#x}..={:#x}", self.start.0, self.end.0)
220 }
221}