Skip to content

Commit 708becc

Browse files
Add global image handle
1 parent bfa88e1 commit 708becc

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

src/table/boot.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,20 @@ use core::ops::{Deref, DerefMut};
1818
use core::ptr::NonNull;
1919
use core::{ptr, slice};
2020

21+
// TODO: this similar to `SyncUnsafeCell`. Once that is stabilized we
22+
// can use it instead.
23+
struct GlobalImageHandle {
24+
handle: UnsafeCell<Option<Handle>>,
25+
}
26+
27+
// Safety: reads and writes are managed via `set_image_handle` and
28+
// `BootServices::image_handle`.
29+
unsafe impl Sync for GlobalImageHandle {}
30+
31+
static IMAGE_HANDLE: GlobalImageHandle = GlobalImageHandle {
32+
handle: UnsafeCell::new(None),
33+
};
34+
2135
/// Contains pointers to all of the boot services.
2236
///
2337
/// # Accessing `BootServices`
@@ -238,6 +252,46 @@ pub struct BootServices {
238252
}
239253

240254
impl BootServices {
255+
/// Get the [`Handle`] of the currently-executing image.
256+
pub fn image_handle(&self) -> Handle {
257+
// Safety:
258+
//
259+
// `IMAGE_HANDLE` is only set by `set_image_handle`, see that
260+
// documentation for more details.
261+
//
262+
// Additionally, `image_handle` takes a `&self` which ensures it
263+
// can only be called while boot services are active. (After
264+
// exiting boot services, the image handle should not be
265+
// considered valid.)
266+
unsafe {
267+
IMAGE_HANDLE
268+
.handle
269+
.get()
270+
.read()
271+
.expect("set_image_handle has not been called")
272+
}
273+
}
274+
275+
/// Update the global image [`Handle`].
276+
///
277+
/// This is called automatically in the `main` entry point as part
278+
/// of [`uefi_macros::entry`]. It should not be called at any other
279+
/// point in time, unless the executable does not use
280+
/// [`uefi_macros::entry`], in which case it should be called once
281+
/// before calling other `BootServices` functions.
282+
///
283+
/// # Safety
284+
///
285+
/// This function should only be called as described above. The
286+
/// safety guarantees of [`BootServices::open_protocol_exclusive`]
287+
/// rely on the global image handle being correct.
288+
pub unsafe fn set_image_handle(&self, image_handle: Handle) {
289+
// As with `image_handle`, `&self` isn't actually used, but it
290+
// enforces that this function is only called while boot
291+
// services are active.
292+
IMAGE_HANDLE.handle.get().write(Some(image_handle));
293+
}
294+
241295
/// Raises a task's priority level and returns its previous level.
242296
///
243297
/// The effect of calling `raise_tpl` with a `Tpl` that is below the current

0 commit comments

Comments
 (0)