Rebase to master
- Update Example - Add thread_parking to sys::uefi - Fix unsafe in unsafe errors - Improve docs - Improve os/exit - Some asserts - Switch back to atomics Signed-off-by: Ayush Singh <ayushdevel1325@gmail.com>
This commit is contained in:
parent
40c3dacc76
commit
c7e5f3ca08
10 changed files with 111 additions and 63 deletions
|
|
@ -60,13 +60,14 @@ pub(crate) fn locate_handles(mut guid: Guid) -> io::Result<Vec<NonNull<crate::ff
|
|||
}
|
||||
|
||||
// The returned buf_len is in bytes
|
||||
let mut buf: Vec<r_efi::efi::Handle> =
|
||||
Vec::with_capacity(buf_len / size_of::<r_efi::efi::Handle>());
|
||||
assert_eq!(buf_len % size_of::<r_efi::efi::Handle>(), 0);
|
||||
let num_of_handles = buf_len / size_of::<r_efi::efi::Handle>();
|
||||
let mut buf: Vec<r_efi::efi::Handle> = Vec::with_capacity(num_of_handles);
|
||||
match inner(&mut guid, boot_services, &mut buf_len, buf.as_mut_ptr()) {
|
||||
Ok(()) => {
|
||||
// This is safe because the call will succeed only if buf_len >= required length.
|
||||
// Also, on success, the `buf_len` is updated with the size of bufferv (in bytes) written
|
||||
unsafe { buf.set_len(buf_len / size_of::<r_efi::efi::Handle>()) };
|
||||
unsafe { buf.set_len(num_of_handles) };
|
||||
Ok(buf.into_iter().filter_map(|x| NonNull::new(x)).collect())
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
|
|
@ -114,16 +115,15 @@ pub(crate) fn create_event(
|
|||
) -> io::Result<NonNull<crate::ffi::c_void>> {
|
||||
let boot_services: NonNull<efi::BootServices> =
|
||||
boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
|
||||
let mut exit_boot_service_event: r_efi::efi::Event = crate::ptr::null_mut();
|
||||
let mut event: r_efi::efi::Event = crate::ptr::null_mut();
|
||||
let r = unsafe {
|
||||
let create_event = (*boot_services.as_ptr()).create_event;
|
||||
(create_event)(signal, tpl, handler, context, &mut exit_boot_service_event)
|
||||
(create_event)(signal, tpl, handler, context, &mut event)
|
||||
};
|
||||
if r.is_error() {
|
||||
Err(crate::io::Error::from_raw_os_error(r.as_usize()))
|
||||
} else {
|
||||
NonNull::new(exit_boot_service_event)
|
||||
.ok_or(const_io_error!(io::ErrorKind::Other, "null protocol"))
|
||||
NonNull::new(event).ok_or(const_io_error!(io::ErrorKind::Other, "null protocol"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
//! [`OsStr`]: crate::ffi::OsStr
|
||||
//! [`OsString`]: crate::ffi::OsString
|
||||
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
pub mod alloc;
|
||||
#[path = "../unsupported/args.rs"]
|
||||
pub mod args;
|
||||
|
|
@ -43,6 +42,8 @@ pub mod stdio;
|
|||
pub mod thread;
|
||||
#[path = "../unsupported/thread_local_key.rs"]
|
||||
pub mod thread_local_key;
|
||||
#[path = "../unsupported/thread_parking.rs"]
|
||||
pub mod thread_parking;
|
||||
#[path = "../unsupported/time.rs"]
|
||||
pub mod time;
|
||||
|
||||
|
|
@ -53,18 +54,17 @@ mod tests;
|
|||
|
||||
pub type RawOsError = usize;
|
||||
|
||||
use crate::cell::Cell;
|
||||
use crate::io as std_io;
|
||||
use crate::os::uefi;
|
||||
use crate::ptr::NonNull;
|
||||
use crate::sync::atomic::{AtomicPtr, Ordering};
|
||||
|
||||
pub mod memchr {
|
||||
pub use core::slice::memchr::{memchr, memrchr};
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static EXIT_BOOT_SERVICE_EVENT: Cell<Option<NonNull<crate::ffi::c_void>>> = Cell::new(None);
|
||||
}
|
||||
static EXIT_BOOT_SERVICE_EVENT: AtomicPtr<crate::ffi::c_void> =
|
||||
AtomicPtr::new(crate::ptr::null_mut());
|
||||
|
||||
/// # SAFETY
|
||||
/// - must be called only once during runtime initialization.
|
||||
|
|
@ -75,8 +75,6 @@ pub(crate) unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) {
|
|||
let image_handle = unsafe { NonNull::new(*argv as *mut crate::ffi::c_void).unwrap() };
|
||||
let system_table = unsafe { NonNull::new(*argv.add(1) as *mut crate::ffi::c_void).unwrap() };
|
||||
unsafe { uefi::env::init_globals(image_handle, system_table) };
|
||||
// Enable boot services once GLOBALS are initialized
|
||||
uefi::env::enable_boot_services();
|
||||
|
||||
// Register exit boot services handler
|
||||
match helpers::create_event(
|
||||
|
|
@ -86,7 +84,17 @@ pub(crate) unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) {
|
|||
crate::ptr::null_mut(),
|
||||
) {
|
||||
Ok(x) => {
|
||||
EXIT_BOOT_SERVICE_EVENT.set(Some(x));
|
||||
if EXIT_BOOT_SERVICE_EVENT
|
||||
.compare_exchange(
|
||||
crate::ptr::null_mut(),
|
||||
x.as_ptr(),
|
||||
Ordering::Release,
|
||||
Ordering::Acquire,
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
abort_internal();
|
||||
};
|
||||
}
|
||||
Err(_) => abort_internal(),
|
||||
}
|
||||
|
|
@ -96,7 +104,9 @@ pub(crate) unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) {
|
|||
/// this is not guaranteed to run, for example when the program aborts.
|
||||
/// - must be called only once during runtime cleanup.
|
||||
pub unsafe fn cleanup() {
|
||||
if let Some(exit_boot_service_event) = EXIT_BOOT_SERVICE_EVENT.take() {
|
||||
if let Some(exit_boot_service_event) =
|
||||
NonNull::new(EXIT_BOOT_SERVICE_EVENT.swap(crate::ptr::null_mut(), Ordering::Acquire))
|
||||
{
|
||||
let _ = unsafe { helpers::close_event(exit_boot_service_event) };
|
||||
}
|
||||
}
|
||||
|
|
@ -159,7 +169,9 @@ pub fn decode_error_kind(code: RawOsError) -> crate::io::ErrorKind {
|
|||
}
|
||||
|
||||
pub fn abort_internal() -> ! {
|
||||
if let Some(exit_boot_service_event) = EXIT_BOOT_SERVICE_EVENT.take() {
|
||||
if let Some(exit_boot_service_event) =
|
||||
NonNull::new(EXIT_BOOT_SERVICE_EVENT.load(Ordering::Acquire))
|
||||
{
|
||||
let _ = unsafe { helpers::close_event(exit_boot_service_event) };
|
||||
}
|
||||
|
||||
|
|
@ -226,3 +238,7 @@ fn get_random() -> Option<(u64, u64)> {
|
|||
extern "efiapi" fn exit_boot_service_handler(_e: r_efi::efi::Event, _ctx: *mut crate::ffi::c_void) {
|
||||
uefi::env::disable_boot_services();
|
||||
}
|
||||
|
||||
pub fn is_interrupted(_code: RawOsError) -> bool {
|
||||
false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,15 +4,16 @@ use crate::ffi::{OsStr, OsString};
|
|||
use crate::fmt;
|
||||
use crate::io;
|
||||
use crate::marker::PhantomData;
|
||||
use crate::os::uefi;
|
||||
use crate::path::{self, PathBuf};
|
||||
use crate::ptr::NonNull;
|
||||
use r_efi::efi::Status;
|
||||
|
||||
pub fn errno() -> RawOsError {
|
||||
0
|
||||
}
|
||||
|
||||
pub fn error_string(errno: RawOsError) -> String {
|
||||
use r_efi::efi::Status;
|
||||
|
||||
// Keep the List in Alphabetical Order
|
||||
// The Messages are taken from UEFI Specification Appendix D - Status Codes
|
||||
match r_efi::efi::Status::from_usize(errno) {
|
||||
|
|
@ -160,12 +161,7 @@ impl fmt::Display for JoinPathsError {
|
|||
}
|
||||
}
|
||||
|
||||
impl StdError for JoinPathsError {
|
||||
#[allow(deprecated)]
|
||||
fn description(&self) -> &str {
|
||||
"not supported on this platform yet"
|
||||
}
|
||||
}
|
||||
impl StdError for JoinPathsError {}
|
||||
|
||||
pub fn current_exe() -> io::Result<PathBuf> {
|
||||
unsupported()
|
||||
|
|
@ -173,6 +169,14 @@ pub fn current_exe() -> io::Result<PathBuf> {
|
|||
|
||||
pub struct Env(!);
|
||||
|
||||
impl Env {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
|
||||
pub fn str_debug(&self) -> impl fmt::Debug + '_ {
|
||||
let Self(inner) = self;
|
||||
match *inner {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for Env {
|
||||
type Item = (OsString, OsString);
|
||||
fn next(&mut self) -> Option<(OsString, OsString)> {
|
||||
|
|
@ -180,6 +184,13 @@ impl Iterator for Env {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Env {
|
||||
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let Self(inner) = self;
|
||||
match *inner {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn env() -> Env {
|
||||
panic!("not supported on this platform")
|
||||
}
|
||||
|
|
@ -204,7 +215,20 @@ pub fn home_dir() -> Option<PathBuf> {
|
|||
None
|
||||
}
|
||||
|
||||
pub fn exit(_code: i32) -> ! {
|
||||
pub fn exit(code: i32) -> ! {
|
||||
if let (Some(boot_services), Some(handle)) =
|
||||
(uefi::env::boot_services(), uefi::env::try_image_handle())
|
||||
{
|
||||
let boot_services: NonNull<r_efi::efi::BootServices> = boot_services.cast();
|
||||
let _ = unsafe {
|
||||
((*boot_services.as_ptr()).exit)(
|
||||
handle.as_ptr(),
|
||||
Status::from_usize(code as usize),
|
||||
0,
|
||||
crate::ptr::null_mut(),
|
||||
)
|
||||
};
|
||||
}
|
||||
crate::intrinsics::abort()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue