Skip to content

Commit af78c64

Browse files
committed
Add support for building std::os::uefi docs
Signed-off-by: Ayush Singh <[email protected]>
1 parent 4262963 commit af78c64

File tree

7 files changed

+38
-34
lines changed

7 files changed

+38
-34
lines changed

library/std/src/os/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ pub mod solid;
141141
#[path = "ios/mod.rs"]
142142
pub(crate) mod tvos;
143143
#[cfg(target_os = "uefi")]
144+
#[cfg(any(target_os = "uefi", doc))]
144145
pub mod uefi;
145146
#[cfg(target_os = "vita")]
146147
pub mod vita;

library/std/src/os/uefi/env.rs

+18-14
Original file line numberDiff line numberDiff line change
@@ -32,41 +32,45 @@ pub unsafe fn init_globals(handle: NonNull<c_void>, system_table: NonNull<c_void
3232
}
3333

3434
/// Get the SystemTable Pointer.
35+
/// If you want to use `BootServices` then please use [`boot_services`] as it performs some
36+
/// additional checks.
37+
///
3538
/// Note: This function panics if the System Table or Image Handle is not initialized
3639
pub fn system_table() -> NonNull<c_void> {
3740
try_system_table().unwrap()
3841
}
3942

4043
/// Get the ImageHandle Pointer.
44+
///
4145
/// Note: This function panics if the System Table or Image Handle is not initialized
4246
pub fn image_handle() -> NonNull<c_void> {
4347
try_image_handle().unwrap()
4448
}
4549

46-
/// Get the SystemTable Pointer.
47-
/// This function is mostly intended for places where panic is not an option
48-
pub(crate) fn try_system_table() -> Option<NonNull<crate::ffi::c_void>> {
49-
GLOBALS.get().map(|x| x.0)
50-
}
51-
52-
/// Get the SystemHandle Pointer.
53-
/// This function is mostly intended for places where panic is not an option
54-
pub(crate) fn try_image_handle() -> Option<NonNull<crate::ffi::c_void>> {
55-
GLOBALS.get().map(|x| x.1)
56-
}
57-
5850
/// Get the BootServices Pointer.
5951
/// This function also checks if `ExitBootServices` has already been called.
60-
pub(crate) fn boot_services() -> Option<NonNull<r_efi::efi::BootServices>> {
52+
pub fn boot_services() -> Option<NonNull<c_void>> {
6153
if BOOT_SERVICES_FLAG.get() {
6254
let system_table: NonNull<r_efi::efi::SystemTable> = try_system_table()?.cast();
6355
let boot_services = unsafe { (*system_table.as_ptr()).boot_services };
64-
NonNull::new(boot_services)
56+
NonNull::new(boot_services).map(|x| x.cast())
6557
} else {
6658
None
6759
}
6860
}
6961

62+
/// Get the SystemTable Pointer.
63+
/// This function is mostly intended for places where panic is not an option
64+
pub(crate) fn try_system_table() -> Option<NonNull<c_void>> {
65+
GLOBALS.get().map(|x| x.0)
66+
}
67+
68+
/// Get the SystemHandle Pointer.
69+
/// This function is mostly intended for places where panic is not an option
70+
pub(crate) fn try_image_handle() -> Option<NonNull<c_void>> {
71+
GLOBALS.get().map(|x| x.1)
72+
}
73+
7074
pub(crate) fn enable_boot_services() {
7175
BOOT_SERVICES_FLAG.set(true);
7276
}

library/std/src/os/uefi/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Platform-specific extensions to `std` for UEFI.
22
33
#![unstable(feature = "uefi_std", issue = "100499")]
4+
#![doc(cfg(target_os = "uefi"))]
45

56
pub mod env;
67
#[path = "../windows/ffi.rs"]

library/std/src/sys/uefi/alloc.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Global Allocator for UEFI.
22
//! Uses [r-efi-alloc](https://crates.io/crates/r-efi-alloc)
33
4-
use crate::alloc::{handle_alloc_error, GlobalAlloc, Layout, System};
4+
use crate::alloc::{GlobalAlloc, Layout, System};
55

66
const MEMORY_TYPE: u32 = r_efi::efi::LOADER_DATA;
77

@@ -13,11 +13,8 @@ unsafe impl GlobalAlloc for System {
1313
return crate::ptr::null_mut();
1414
}
1515

16-
let system_table = match crate::os::uefi::env::try_system_table() {
17-
None => return crate::ptr::null_mut(),
18-
Some(x) => x.as_ptr() as *mut _,
19-
};
20-
16+
// If boot services is valid then SystemTable is not null.
17+
let system_table = crate::os::uefi::env::system_table().as_ptr().cast();
2118
// The caller must ensure non-0 layout
2219
unsafe { r_efi_alloc::raw::alloc(system_table, layout, MEMORY_TYPE) }
2320
}
@@ -28,10 +25,8 @@ unsafe impl GlobalAlloc for System {
2825
return;
2926
}
3027

31-
let system_table = match crate::os::uefi::env::try_system_table() {
32-
None => handle_alloc_error(layout),
33-
Some(x) => x.as_ptr() as *mut _,
34-
};
28+
// If boot services is valid then SystemTable is not null.
29+
let system_table = crate::os::uefi::env::system_table().as_ptr().cast();
3530
// The caller must ensure non-0 layout
3631
unsafe { r_efi_alloc::raw::dealloc(system_table, ptr, layout) }
3732
}

library/std/src/sys/uefi/helpers.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub(crate) fn locate_handles(mut guid: Guid) -> io::Result<Vec<NonNull<crate::ff
4646
if r.is_error() { Err(status_to_io_error(r)) } else { Ok(()) }
4747
}
4848

49-
let boot_services = boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?;
49+
let boot_services = boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
5050
let mut buf_len = 0usize;
5151

5252
// This should always fail since the size of buffer is 0. This call should update the buf_len
@@ -82,7 +82,8 @@ pub(crate) fn open_protocol<T>(
8282
handle: NonNull<crate::ffi::c_void>,
8383
mut protocol_guid: Guid,
8484
) -> io::Result<NonNull<T>> {
85-
let boot_services = boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?;
85+
let boot_services: NonNull<efi::BootServices> =
86+
boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
8687
let system_handle = uefi::env::image_handle();
8788
let mut protocol: MaybeUninit<*mut T> = MaybeUninit::uninit();
8889

@@ -279,7 +280,8 @@ pub(crate) fn create_event(
279280
handler: Option<efi::EventNotify>,
280281
context: *mut crate::ffi::c_void,
281282
) -> io::Result<NonNull<crate::ffi::c_void>> {
282-
let boot_services = boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?;
283+
let boot_services: NonNull<efi::BootServices> =
284+
boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
283285
let mut exit_boot_service_event: r_efi::efi::Event = crate::ptr::null_mut();
284286
let r = unsafe {
285287
let create_event = (*boot_services.as_ptr()).create_event;
@@ -294,7 +296,8 @@ pub(crate) fn create_event(
294296
}
295297

296298
pub(crate) fn close_event(evt: NonNull<crate::ffi::c_void>) -> io::Result<()> {
297-
let boot_services = boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?;
299+
let boot_services: NonNull<efi::BootServices> =
300+
boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
298301
let r = unsafe {
299302
let close_event = (*boot_services.as_ptr()).close_event;
300303
(close_event)(evt.as_ptr())

library/std/src/sys/uefi/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ pub fn abort_internal() -> ! {
129129
if let (Some(boot_services), Some(handle)) =
130130
(uefi::env::boot_services(), uefi::env::try_image_handle())
131131
{
132+
let boot_services: NonNull<r_efi::efi::BootServices> = boot_services.cast();
132133
let _ = unsafe {
133134
((*boot_services.as_ptr()).exit)(
134135
handle.as_ptr(),

src/doc/rustc/src/platform-support/unknown-uefi.md

+5-6
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,6 @@ Then just build the project using the following command:
251251
cargo build --target x86_64-unknown-uefi -Zbuild-std=std,panic_abort
252252
```
253253

254-
### Std Requirements
255-
The current std has a few basic requirements to function:
256-
1. Memory Allocation Services (`EFI_BOOT_SERVICES.AllocatePool()` and `EFI_BOOT_SERVICES.FreePool()`) are available. This should be true in in the Driver Execution Environment or later.
257-
If the above requirement is satisfied, the Rust code will reach `main`.
258-
Now we will discuss what the different modules of std use in UEFI.
259-
260254
### Implemented features
261255
#### alloc
262256
- Implemented using `EFI_BOOT_SERVICES.AllocatePool()` and `EFI_BOOT_SERVICES.FreePool()`.
@@ -302,3 +296,8 @@ pub fn main() {
302296
assert!(!r.is_error())
303297
}
304298
```
299+
300+
### BootServices
301+
The current implementation of std make `BootServices` unavailable once `ExitBootServices` is called. Refer to [Runtime Drivers](https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/7_driver_entry_point/711_runtime_drivers) for more information regarding how to handle switching from using physical addresses to using virtual addresses.
302+
303+
Note: It should be noted that it is upto the user to drop all allocated memory before `ExitBootServices` is called.

0 commit comments

Comments
 (0)