Skip to content

Commit b315e95

Browse files
authored
Merge branch 'rust-osdev:main' into main
2 parents 912e9cb + da9b3b1 commit b315e95

File tree

3 files changed

+94
-56
lines changed

3 files changed

+94
-56
lines changed

acpi/src/lib.rs

Lines changed: 63 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,43 @@ pub enum AcpiError {
149149
AllocError,
150150
}
151151

152+
macro_rules! read_root_table {
153+
($signature_name:ident, $address:ident, $acpi_handler:ident) => {{
154+
#[repr(transparent)]
155+
struct RootTable {
156+
header: SdtHeader,
157+
}
158+
159+
unsafe impl AcpiTable for RootTable {
160+
const SIGNATURE: Signature = Signature::$signature_name;
161+
162+
fn header(&self) -> &SdtHeader {
163+
&self.header
164+
}
165+
}
166+
167+
// Map and validate root table
168+
// SAFETY: Addresses from a validated RSDP are also guaranteed to be valid.
169+
let table_mapping = unsafe { read_table::<_, RootTable>($acpi_handler.clone(), $address) }?;
170+
171+
// Convert `table_mapping` to header mapping for storage
172+
// Avoid requesting table unmap twice (from both original and converted `table_mapping`s)
173+
let table_mapping = mem::ManuallyDrop::new(table_mapping);
174+
// SAFETY: `SdtHeader` is equivalent to `Sdt` memory-wise
175+
let table_mapping = unsafe {
176+
PhysicalMapping::new(
177+
table_mapping.physical_start(),
178+
table_mapping.virtual_start().cast::<SdtHeader>(),
179+
table_mapping.region_length(),
180+
table_mapping.mapped_length(),
181+
$acpi_handler.clone(),
182+
)
183+
};
184+
185+
table_mapping
186+
}};
187+
}
188+
152189
/// Type capable of enumerating the existing ACPI tables on the system.
153190
///
154191
///
@@ -199,61 +236,44 @@ where
199236
///
200237
/// ### Safety: Caller must ensure that the provided mapping is a fully validated RSDP.
201238
pub unsafe fn from_validated_rsdp(handler: H, rsdp_mapping: PhysicalMapping<H, Rsdp>) -> AcpiResult<Self> {
202-
macro_rules! read_root_table {
203-
($signature_name:ident, $address_getter:ident) => {{
204-
#[repr(transparent)]
205-
struct RootTable {
206-
header: SdtHeader,
207-
}
208-
209-
unsafe impl AcpiTable for RootTable {
210-
const SIGNATURE: Signature = Signature::$signature_name;
211-
212-
fn header(&self) -> &SdtHeader {
213-
&self.header
214-
}
215-
}
239+
let revision = rsdp_mapping.revision();
240+
let root_table_mapping = if revision == 0 {
241+
/*
242+
* We're running on ACPI Version 1.0. We should use the 32-bit RSDT address.
243+
*/
244+
let table_phys_start = rsdp_mapping.rsdt_address() as usize;
245+
drop(rsdp_mapping);
246+
read_root_table!(RSDT, table_phys_start, handler)
247+
} else {
248+
/*
249+
* We're running on ACPI Version 2.0+. We should use the 64-bit XSDT address, truncated
250+
* to 32 bits on x86.
251+
*/
252+
let table_phys_start = rsdp_mapping.xsdt_address() as usize;
253+
drop(rsdp_mapping);
254+
read_root_table!(XSDT, table_phys_start, handler)
255+
};
216256

217-
// Unmap RSDP as soon as possible
218-
let table_phys_start = rsdp_mapping.$address_getter() as usize;
219-
drop(rsdp_mapping);
220-
221-
// Map and validate root table
222-
// SAFETY: Addresses from a validated RSDP are also guaranteed to be valid.
223-
let table_mapping = unsafe { read_table::<_, RootTable>(handler.clone(), table_phys_start) }?;
224-
225-
// Convert `table_mapping` to header mapping for storage
226-
// Avoid requesting table unmap twice (from both original and converted `table_mapping`s)
227-
let table_mapping = mem::ManuallyDrop::new(table_mapping);
228-
// SAFETY: `SdtHeader` is equivalent to `Sdt` memory-wise
229-
let table_mapping = unsafe {
230-
PhysicalMapping::new(
231-
table_mapping.physical_start(),
232-
table_mapping.virtual_start().cast::<SdtHeader>(),
233-
table_mapping.region_length(),
234-
table_mapping.mapped_length(),
235-
handler.clone(),
236-
)
237-
};
238-
239-
table_mapping
240-
}};
241-
}
257+
Ok(Self { mapping: root_table_mapping, revision, handler })
258+
}
242259

243-
let revision = rsdp_mapping.revision();
260+
/// Create an `AcpiTables` if you have the physical address of the RSDT/XSDT.
261+
///
262+
/// ### Safety: Caller must ensure the provided address is valid RSDT/XSDT address.
263+
pub unsafe fn from_rsdt(handler: H, revision: u8, address: usize) -> AcpiResult<Self> {
244264
let root_table_mapping = if revision == 0 {
245265
/*
246266
* We're running on ACPI Version 1.0. We should use the 32-bit RSDT address.
247267
*/
248268

249-
read_root_table!(RSDT, rsdt_address)
269+
read_root_table!(RSDT, address, handler)
250270
} else {
251271
/*
252272
* We're running on ACPI Version 2.0+. We should use the 64-bit XSDT address, truncated
253273
* to 32 bits on x86.
254274
*/
255275

256-
read_root_table!(XSDT, xsdt_address)
276+
read_root_table!(XSDT, address, handler)
257277
};
258278

259279
Ok(Self { mapping: root_table_mapping, revision, handler })
@@ -490,9 +510,7 @@ where
490510
log::warn!("Found invalid SDT at physical address {:p}: {:?}", table_phys_ptr, r);
491511
continue;
492512
}
493-
let result = header_mapping.clone();
494-
drop(header_mapping);
495-
return Some(result);
513+
return Some(*header_mapping);
496514
}
497515
}
498516
}

acpi/src/madt.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,8 @@ impl Madt {
293293
local_apic_address = entry.local_apic_address;
294294
}
295295

296+
MadtEntry::MultiprocessorWakeup(_) => {}
297+
296298
_ => {
297299
return Err(AcpiError::InvalidMadt(MadtError::UnexpectedEntry));
298300
}

aml_tester/src/main.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
use aml::{AmlContext, DebugVerbosity};
1313
use clap::{Arg, ArgAction, ArgGroup};
1414
use std::{
15-
collections::HashSet,
15+
cell::RefCell,
16+
collections::{HashMap, HashSet},
1617
ffi::OsStr,
1718
fs::{self, File},
1819
io::{Read, Write},
@@ -30,19 +31,23 @@ enum CompilationOutcome {
3031
}
3132

3233
fn main() -> std::io::Result<()> {
33-
log::set_logger(&Logger).unwrap();
34-
log::set_max_level(log::LevelFilter::Trace);
35-
36-
let matches = clap::Command::new("aml_tester")
34+
let mut cmd = clap::Command::new("aml_tester")
3735
.version("v0.1.0")
3836
.author("Isaac Woods")
3937
.about("Compiles and tests ASL files")
4038
.arg(Arg::new("no_compile").long("no-compile").action(ArgAction::SetTrue).help("Don't compile asl to aml"))
4139
.arg(Arg::new("reset").long("reset").action(ArgAction::SetTrue).help("Clear namespace after each file"))
4240
.arg(Arg::new("path").short('p').long("path").required(false).action(ArgAction::Set).value_name("DIR"))
4341
.arg(Arg::new("files").action(ArgAction::Append).value_name("FILE.{asl,aml}"))
44-
.group(ArgGroup::new("files_list").args(["path", "files"]).required(true))
45-
.get_matches();
42+
.group(ArgGroup::new("files_list").args(["path", "files"]).required(true));
43+
if std::env::args().count() <= 1 {
44+
cmd.print_help()?;
45+
return Ok(());
46+
}
47+
log::set_logger(&Logger).unwrap();
48+
log::set_max_level(log::LevelFilter::Trace);
49+
50+
let matches = cmd.get_matches();
4651

4752
// Get an initial list of files - may not work correctly on non-UTF8 OsString
4853
let files: Vec<String> = if matches.contains_id("path") {
@@ -110,17 +115,23 @@ fn main() -> std::io::Result<()> {
110115

111116
// Make a list of the files we have processed, and skip them if we see them again
112117
let mut dedup_list: HashSet<PathBuf> = HashSet::new();
113-
118+
let summaries: RefCell<HashSet<(PathBuf, &str)>> = RefCell::new(HashSet::new());
114119
// Filter down to the final list of AML files
115120
let aml_files = compiled_files
116121
.iter()
117122
.filter_map(|outcome| match outcome {
118123
CompilationOutcome::IsAml(path) => Some(path.clone()),
119124
CompilationOutcome::Newer(path) => Some(path.clone()),
120125
CompilationOutcome::Succeeded(path) => Some(path.clone()),
121-
CompilationOutcome::Ignored | CompilationOutcome::Failed(_) | CompilationOutcome::NotCompiled(_) => {
126+
CompilationOutcome::Failed(path) => {
127+
summaries.borrow_mut().insert((path.clone(), "COMPILE FAILED"));
122128
None
123129
}
130+
CompilationOutcome::NotCompiled(path) => {
131+
summaries.borrow_mut().insert((path.clone(), "NotCompiled"));
132+
None
133+
}
134+
CompilationOutcome::Ignored => None,
124135
})
125136
.filter(|path| {
126137
if dedup_list.contains(path) {
@@ -138,7 +149,7 @@ fn main() -> std::io::Result<()> {
138149
print!("Testing AML file: {:?}... ", file_entry);
139150
std::io::stdout().flush().unwrap();
140151

141-
let mut file = File::open(file_entry).unwrap();
152+
let mut file = File::open(&file_entry).unwrap();
142153
let mut contents = Vec::new();
143154
file.read_to_end(&mut contents).unwrap();
144155

@@ -152,18 +163,25 @@ fn main() -> std::io::Result<()> {
152163
Ok(()) => {
153164
println!("{}OK{}", termion::color::Fg(termion::color::Green), termion::style::Reset);
154165
println!("Namespace: {:#?}", context.namespace);
166+
summaries.borrow_mut().insert((file_entry, "PASS"));
155167
(passed + 1, failed)
156168
}
157169

158170
Err(err) => {
159171
println!("{}Failed ({:?}){}", termion::color::Fg(termion::color::Red), err, termion::style::Reset);
160172
println!("Namespace: {:#?}", context.namespace);
173+
summaries.borrow_mut().insert((file_entry, "PARSE FAIL"));
161174
(passed, failed + 1)
162175
}
163176
}
164177
});
165178

166-
println!("Test results: {} passed, {} failed", passed, failed);
179+
// Print summaries
180+
println!("Summary:");
181+
for (file, status) in summaries.borrow().iter() {
182+
println!("{:<50}: {}", file.to_str().unwrap(), status);
183+
}
184+
println!("\nTest results:\n\tpassed:{}\n\tfailed:{}", passed, failed);
167185
Ok(())
168186
}
169187

0 commit comments

Comments
 (0)