1
1
//! UEFI services available at runtime, even after the OS boots.
2
2
3
3
use super :: Header ;
4
+ use crate :: table:: boot:: MemoryDescriptor ;
4
5
use crate :: { Result , Status } ;
5
6
use bitflags:: bitflags;
6
7
use core:: mem:: MaybeUninit ;
@@ -17,9 +18,17 @@ pub struct RuntimeServices {
17
18
unsafe extern "efiapi" fn ( time : * mut Time , capabilities : * mut TimeCapabilities ) -> Status ,
18
19
set_time : unsafe extern "efiapi" fn ( time : & Time ) -> Status ,
19
20
// 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 ] ,
21
29
reset : unsafe extern "efiapi" fn (
22
30
rt : ResetType ,
31
+
23
32
status : Status ,
24
33
data_size : usize ,
25
34
data : * const u8 ,
@@ -55,6 +64,23 @@ impl RuntimeServices {
55
64
( self . set_time ) ( time) . into ( )
56
65
}
57
66
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
+
58
84
/// Resets the computer.
59
85
pub fn reset ( & self , rt : ResetType , status : Status , data : Option < & [ u8 ] > ) -> ! {
60
86
let ( size, data) = match data {
0 commit comments