Skip to content

Commit d0b78d0

Browse files
Merge pull request #301 from foxcob/fix_set_virtual_address_map
Update `set_virtual_address_map()` to allow remapping of SystemTable
2 parents a654c08 + c9986a4 commit d0b78d0

File tree

2 files changed

+41
-18
lines changed

2 files changed

+41
-18
lines changed

src/table/runtime.rs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub struct RuntimeServices {
2626
set_time: unsafe extern "efiapi" fn(time: &Time) -> Status,
2727
// Skip some useless functions.
2828
_pad: [usize; 2],
29-
set_virtual_address_map: unsafe extern "efiapi" fn(
29+
pub(crate) set_virtual_address_map: unsafe extern "efiapi" fn(
3030
map_size: usize,
3131
desc_size: usize,
3232
desc_version: u32,
@@ -91,23 +91,6 @@ impl RuntimeServices {
9191
(self.set_time)(time).into()
9292
}
9393

94-
/// Changes the runtime addressing mode of EFI firmware from physical to virtual.
95-
///
96-
/// # Safety
97-
///
98-
/// Setting new virtual memory map is unsafe and may cause undefined behaviors.
99-
pub unsafe fn set_virtual_address_map(&self, map: &mut [MemoryDescriptor]) -> Result {
100-
// Unsafe Code Guidelines guarantees that there is no padding in an array or a slice
101-
// between its elements if the element type is `repr(C)`, which is our case.
102-
//
103-
// See https://rust-lang.github.io/unsafe-code-guidelines/layout/arrays-and-slices.html
104-
let map_size = core::mem::size_of_val(map);
105-
let entry_size = core::mem::size_of::<MemoryDescriptor>();
106-
let entry_version = crate::table::boot::MEMORY_DESCRIPTOR_VERSION;
107-
let map_ptr = map.as_mut_ptr();
108-
(self.set_virtual_address_map)(map_size, entry_size, entry_version, map_ptr).into()
109-
}
110-
11194
/// Get the size (in bytes) of a variable. This can be used to find out how
11295
/// big of a buffer should be passed in to `get_variable`.
11396
pub fn get_variable_size(&self, name: &CStr16, vendor: &VariableVendor) -> Result<usize> {

src/table/system.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,46 @@ impl SystemTable<Runtime> {
208208
pub unsafe fn runtime_services(&self) -> &RuntimeServices {
209209
self.table.runtime
210210
}
211+
212+
/// Changes the runtime addressing mode of EFI firmware from physical to virtual.
213+
/// It is up to the caller to translate the old SystemTable address to a new virtual
214+
/// address and provide it for this function.
215+
/// See [`get_current_system_table_addr`]
216+
///
217+
/// # Safety
218+
///
219+
/// Setting new virtual memory map is unsafe and may cause undefined behaviors.
220+
///
221+
/// [`get_current_system_table_addr`]: SystemTable::get_current_system_table_addr
222+
pub unsafe fn set_virtual_address_map(
223+
self,
224+
map: &mut [MemoryDescriptor],
225+
new_system_table_virtual_addr: u64,
226+
) -> Result<Self> {
227+
// Unsafe Code Guidelines guarantees that there is no padding in an array or a slice
228+
// between its elements if the element type is `repr(C)`, which is our case.
229+
//
230+
// See https://rust-lang.github.io/unsafe-code-guidelines/layout/arrays-and-slices.html
231+
let map_size = core::mem::size_of_val(map);
232+
let entry_size = core::mem::size_of::<MemoryDescriptor>();
233+
let entry_version = crate::table::boot::MEMORY_DESCRIPTOR_VERSION;
234+
let map_ptr = map.as_mut_ptr();
235+
(self.table.runtime.set_virtual_address_map)(map_size, entry_size, entry_version, map_ptr)
236+
.into_with_val(|| {
237+
let new_table_ref =
238+
&mut *(new_system_table_virtual_addr as usize as *mut SystemTableImpl);
239+
Self {
240+
table: new_table_ref,
241+
_marker: PhantomData,
242+
}
243+
})
244+
}
245+
246+
/// Return the address of the SystemTable that resides in a UEFI runtime services
247+
/// memory region.
248+
pub fn get_current_system_table_addr(&self) -> u64 {
249+
self.table as *const _ as usize as u64
250+
}
211251
}
212252

213253
/// The actual UEFI system table

0 commit comments

Comments
 (0)