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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//! Memory Array Mapped Address (Type 19)
//!
//! This structure provides the address mapping for a Physical Memory Array.
//! One structure is present for each contiguous address range described.
use crate::{
InfoType,
MalformedStructureError::{self, InvalidFormattedSectionLength},
RawStructure,
};
/// Main struct for *Memory Array Mapped Address (Type 19)*
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct MemoryArrayMappedAddress {
/// Specifies the structure’s handle
pub handle: u16,
/// Physical address, in kilobytes, of a range of memory mapped to the specified Physical
/// Memory Array.\
/// When the field value is FFFF FFFFh, the actual address is stored in the Extended Starting
/// Address field. When this field contains a valid address, Ending Address must also contain a
/// valid address. When this field contains FFFF FFFFh, Ending Address must also contain FFFF
/// FFFFh
pub starting_address: u32,
/// Physical ending address of the last kilobyte of a range of addresses mapped to the
/// specified Physical Memory Array.\
/// When the field value is FFFF FFFFh and the Starting Address field also contains FFFF FFFFh,
/// the actual address is stored in the Extended Ending Address field. When this field contains
/// a valid address, Starting Address must also contain a valid address.
pub ending_address: u32,
/// Handle, or instance number, associated with the Physical Memory Array to which this address
/// range is mapped.\
/// Multiple address ranges can be mapped to a single Physical Memory Array.
pub memory_array_handle: u16,
/// Number of Memory Devices that form a single row of memory for the address partition defined
/// by this structure.
pub partition_width: u8,
/// Physical address, in bytes, of a range of memory mapped to the specified Physical Memory
/// Array.\
/// This field is valid when Starting Address contains the value FFFF FFFFh. If Starting
/// Address contains a value other than FFFF FFFFh, this field contains zeros. When this field
/// contains a valid address, Extended Ending Address must also contain a valid address.
pub extended_starting_address: Option<u64>,
/// Physical ending address, in bytes, of the last of a range of addresses mapped to the
/// specified Physical Memory Array.\
/// This field is valid when both Starting Address and Ending Address contain the value FFFF
/// FFFFh. If Ending Address contains a value other than FFFF FFFFh, this field contains zeros.
/// When this field contains a valid address, Extended Starting Address must also contain a
/// valid address.
pub extended_ending_address: Option<u64>,
}
impl<'a> MemoryArrayMappedAddress {
pub(crate) fn try_from(structure: RawStructure<'a>) -> Result<Self, MalformedStructureError> {
let handle = structure.handle;
match (structure.version.major, structure.version.minor) {
v if ((2, 1)..(2, 7)).contains(&v) && structure.length != 0x0F => Err(InvalidFormattedSectionLength(
InfoType::MemoryArrayMappedAddress,
handle,
"",
0x0F,
)),
v if v >= (2, 7) && structure.length != 0x1F => Err(InvalidFormattedSectionLength(
InfoType::MemoryArrayMappedAddress,
handle,
"",
0x1F,
)),
_ => Ok(Self {
handle,
starting_address: structure.get::<u32>(0x04)?,
ending_address: structure.get::<u32>(0x08)?,
memory_array_handle: structure.get::<u16>(0x0C)?,
partition_width: structure.get::<u8>(0x0E)?,
extended_starting_address: structure.get::<u64>(0x0F).ok(),
extended_ending_address: structure.get::<u64>(0x17).ok(),
}),
}
}
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq as pretty_assert_eq;
use std::prelude::v1::*;
#[test]
fn memory_array_mapped_address() {
use super::*;
use crate::{InfoType, RawStructure};
let length = 31;
let (data, strings) =
include_bytes!("../../tests/data/02daadcd/entries/19-0/bin")[4..].split_at(length as usize - 4);
let structure = RawStructure {
version: (2, 7).into(),
info: InfoType::MemoryArrayMappedAddress,
length,
handle: 0x0027,
data,
strings,
};
let sample = MemoryArrayMappedAddress {
handle: 0x0027,
starting_address: 0,
ending_address: 0x0207C000,
memory_array_handle: 0x0026,
partition_width: 255,
extended_starting_address: Some(0),
extended_ending_address: Some(0),
};
let result = MemoryArrayMappedAddress::try_from(structure).unwrap();
pretty_assert_eq!(sample, result, "MemoryArrayMappedAddress");
}
}