acpi_tables/
rsdp.rs

1// Copyright 2020 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use 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}