1use crate::AcpiError;
5use core::convert::TryFrom;
6
7#[derive(Clone, Copy, Debug)]
10#[repr(C, packed)]
11pub(crate) struct RawGenericAddress {
12 pub address_space: u8,
13 pub bit_width: u8,
14 pub bit_offset: u8,
15 pub access_size: u8,
16 pub address: u64,
17}
18
19impl RawGenericAddress {
20 pub(crate) const fn is_empty(&self) -> bool {
21 self.address_space == 0
22 && self.bit_width == 0
23 && self.bit_offset == 0
24 && self.access_size == 0
25 && self.address == 0
26 }
27}
28
29#[derive(PartialEq, Eq, Clone, Copy, Debug)]
30pub enum AddressSpace {
31 SystemMemory,
32 SystemIo,
33 PciConfigSpace,
42 EmbeddedController,
43 SMBus,
44 SystemCmos,
45 PciBarTarget,
46 Ipmi,
47 GeneralIo,
48 GenericSerialBus,
49 PlatformCommunicationsChannel,
50 FunctionalFixedHardware,
51 OemDefined(u8),
52}
53
54#[derive(PartialEq, Eq, Clone, Copy, Debug)]
55pub enum AccessSize {
56 Undefined,
57 ByteAccess,
58 WordAccess,
59 DWordAccess,
60 QWordAccess,
61}
62
63impl TryFrom<u8> for AccessSize {
64 type Error = AcpiError;
65
66 fn try_from(size: u8) -> Result<Self, Self::Error> {
67 match size {
68 0 => Ok(AccessSize::Undefined),
69 1 => Ok(AccessSize::ByteAccess),
70 2 => Ok(AccessSize::WordAccess),
71 3 => Ok(AccessSize::DWordAccess),
72 4 => Ok(AccessSize::QWordAccess),
73 _ => Err(AcpiError::InvalidGenericAddress),
74 }
75 }
76}
77
78#[derive(PartialEq, Eq, Clone, Copy, Debug)]
79pub struct GenericAddress {
80 pub address_space: AddressSpace,
81 pub bit_width: u8,
82 pub bit_offset: u8,
83 pub access_size: AccessSize,
84 pub address: u64,
85}
86
87impl GenericAddress {
88 pub(crate) fn from_raw(raw: RawGenericAddress) -> crate::AcpiResult<GenericAddress> {
89 let address_space = match raw.address_space {
90 0x00 => AddressSpace::SystemMemory,
91 0x01 => AddressSpace::SystemIo,
92 0x02 => AddressSpace::PciConfigSpace,
93 0x03 => AddressSpace::EmbeddedController,
94 0x04 => AddressSpace::SMBus,
95 0x05 => AddressSpace::SystemCmos,
96 0x06 => AddressSpace::PciBarTarget,
97 0x07 => AddressSpace::Ipmi,
98 0x08 => AddressSpace::GeneralIo,
99 0x09 => AddressSpace::GenericSerialBus,
100 0x0a => AddressSpace::PlatformCommunicationsChannel,
101 0x0b..=0x7e => return Err(AcpiError::InvalidGenericAddress),
102 0x7f => AddressSpace::FunctionalFixedHardware,
103 0x80..=0xbf => return Err(AcpiError::InvalidGenericAddress),
104 0xc0..=0xff => AddressSpace::OemDefined(raw.address_space),
105 };
106
107 Ok(GenericAddress {
108 address_space,
109 bit_width: raw.bit_width,
110 bit_offset: raw.bit_offset,
111 access_size: AccessSize::try_from(raw.access_size)?,
112 address: raw.address,
113 })
114 }
115}