Skip to content

Commit 7dac481

Browse files
authored
chore: rewrite field accessors of the Registers with macros (#111)
* chore: rewrite `src/register/capability.rs` with macros * chore: rewrite `operational.rs` with macros * chore: rewrite methods with macros * chore: return a mutable reference to `Self` * refactor: rewrite `doorbell.rs` with macros * chore: rewrite `runtime.rs` with macros
1 parent 1209652 commit 7dac481

File tree

5 files changed

+149
-299
lines changed

5 files changed

+149
-299
lines changed

src/macros.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,46 @@ macro_rules! rw1s_bit {
105105
w1s_bit!($bit, $method, $name);
106106
};
107107
}
108+
109+
macro_rules! field_getter {
110+
($range:expr,$method:ident,$name:literal,$ty:ty) => {
111+
#[doc = "Returns the value of the"]
112+
#[doc = $name]
113+
#[doc = "field."]
114+
#[must_use]
115+
pub fn $method(self) -> $ty {
116+
use bit_field::BitField;
117+
use core::convert::TryInto;
118+
self.0.get_bits($range).try_into().unwrap()
119+
}
120+
};
121+
}
122+
123+
macro_rules! field_setter {
124+
($range:expr,$method:ident,$name:literal,$ty:ty) => {
125+
paste::paste! {
126+
#[doc = "Sets the value of the"]
127+
#[doc = $name]
128+
#[doc = "field."]
129+
pub fn [<set_ $method>](&mut self,value:$ty) -> &mut Self {
130+
use bit_field::BitField;
131+
use core::convert::TryInto;
132+
self.0.set_bits($range,value.try_into().unwrap());
133+
self
134+
}
135+
}
136+
};
137+
}
138+
139+
macro_rules! ro_field {
140+
($range:expr,$method:ident,$name:literal,$ty:ty) => {
141+
field_getter!($range, $method, $name, $ty);
142+
};
143+
}
144+
145+
macro_rules! rw_field {
146+
($range:expr,$method:ident,$name:literal,$ty:ty) => {
147+
field_getter!($range, $method, $name, $ty);
148+
field_setter!($range, $method, $name, $ty);
149+
};
150+
}

src/registers/capability.rs

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
use accessor::Mapper;
44
use bit_field::BitField;
5-
use core::convert::TryInto;
65

76
/// Host Controller Capability Registers
87
#[derive(Debug)]
@@ -105,23 +104,9 @@ impl InterfaceVersionNumber {
105104
#[derive(Copy, Clone)]
106105
pub struct StructuralParameters1(u32);
107106
impl StructuralParameters1 {
108-
/// Returns the number of available device slots.
109-
#[must_use]
110-
pub fn number_of_device_slots(self) -> u8 {
111-
self.0.get_bits(0..=7).try_into().unwrap()
112-
}
113-
114-
/// Returns the number of interrupts implemented on HC.
115-
#[must_use]
116-
pub fn number_of_interrupts(self) -> u16 {
117-
self.0.get_bits(8..=18).try_into().unwrap()
118-
}
119-
120-
/// Returns the number of ports.
121-
#[must_use]
122-
pub fn number_of_ports(self) -> u8 {
123-
self.0.get_bits(24..=31).try_into().unwrap()
124-
}
107+
ro_field!(0..=7, number_of_device_slots, "Number of Device Slots", u8);
108+
ro_field!(8..=18, number_of_interrupts, "Number of Interrupts", u16);
109+
ro_field!(24..=31, number_of_ports, "Number of Ports", u8);
125110
}
126111
impl_debug_from_methods! {
127112
StructuralParameters1{
@@ -136,11 +121,12 @@ impl_debug_from_methods! {
136121
#[derive(Copy, Clone)]
137122
pub struct StructuralParameters2(u32);
138123
impl StructuralParameters2 {
139-
/// Returns the value of the Isochronous Scheduling Threshold field.
140-
#[must_use]
141-
pub fn isochronous_scheduling_threshold(self) -> u8 {
142-
self.0.get_bits(0..=3).try_into().unwrap()
143-
}
124+
ro_field!(
125+
0..=3,
126+
isochronous_scheduling_threshold,
127+
"Isochronous Scheduling Threshold",
128+
u8
129+
);
144130

145131
/// Returns the maximum number of the elements the Event Ring Segment Table can contain.
146132
///
@@ -188,17 +174,13 @@ impl_debug_from_methods! {
188174
#[derive(Copy, Clone)]
189175
pub struct StructuralParameters3(u32);
190176
impl StructuralParameters3 {
191-
/// Returns the value of the U1 Device Exit Latency field.
192-
#[must_use]
193-
pub fn u1_device_exit_latency(self) -> u8 {
194-
self.0.get_bits(0..=7).try_into().unwrap()
195-
}
196-
197-
/// Returns the value of the U2 Device Exit Latency field.
198-
#[must_use]
199-
pub fn u2_device_exit_latency(self) -> u16 {
200-
self.0.get_bits(16..=31).try_into().unwrap()
201-
}
177+
ro_field!(0..=7, u1_device_exit_latency, "U1 Device Exit Latency", u8);
178+
ro_field!(
179+
16..=31,
180+
u2_device_exit_latency,
181+
"U2 Device Exit Latency",
182+
u16
183+
);
202184
}
203185
impl_debug_from_methods! {
204186
StructuralParameters3{
@@ -237,20 +219,18 @@ impl CapabilityParameters1 {
237219
contiguous_frame_id_capability,
238220
"Contiguous Frame ID Capability"
239221
);
240-
241-
/// Returns the value of the Maximum Primary Stream Array Size field.
242-
#[must_use]
243-
pub fn maximum_primary_stream_array_size(self) -> u8 {
244-
self.0.get_bits(12..=15).try_into().unwrap()
245-
}
246-
247-
/// Returns the offset of the xHCI extended capability list from the MMIO base. If this value is
248-
/// zero, the list does not exist.
249-
/// The base address can be calculated by `(MMIO base) + (xECP) << 2`
250-
#[must_use]
251-
pub fn xhci_extended_capabilities_pointer(self) -> u16 {
252-
self.0.get_bits(16..=31).try_into().unwrap()
253-
}
222+
ro_field!(
223+
12..=15,
224+
maximum_primary_stream_array_size,
225+
"Maximum Primary Stream Array Size",
226+
u8
227+
);
228+
ro_field!(
229+
16..=31,
230+
xhci_extended_capabilities_pointer,
231+
"xHCI Extended Capabilities Pointer",
232+
u16
233+
);
254234
}
255235
impl_debug_from_methods! {
256236
CapabilityParameters1 {

src/registers/doorbell.rs

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22
33
use super::capability::Capability;
44
use accessor::Mapper;
5-
use bit_field::BitField;
6-
use core::{
7-
convert::{TryFrom, TryInto},
8-
fmt,
9-
};
5+
use core::{convert::TryFrom, fmt};
106

117
/// The element of the Doorbell Array.
128
#[repr(transparent)]
@@ -39,27 +35,9 @@ impl Register {
3935
mapper,
4036
)
4137
}
42-
/// Get a doorbell target.
43-
#[must_use]
44-
pub fn doorbell_target(self) -> u8 {
45-
self.0.get_bits(0..=7).try_into().unwrap()
46-
}
47-
48-
/// Set a doorbell target.
49-
pub fn set_doorbell_target(&mut self, target: u8) {
50-
self.0.set_bits(0..=7, target.into());
51-
}
5238

53-
/// Get a Doorbell Stream ID.
54-
#[must_use]
55-
pub fn doorbell_stream_id(self) -> u16 {
56-
self.0.get_bits(16..=31).try_into().unwrap()
57-
}
58-
59-
/// Set a Doorbell Stream ID.
60-
pub fn set_doorbell_stream_id(&mut self, id: u16) {
61-
self.0.set_bits(16..=31, id.into());
62-
}
39+
rw_field!(0..=7, doorbell_target, "Doorbell Target", u8);
40+
rw_field!(16..=31, doorbell_stream_id, "Doorbell Stream ID", u16);
6341
}
6442
impl fmt::Debug for Register {
6543
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

0 commit comments

Comments
 (0)