1use zerocopy::FromBytes;
6use zerocopy::Immutable;
7use zerocopy::IntoBytes;
8use zerocopy::KnownLayout;
9
10#[repr(C, packed)]
11#[derive(Clone, Copy, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
12pub struct RSDP {
13 pub signature: [u8; 8],
14 pub checksum: u8,
15 pub oem_id: [u8; 6],
16 pub revision: u8,
17 _rsdt_addr: u32,
18 pub length: u32,
19 pub xsdt_addr: u64,
20 pub extended_checksum: u8,
21 _reserved: [u8; 3],
22}
23
24impl RSDP {
25 pub fn new(oem_id: [u8; 6], xsdt_addr: u64) -> Self {
26 let mut rsdp = RSDP {
27 signature: *b"RSD PTR ",
28 checksum: 0,
29 oem_id,
30 revision: 2,
31 _rsdt_addr: 0,
32 length: std::mem::size_of::<RSDP>() as u32,
33 xsdt_addr,
34 extended_checksum: 0,
35 _reserved: [0; 3],
36 };
37
38 rsdp.checksum = super::generate_checksum(&rsdp.as_bytes()[0..19]);
39 rsdp.extended_checksum = super::generate_checksum(rsdp.as_bytes());
40 rsdp
41 }
42
43 pub fn len() -> usize {
44 std::mem::size_of::<RSDP>()
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use zerocopy::IntoBytes;
51
52 use super::RSDP;
53
54 #[test]
55 fn test_rsdp() {
56 let rsdp = RSDP::new(*b"CHYPER", 0xdead_beef);
57 let sum = rsdp
58 .as_bytes()
59 .iter()
60 .fold(0u8, |acc, x| acc.wrapping_add(*x));
61 assert_eq!(sum, 0);
62 let sum: u8 = rsdp
63 .as_bytes()
64 .iter()
65 .fold(0u8, |acc, x| acc.wrapping_add(*x));
66 assert_eq!(sum, 0);
67 }
68}