Skip to content
This repository was archived by the owner on Sep 22, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ fn status_str() {
}

/// Type for EFI_MEMORY_TYPE
#[derive(PartialEq, PartialOrd, Debug)]
#[derive(PartialEq, PartialOrd, Clone, Debug)]
#[repr(C)]
pub enum MemoryType {
Reserved = 0,
Expand Down Expand Up @@ -219,3 +219,14 @@ pub struct TimeCapabilities {
sets_to_zero: bool,
}

pub type PhysicalAddress = u64;
pub type VirtualAddress = u64;

#[repr(C)]
pub struct MemoryDescriptor {
memory_type: MemoryType,
physical_start: PhysicalAddress,
virtual_start: VirtualAddress,
number_of_pages: u64,
attribute: u64
}
58 changes: 47 additions & 11 deletions src/bootservices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use core::ptr;
use core::mem;

use void::{NotYetDef, CVoid};
use base::{Event, Handle, Handles, MemoryType, Status};
use base::{Event, Handle, Handles, MemoryType, MemoryDescriptor, Status};
use protocols;
use guid;
use table;

Expand All @@ -21,8 +22,8 @@ pub struct BootServices {
restore_tpl: *const NotYetDef,
allocate_pages: *const NotYetDef,
free_pages: *const NotYetDef,
get_memory_map: *const NotYetDef,
allocate_pool: unsafe extern "win64" fn(pool_type: MemoryType, size: usize, out: *mut *mut u8) -> Status,
get_memory_map: unsafe extern "win64" fn(memory_map_size: *mut usize, memory_map: *mut MemoryDescriptor, *mut usize, descriptor_size: *mut usize, descriptor_version: *mut u32) -> Status,
allocate_pool: unsafe extern "win64" fn(pool_type: MemoryType, size: usize, out: &mut *mut CVoid) -> Status,
free_pool: unsafe extern "win64" fn(*mut CVoid),
create_event: *const NotYetDef,
set_timer: *const NotYetDef,
Expand All @@ -34,7 +35,7 @@ pub struct BootServices {
install_protocol_interface: *const NotYetDef,
reinstall_protocol_interface: *const NotYetDef,
uninstall_protocol_interface: *const NotYetDef,
handle_protocol: unsafe extern "win64" fn(Handle, &guid::Guid, &mut *mut CVoid) -> Status,
handle_protocol: unsafe extern "win64" fn(Handle, *const guid::Guid, &mut *mut CVoid) -> Status,
__reserved: *const NotYetDef,
register_protocol_notify: *const NotYetDef,
locate_handle: *const NotYetDef,
Expand All @@ -44,17 +45,17 @@ pub struct BootServices {
start_image: *const NotYetDef,
exit: *const NotYetDef,
unload_image: *const NotYetDef,
exit_boot_services: *const NotYetDef,
exit_boot_services: unsafe extern "win64" fn(image_handle: Handle, map_key: usize) -> Status,
get_next_monotonic_count: *const NotYetDef,
stall: unsafe extern "win64" fn(usize) -> Status,
set_watchdog_timer: unsafe extern "win64" fn(timeout: usize, code: u64, data_size: usize, data: *const u16) -> Status,
connect_controller: *const NotYetDef,
disconnect_controller: *const NotYetDef,
open_protocol: *const NotYetDef,
close_protocol: unsafe extern "win64" fn(handle: Handle, protocol: &guid::Guid, agent_handle: Handle, controller_handle: Handle) -> Status,
close_protocol: unsafe extern "win64" fn(handle: Handle, protocol: *const guid::Guid, agent_handle: Handle, controller_handle: Handle) -> Status,
open_protocol_information: *const NotYetDef,
protocols_per_handle: *const NotYetDef,
locate_handle_buffer: unsafe extern "win64" fn(search_type: LocateSearchType, protocol: &guid::Guid, search_key: *const CVoid, nhandles: *mut usize, handles: *mut *mut CVoid) -> Status,
locate_handle_buffer: unsafe extern "win64" fn(search_type: LocateSearchType, protocol: *const guid::Guid, search_key: *const CVoid, nhandles: *mut usize, handles: *mut *mut CVoid) -> Status,
locate_protocol: *const NotYetDef,
install_multiple_protocol_interfaces: *const NotYetDef,
uninstall_multiple_protocol_interfaces: *const NotYetDef,
Expand All @@ -65,6 +66,35 @@ pub struct BootServices {
}

impl BootServices {
// return (memory_map, memory_map_size, map_key, descriptor_size, descriptor_version)
pub unsafe fn get_memory_map(&self, memory_map_size: &mut usize)
-> Result<(&'static MemoryDescriptor, usize, usize, usize, u32), Status> {
let ptr = try!(self.allocate_pool::<MemoryDescriptor>(*memory_map_size));
let mut map_key: usize = 0;
let mut descriptor_size: usize = 0;
let mut descriptor_version: u32 = 0;

let status = (self.get_memory_map)(memory_map_size, ptr, &mut map_key,
&mut descriptor_size, &mut descriptor_version);
if status == Status::Success {
let r = mem::transmute::<*mut MemoryDescriptor, &'static MemoryDescriptor>(ptr);
Ok((r, map_key, *memory_map_size, descriptor_size,descriptor_version))

} else {
self.free_pool::<MemoryDescriptor>(ptr);
Err(status)
}
}

pub fn allocate_pool<T>(&self, buffer_size: usize) -> Result<*mut T, Status>{
let mut ptr: *mut CVoid = 0 as *mut CVoid;
let status = unsafe { (self.allocate_pool)(::get_pool_allocation_type(), buffer_size, &mut ptr) };
if status != Status::Success {
return Err(status);
}
Ok(ptr as *mut T)
}

pub fn free_pool<T>(&self, p: *const T) {
unsafe {
(self.free_pool)(p as *mut CVoid);
Expand All @@ -88,13 +118,13 @@ impl BootServices {
Ok(index)
}

pub fn handle_protocol<T: ::Protocol>(&self, handle: Handle) -> Result<&'static T, Status> {
pub fn handle_protocol<T: protocols::Protocol>(&self, handle: &Handle) -> Result<&'static T, Status> {
let mut ptr : *mut CVoid = 0 as *mut CVoid;
let guid = T::guid();


unsafe {
let status = (self.handle_protocol)(handle, guid, &mut ptr);
let status = (self.handle_protocol)(*handle, guid, &mut ptr);
if status != Status::Success {
return Err(status);
}
Expand All @@ -105,7 +135,7 @@ impl BootServices {
}

// TODO: for the love of types, fix me
pub fn close_protocol<T: ::Protocol>(&self, handle: Handle, agent_handle: Handle, controller_handle: Handle) -> Status {
pub fn close_protocol<T: protocols::Protocol>(&self, handle: Handle, agent_handle: Handle, controller_handle: Handle) -> Status {
let guid = T::guid();

unsafe {
Expand All @@ -114,7 +144,7 @@ impl BootServices {
}

/// Retrives a slice of handles by protocol GUID.
pub fn locate_handle_by_protocol<T: ::Protocol>(&self) -> Result<Handles, Status> {
pub fn locate_handle_by_protocol<T: protocols::Protocol>(&self) -> Result<Handles, Status> {
let mut nhandles : usize = 0;
let mut handles : *mut CVoid = ptr::null_mut();
let guid = T::guid();
Expand All @@ -128,6 +158,12 @@ impl BootServices {
return Ok(Handles::new(handles as *mut Handle, nhandles));
}

pub fn exit_boot_services(&self, image_handle: &Handle, map_key: &usize) -> Status {
unsafe {
(self.exit_boot_services)(*image_handle, *map_key)
}
}

/// Sleep for a number of microseconds.
pub fn stall(&self, microseconds: usize) {
unsafe {
Expand Down
61 changes: 30 additions & 31 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,51 @@ mod table;
mod systemtable;
mod bootservices;
mod runtimeservices;
mod protocols;
mod console;


use void::{NotYetDef};

pub use base::{Handle, Handles, Event, MemoryType, Status, Time};
pub use base::{Handle, Handles, Event, MemoryType, MemoryDescriptor, Status, Time};
pub use guid::*;

pub use systemtable::*;

pub use bootservices::BootServices;

pub use protocols::*;

pub use runtimeservices::{ResetType, RuntimeServices};

pub use console::{Attribute, ForegroundColor, BackgroundColor, InputKey, SimpleTextOutput, SimpleTextInput, Console};

pub trait Protocol {
fn guid() -> &'static guid::Guid;
use core::mem;

static mut POOL_ALLOCATION_TYPE: base::MemoryType = base::MemoryType::BootServicesData;

pub fn initialize_lib(hdl: &base::Handle, sys: &systemtable::SystemTable) {
let bs = systemtable::set_system_table(sys).boot_services();
let loaded_image = match bs.handle_protocol::<LoadedImageProtocol>(hdl) {
Ok(val) => val,
Err(status) => panic!("Error! {}", status.str())
};

unsafe {
POOL_ALLOCATION_TYPE = loaded_image.image_data_type.clone()
}
}

/// GUID for UEFI protocol for loaded images
pub static EFI_LOADED_IMAGE_PROTOCOL_GUID: Guid = Guid(0x5B1B31A1, 0x9562, 0x11d2, [0x8E,0x3F,0x00,0xA0,0xC9,0x69,0x72,0x3B]);

#[derive(Debug)]
#[repr(C)]
pub struct LoadedImageProtocol {
revision: u32,
parent_handle: ::base::Handle,
system_table: *const NotYetDef,
device_handle: Handle,
file_path: *const NotYetDef,
__reserved: *const NotYetDef,
load_options_size: u32,
load_options: *const NotYetDef,
pub image_base: usize,
pub image_size: u64,
image_code_type: ::base::MemoryType,
image_data_type: ::base::MemoryType,

//unload: unsafe extern "win64" fn(handle: ::base::Handle),
unload: *const NotYetDef,
pub fn get_pool_allocation_type() -> base::MemoryType {
unsafe{ POOL_ALLOCATION_TYPE.clone() }
}

impl Protocol for LoadedImageProtocol {
fn guid() -> &'static Guid {
return &EFI_LOADED_IMAGE_PROTOCOL_GUID;
// return (memory_map, memory_map_size, map_key, descriptor_size, descriptor_version)
pub fn lib_memory_map() -> (&'static MemoryDescriptor, usize, usize, usize, u32) {
let bs = systemtable::get_system_table().boot_services();
let mut buffer_size: usize = mem::size_of::<MemoryDescriptor>();

loop {
match unsafe { bs.get_memory_map(&mut buffer_size) } {
Ok(val) => return val,
Err(_) => { continue; },
};
}
}

36 changes: 36 additions & 0 deletions src/protocols.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use void;
use base;
use guid;

pub trait Protocol {
fn guid() -> *const guid::Guid;
}

/// GUID for UEFI protocol for loaded images
pub const EFI_LOADED_IMAGE_PROTOCOL_GUID: guid::Guid = guid::Guid(0x5B1B31A1, 0x9562, 0x11d2, [0x8E,0x3F,0x00,0xA0,0xC9,0x69,0x72,0x3B]);

#[derive(Debug)]
#[repr(C)]
pub struct LoadedImageProtocol {
revision: u32,
parent_handle: base::Handle,
system_table: *const void::NotYetDef,
device_handle: base::Handle,
file_path: *const void::NotYetDef,
__reserved: *const void::NotYetDef,
load_options_size: u32,
load_options: *const void::NotYetDef,
pub image_base: usize,
pub image_size: u64,
image_code_type: base::MemoryType,
pub image_data_type: base::MemoryType,

//unload: unsafe extern "win64" fn(handle: Handle),
unload: *const void::NotYetDef,
}

impl Protocol for LoadedImageProtocol {
fn guid() -> *const guid::Guid {
return &EFI_LOADED_IMAGE_PROTOCOL_GUID;
}
}
9 changes: 7 additions & 2 deletions src/runtimeservices.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use core::ptr;

use void::NotYetDef;
use base::{Status, Time, TimeCapabilities};
use base::{Status, Time, TimeCapabilities, MemoryDescriptor};
use guid::Guid;
use table::TableHeader;

Expand All @@ -23,7 +23,7 @@ pub struct RuntimeServices {
set_time: *const NotYetDef,
get_wakeup_time: *const NotYetDef,
set_wakeup_time: *const NotYetDef,
set_virtual_address_map: *const NotYetDef,
set_virtual_address_map: unsafe extern "win64" fn(memory_map_size: usize, descriptor_size: usize, descriptor_version: u32, efi_memory_descriptor: *const MemoryDescriptor) -> Status,
convert_pointer: *const NotYetDef,
get_variable: unsafe extern "win64" fn(name: *const u16, guid: &Guid, attributes: *mut u32, size: *mut usize, data: *mut u8) -> Status,
get_next_variable_name: *const NotYetDef,
Expand All @@ -36,6 +36,11 @@ pub struct RuntimeServices {
}

impl RuntimeServices {
pub fn set_virtual_address_map(&self, memory_map_size: &usize, descriptor_size: &usize, descriptor_version: &u32, efi_memory_descriptor: *const MemoryDescriptor) -> Status {
unsafe {
(self.set_virtual_address_map)(*memory_map_size, *descriptor_size, *descriptor_version, efi_memory_descriptor)
}
}
pub fn get_time(&self) -> Result<Time, Status> {
let mut t : Time = Time::default();
let status = unsafe { (self.get_time)(&mut t, ptr::null_mut()) };
Expand Down