Skip to content

Commit c6d7bd7

Browse files
committed
uefi::helper: clean up, multiple sub modules
I didn't change anything about the implementations, just moved the existing code into the corresponding modules.
1 parent 85d6efd commit c6d7bd7

File tree

7 files changed

+159
-144
lines changed

7 files changed

+159
-144
lines changed

uefi/src/allocator.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,5 +130,3 @@ unsafe impl GlobalAlloc for Allocator {
130130
(*boot_services()).free_pool(ptr).unwrap();
131131
}
132132
}
133-
134-

uefi/src/helpers/global_allocator.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
use crate::allocator::Allocator;
2+
3+
#[global_allocator]
4+
static ALLOCATOR: Allocator = Allocator;

uefi/src/helpers/logger.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,36 @@
1414
1515
use crate::proto::console::text::Output;
1616

17+
use crate::helpers::logger;
18+
use crate::prelude::{Boot, SystemTable};
1719
use core::fmt::{self, Write};
1820
use core::ptr;
1921
use core::sync::atomic::{AtomicPtr, Ordering};
2022

23+
/// Global logger object
24+
#[cfg(feature = "logger")]
25+
static LOGGER: logger::Logger = logger::Logger::new();
26+
27+
/// Set up logging
28+
///
29+
/// This is unsafe because you must arrange for the logger to be reset with
30+
/// disable() on exit from UEFI boot services.
31+
#[cfg(feature = "logger")]
32+
pub unsafe fn init(st: &mut SystemTable<Boot>) {
33+
// Connect the logger to stdout.
34+
LOGGER.set_output(st.stdout());
35+
36+
// Set the logger.
37+
log::set_logger(&LOGGER).unwrap(); // Can only fail if already initialized.
38+
39+
// Set logger max level to level specified by log features
40+
log::set_max_level(log::STATIC_MAX_LEVEL);
41+
}
42+
43+
pub fn disable() {
44+
LOGGER.disable();
45+
}
46+
2147
/// Logging implementation which writes to a UEFI output stream.
2248
///
2349
/// If this logger is used as a global logger, you must disable it using the

uefi/src/helpers/mod.rs

Lines changed: 22 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,33 @@
1212
//! **PLEASE NOTE** that these helpers are meant for the pre exit boot service
1313
//! epoch.
1414
15-
#[cfg(feature = "logger")]
16-
pub mod logger;
17-
18-
#[cfg(feature = "panic_handler")]
19-
use cfg_if::cfg_if;
15+
use crate::prelude::{Boot, SystemTable};
16+
use crate::Event;
17+
use crate::Result;
18+
use crate::StatusExt;
2019
use core::ffi::c_void;
21-
use core::fmt::Write;
22-
use core::ptr::{self, NonNull};
20+
use core::ptr;
21+
use core::ptr::NonNull;
2322
use core::sync::atomic::{AtomicPtr, Ordering};
24-
use log::Log;
25-
use uefi::allocator::Allocator;
26-
use uefi::table::boot::{EventType, Tpl};
27-
use uefi::table::{Boot, SystemTable};
28-
use uefi::{Event, Result, Status, StatusExt};
23+
#[doc(hidden)]
24+
pub use println::_print;
25+
use uefi_raw::table::boot::{EventType, Tpl};
26+
use uefi_raw::Status;
2927

30-
#[cfg_attr(feature = "global_allocator", global_allocator)]
31-
static ALLOCATOR: Allocator = Allocator;
28+
#[cfg(feature = "global_allocator")]
29+
mod global_allocator;
30+
#[cfg(feature = "logger")]
31+
mod logger;
32+
#[cfg(feature = "panic_handler")]
33+
mod panic_handler;
34+
mod println;
3235

3336
/// Reference to the system table.
3437
///
3538
/// This table is only fully safe to use until UEFI boot services have been exited.
3639
/// After that, some fields and methods are unsafe to use, see the documentation of
3740
/// UEFI's ExitBootServices entry point for more details.
38-
static SYSTEM_TABLE: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
39-
40-
/// Global logger object
41-
#[cfg(feature = "logger")]
42-
static LOGGER: logger::Logger = logger::Logger::new();
41+
static SYSTEM_TABLE: AtomicPtr<c_void> = AtomicPtr::new(core::ptr::null_mut());
4342

4443
#[must_use]
4544
fn system_table_opt() -> Option<SystemTable<Boot>> {
@@ -62,7 +61,7 @@ fn system_table_opt() -> Option<SystemTable<Boot>> {
6261
///
6362
/// The returned pointer is only valid until boot services are exited.
6463
#[must_use]
65-
pub fn system_table() -> SystemTable<Boot> {
64+
fn system_table() -> SystemTable<Boot> {
6665
system_table_opt().expect("The system table handle is not available")
6766
}
6867

@@ -87,7 +86,7 @@ pub fn init(st: &mut SystemTable<Boot>) -> Result<Option<Event>> {
8786
// Setup logging and memory allocation
8887

8988
#[cfg(feature = "logger")]
90-
init_logger(st);
89+
logger::init(st);
9190

9291
uefi::allocator::init(st);
9392

@@ -104,64 +103,6 @@ pub fn init(st: &mut SystemTable<Boot>) -> Result<Option<Event>> {
104103
}
105104
}
106105

107-
/// INTERNAL API! Helper for print macros.
108-
#[doc(hidden)]
109-
pub fn _print(args: core::fmt::Arguments) {
110-
system_table()
111-
.stdout()
112-
.write_fmt(args)
113-
.expect("Failed to write to stdout");
114-
}
115-
116-
/// Prints to the standard output.
117-
///
118-
/// # Panics
119-
/// Will panic if `SYSTEM_TABLE` is `None` (Before [init()] and after [uefi::prelude::SystemTable::exit_boot_services()]).
120-
///
121-
/// # Examples
122-
/// ```
123-
/// print!("");
124-
/// print!("Hello World\n");
125-
/// print!("Hello {}", "World");
126-
/// ```
127-
#[macro_export]
128-
macro_rules! print {
129-
($($arg:tt)*) => ($crate::helpers::_print(core::format_args!($($arg)*)));
130-
}
131-
132-
/// Prints to the standard output, with a newline.
133-
///
134-
/// # Panics
135-
/// Will panic if `SYSTEM_TABLE` is `None` (Before [init()] and after [uefi::prelude::SystemTable::exit_boot_services()]).
136-
///
137-
/// # Examples
138-
/// ```
139-
/// println!();
140-
/// println!("Hello World");
141-
/// println!("Hello {}", "World");
142-
/// ```
143-
#[macro_export]
144-
macro_rules! println {
145-
() => ($crate::print!("\n"));
146-
($($arg:tt)*) => ($crate::helpers::_print(core::format_args!("{}{}", core::format_args!($($arg)*), "\n")));
147-
}
148-
149-
/// Set up logging
150-
///
151-
/// This is unsafe because you must arrange for the logger to be reset with
152-
/// disable() on exit from UEFI boot services.
153-
#[cfg(feature = "logger")]
154-
unsafe fn init_logger(st: &mut SystemTable<Boot>) {
155-
// Connect the logger to stdout.
156-
LOGGER.set_output(st.stdout());
157-
158-
// Set the logger.
159-
log::set_logger(&LOGGER).unwrap(); // Can only fail if already initialized.
160-
161-
// Set logger max level to level specified by log features
162-
log::set_max_level(log::STATIC_MAX_LEVEL);
163-
}
164-
165106
/// Notify the utility library that boot services are not safe to call anymore
166107
/// As this is a callback, it must be `extern "efiapi"`.
167108
unsafe extern "efiapi" fn exit_boot_services(_e: Event, _ctx: Option<NonNull<c_void>>) {
@@ -174,68 +115,8 @@ unsafe extern "efiapi" fn exit_boot_services(_e: Event, _ctx: Option<NonNull<c_v
174115
SYSTEM_TABLE.store(ptr::null_mut(), Ordering::Release);
175116

176117
#[cfg(feature = "logger")]
177-
LOGGER.disable();
118+
logger::disable();
178119

120+
#[cfg(feature = "global_allocator")]
179121
uefi::allocator::exit_boot_services();
180122
}
181-
182-
#[cfg(feature = "panic_handler")]
183-
#[panic_handler]
184-
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
185-
println!("[PANIC]: {}", info);
186-
187-
// Give the user some time to read the message
188-
if let Some(st) = system_table_opt() {
189-
st.boot_services().stall(10_000_000);
190-
} else {
191-
let mut dummy = 0u64;
192-
// FIXME: May need different counter values in debug & release builds
193-
for i in 0..300_000_000 {
194-
unsafe {
195-
core::ptr::write_volatile(&mut dummy, i);
196-
}
197-
}
198-
}
199-
200-
cfg_if! {
201-
if #[cfg(all(target_arch = "x86_64", feature = "qemu"))] {
202-
// If running in QEMU, use the f4 exit port to signal the error and exit
203-
use qemu_exit::QEMUExit;
204-
let custom_exit_success = 3;
205-
let qemu_exit_handle = qemu_exit::X86::new(0xF4, custom_exit_success);
206-
qemu_exit_handle.exit_failure();
207-
} else {
208-
// If the system table is available, use UEFI's standard shutdown mechanism
209-
if let Some(st) = system_table_opt() {
210-
use uefi::table::runtime::ResetType;
211-
st.runtime_services()
212-
.reset(ResetType::SHUTDOWN, uefi::Status::ABORTED, None);
213-
}
214-
215-
// If we don't have any shutdown mechanism handy, the best we can do is loop
216-
log::error!("Could not shut down, please power off the system manually...");
217-
218-
cfg_if! {
219-
if #[cfg(target_arch = "x86_64")] {
220-
loop {
221-
unsafe {
222-
// Try to at least keep CPU from running at 100%
223-
core::arch::asm!("hlt", options(nomem, nostack));
224-
}
225-
}
226-
} else if #[cfg(target_arch = "aarch64")] {
227-
loop {
228-
unsafe {
229-
// Try to at least keep CPU from running at 100%
230-
core::arch::asm!("hlt 420", options(nomem, nostack));
231-
}
232-
}
233-
} else {
234-
loop {
235-
// just run forever dammit how do you return never anyway
236-
}
237-
}
238-
}
239-
}
240-
}
241-
}

uefi/src/helpers/panic_handler.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use crate::helpers::system_table_opt;
2+
use crate::println;
3+
use cfg_if::cfg_if;
4+
5+
#[panic_handler]
6+
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
7+
println!("[PANIC]: {}", info);
8+
9+
// Give the user some time to read the message
10+
if let Some(st) = system_table_opt() {
11+
st.boot_services().stall(10_000_000);
12+
} else {
13+
let mut dummy = 0u64;
14+
// FIXME: May need different counter values in debug & release builds
15+
for i in 0..300_000_000 {
16+
unsafe {
17+
core::ptr::write_volatile(&mut dummy, i);
18+
}
19+
}
20+
}
21+
22+
cfg_if! {
23+
if #[cfg(all(target_arch = "x86_64", feature = "qemu"))] {
24+
// If running in QEMU, use the f4 exit port to signal the error and exit
25+
use qemu_exit::QEMUExit;
26+
let custom_exit_success = 3;
27+
let qemu_exit_handle = qemu_exit::X86::new(0xF4, custom_exit_success);
28+
qemu_exit_handle.exit_failure();
29+
} else {
30+
// If the system table is available, use UEFI's standard shutdown mechanism
31+
if let Some(st) = system_table_opt() {
32+
use uefi::table::runtime::ResetType;
33+
st.runtime_services()
34+
.reset(ResetType::SHUTDOWN, uefi::Status::ABORTED, None);
35+
}
36+
37+
// If we don't have any shutdown mechanism handy, the best we can do is loop
38+
log::error!("Could not shut down, please power off the system manually...");
39+
40+
cfg_if! {
41+
if #[cfg(target_arch = "x86_64")] {
42+
loop {
43+
unsafe {
44+
// Try to at least keep CPU from running at 100%
45+
core::arch::asm!("hlt", options(nomem, nostack));
46+
}
47+
}
48+
} else if #[cfg(target_arch = "aarch64")] {
49+
loop {
50+
unsafe {
51+
// Try to at least keep CPU from running at 100%
52+
core::arch::asm!("hlt 420", options(nomem, nostack));
53+
}
54+
}
55+
} else {
56+
loop {
57+
// just run forever dammit how do you return never anyway
58+
}
59+
}
60+
}
61+
}
62+
}
63+
}

uefi/src/helpers/println.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use crate::helpers::system_table;
2+
use core::fmt::Write;
3+
4+
/// INTERNAL API! Helper for print macros.
5+
#[doc(hidden)]
6+
pub fn _print(args: core::fmt::Arguments) {
7+
system_table()
8+
.stdout()
9+
.write_fmt(args)
10+
.expect("Failed to write to stdout");
11+
}
12+
13+
/// Prints to the standard output.
14+
///
15+
/// # Panics
16+
/// Will panic if `SYSTEM_TABLE` is `None` (Before [init()] and after [uefi::prelude::SystemTable::exit_boot_services()]).
17+
///
18+
/// # Examples
19+
/// ```
20+
/// print!("");
21+
/// print!("Hello World\n");
22+
/// print!("Hello {}", "World");
23+
/// ```
24+
#[macro_export]
25+
macro_rules! print {
26+
($($arg:tt)*) => ($crate::helpers::_print(core::format_args!($($arg)*)));
27+
}
28+
29+
/// Prints to the standard output, with a newline.
30+
///
31+
/// # Panics
32+
/// Will panic if `SYSTEM_TABLE` is `None` (Before [init()] and after [uefi::prelude::SystemTable::exit_boot_services()]).
33+
///
34+
/// # Examples
35+
/// ```
36+
/// println!();
37+
/// println!("Hello World");
38+
/// println!("Hello {}", "World");
39+
/// ```
40+
#[macro_export]
41+
macro_rules! println {
42+
() => ($crate::print!("\n"));
43+
($($arg:tt)*) => ($crate::helpers::_print(core::format_args!("{}{}", core::format_args!($($arg)*), "\n")));
44+
}

uefi/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ pub mod helpers;
127127

128128
mod util;
129129

130-
131130
#[cfg(test)]
132131
// Crates that create procedural macros can't unit test the macros they export.
133132
// Therefore, we do some tests here.

0 commit comments

Comments
 (0)