Skip to content

uefi: Use uefi_raw's SystemTable to implement SystemTable #883

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 29, 2023
Merged
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
76 changes: 16 additions & 60 deletions uefi/src/table/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ use core::ffi::c_void;
use core::fmt::{Debug, Formatter};
use core::marker::PhantomData;
use core::ptr::NonNull;
use core::{ptr, slice};
use core::slice;

use crate::proto::console::text;
use crate::{CStr16, Char16, Handle, Result, Status, StatusExt};
use crate::{CStr16, Result, Status, StatusExt};

use super::boot::{BootServices, MemoryDescriptor, MemoryMap, MemoryType};
use super::runtime::{ResetType, RuntimeServices};
use super::{cfg, Header, Revision};
use super::{cfg, Revision};

/// Marker trait used to provide different views of the UEFI System Table.
pub trait SystemTableView {}
Expand Down Expand Up @@ -47,7 +47,7 @@ impl SystemTableView for Runtime {}
/// will be provided to replace it.
#[repr(transparent)]
pub struct SystemTable<View: SystemTableView> {
table: *const SystemTableImpl,
table: *const uefi_raw::table::system::SystemTable,
_marker: PhantomData<View>,
}

Expand All @@ -56,13 +56,13 @@ impl<View: SystemTableView> SystemTable<View> {
/// Return the firmware vendor string
#[must_use]
pub fn firmware_vendor(&self) -> &CStr16 {
unsafe { CStr16::from_ptr((*self.table).fw_vendor) }
unsafe { CStr16::from_ptr((*self.table).firmware_vendor.cast()) }
}

/// Return the firmware revision
#[must_use]
pub const fn firmware_revision(&self) -> u32 {
unsafe { (*self.table).fw_revision }
unsafe { (*self.table).firmware_revision }
}

/// Returns the revision of this table, which is defined to be
Expand All @@ -80,9 +80,10 @@ impl<View: SystemTableView> SystemTable<View> {
unsafe {
let table = &*self.table;
table
.cfg_table
.configuration_table
.cast::<cfg::ConfigTableEntry>()
.as_ref()
.map(|ptr| slice::from_raw_parts(ptr, table.nr_cfg))
.map(|ptr| slice::from_raw_parts(ptr, table.number_of_configuration_table_entries))
.unwrap_or(&[])
}
}
Expand Down Expand Up @@ -119,7 +120,7 @@ impl<View: SystemTableView> SystemTable<View> {
impl SystemTable<Boot> {
/// Returns the standard input protocol.
pub fn stdin(&mut self) -> &mut text::Input {
unsafe { &mut *(*self.table).stdin }
unsafe { &mut *(*self.table).stdin.cast() }
}

/// Returns the standard output protocol.
Expand All @@ -135,13 +136,13 @@ impl SystemTable<Boot> {
/// Access runtime services
#[must_use]
pub const fn runtime_services(&self) -> &RuntimeServices {
unsafe { &*(*self.table).runtime }
unsafe { &*(*self.table).runtime_services.cast_const().cast() }
}

/// Access boot services
#[must_use]
pub const fn boot_services(&self) -> &BootServices {
unsafe { &*(*self.table).boot }
unsafe { &*(*self.table).boot_services.cast_const().cast() }
}

/// Get the size in bytes of the buffer to allocate for storing the memory
Expand Down Expand Up @@ -299,7 +300,7 @@ impl SystemTable<Runtime> {
/// "Calling Conventions" chapter of the UEFI specification for details.
#[must_use]
pub const unsafe fn runtime_services(&self) -> &RuntimeServices {
&*(*self.table).runtime
&*(*self.table).runtime_services.cast_const().cast()
}

/// Changes the runtime addressing mode of EFI firmware from physical to virtual.
Expand All @@ -325,11 +326,11 @@ impl SystemTable<Runtime> {
let entry_size = core::mem::size_of::<MemoryDescriptor>();
let entry_version = MemoryDescriptor::VERSION;
let map_ptr = map.as_mut_ptr();
(*(*self.table).runtime)
self.runtime_services()
.set_virtual_address_map(map_size, entry_size, entry_version, map_ptr)
.to_result_with_val(|| {
let new_table_ref =
&mut *(new_system_table_virtual_addr as usize as *mut SystemTableImpl);
let new_table_ref = &mut *(new_system_table_virtual_addr as usize
as *mut uefi_raw::table::system::SystemTable);
Self {
table: new_table_ref,
_marker: PhantomData,
Expand All @@ -345,51 +346,6 @@ impl SystemTable<Runtime> {
}
}

/// The actual UEFI system table
#[repr(C)]
struct SystemTableImpl {
header: Header,
/// Null-terminated string representing the firmware's vendor.
fw_vendor: *const Char16,
fw_revision: u32,
stdin_handle: Handle,
stdin: *mut text::Input,
stdout_handle: Handle,
stdout: *mut text::Output,
stderr_handle: Handle,
stderr: *mut text::Output,
/// Runtime services table.
runtime: *const RuntimeServices,
/// Boot services table.
boot: *const BootServices,
/// Number of entries in the configuration table.
nr_cfg: usize,
/// Pointer to beginning of the array.
cfg_table: *const cfg::ConfigTableEntry,
}

impl<View: SystemTableView> super::Table for SystemTable<View> {
const SIGNATURE: u64 = 0x5453_5953_2049_4249;
}

impl Debug for SystemTableImpl {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("UefiSystemTable")
.field("header", &self.header)
.field("fw_vendor", &(unsafe { CStr16::from_ptr(self.fw_vendor) }))
.field("fw_revision", &self.fw_revision)
.field("stdin_handle", &self.stdin_handle)
.field("stdin", &self.stdin)
.field("stdout_handle", &self.stdout_handle)
.field("stdout", &self.stdout)
.field("stderr_handle", &self.stderr_handle)
.field("stderr", &self.stderr)
.field("runtime", &self.runtime)
// a little bit of extra work needed to call debug-fmt on the BootServices
// instead of printing the raw pointer
.field("boot", &(unsafe { ptr::read(self.boot) }))
.field("nf_cfg", &self.nr_cfg)
.field("cfg_table", &self.cfg_table)
.finish()
}
}