acpica_bindings/interface/types/
object.rs1use core::ffi::CStr;
4
5use log::{debug, warn};
6
7use crate::bindings::{
8 consts::{
9 ACPI_TYPE_ANY, ACPI_TYPE_BUFFER, ACPI_TYPE_INTEGER, ACPI_TYPE_LOCAL_REFERENCE,
10 ACPI_TYPE_PACKAGE, ACPI_TYPE_POWER, ACPI_TYPE_PROCESSOR, ACPI_TYPE_STRING,
11 },
12 types::{
13 object::{FfiAcpiObject, FfiAcpiObjectType},
14 FfiAcpiHandle, FfiAcpiIoAddress,
15 },
16};
17
18#[derive(Debug)]
20pub struct AcpiObjectPackage {
21 count: u32,
22 elements: *mut FfiAcpiObject,
23}
24
25#[derive(Debug)]
27pub struct AcpiObjectString {
28 length: u32,
29 pointer: *mut u8,
30}
31
32#[derive(Debug)]
34pub struct AcpiObjectBuffer {
35 length: u32,
36 pointer: *mut u8,
37}
38
39#[derive(Debug)]
41pub struct AcpiObjectReference {
42 actual_type: FfiAcpiObjectType,
43 handle: FfiAcpiHandle,
44}
45
46#[derive(Debug)]
48pub struct AcpiObjectProcessor {
49 proc_id: u32,
50 pblk_address: FfiAcpiIoAddress,
51 pblk_length: u32,
52}
53
54#[derive(Debug)]
56pub struct AcpiObjectPowerResource {
57 system_level: u32,
58 resource_order: u32,
59}
60
61#[derive(Debug)]
63pub enum AcpiObject<'a> {
64 Any,
67 Integer(u64),
69 String(&'a str),
71 Buffer(&'a [u8]),
73 Package(AcpiObjectPackage),
75 Reference(AcpiObjectReference),
77 Processor(AcpiObjectProcessor),
79 PowerResource(AcpiObjectPowerResource),
81}
82
83impl<'a> AcpiObject<'a> {
84 pub(crate) unsafe fn from_ffi(pointer: *const FfiAcpiObject) -> Self {
89 let ffi_acpi_object = unsafe { *pointer };
91 let object_type = unsafe { ffi_acpi_object.object_type };
94
95 match object_type {
96 _t @ ACPI_TYPE_ANY => Self::Any,
97 _t @ ACPI_TYPE_INTEGER => unsafe { Self::Integer(ffi_acpi_object.integer.value) },
99 _t @ ACPI_TYPE_STRING => {
100 let string = unsafe { ffi_acpi_object.string };
102
103 let bytes = unsafe {
105 core::slice::from_raw_parts(string.pointer.cast(), string.length as _)
106 };
107
108 let str = core::str::from_utf8(bytes).unwrap();
109
110 Self::String(str)
111 }
112 _t @ ACPI_TYPE_BUFFER => {
113 let buffer = unsafe { ffi_acpi_object.buffer };
115
116 let bytes =
117 unsafe { core::slice::from_raw_parts(buffer.pointer, buffer.length as _) };
119
120 Self::Buffer(bytes)
121 }
122 _t @ ACPI_TYPE_PACKAGE => {
123 let package = unsafe { ffi_acpi_object.package };
125
126 Self::Package(AcpiObjectPackage {
127 count: package.count,
128 elements: package.elements,
129 })
130 }
131 _t @ ACPI_TYPE_LOCAL_REFERENCE => {
132 let reference = unsafe { ffi_acpi_object.reference };
134
135 Self::Reference(AcpiObjectReference {
136 actual_type: reference.actual_type,
137 handle: reference.handle,
138 })
139 }
140 _t @ ACPI_TYPE_PROCESSOR => {
141 let processor = unsafe { ffi_acpi_object.processor };
143
144 Self::Processor(AcpiObjectProcessor {
145 proc_id: processor.proc_id,
146 pblk_address: processor.pblk_address,
147 pblk_length: processor.pblk_length,
148 })
149 }
150 _t @ ACPI_TYPE_POWER => {
151 let power_resource = unsafe { ffi_acpi_object.power_resource };
153
154 Self::PowerResource(AcpiObjectPowerResource {
155 system_level: power_resource.system_level,
156 resource_order: power_resource.resource_order,
157 })
158 }
159
160 _ => Self::Any,
161 }
162 }
163
164 pub(crate) unsafe fn from_type_and_val(object_type: u8, val: *mut i8) -> Self {
169 match object_type.into() {
170 _t @ ACPI_TYPE_ANY => Self::Any,
171 _t @ ACPI_TYPE_INTEGER => Self::Integer(val as _),
172 _t @ ACPI_TYPE_STRING => {
173 let s = unsafe {
175 CStr::from_ptr(val)
176 .to_str()
177 .expect("String object should have been valid utf-8")
178 };
179 Self::String(s)
180 }
181
182 _ => {
183 warn!(target: "acpi_object_from_type_and_val", "Check object type meaning. Type is {}, val is {:p}", object_type, val);
184 Self::Any
185 }
186 }
187 }
188
189 #[must_use]
191 pub fn get_type(&self) -> AcpiObjectType {
192 match self {
193 AcpiObject::Any => AcpiObjectType::Any,
194 AcpiObject::Integer(_) => AcpiObjectType::Integer,
195 AcpiObject::String(_) => AcpiObjectType::String,
196 AcpiObject::Buffer(_) => AcpiObjectType::Buffer,
197 AcpiObject::Package(_) => AcpiObjectType::Package,
198 AcpiObject::Reference(_) => AcpiObjectType::Reference,
199 AcpiObject::Processor(_) => AcpiObjectType::Processor,
200 AcpiObject::PowerResource(_) => AcpiObjectType::PowerResource,
201 }
202 }
203}
204
205#[derive(Debug, Clone, Copy, PartialEq, Eq)]
207pub enum AcpiObjectType {
208 Any,
211 Integer,
213 String,
215 Buffer,
217 Package,
219 Reference,
221 Processor,
223 PowerResource,
225}
226
227impl AcpiObjectType {
228 pub(crate) fn from_type_id(id: FfiAcpiObjectType) -> Self {
229 match id {
230 _t @ ACPI_TYPE_ANY => Self::Any,
231 _t @ ACPI_TYPE_INTEGER => Self::Integer,
232 _t @ ACPI_TYPE_STRING => Self::String,
233 _t @ ACPI_TYPE_BUFFER => Self::Buffer,
234 _t @ ACPI_TYPE_PACKAGE => Self::Package,
235 _t @ ACPI_TYPE_LOCAL_REFERENCE => Self::Reference,
236 _t @ ACPI_TYPE_PROCESSOR => Self::Processor,
237 _t @ ACPI_TYPE_POWER => Self::PowerResource,
238
239 _ => Self::Any,
240 }
241 }
242}