diff --git a/boot2snow/uefi_alloc/.gitignore b/boot2snow/uefi_alloc/.gitignore new file mode 100644 index 0000000..fa8d85a --- /dev/null +++ b/boot2snow/uefi_alloc/.gitignore @@ -0,0 +1,2 @@ +Cargo.lock +target diff --git a/boot2snow/uefi_alloc/Cargo.toml b/boot2snow/uefi_alloc/Cargo.toml new file mode 100644 index 0000000..ee5c2b2 --- /dev/null +++ b/boot2snow/uefi_alloc/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "uefi_alloc" +version = "0.1.0" + +[dependencies] +uefi = { git = "https://github.com/SnowFlakeOS/uefi" } diff --git a/boot2snow/uefi_alloc/LICENSE b/boot2snow/uefi_alloc/LICENSE new file mode 100644 index 0000000..5deeece --- /dev/null +++ b/boot2snow/uefi_alloc/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Redox OS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/boot2snow/uefi_alloc/rust-toolchain b/boot2snow/uefi_alloc/rust-toolchain new file mode 100644 index 0000000..577d7d7 --- /dev/null +++ b/boot2snow/uefi_alloc/rust-toolchain @@ -0,0 +1 @@ +nightly-2018-03-31 \ No newline at end of file diff --git a/boot2snow/uefi_alloc/src/lib.rs b/boot2snow/uefi_alloc/src/lib.rs new file mode 100644 index 0000000..6b32b2c --- /dev/null +++ b/boot2snow/uefi_alloc/src/lib.rs @@ -0,0 +1,56 @@ +#![feature(alloc)] +#![feature(allocator_api)] +#![feature(const_fn)] +#![feature(try_trait)] +#![no_std] + +extern crate alloc; +extern crate uefi; + +use alloc::heap::{Alloc, AllocErr, Layout}; +use core::ops::Try; +use uefi::Void; +use uefi::boot_services::{BootServices, MemoryType}; + +static mut S_BOOT_SERVICES: *const BootServices = 0 as *const BootServices; + +pub unsafe fn init(table: *const BootServices) { + S_BOOT_SERVICES = table; +} + +fn get_boot_services() -> Option<&'static BootServices> { + unsafe { + if S_BOOT_SERVICES as usize == 0 { + None + } else { + Some(&*S_BOOT_SERVICES) + } + } +} + +pub struct Allocator; + +unsafe impl<'a> Alloc for &'a Allocator { + unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + let boot_services = get_boot_services().unwrap(); + let size = layout.size(); + let align = layout.align(); + + // TODO: add support for other alignments. + if align > 8 { + let details = "Unsupported alignment for allocation, UEFI can only allocate 8-byte aligned addresses"; + Err(AllocErr::Unsupported { details }) + } else { + boot_services + .allocate_pool(size) + .map(|addr| addr as *mut u8) + // This is the only possible error, according to the spec. + .map_err(|_status| AllocErr::Exhausted { request: layout }) + } + } + + unsafe fn dealloc(&mut self, ptr: *mut u8, _layout: Layout) { + let boot_services = get_boot_services().unwrap(); + let _ = (boot_services.free_pool)(ptr as *mut Void); + } +}