mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-10 13:56:48 +00:00
Remove lots of unsafe code in acpi/
This commit is contained in:
parent
3322710900
commit
2cefa7e5fa
@ -3,7 +3,7 @@
|
|||||||
#![expect(dead_code)]
|
#![expect(dead_code)]
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{fmt::Debug, mem::size_of, slice::Iter};
|
use core::{fmt::Debug, slice::Iter};
|
||||||
|
|
||||||
use acpi::{
|
use acpi::{
|
||||||
sdt::{SdtHeader, Signature},
|
sdt::{SdtHeader, Signature},
|
||||||
@ -11,17 +11,22 @@ use acpi::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::remapping::{Andd, Atsr, Drhd, Rhsa, Rmrr, Satc, Sidp};
|
use super::remapping::{Andd, Atsr, Drhd, Rhsa, Rmrr, Satc, Sidp};
|
||||||
use crate::mm::paddr_to_vaddr;
|
|
||||||
|
|
||||||
/// DMA Remapping structure. When IOMMU is enabled, the structure should be present in the ACPI table,
|
/// DMA Remapping structure.
|
||||||
/// and the user can use the DRHD table in this structure to obtain the register base addresses used to configure functions such as IOMMU.
|
///
|
||||||
|
/// When IOMMU is enabled, the structure should be present in the ACPI table, and the user can use
|
||||||
|
/// the DRHD table in this structure to obtain the register base addresses used to configure
|
||||||
|
/// functions such IOMMU.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Dmar {
|
pub struct Dmar {
|
||||||
header: DmarHeader,
|
header: DmarHeader,
|
||||||
/// Actual size is indicated by `length` in header
|
// The actual size is indicated by `length` in `header`.
|
||||||
remapping_structures: Vec<Remapping>, // Followed by `n` entries with format `Remapping Structures`
|
// Entries with the format of Remapping Structures are followed.
|
||||||
|
remapping_structures: Vec<Remapping>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Remapping Structures.
|
||||||
|
///
|
||||||
/// A DMAR structure contains serval remapping structures. Among these structures,
|
/// A DMAR structure contains serval remapping structures. Among these structures,
|
||||||
/// one DRHD must exist, the others must not exist at all.
|
/// one DRHD must exist, the others must not exist at all.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -57,6 +62,8 @@ struct DmarHeader {
|
|||||||
reserved: [u8; 10],
|
reserved: [u8; 10],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: The `DmarHeader` is the header for the DMAR structure. All its fields are described in
|
||||||
|
// the Intel manual.
|
||||||
unsafe impl AcpiTable for DmarHeader {
|
unsafe impl AcpiTable for DmarHeader {
|
||||||
const SIGNATURE: Signature = Signature::DMAR;
|
const SIGNATURE: Signature = Signature::DMAR;
|
||||||
fn header(&self) -> &acpi::sdt::SdtHeader {
|
fn header(&self) -> &acpi::sdt::SdtHeader {
|
||||||
@ -67,34 +74,34 @@ unsafe impl AcpiTable for DmarHeader {
|
|||||||
impl Dmar {
|
impl Dmar {
|
||||||
/// Creates a instance from ACPI table.
|
/// Creates a instance from ACPI table.
|
||||||
pub fn new() -> Option<Self> {
|
pub fn new() -> Option<Self> {
|
||||||
if !super::ACPI_TABLES.is_completed() {
|
let acpi_table_lock = super::ACPI_TABLES.get()?.lock();
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let acpi_table_lock = super::ACPI_TABLES.get().unwrap().lock();
|
|
||||||
// SAFETY: The DmarHeader is the header for the DMAR structure, it fits all the field described in Intel manual.
|
|
||||||
let dmar_mapping = acpi_table_lock.find_table::<DmarHeader>().ok()?;
|
let dmar_mapping = acpi_table_lock.find_table::<DmarHeader>().ok()?;
|
||||||
|
|
||||||
let physical_address = dmar_mapping.physical_start();
|
let header = *dmar_mapping;
|
||||||
let len = dmar_mapping.mapped_length();
|
// SAFETY: `find_table` returns a region of memory that belongs to the ACPI table. This
|
||||||
// SAFETY: The target address is the start of the remapping structures,
|
// memory region is valid to read, properly initialized, lives for `'static`, and will
|
||||||
// and the length is valid since the value is read from the length field in SDTHeader minus the size of DMAR header.
|
// never be mutated.
|
||||||
let dmar_slice = unsafe {
|
let slice = unsafe {
|
||||||
core::slice::from_raw_parts_mut(
|
core::slice::from_raw_parts(
|
||||||
paddr_to_vaddr(physical_address + size_of::<DmarHeader>()) as *mut u8,
|
dmar_mapping
|
||||||
len - size_of::<DmarHeader>(),
|
.virtual_start()
|
||||||
|
.as_ptr()
|
||||||
|
.cast::<u8>()
|
||||||
|
.cast_const(),
|
||||||
|
dmar_mapping.mapped_length(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut index = core::mem::size_of::<DmarHeader>();
|
||||||
let mut remapping_structures = Vec::new();
|
let mut remapping_structures = Vec::new();
|
||||||
let mut index = 0;
|
while index != (header.header.length as usize) {
|
||||||
let mut remain_length = len - size_of::<DmarHeader>();
|
// CommonHeader { type: u16, length: u16 }
|
||||||
// SAFETY: Indexes and offsets are strictly followed by the manual.
|
let typ = u16::from_ne_bytes(slice[index..index + 2].try_into().unwrap());
|
||||||
unsafe {
|
let length =
|
||||||
while remain_length > 0 {
|
u16::from_ne_bytes(slice[index + 2..index + 4].try_into().unwrap()) as usize;
|
||||||
// Common header: type: u16, length: u16
|
|
||||||
let length = *dmar_slice[index + 2..index + 4].as_ptr() as usize;
|
let bytes = &slice[index..index + length];
|
||||||
let typ = *dmar_slice[index..index + 2].as_ptr() as usize;
|
|
||||||
let bytes = &&dmar_slice[index..index + length];
|
|
||||||
let remapping = match typ {
|
let remapping = match typ {
|
||||||
0 => Remapping::Drhd(Drhd::from_bytes(bytes)),
|
0 => Remapping::Drhd(Drhd::from_bytes(bytes)),
|
||||||
1 => Remapping::Rmrr(Rmrr::from_bytes(bytes)),
|
1 => Remapping::Rmrr(Rmrr::from_bytes(bytes)),
|
||||||
@ -104,16 +111,15 @@ impl Dmar {
|
|||||||
5 => Remapping::Satc(Satc::from_bytes(bytes)),
|
5 => Remapping::Satc(Satc::from_bytes(bytes)),
|
||||||
6 => Remapping::Sidp(Sidp::from_bytes(bytes)),
|
6 => Remapping::Sidp(Sidp::from_bytes(bytes)),
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Unidentified remapping structure type");
|
panic!(
|
||||||
|
"the type of the remapping structure is invalid or not supported: {}",
|
||||||
|
typ
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// let temp = DeviceScope::from_bytes(
|
|
||||||
// &bytes[index as usize..index as usize + length],
|
|
||||||
// );
|
|
||||||
remapping_structures.push(remapping);
|
remapping_structures.push(remapping);
|
||||||
|
|
||||||
index += length;
|
index += length;
|
||||||
remain_length -= length;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Dmar {
|
Some(Dmar {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
#![expect(unused_variables)]
|
|
||||||
|
|
||||||
pub mod dmar;
|
pub mod dmar;
|
||||||
pub mod remapping;
|
pub mod remapping;
|
||||||
|
|
||||||
@ -29,16 +27,19 @@ impl AcpiHandler for AcpiMemoryHandler {
|
|||||||
physical_address: usize,
|
physical_address: usize,
|
||||||
size: usize,
|
size: usize,
|
||||||
) -> acpi::PhysicalMapping<Self, T> {
|
) -> acpi::PhysicalMapping<Self, T> {
|
||||||
acpi::PhysicalMapping::new(
|
let virtual_address = NonNull::new(paddr_to_vaddr(physical_address) as *mut T).unwrap();
|
||||||
physical_address,
|
|
||||||
NonNull::new(paddr_to_vaddr(physical_address) as *mut T).unwrap(),
|
// SAFETY: The caller should guarantee that `physical_address..physical_address + size` is
|
||||||
size,
|
// part of the ACPI table. Then the memory region is mapped to `virtual_address` and is
|
||||||
size,
|
// valid for read and immutable dereferencing.
|
||||||
self.clone(),
|
// FIXME: The caller guarantee only holds if we trust the hardware to provide a valid ACPI
|
||||||
)
|
// table. Otherwise, if the table is corrupted, it may reference arbitrary memory regions.
|
||||||
|
unsafe {
|
||||||
|
acpi::PhysicalMapping::new(physical_address, virtual_address, size, size, self.clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unmap_physical_region<T>(region: &acpi::PhysicalMapping<Self, T>) {}
|
fn unmap_physical_region<T>(_region: &acpi::PhysicalMapping<Self, T>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
|
@ -1,20 +1,23 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
#![expect(dead_code)]
|
#![expect(dead_code)]
|
||||||
#![expect(unused_variables)]
|
|
||||||
|
|
||||||
//! Remapping structures of DMAR table.
|
//! Remapping structures of DMAR table.
|
||||||
//! This file defines these structures and provides a "Debug" implementation to see the value inside these structures.
|
//!
|
||||||
|
//! This file defines these structures and provides a `Debug` implementation to see the value
|
||||||
|
//! inside these structures.
|
||||||
|
//!
|
||||||
//! Most of the introduction are copied from Intel vt-directed-io-specification.
|
//! Most of the introduction are copied from Intel vt-directed-io-specification.
|
||||||
|
|
||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{borrow::ToOwned, string::String, vec::Vec};
|
||||||
use core::{fmt::Debug, mem::size_of};
|
use core::fmt::Debug;
|
||||||
|
|
||||||
|
use ostd_pod::Pod;
|
||||||
|
|
||||||
/// DMA-remapping hardware unit definition (DRHD).
|
/// DMA-remapping hardware unit definition (DRHD).
|
||||||
///
|
///
|
||||||
/// A DRHD structure uniquely represents a remapping hardware unit present in the platform.
|
/// A DRHD structure uniquely represents a remapping hardware unit present in the platform.
|
||||||
/// There must be at least one instance of this structure for each
|
/// There must be at least one instance of this structure for each PCI segment in the platform.
|
||||||
/// PCI segment in the platform.
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Drhd {
|
pub struct Drhd {
|
||||||
header: DrhdHeader,
|
header: DrhdHeader,
|
||||||
@ -28,7 +31,7 @@ impl Drhd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, Pod)]
|
||||||
pub struct DrhdHeader {
|
pub struct DrhdHeader {
|
||||||
typ: u16,
|
typ: u16,
|
||||||
length: u16,
|
length: u16,
|
||||||
@ -50,7 +53,7 @@ pub struct Rmrr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, Pod)]
|
||||||
pub struct RmrrHeader {
|
pub struct RmrrHeader {
|
||||||
typ: u16,
|
typ: u16,
|
||||||
length: u16,
|
length: u16,
|
||||||
@ -71,7 +74,7 @@ pub struct Atsr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, Pod)]
|
||||||
pub struct AtsrHeader {
|
pub struct AtsrHeader {
|
||||||
typ: u16,
|
typ: u16,
|
||||||
length: u16,
|
length: u16,
|
||||||
@ -82,11 +85,12 @@ pub struct AtsrHeader {
|
|||||||
|
|
||||||
/// Remapping Hardware Status Affinity (RHSA).
|
/// Remapping Hardware Status Affinity (RHSA).
|
||||||
///
|
///
|
||||||
/// It is applicable for platforms supporting non-uniform memory (NUMA), where Remapping hardware units spans across nodes.
|
/// It is applicable for platforms supporting non-uniform memory (NUMA),
|
||||||
/// This optional structure provides the association between each Remapping hardware unit (identified by its
|
/// where Remapping hardware units spans across nodes.
|
||||||
/// espective Base Address) and the proximity domain to which that hardware unit belongs.
|
/// This optional structure provides the association between each Remapping hardware unit (identified
|
||||||
|
/// by its espective Base Address) and the proximity domain to which that hardware unit belongs.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, Pod)]
|
||||||
pub struct Rhsa {
|
pub struct Rhsa {
|
||||||
typ: u16,
|
typ: u16,
|
||||||
length: u16,
|
length: u16,
|
||||||
@ -106,7 +110,7 @@ pub struct Andd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, Pod)]
|
||||||
pub struct AnddHeader {
|
pub struct AnddHeader {
|
||||||
typ: u16,
|
typ: u16,
|
||||||
length: u16,
|
length: u16,
|
||||||
@ -125,7 +129,7 @@ pub struct Satc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, Pod)]
|
||||||
pub struct SatcHeader {
|
pub struct SatcHeader {
|
||||||
typ: u16,
|
typ: u16,
|
||||||
length: u16,
|
length: u16,
|
||||||
@ -139,7 +143,6 @@ pub struct SatcHeader {
|
|||||||
/// The (SIDP) reporting structure identifies devices that have special
|
/// The (SIDP) reporting structure identifies devices that have special
|
||||||
/// properties and that may put restrictions on how system software must configure remapping
|
/// properties and that may put restrictions on how system software must configure remapping
|
||||||
/// structures that govern such devices in a platform where remapping hardware is enabled.
|
/// structures that govern such devices in a platform where remapping hardware is enabled.
|
||||||
///
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Sidp {
|
pub struct Sidp {
|
||||||
header: SidpHeader,
|
header: SidpHeader,
|
||||||
@ -147,7 +150,7 @@ pub struct Sidp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, Pod)]
|
||||||
pub struct SidpHeader {
|
pub struct SidpHeader {
|
||||||
typ: u16,
|
typ: u16,
|
||||||
length: u16,
|
length: u16,
|
||||||
@ -164,7 +167,7 @@ pub struct DeviceScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, Pod)]
|
||||||
pub struct DeviceScopeHeader {
|
pub struct DeviceScopeHeader {
|
||||||
typ: u8,
|
typ: u8,
|
||||||
length: u8,
|
length: u8,
|
||||||
@ -175,35 +178,32 @@ pub struct DeviceScopeHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_from_bytes {
|
macro_rules! impl_from_bytes {
|
||||||
($(($struct:tt,$header_struct:tt,$dst_name:ident)),*) => {
|
($(($struct:tt, $header_struct:tt),)*) => {
|
||||||
$(impl $struct {
|
$(impl $struct {
|
||||||
/// Creates instance from bytes
|
#[doc = concat!("Parses a [`", stringify!($struct), "`] from bytes.")]
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// User must ensure the bytes is valid.
|
#[doc = concat!(
|
||||||
///
|
"This method may panic if the bytes do not represent a valid [`",
|
||||||
pub unsafe fn from_bytes(bytes: &[u8]) -> Self {
|
stringify!($struct),
|
||||||
let length = u16_from_slice(&bytes[2..4]) as usize;
|
"`].",
|
||||||
debug_assert_eq!(length, bytes.len());
|
)]
|
||||||
|
pub fn from_bytes(bytes: &[u8]) -> Self {
|
||||||
|
let header = $header_struct::from_bytes(bytes);
|
||||||
|
debug_assert_eq!(header.length as usize, bytes.len());
|
||||||
|
|
||||||
let mut index = core::mem::size_of::<$header_struct>();
|
let mut index = core::mem::size_of::<$header_struct>();
|
||||||
let mut remain_length = length - core::mem::size_of::<$header_struct>();
|
let mut device_scopes = Vec::new();
|
||||||
let mut $dst_name = Vec::new();
|
while index != (header.length as usize) {
|
||||||
while remain_length > 0 {
|
let val = DeviceScope::from_bytes_prefix(&bytes[index..]);
|
||||||
let length = *bytes[index + 1..index + 2].as_ptr() as usize;
|
index += val.header.length as usize;
|
||||||
let temp = DeviceScope::from_bytes(
|
device_scopes.push(val);
|
||||||
&bytes[index..index + length],
|
|
||||||
);
|
|
||||||
$dst_name.push(temp);
|
|
||||||
index += length;
|
|
||||||
remain_length -= length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let header = *(bytes.as_ptr() as *const $header_struct);
|
|
||||||
Self{
|
Self{
|
||||||
header,
|
header,
|
||||||
$dst_name
|
device_scopes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})*
|
})*
|
||||||
@ -211,33 +211,31 @@ macro_rules! impl_from_bytes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl_from_bytes!(
|
impl_from_bytes!(
|
||||||
(Drhd, DrhdHeader, device_scopes),
|
(Drhd, DrhdHeader),
|
||||||
(Rmrr, RmrrHeader, device_scopes),
|
(Rmrr, RmrrHeader),
|
||||||
(Atsr, AtsrHeader, device_scopes),
|
(Atsr, AtsrHeader),
|
||||||
(Satc, SatcHeader, device_scopes),
|
(Satc, SatcHeader),
|
||||||
(Sidp, SidpHeader, device_scopes)
|
(Sidp, SidpHeader),
|
||||||
);
|
);
|
||||||
|
|
||||||
impl DeviceScope {
|
impl DeviceScope {
|
||||||
/// Creates instance from bytes
|
/// Parses a [`DeviceScope`] from a prefix of the bytes.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// User must ensure the bytes is valid.
|
/// This method may panic if the byte prefix does not represent a valid [`DeviceScope`].
|
||||||
///
|
fn from_bytes_prefix(bytes: &[u8]) -> Self {
|
||||||
unsafe fn from_bytes(bytes: &[u8]) -> Self {
|
let header = DeviceScopeHeader::from_bytes(bytes);
|
||||||
let length = bytes[1] as u32;
|
debug_assert!((header.length as usize) <= bytes.len());
|
||||||
debug_assert_eq!(length, bytes.len() as u32);
|
|
||||||
let header = *(bytes.as_ptr() as *const DeviceScopeHeader);
|
let mut index = core::mem::size_of::<DeviceScopeHeader>();
|
||||||
|
debug_assert!((header.length as usize) >= index);
|
||||||
|
|
||||||
let mut index = size_of::<DeviceScopeHeader>();
|
|
||||||
let mut remain_length = length - index as u32;
|
|
||||||
let mut path = Vec::new();
|
let mut path = Vec::new();
|
||||||
while remain_length > 0 {
|
while index != (header.length as usize) {
|
||||||
let temp: (u8, u8) = *(bytes[index..index + 2].as_ptr() as *const (u8, u8));
|
let val = (bytes[index], bytes[index + 1]);
|
||||||
path.push(temp);
|
path.push(val);
|
||||||
index += 2;
|
index += 2;
|
||||||
remain_length -= 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Self { header, path }
|
Self { header, path }
|
||||||
@ -245,42 +243,37 @@ impl DeviceScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Rhsa {
|
impl Rhsa {
|
||||||
/// Creates instance from bytes
|
/// Parses an [`Rhsa`] from the bytes.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// User must ensure the bytes is valid.
|
/// This method may panic if the bytes do not represent a valid [`Rhsa`].
|
||||||
///
|
pub fn from_bytes(bytes: &[u8]) -> Self {
|
||||||
pub unsafe fn from_bytes(bytes: &[u8]) -> Self {
|
let val = <Self as Pod>::from_bytes(bytes);
|
||||||
let length = u16_from_slice(&bytes[2..4]) as u32;
|
debug_assert_eq!(val.length as usize, bytes.len());
|
||||||
debug_assert_eq!(length, bytes.len() as u32);
|
|
||||||
*(bytes.as_ptr() as *const Self)
|
val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Andd {
|
impl Andd {
|
||||||
/// Creates instance from bytes
|
/// Parses an [`Andd`] from the bytes.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// User must ensure the bytes is valid.
|
/// This method may panic if the bytes do not represent a valid [`Andd`].
|
||||||
///
|
pub fn from_bytes(bytes: &[u8]) -> Self {
|
||||||
pub unsafe fn from_bytes(bytes: &[u8]) -> Self {
|
let header = AnddHeader::from_bytes(bytes);
|
||||||
let length = u16_from_slice(&bytes[2..4]) as usize;
|
debug_assert_eq!(header.length as usize, bytes.len());
|
||||||
debug_assert_eq!(length, bytes.len());
|
|
||||||
|
|
||||||
let index = core::mem::size_of::<AnddHeader>();
|
let header_len = core::mem::size_of::<AnddHeader>();
|
||||||
let remain_length = length - core::mem::size_of::<AnddHeader>();
|
let acpi_object_name = core::str::from_utf8(&bytes[header_len..])
|
||||||
let string = String::from_utf8(bytes[index..index + length].to_vec()).unwrap();
|
.unwrap()
|
||||||
|
.to_owned();
|
||||||
|
|
||||||
let header = *(bytes.as_ptr() as *const AnddHeader);
|
|
||||||
Self {
|
Self {
|
||||||
header,
|
header,
|
||||||
acpi_object_name: string,
|
acpi_object_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn u16_from_slice(input: &[u8]) -> u16 {
|
|
||||||
u16::from_ne_bytes(input[0..size_of::<u16>()].try_into().unwrap())
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user