Skip to content

Commit 897d100

Browse files
committed
Add Rsdp2::new() to construct a new RSDP
The main use for this will be to be a test helper. Change-Id: Iadb050c53377574b7f5125424c1f14126a6a6964
1 parent d1557b6 commit 897d100

1 file changed

Lines changed: 49 additions & 1 deletion

File tree

stage0/src/acpi/tables/rsdp.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// limitations under the License.
1515
//
1616

17+
use alloc::boxed::Box;
1718
use core::fmt::Debug;
1819

1920
use x86_64::VirtAddr;
@@ -140,7 +141,7 @@ impl Rsdp for Rsdp1 {
140141
/// See Section 5.2.5.3 in the ACPI specification, Version 6.6 for more details.
141142
#[repr(C, packed)]
142143
#[derive(Debug, IntoBytes, Immutable, KnownLayout, TryFromBytes)]
143-
struct Rsdp2 {
144+
pub struct Rsdp2 {
144145
/// Signature: "RSD PTR " (note the trailing space).
145146
signature: RsdpSignature,
146147

@@ -172,6 +173,41 @@ struct Rsdp2 {
172173
}
173174
static_assertions::assert_eq_size!(Rsdp2, [u8; 36usize]);
174175

176+
impl Rsdp2 {
177+
#[allow(unused)]
178+
fn checksum(&self) -> u8 {
179+
// Just the RSDP1 header.
180+
self.as_bytes()[..size_of::<Rsdp1>()].iter().fold(0u8, |lhs, &rhs| lhs.wrapping_add(rhs))
181+
}
182+
183+
#[allow(unused)]
184+
fn extended_checksum(&self) -> u8 {
185+
self.as_bytes().iter().fold(0u8, |lhs, &rhs| lhs.wrapping_add(rhs))
186+
}
187+
188+
#[allow(unused)]
189+
pub fn new(rsdt: VirtAddr) -> Result<Box<Self>> {
190+
let mut rsdp = Box::new(Self {
191+
signature: RsdpSignature::default(),
192+
checksum: 0,
193+
oemid: [0; 6],
194+
revision: RsdpAcpi2Version::default(),
195+
rsdt_address: rsdt
196+
.as_u64()
197+
.try_into()
198+
.map_err(|_| "RSDT address not in low 32 bits")?,
199+
length: size_of::<Rsdp2>() as u32,
200+
xsdt_address: 0,
201+
extended_checksum: 0,
202+
_reserved: [0; 3],
203+
});
204+
rsdp.checksum = rsdp.checksum.wrapping_sub(rsdp.checksum());
205+
rsdp.extended_checksum = rsdp.extended_checksum.wrapping_sub(rsdp.extended_checksum());
206+
207+
Ok(rsdp)
208+
}
209+
}
210+
175211
impl Rsdp for Rsdp2 {
176212
fn validate(&self) -> Result<()> {
177213
let checksum = self.as_bytes().iter().fold(0u8, |lhs, &rhs| lhs.wrapping_add(rhs));
@@ -256,4 +292,16 @@ mod tests {
256292
let mut buf = Vec::from(b"\x01\x02\x03\x04\x05\x06\x07\x08\x55 TEST \x00\x02\x02\x03\x04");
257293
assert_that!(<dyn Rsdp>::try_from_bytes_mut(&mut buf[..]), err(anything()));
258294
}
295+
296+
#[test]
297+
pub fn test_new_parse() {
298+
let rsdp = Rsdp2::new(VirtAddr::new(0x1000)).unwrap();
299+
assert_that!(rsdp.rsdt(), some(eq(VirtAddr::new(0x1000))));
300+
assert_that!(rsdp.xsdt(), none());
301+
302+
let mut buf = rsdp.as_bytes().to_vec();
303+
let rsdp2 = <dyn Rsdp>::try_from_bytes_mut(&mut buf[..]).unwrap();
304+
assert_that!(rsdp2.rsdt(), eq(rsdp.rsdt()));
305+
assert_that!(rsdp2.xsdt(), eq(rsdp.xsdt()));
306+
}
259307
}

0 commit comments

Comments
 (0)