Add efi::Result and Termination

This commit is contained in:
Mark
2020-09-14 23:58:50 +03:00
parent 841bc67123
commit 0f5746dcc1
5 changed files with 54 additions and 28 deletions
+38 -1
View File
@@ -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 {
+6 -6
View File
@@ -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
View File
@@ -1,3 +1,4 @@
#![feature(never_type)]
#![no_std]
use core::ffi::c_void;
+3 -6
View File
@@ -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
View File
@@ -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;