Add efi::Result and Termination
This commit is contained in:
+38
-1
@@ -3,7 +3,9 @@ use core::ffi::c_void;
|
||||
pub type Handle = *mut c_void;
|
||||
pub type Event = *mut c_void;
|
||||
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
pub type Result<T> = core::result::Result<T, Status>;
|
||||
|
||||
#[derive(Eq, PartialEq, Debug, Clone, Copy)]
|
||||
pub enum Status {
|
||||
Success,
|
||||
Err,
|
||||
@@ -12,6 +14,10 @@ pub enum Status {
|
||||
NotReady
|
||||
}
|
||||
|
||||
pub trait Termination {
|
||||
fn to_efi(&self) -> u64;
|
||||
}
|
||||
|
||||
const EFI_SUCCESS: u64 = 0;
|
||||
const EFI_ERR: u64 = 0x8000000000000000;
|
||||
const EFI_INVALID_PARAMETER: u64 = EFI_ERR | 0x02;
|
||||
@@ -38,6 +44,37 @@ impl Status {
|
||||
_ => Status::Err
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_result(&self) -> Result<()> {
|
||||
match self {
|
||||
Status::Success => Ok(()),
|
||||
err => Err(*err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Termination for () {
|
||||
fn to_efi(&self) -> u64 {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
impl Termination for ! {
|
||||
fn to_efi(&self) -> u64 {
|
||||
return EFI_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Termination for Result<T> {
|
||||
fn to_efi(&self) -> u64 {
|
||||
match self {
|
||||
Ok(_) => EFI_SUCCESS,
|
||||
Err(err) => {
|
||||
assert!(*err != Status::Success);
|
||||
err.to_num()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Guid {
|
||||
|
||||
@@ -66,7 +66,7 @@ pub struct BootServices {
|
||||
}
|
||||
|
||||
impl BootServices {
|
||||
pub fn get_memory_map(&self, out: &mut MemoryMap) -> Status {
|
||||
pub fn get_memory_map(&self, out: &mut MemoryMap) -> Result<(), Status> {
|
||||
out.size = out.storage_ref.len();
|
||||
return Status::from_num(unsafe {
|
||||
let mut trash: u32 = 0;
|
||||
@@ -77,11 +77,11 @@ impl BootServices {
|
||||
(&mut out.descriptor_size) as *mut usize,
|
||||
(&mut trash) as *mut u32
|
||||
)
|
||||
});
|
||||
}).to_result();
|
||||
}
|
||||
|
||||
// Unlike EFI's variant, just for one event
|
||||
pub fn wait_for_event(&self, ev: Event) -> Status {
|
||||
pub fn wait_for_event(&self, ev: Event) -> Result<(), Status> {
|
||||
let mut index = 0usize;
|
||||
return Status::from_num(unsafe {
|
||||
(self.wait_for_event)(
|
||||
@@ -89,7 +89,7 @@ impl BootServices {
|
||||
&ev,
|
||||
&mut index
|
||||
)
|
||||
});
|
||||
}).to_result();
|
||||
}
|
||||
|
||||
pub fn exit(&self, status: Status) -> ! {
|
||||
@@ -102,10 +102,10 @@ impl BootServices {
|
||||
unsafe { (self.stall)(micros) }
|
||||
}
|
||||
|
||||
pub fn exit_boot_services(&self, map_key: usize) -> Status {
|
||||
pub fn exit_boot_services(&self, map_key: usize) -> Result<(), Status> {
|
||||
return Status::from_num(unsafe {
|
||||
(self.exit_boot_services)(super::image_handle(), map_key)
|
||||
});
|
||||
}).to_result();
|
||||
}
|
||||
|
||||
pub fn locate_protocol<T: Protocol>(&self) -> Result<&'static mut T, Status> {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#![feature(never_type)]
|
||||
#![no_std]
|
||||
|
||||
use core::ffi::c_void;
|
||||
|
||||
@@ -16,17 +16,14 @@ pub struct SimpleTextInputProtocol {
|
||||
}
|
||||
|
||||
impl SimpleTextInputProtocol {
|
||||
pub fn reset(&mut self, extended_verification: bool) -> Status {
|
||||
pub fn reset(&mut self, extended_verification: bool) -> Result<(), Status> {
|
||||
return Status::from_num(unsafe {
|
||||
(self.reset)(self as *mut SimpleTextInputProtocol, extended_verification)
|
||||
});
|
||||
}).to_result();
|
||||
}
|
||||
|
||||
pub fn read_key_blocking(&mut self) -> Result<InputKey, Status> {
|
||||
let res = system_table().boot_services.wait_for_event(self.wait_for_key);
|
||||
if res != Status::Success {
|
||||
return Err(res);
|
||||
}
|
||||
let res = system_table().boot_services.wait_for_event(self.wait_for_key)?;
|
||||
loop {
|
||||
let res = self.read_key_stroke();
|
||||
match res {
|
||||
|
||||
+6
-15
@@ -10,32 +10,23 @@ use efi::{Status, Handle, SystemTable, system_table};
|
||||
#[macro_use]
|
||||
mod println;
|
||||
|
||||
fn main() -> Status {
|
||||
fn main() -> efi::Result<()> {
|
||||
let mut desc_array = [0u8; 4096];
|
||||
let mut mmap = efi::MemoryMap::new(&mut desc_array);
|
||||
let bs = &system_table().boot_services;
|
||||
let rs = &system_table().runtime_services;
|
||||
|
||||
if bs.get_memory_map(&mut mmap) != Status::Success {
|
||||
println!("Failed to get memory map");
|
||||
return Status::Err;
|
||||
}
|
||||
bs.get_memory_map(&mut mmap)?;
|
||||
|
||||
system_table().con_in.reset(false);
|
||||
while let Ok(key) = system_table().con_in.read_key_blocking() {
|
||||
println!("Got key: {:?}", key);
|
||||
if key.scan_code == 23 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Status::Success;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn efi_main(ih: Handle, st: *mut SystemTable) -> u64 {
|
||||
efi::init(ih, st);
|
||||
return main().to_num();
|
||||
let ret = efi::Termination::to_efi(&main());
|
||||
println!("result -> {}", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
Reference in New Issue
Block a user