Skip to content

Commit c08cc36

Browse files
imtsukiGabrielMajeri
authored andcommitted
Add set_virtual_address_map interface in runtime services
Signed-off-by: imtsuki <me@qjx.app>
1 parent dc4d159 commit c08cc36

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

src/table/boot.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,9 @@ pub enum MemoryType: u32 => {
633633
PERSISTENT_MEMORY = 14,
634634
}}
635635

636+
/// Memory descriptor version number
637+
pub const MEMORY_DESCRIPTOR_VERSION: u32 = 1;
638+
636639
/// A structure describing a region of memory.
637640
#[derive(Debug, Copy, Clone)]
638641
#[repr(C)]

src/table/runtime.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! UEFI services available at runtime, even after the OS boots.
22
33
use super::Header;
4+
use crate::table::boot::MemoryDescriptor;
45
use crate::{Result, Status};
56
use bitflags::bitflags;
67
use core::mem::MaybeUninit;
@@ -17,9 +18,17 @@ pub struct RuntimeServices {
1718
unsafe extern "efiapi" fn(time: *mut Time, capabilities: *mut TimeCapabilities) -> Status,
1819
set_time: unsafe extern "efiapi" fn(time: &Time) -> Status,
1920
// Skip some useless functions.
20-
_pad: [usize; 8],
21+
_pad: [usize; 2],
22+
set_virtual_address_map: unsafe extern "efiapi" fn(
23+
map_size: usize,
24+
desc_size: usize,
25+
desc_version: u32,
26+
virtual_map: *mut MemoryDescriptor,
27+
) -> Status,
28+
_pad2: [usize; 5],
2129
reset: unsafe extern "efiapi" fn(
2230
rt: ResetType,
31+
2332
status: Status,
2433
data_size: usize,
2534
data: *const u8,
@@ -55,6 +64,23 @@ impl RuntimeServices {
5564
(self.set_time)(time).into()
5665
}
5766

67+
/// Changes the runtime addressing mode of EFI firmware from physical to virtual.
68+
///
69+
/// # Safety
70+
///
71+
/// Setting new virtual memory map is unsafe and may cause undefined behaviors.
72+
pub unsafe fn set_virtual_address_map(&self, map: &mut [MemoryDescriptor]) -> Result {
73+
// Unsafe Code Guidelines guarantees that there is no padding in an array or a slice
74+
// between its elements if the element type is `repr(C)`, which is our case.
75+
//
76+
// See https://rust-lang.github.io/unsafe-code-guidelines/layout/arrays-and-slices.html
77+
let map_size = core::mem::size_of_val(map);
78+
let entry_size = core::mem::size_of::<MemoryDescriptor>();
79+
let entry_version = crate::table::boot::MEMORY_DESCRIPTOR_VERSION;
80+
let map_ptr = map.as_mut_ptr();
81+
(self.set_virtual_address_map)(map_size, entry_size, entry_version, map_ptr).into()
82+
}
83+
5884
/// Resets the computer.
5985
pub fn reset(&self, rt: ResetType, status: Status, data: Option<&[u8]>) -> ! {
6086
let (size, data) = match data {

0 commit comments

Comments
 (0)