strat9_kernel/acpi/
rsdt.rs1use super::sdt::Sdt;
5
6pub const RSDT_SIGNATURE: &[u8; 4] = b"RSDT";
7pub const XSDT_SIGNATURE: &[u8; 4] = b"XSDT";
8
9pub enum RsdtXsdt {
10 Regular(*const Sdt),
11 Extended(*const Sdt),
12}
13
14impl RsdtXsdt {
15 pub fn from_rsdp(rsdp_vaddr: u64, revision: u8) -> Option<Self> {
17 if revision >= 2 {
19 let xsdt_phys = unsafe {
20 core::ptr::read_unaligned((rsdp_vaddr as *const u8).add(24) as *const u64)
21 };
22 if xsdt_phys != 0 {
23 crate::memory::paging::ensure_identity_map_range(
24 xsdt_phys,
25 core::mem::size_of::<Sdt>() as u64,
26 );
27 let xsdt_ptr = crate::memory::phys_to_virt(xsdt_phys) as *const Sdt;
28 return Some(RsdtXsdt::Extended(xsdt_ptr));
29 }
30 }
31
32 let rsdt_phys =
34 unsafe { core::ptr::read_unaligned((rsdp_vaddr as *const u8).add(16) as *const u32) }
35 as u64;
36 if rsdt_phys == 0 {
37 return None;
38 }
39 crate::memory::paging::ensure_identity_map_range(
40 rsdt_phys,
41 core::mem::size_of::<Sdt>() as u64,
42 );
43 let rsdt_ptr = crate::memory::phys_to_virt(rsdt_phys) as *const Sdt;
44 Some(RsdtXsdt::Regular(rsdt_ptr))
45 }
46
47 pub fn sdt(&self) -> &'static Sdt {
49 match self {
50 RsdtXsdt::Regular(ptr) => unsafe { &**ptr },
51 RsdtXsdt::Extended(ptr) => unsafe { &**ptr },
52 }
53 }
54
55 pub fn addresses(&self) -> RsdtXsdtIter {
57 let sdt = self.sdt();
58 let header_size = core::mem::size_of::<Sdt>();
59 if (sdt.length as usize) < header_size {
60 return RsdtXsdtIter::Empty;
61 }
62 let data_ptr = (sdt as *const Sdt as u64 + header_size as u64) as *const u8;
63 let data_len = sdt.length as usize - header_size;
64
65 match self {
66 RsdtXsdt::Regular(_) => RsdtXsdtIter::Regular {
67 ptr: data_ptr as *const u32,
68 count: data_len / 4,
69 index: 0,
70 },
71 RsdtXsdt::Extended(_) => RsdtXsdtIter::Extended {
72 ptr: data_ptr as *const u64,
73 count: data_len / 8,
74 index: 0,
75 },
76 }
77 }
78}
79
80pub enum RsdtXsdtIter {
81 Empty,
82 Regular {
83 ptr: *const u32,
84 count: usize,
85 index: usize,
86 },
87 Extended {
88 ptr: *const u64,
89 count: usize,
90 index: usize,
91 },
92}
93
94impl Iterator for RsdtXsdtIter {
95 type Item = u64;
96
97 fn next(&mut self) -> Option<Self::Item> {
99 match self {
100 RsdtXsdtIter::Empty => None,
101 RsdtXsdtIter::Regular { ptr, count, index } => {
102 if index < count {
103 let addr = unsafe { core::ptr::read_unaligned(ptr.add(*index)) };
104 *index += 1;
105 Some(addr as u64)
106 } else {
107 None
108 }
109 }
110 RsdtXsdtIter::Extended { ptr, count, index } => {
111 if index < count {
112 let addr = unsafe { core::ptr::read_unaligned(ptr.add(*index)) };
113 *index += 1;
114 Some(addr)
115 } else {
116 None
117 }
118 }
119 }
120 }
121}