globally_ordered_mock_mmio/
mmio_operand_value.rs1use mmio::{Mmio, MmioError, MmioOperand};
8
9pub type MmioOperandValue = u64;
11
12pub fn mmio_operand_to_u64<T: MmioOperand>(operand_value: T) -> MmioOperandValue {
14 let mut value_extractor = MmioWriteOperandValueExtractor::new();
15 T::try_store(&mut value_extractor, 0, operand_value)
16 .expect("MmioWriteOperandValueExtractor failed to intercept the write operation");
17 value_extractor.operand_value()
18}
19
20struct MmioWriteOperandValueExtractor {
26 operand_value: MmioOperandValue,
27}
28
29impl MmioWriteOperandValueExtractor {
30 fn new() -> Self {
32 Self { operand_value: 0 }
33 }
34
35 fn operand_value(&self) -> MmioOperandValue {
39 self.operand_value
40 }
41}
42
43impl Mmio for MmioWriteOperandValueExtractor {
44 fn len(&self) -> usize {
45 core::mem::size_of::<MmioOperandValue>()
46 }
47
48 fn align_offset(&self, _align: usize) -> usize {
49 0
50 }
51
52 fn try_load8(&self, _offset: usize) -> Result<u8, MmioError> {
53 unimplemented!("MmioOperand::try_store never performs load operations")
54 }
55
56 fn try_load16(&self, _offset: usize) -> Result<u16, MmioError> {
57 unimplemented!("MmioOperand::try_store never performs load operations")
58 }
59
60 fn try_load32(&self, _offset: usize) -> Result<u32, MmioError> {
61 unimplemented!("MmioOperand::try_store never performs load operations")
62 }
63
64 fn try_load64(&self, _offset: usize) -> Result<u64, MmioError> {
65 unimplemented!("MmioOperand::try_store never performs load operations")
66 }
67
68 fn try_store8(&mut self, _offset: usize, value: u8) -> Result<(), MmioError> {
69 self.operand_value = u64::from(value);
70 Ok(())
71 }
72
73 fn try_store16(&mut self, _offset: usize, value: u16) -> Result<(), MmioError> {
74 self.operand_value = u64::from(value);
75 Ok(())
76 }
77
78 fn try_store32(&mut self, _offset: usize, value: u32) -> Result<(), MmioError> {
79 self.operand_value = u64::from(value);
80 Ok(())
81 }
82
83 fn try_store64(&mut self, _offset: usize, value: u64) -> Result<(), MmioError> {
84 self.operand_value = value;
85 Ok(())
86 }
87
88 fn write_barrier(&self) {
89 unimplemented!("MmioOperand::try_store never issues write barriers")
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[fuchsia::test]
98 fn test_mmio_operand_to_u64_u8() {
99 assert_eq!(mmio_operand_to_u64(0x5au8), 0x5a);
100 }
101
102 #[fuchsia::test]
103 fn test_mmio_operand_to_u64_u16() {
104 assert_eq!(mmio_operand_to_u64(0x1234u16), 0x1234);
105 }
106
107 #[fuchsia::test]
108 fn test_mmio_operand_to_u64_u32() {
109 assert_eq!(mmio_operand_to_u64(0x1234_5678u32), 0x1234_5678);
110 }
111
112 #[fuchsia::test]
113 fn test_mmio_operand_to_u64_u64() {
114 assert_eq!(mmio_operand_to_u64(0x1234_5678_9abc_def0u64), 0x1234_5678_9abc_def0);
115 }
116
117 #[fuchsia::test]
118 fn test_extractor_captures_stores_of_every_size() {
119 let mut extractor = MmioWriteOperandValueExtractor::new();
120 assert_eq!(extractor.operand_value(), 0);
121
122 extractor.try_store8(0x10, 0x42).unwrap();
123 assert_eq!(extractor.operand_value(), 0x42);
124
125 extractor.try_store16(0x20, 0x1234).unwrap();
126 assert_eq!(extractor.operand_value(), 0x1234);
127
128 extractor.try_store32(0x30, 0x1234_5678).unwrap();
129 assert_eq!(extractor.operand_value(), 0x1234_5678);
130
131 extractor.try_store64(0x40, 0x0123_4567_89ab_cdef).unwrap();
132 assert_eq!(extractor.operand_value(), 0x0123_4567_89ab_cdef);
133 }
134
135 #[fuchsia::test]
136 fn test_extractor_covers_the_largest_operand() {
137 let extractor = MmioWriteOperandValueExtractor::new();
141 assert_eq!(extractor.len(), core::mem::size_of::<u64>());
142 assert_eq!(extractor.align_offset(4), 0);
143 }
144}