diff options
author | Ard Biesheuvel <ardb@kernel.org> | 2023-10-07 15:56:06 +0200 |
---|---|---|
committer | Ard Biesheuvel <ardb@kernel.org> | 2023-10-07 15:56:06 +0200 |
commit | 712e6fe19da8c0f32d901ae2969a2477bb3e76a5 (patch) | |
tree | 7855540d78b96ec4028c8400270b496b5b7a9406 | |
parent | 95bf7cebcfb02433270a38e4d99a330df6096ccc (diff) | |
download | efilite-712e6fe19da8c0f32d901ae2969a2477bb3e76a5.tar.gz |
WIP
-rw-r--r-- | src/efi/initrdloadfile2.rs | 4 | ||||
-rw-r--r-- | src/efi/memmap.rs | 5 | ||||
-rw-r--r-- | src/efi/mod.rs | 7 | ||||
-rw-r--r-- | src/efi/systemtable.rs | 1 | ||||
-rw-r--r-- | src/fwcfg.rs | 49 | ||||
-rw-r--r-- | src/initrd.rs | 4 | ||||
-rw-r--r-- | src/main.rs | 14 |
7 files changed, 49 insertions, 35 deletions
diff --git a/src/efi/initrdloadfile2.rs b/src/efi/initrdloadfile2.rs index 74fb53b..d5c8d3c 100644 --- a/src/efi/initrdloadfile2.rs +++ b/src/efi/initrdloadfile2.rs @@ -10,6 +10,8 @@ use crate::efi::devicepath::{DevicePathType::*, DevicePathSubtype::*}; use crate::initrd::InitrdLoader; +use core::mem::MaybeUninit; + pub const EFI_LOAD_FILE2_PROTOCOL_GUID: Guid = guid!( 0x4006c0c1, 0xfcb3, 0x403e, [0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d] ); @@ -90,7 +92,7 @@ extern "C" fn load_file( } let region = unsafe { - core::slice::from_raw_parts_mut(buffer as *mut u8, initrdsize) + core::slice::from_raw_parts_mut(buffer as *mut MaybeUninit<u8>, initrdsize) }; if let Ok(_) = this.loader.load_initrd_image(region) { diff --git a/src/efi/memmap.rs b/src/efi/memmap.rs index 342f771..d8b8365 100644 --- a/src/efi/memmap.rs +++ b/src/efi/memmap.rs @@ -9,6 +9,7 @@ use crate::Placement::*; use alloc::vec::Vec; use alloc::collections::BTreeMap; +use core::mem::MaybeUninit; use core::sync::atomic::{AtomicUsize, Ordering}; use core::slice; use core::ops::Range; @@ -201,7 +202,7 @@ pub fn allocate_pages( pages: usize, _type: MemoryType, placement: Placement -) -> Option<&'static mut [u8]> { +) -> Option<&'static mut [MaybeUninit<u8>]> { let mut mm = MEMMAP.lock(); let p = pages as u64; @@ -281,7 +282,7 @@ pub fn allocate_pages( convert_region(&mut mm, base, size, Some(EfiConventionalMemory), _type).ok()?; unsafe { - Some(slice::from_raw_parts_mut(base as *mut u8, size)) + Some(slice::from_raw_parts_mut(base as *mut MaybeUninit<u8>, size)) } } diff --git a/src/efi/mod.rs b/src/efi/mod.rs index 7522952..373b069 100644 --- a/src/efi/mod.rs +++ b/src/efi/mod.rs @@ -158,7 +158,6 @@ pub(crate) use guid; struct ProtocolPtr(*const ()); unsafe impl Send for ProtocolPtr {} -unsafe impl Sync for ProtocolPtr {} impl ProtocolPtr { pub fn from<T>(p: &T) -> ProtocolPtr { @@ -175,11 +174,9 @@ static RTSDATA_ALLOCATOR: LockedHeap = LockedHeap::empty(); pub fn init() { let rtspool = - memmap::allocate_pages(16, MemoryType::EfiRuntimeServicesData, Placement::Anywhere) + memmap::allocate_pages(16, MemoryType::EfiRuntimeServicesData, Placement::Aligned(0x1_0000)) .unwrap(); - unsafe { - RTSDATA_ALLOCATOR.lock().init(rtspool.as_mut_ptr(), rtspool.len()); - } + RTSDATA_ALLOCATOR.lock().init_from_slice(rtspool); install_configtable(&EFI_RT_PROPERTIES_TABLE_GUID, &RT_PROPERTIES_TABLE as *const _ as *const ()); diff --git a/src/efi/systemtable.rs b/src/efi/systemtable.rs index 9eb6a69..f3841fa 100644 --- a/src/efi/systemtable.rs +++ b/src/efi/systemtable.rs @@ -29,7 +29,6 @@ pub struct SystemTable { } unsafe impl Send for SystemTable {} -unsafe impl Sync for SystemTable {} use once_cell::race::OnceBox; use alloc::boxed::Box; diff --git a/src/fwcfg.rs b/src/fwcfg.rs index 68f4c6e..7dacdda 100644 --- a/src/fwcfg.rs +++ b/src/fwcfg.rs @@ -4,6 +4,8 @@ use mmio::{Allow, Deny, VolBox}; use crate::initrd; +use core::mem::MaybeUninit; +use core::slice; use core::sync::atomic::{fence, Ordering}; pub struct FwCfg { @@ -48,10 +50,10 @@ impl FwCfg { fn dma_transfer( &mut self, - loadbuffer: &mut [u8], + loadbuffer: &mut [MaybeUninit<u8>], size: usize, config_item: u16, - ) -> Result<(), &str> { + ) -> Result<(), ()> { let addr = loadbuffer.as_ptr() as u64; let xfer = DmaTransfer { control: u32::to_be(CFG_DMACTL_READ), @@ -68,7 +70,7 @@ impl FwCfg { loop { match control.read() { CFG_DMACTL_DONE => return Ok(()), - CFG_DMACTL_ERROR => return Err("fwcfg DMA error"), + CFG_DMACTL_ERROR => return Err(()), _ => (), // keep polling } } @@ -81,16 +83,29 @@ impl FwCfg { self.data.read() as usize } - pub fn load_kernel_image(&mut self, loadbuffer: &mut [u8]) -> Result<(), &str> { - let size = self.get_kernel_size(); - if size > 0 { - self.dma_transfer(loadbuffer, - size.min(loadbuffer.len()), - CFG_KERNEL_DATA) - } else { - Err("No kernel image provided by fwcfg") + fn load_image<'a>(&mut self, + loadbuffer: &'a mut [MaybeUninit<u8>], + config_item: u16 + ) -> Result<&'a [u8], ()> { + self.selector.write(u16::to_be(config_item)); + fence(Ordering::Release); + let size = self.data.read() as usize; + if size == 0 { + return Err(()); + } + let size = size.min(loadbuffer.len()); + self.dma_transfer(loadbuffer, size, config_item)?; + unsafe { + Ok(slice::from_raw_parts(loadbuffer.as_ptr() as *const _, size)) } } + + pub fn load_kernel_image<'a>(&mut self, + loadbuffer: &'a mut [MaybeUninit<u8>] + ) -> Result<&'a [u8], &str> { + self.load_image(loadbuffer, CFG_KERNEL_DATA) + .or(Err("Failed to load kernel image from fwcfg")) + } } impl initrd::InitrdLoader for FwCfg { @@ -100,14 +115,8 @@ impl initrd::InitrdLoader for FwCfg { self.data.read() as usize } - fn load_initrd_image(&mut self, loadbuffer: &mut[u8]) -> Result<(), &str> { - let size = self.get_size(); - if size > 0 { - self.dma_transfer(loadbuffer, - size.min(loadbuffer.len()), - CFG_INITRD_DATA) - } else { - Err("No initrd image provided by fwcfg") - } + fn load_initrd_image<'a>(&mut self, loadbuffer: &'a mut[MaybeUninit<u8>]) -> Result<&'a [u8], &str> { + self.load_image(loadbuffer, CFG_INITRD_DATA) + .or(Err("Failed to load initrd image from fwcfg")) } } diff --git a/src/initrd.rs b/src/initrd.rs index f9c152d..7bd5068 100644 --- a/src/initrd.rs +++ b/src/initrd.rs @@ -2,10 +2,12 @@ // Copyright 2022 Google LLC // Author: Ard Biesheuvel <ardb@google.com> +use core::mem::MaybeUninit; + pub trait InitrdLoader { fn get_size(&mut self) -> usize; - fn load_initrd_image(&mut self, loadbuffer: &mut[u8]) -> Result<(), &str>; + fn load_initrd_image<'a>(&mut self, loadbuffer: &'a mut[MaybeUninit<u8>]) -> Result<&'a [u8], &str>; } diff --git a/src/main.rs b/src/main.rs index fd91ee2..a21df55 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,7 +43,7 @@ extern crate aarch64_intrinsics; use crate::paging::Attributes; use crate::efi::memorytype::*; use crate::efi::memmap::Placement; -use crate::MemoryType::{EfiBootServicesData,EfiRuntimeServicesData}; +use crate::MemoryType::EfiBootServicesData; #[macro_use] extern crate bitflags; @@ -143,8 +143,13 @@ extern "C" fn efilite_main(base: *mut u8, mapped: usize, used: isize, avail: usi }; let loadbuffer = { - let mut buf: [u8; 256] = [0; 256]; - fwcfg.load_kernel_image(&mut buf).expect("Failed to load image header"); + let size = fwcfg.get_kernel_size(); + let buf = efi::memmap::allocate_pages(efi::memmap::size_to_pages(size), + MemoryType::EfiLoaderData, + Placement::Anywhere) + .expect("Failed to allocate memory for kernel image"); + + let buf = fwcfg.load_kernel_image(buf).expect("Failed to load image header"); let size = pecoff::Parser::get_image_size(&buf) .expect("Failed to parse PE/COFF header"); @@ -154,8 +159,7 @@ extern "C" fn efilite_main(base: *mut u8, mapped: usize, used: isize, avail: usi placement) .expect("Failed to allocate memory for EFI program"); - fwcfg.load_kernel_image(buf).expect("Failed to load kernel image"); - buf + fwcfg.load_kernel_image(buf).expect("Failed to load kernel image") }; let pe_image = pecoff::Parser::from_slice(loadbuffer) |