summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2023-10-07 15:56:06 +0200
committerArd Biesheuvel <ardb@kernel.org>2023-10-07 15:56:06 +0200
commit712e6fe19da8c0f32d901ae2969a2477bb3e76a5 (patch)
tree7855540d78b96ec4028c8400270b496b5b7a9406
parent95bf7cebcfb02433270a38e4d99a330df6096ccc (diff)
downloadefilite-712e6fe19da8c0f32d901ae2969a2477bb3e76a5.tar.gz
WIP
-rw-r--r--src/efi/initrdloadfile2.rs4
-rw-r--r--src/efi/memmap.rs5
-rw-r--r--src/efi/mod.rs7
-rw-r--r--src/efi/systemtable.rs1
-rw-r--r--src/fwcfg.rs49
-rw-r--r--src/initrd.rs4
-rw-r--r--src/main.rs14
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)