1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use core::convert::From;
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Address {
base: u16,
ramp: u8,
}
impl Address {
const PCWORD_MASK: u16 = (crate::SPM_PAGESIZE_BYTES - 1) as u16;
const PCPAGE_MASK: u16 = !Self::PCWORD_MASK;
fn new(base: u32) -> Self {
Self {
base: base as u16,
ramp: (base >> 16) as u8,
}
}
pub fn into_page_aligned(self) -> Self {
Self {
base: self.base & Self::PCPAGE_MASK,
ramp: self.ramp,
}
}
pub fn word(&self) -> u16 {
self.base & Self::PCWORD_MASK
}
pub fn ramp(&self) -> u8 {
self.ramp
}
}
impl From<u16> for Address {
fn from(i: u16) -> Self {
Self::new(i as u32)
}
}
impl From<u8> for Address {
fn from(i: u8) -> Self {
Self::new(i as u32)
}
}
impl From<u32> for Address {
fn from(i: u32) -> Self {
Self::new(i)
}
}
impl From<Address> for u32 {
fn from(address: Address) -> u32 {
address.base as u32 + ((address.ramp as u32) << 16)
}
}
impl From<Address> for u16 {
fn from(address: Address) -> u16 {
address.base
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_aligns_addess_to_page() {
let start_address = crate::SPM_PAGESIZE_BYTES as u32 * 8 + 17;
let address: Address = start_address.into();
assert_eq!(
address.into_page_aligned(),
Address::new(crate::SPM_PAGESIZE_BYTES as u32 * 8)
);
}
#[test]
fn it_masks_pcword_part() {
let start_address = crate::SPM_PAGESIZE_BYTES as u32 * 8 + 17;
let address: Address = start_address.into();
assert_eq!(address.word(), 17);
}
}