Skip to content

Commit 108fe8e

Browse files
author
Sherry Fan
committed
ACPI: Improvements from PR suggestions
1 parent f85416c commit 108fe8e

File tree

12 files changed

+763
-608
lines changed

12 files changed

+763
-608
lines changed

components/patina_acpi/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ installed by the Patina ACPI component.
5252
The Patina ACPI component supports ACPI 2.0+ only, with one important caveat.
5353

5454
In order to be compatible with current Windows OS code, the FACS is produced within a 32-bit address range to prevent
55-
overflow in the kernel. This supports both ACPI 1.0 and ACPI 2.0, as both the `firmware_ctrl` (32-bit) and
55+
overflow in the kernel. This supports both ACPI 1.0 and ACPI 2.0, as both the `firmware_ctrl` (32-bit) and
5656
`x_firmware_ctrl` (64-bit) fields in the FADT are set to the address of the FACS. Code that utilizes the FACS can choose
5757
to read either field.
5858

@@ -122,7 +122,7 @@ let my_acpi_table: MyAcpiTable = acpi_table_service.get_acpi_table::<MyAcpiTable
122122
```
123123

124124
Both `get_acpi_table` and `get_acpi_table_unchecked` require the caller to provide the expected type of the table.
125-
`get_acpi_table` will verify that the type matches the original type at installation, while `get_acpi_table_unchecked`
125+
`get_acpi_table` will verify that the type matches the original type at installation, while `get_acpi_table_unchecked`
126126
does not. **Only use `get_acpi_table_unchecked` if you are attempting to cast a table to a known safe type that matches
127127
the structure of the table.**
128128

components/patina_acpi/src/acpi.rs

Lines changed: 382 additions & 347 deletions
Large diffs are not rendered by default.

components/patina_acpi/src/acpi_protocol.rs

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//!
66
//! Copyright (C) Microsoft Corporation.
77
//!
8-
//! SPDX-License-Identifier: BSD-2-Clause-Patent
8+
//! SPDX-License-Identifier: Apache-2.0
99
//!
1010
1111
use crate::{
@@ -18,7 +18,7 @@ use patina::uefi_protocol::ProtocolInterface;
1818
use r_efi::efi;
1919

2020
use crate::{
21-
acpi::ACPI_TABLE_INFO,
21+
acpi::STANDARD_ACPI_PROVIDER,
2222
service::{AcpiNotifyFn, AcpiProvider, TableKey},
2323
};
2424

@@ -81,57 +81,47 @@ impl AcpiTableProtocol {
8181

8282
// The size of the allocated table buffer must be large enough to store the whole table.
8383
// SAFETY: `acpi_table_buffer` is checked non-null and large enough to read an AcpiTableHeader.
84-
let tbl_length = unsafe { (*(acpi_table_buffer as *const AcpiTableHeader)).length } as usize;
84+
let table_header = unsafe { (*(acpi_table_buffer as *const AcpiTableHeader)).clone() };
85+
let tbl_length = table_header.length as usize;
8586
if tbl_length != acpi_table_buffer_size {
8687
return efi::Status::INVALID_PARAMETER;
8788
}
8889

8990
// The size of the allocated table buffer must be large enough to store the table, for known table types.
90-
// SAFETY: `acpi_table_buffer` is checked non-null and large enough to read an AcpiTableHeader.
91-
let signature = unsafe { (*(acpi_table_buffer as *const AcpiTableHeader)).signature };
91+
let signature = table_header.signature;
9292
let min_size = signature::acpi_table_min_size(signature);
9393
if tbl_length < min_size {
9494
return efi::Status::INVALID_PARAMETER;
9595
}
9696

97-
// SAFETY: acpi_table_buffer is checked non-null and large enough to read an AcpiTableHeader.
98-
if let Some(global_mm) = ACPI_TABLE_INFO.memory_manager.get() {
97+
if let Some(global_mm) = STANDARD_ACPI_PROVIDER.memory_manager.get() {
9998
// SAFETY: `acpi_table_buffer` has been validated as non-null and of sufficient size above.
10099
let acpi_table =
101100
unsafe { AcpiTable::new_from_ptr(acpi_table_buffer as *const AcpiTableHeader, None, global_mm) };
102101

103102
if let Ok(table) = acpi_table {
104-
let install_result = match table.signature() {
105-
signature::FACS => ACPI_TABLE_INFO.install_facs(table),
106-
signature::FADT => ACPI_TABLE_INFO.install_fadt(table),
107-
signature::DSDT => ACPI_TABLE_INFO.install_dsdt(table),
108-
_ => ACPI_TABLE_INFO.install_standard_table(table),
109-
};
103+
let signature = table.signature();
104+
let install_result = STANDARD_ACPI_PROVIDER.install_acpi_table(table);
110105

111106
match install_result {
112107
Ok(key) => {
113108
// SAFETY: The caller must ensure the buffer passed in for the key is appropriately sized and non-null.
114109
unsafe { *table_key = key.0 };
110+
log::trace!(
111+
"ACPI protocol: Successfully installed table with signature: 0x{:08X}, key: {}",
112+
signature,
113+
key.0
114+
);
115115
}
116116
Err(e) => {
117-
log::info!("Protocol install failed: {:?} for table with signature {}", e, table.signature());
117+
log::error!(
118+
"ACPI protocol: Install failed with error {:?} for table with signature: 0x{:08X}",
119+
e,
120+
signature,
121+
);
118122
return e.into();
119123
}
120124
}
121-
122-
let publish_result = ACPI_TABLE_INFO.publish_tables();
123-
if let Err(e) = publish_result {
124-
log::info!("Failed to publish ACPI tables: {:?}", e);
125-
return e.into();
126-
}
127-
128-
// SAFETY: `table_key` has been checked non-null above.
129-
let notify_result = ACPI_TABLE_INFO.notify_acpi_list(TableKey(unsafe { *table_key }));
130-
if let Err(e) = notify_result {
131-
log::info!("Failed to notify ACPI list: {:?}", e);
132-
return e.into();
133-
}
134-
135125
efi::Status::SUCCESS
136126
} else {
137127
efi::Status::OUT_OF_RESOURCES
@@ -153,9 +143,15 @@ impl AcpiTableProtocol {
153143
/// Returns [`INVALID_PARAMETER`](r_efi::efi::Status::INVALID_PARAMETER) if the table key does not correspond to an installed table.
154144
/// Returns [`OUT_OF_RESOURCES`](r_efi::efi::Status::OUT_OF_RESOURCES) if memory operations fail.
155145
extern "efiapi" fn uninstall_acpi_table_ext(_protocol: *const AcpiTableProtocol, table_key: usize) -> efi::Status {
156-
match ACPI_TABLE_INFO.uninstall_acpi_table(TableKey(table_key)) {
157-
Ok(_) => efi::Status::SUCCESS,
158-
Err(e) => e.into(),
146+
match STANDARD_ACPI_PROVIDER.uninstall_acpi_table(TableKey(table_key)) {
147+
Ok(_) => {
148+
log::trace!("ACPI protocol: Successfully uninstalled table with key: {}", table_key);
149+
efi::Status::SUCCESS
150+
}
151+
Err(e) => {
152+
log::error!("ACPI protocol: Failed to uninstall table with key: {} - error: {:?}", table_key, e);
153+
e.into()
154+
}
159155
}
160156
}
161157
}
@@ -207,23 +203,27 @@ impl AcpiGetProtocol {
207203
return efi::Status::INVALID_PARAMETER;
208204
}
209205

210-
match ACPI_TABLE_INFO.get_table_at_idx(index) {
211-
Ok(table_info) => {
206+
match STANDARD_ACPI_PROVIDER.get_table_at_idx(index) {
207+
Ok((key_at_idx, table_at_idx)) => {
212208
// SAFETY: table_info is valid and output pointers have been checked for null
213209
// We only support ACPI versions >= 2.0
214-
let (key_at_idx, table_at_idx) = table_info;
215210
// SAFETY: We check that `version` is non-null above.
216211
unsafe { *version = ACPI_VERSIONS_GTE_2 };
217212
// SAFETY: We check that `table_key` is non-null above.
218213
unsafe { *table_key = key_at_idx.0 };
219214

220-
let sdt_ptr = table_at_idx.as_mut_ptr();
221215
// SAFETY: We check that `table` is non-null above.
222-
unsafe { *table = sdt_ptr };
216+
unsafe { *table = table_at_idx.as_mut_ptr() };
217+
log::trace!(
218+
"ACPI protocol: Successfully retrieved table at index {} with key: {} and signature: 0x{:08X}",
219+
index,
220+
key_at_idx.0,
221+
table_at_idx.signature()
222+
);
223223
efi::Status::SUCCESS
224224
}
225225
Err(e) => {
226-
log::info!("get_acpi_table from ACPI protocol failed with error {:?}", e);
226+
log::error!("ACPI protocol: Failed to get table at index {} with error: {:?}", index, e);
227227
e.into()
228228
}
229229
}
@@ -250,7 +250,7 @@ impl AcpiGetProtocol {
250250
}
251251
};
252252

253-
match ACPI_TABLE_INFO.register_notify(register, rust_fn) {
253+
match STANDARD_ACPI_PROVIDER.register_notify(register, rust_fn) {
254254
Ok(_) => efi::Status::SUCCESS,
255255
Err(err) => err.into(),
256256
}

0 commit comments

Comments
 (0)