1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15- use core:: ffi:: c_void;
15+ use core:: { ffi:: c_void, mem :: transmute } ;
1616
1717use atomic_refcell:: AtomicRefCell ;
1818use r_efi:: {
@@ -52,11 +52,142 @@ struct HandleWrapper {
5252
5353pub static ALLOCATOR : AtomicRefCell < Allocator > = AtomicRefCell :: new ( Allocator :: new ( ) ) ;
5454
55+ static mut RS : efi:: RuntimeServices = efi:: RuntimeServices {
56+ hdr : efi:: TableHeader {
57+ signature : efi:: RUNTIME_SERVICES_SIGNATURE ,
58+ revision : efi:: RUNTIME_SERVICES_REVISION ,
59+ header_size : core:: mem:: size_of :: < efi:: RuntimeServices > ( ) as u32 ,
60+ crc32 : 0 , // TODO
61+ reserved : 0 ,
62+ } ,
63+ get_time,
64+ set_time,
65+ get_wakeup_time,
66+ set_wakeup_time,
67+ set_virtual_address_map,
68+ convert_pointer,
69+ get_variable,
70+ get_next_variable_name,
71+ set_variable,
72+ get_next_high_mono_count,
73+ reset_system,
74+ update_capsule,
75+ query_capsule_capabilities,
76+ query_variable_info,
77+ } ;
78+
79+ static mut BS : efi:: BootServices = efi:: BootServices {
80+ hdr : efi:: TableHeader {
81+ signature : efi:: BOOT_SERVICES_SIGNATURE ,
82+ revision : efi:: BOOT_SERVICES_REVISION ,
83+ header_size : core:: mem:: size_of :: < efi:: BootServices > ( ) as u32 ,
84+ crc32 : 0 , // TODO
85+ reserved : 0 ,
86+ } ,
87+ raise_tpl,
88+ restore_tpl,
89+ allocate_pages,
90+ free_pages,
91+ get_memory_map,
92+ allocate_pool,
93+ free_pool,
94+ create_event,
95+ set_timer,
96+ wait_for_event,
97+ signal_event,
98+ close_event,
99+ check_event,
100+ install_protocol_interface,
101+ reinstall_protocol_interface,
102+ uninstall_protocol_interface,
103+ handle_protocol,
104+ register_protocol_notify,
105+ locate_handle,
106+ locate_device_path,
107+ install_configuration_table,
108+ load_image,
109+ start_image,
110+ exit,
111+ unload_image,
112+ exit_boot_services,
113+ get_next_monotonic_count,
114+ stall,
115+ set_watchdog_timer,
116+ connect_controller,
117+ disconnect_controller,
118+ open_protocol,
119+ close_protocol,
120+ open_protocol_information,
121+ protocols_per_handle,
122+ locate_handle_buffer,
123+ locate_protocol,
124+ install_multiple_protocol_interfaces,
125+ uninstall_multiple_protocol_interfaces,
126+ calculate_crc32,
127+ copy_mem,
128+ set_mem,
129+ create_event_ex,
130+ reserved : core:: ptr:: null_mut ( ) ,
131+ } ;
132+
133+ static mut ST : efi:: SystemTable = efi:: SystemTable {
134+ hdr : efi:: TableHeader {
135+ signature : efi:: SYSTEM_TABLE_SIGNATURE ,
136+ revision : ( 2 << 16 ) | ( 80 ) ,
137+ header_size : core:: mem:: size_of :: < efi:: SystemTable > ( ) as u32 ,
138+ crc32 : 0 , // TODO
139+ reserved : 0 ,
140+ } ,
141+ firmware_vendor : core:: ptr:: null_mut ( ) , // TODO,
142+ firmware_revision : 0 ,
143+ console_in_handle : console:: STDIN_HANDLE ,
144+ con_in : core:: ptr:: null_mut ( ) ,
145+ console_out_handle : console:: STDOUT_HANDLE ,
146+ con_out : core:: ptr:: null_mut ( ) ,
147+ standard_error_handle : console:: STDERR_HANDLE ,
148+ std_err : core:: ptr:: null_mut ( ) ,
149+ runtime_services : core:: ptr:: null_mut ( ) ,
150+ boot_services : core:: ptr:: null_mut ( ) ,
151+ number_of_table_entries : 0 ,
152+ configuration_table : core:: ptr:: null_mut ( ) ,
153+ } ;
154+
55155static mut BLOCK_WRAPPERS : block:: BlockWrappers = block:: BlockWrappers {
56156 wrappers : [ core:: ptr:: null_mut ( ) ; 16 ] ,
57157 count : 0 ,
58158} ;
59159
160+ unsafe fn fixup_at_virtual ( offset : u64 ) {
161+ let mut st = & mut ST ;
162+ let mut rs = & mut RS ;
163+
164+ let ptr = offset + ( rs as * const efi:: RuntimeServices ) as u64 ;
165+ st. runtime_services = transmute ( ptr) ;
166+
167+ let ct = st. configuration_table ;
168+ let ptr = offset + ( ct as * const efi:: ConfigurationTable ) as u64 ;
169+ st. configuration_table = transmute ( ptr) ;
170+
171+ let ptr = offset + ( not_available as * const ( ) ) as u64 ;
172+ rs. get_time = transmute ( ptr) ;
173+ rs. set_time = transmute ( ptr) ;
174+ rs. get_wakeup_time = transmute ( ptr) ;
175+ rs. set_wakeup_time = transmute ( ptr) ;
176+ rs. set_virtual_address_map = transmute ( ptr) ;
177+ rs. convert_pointer = transmute ( ptr) ;
178+ rs. get_variable = transmute ( ptr) ;
179+ rs. set_variable = transmute ( ptr) ;
180+ rs. get_next_variable_name = transmute ( ptr) ;
181+ rs. reset_system = transmute ( ptr) ;
182+ rs. update_capsule = transmute ( ptr) ;
183+ rs. query_capsule_capabilities = transmute ( ptr) ;
184+ rs. query_variable_info = transmute ( ptr) ;
185+ }
186+
187+ pub extern "win64" fn not_available ( ) -> Status {
188+ Status :: UNSUPPORTED
189+ }
190+
60191pub extern "win64" fn get_time ( _: * mut Time , _: * mut TimeCapabilities ) -> Status {
61192 Status :: DEVICE_ERROR
62193}
@@ -89,6 +220,16 @@ pub extern "win64" fn set_virtual_address_map(
89220 core:: slice:: from_raw_parts_mut ( descriptors as * mut alloc:: MemoryDescriptor , count)
90221 } ;
91222
223+ for descriptor in descriptors. iter ( ) {
224+ if descriptor. r#type == MemoryType :: RuntimeServicesCode as u32 {
225+ let offset = descriptor. virtual_start - descriptor. physical_start ;
226+ unsafe {
227+ fixup_at_virtual ( offset) ;
228+ }
229+ break ;
230+ }
231+ }
232+
92233 ALLOCATOR . borrow_mut ( ) . update_virtual_addresses ( descriptors)
93234}
94235
@@ -627,84 +768,6 @@ pub fn efi_exec(
627768 fs : & crate :: fat:: Filesystem ,
628769 block : * const crate :: block:: VirtioBlockDevice ,
629770) {
630- let mut rs = efi:: RuntimeServices {
631- hdr : efi:: TableHeader {
632- signature : efi:: RUNTIME_SERVICES_SIGNATURE ,
633- revision : efi:: RUNTIME_SERVICES_REVISION ,
634- header_size : core:: mem:: size_of :: < efi:: RuntimeServices > ( ) as u32 ,
635- crc32 : 0 , // TODO
636- reserved : 0 ,
637- } ,
638- get_time,
639- set_time,
640- get_wakeup_time,
641- set_wakeup_time,
642- set_virtual_address_map,
643- convert_pointer,
644- get_variable,
645- get_next_variable_name,
646- set_variable,
647- get_next_high_mono_count,
648- reset_system,
649- update_capsule,
650- query_capsule_capabilities,
651- query_variable_info,
652- } ;
653-
654- let mut bs = efi:: BootServices {
655- hdr : efi:: TableHeader {
656- signature : efi:: BOOT_SERVICES_SIGNATURE ,
657- revision : efi:: BOOT_SERVICES_REVISION ,
658- header_size : core:: mem:: size_of :: < efi:: BootServices > ( ) as u32 ,
659- crc32 : 0 , // TODO
660- reserved : 0 ,
661- } ,
662- raise_tpl,
663- restore_tpl,
664- allocate_pages,
665- free_pages,
666- get_memory_map,
667- allocate_pool,
668- free_pool,
669- create_event,
670- set_timer,
671- wait_for_event,
672- signal_event,
673- close_event,
674- check_event,
675- install_protocol_interface,
676- reinstall_protocol_interface,
677- uninstall_protocol_interface,
678- handle_protocol,
679- register_protocol_notify,
680- locate_handle,
681- locate_device_path,
682- install_configuration_table,
683- load_image,
684- start_image,
685- exit,
686- unload_image,
687- exit_boot_services,
688- get_next_monotonic_count,
689- stall,
690- set_watchdog_timer,
691- connect_controller,
692- disconnect_controller,
693- open_protocol,
694- close_protocol,
695- open_protocol_information,
696- protocols_per_handle,
697- locate_handle_buffer,
698- locate_protocol,
699- install_multiple_protocol_interfaces,
700- uninstall_multiple_protocol_interfaces,
701- calculate_crc32,
702- copy_mem,
703- set_mem,
704- create_event_ex,
705- reserved : core:: ptr:: null_mut ( ) ,
706- } ;
707-
708771 let vendor_data = 0u32 ;
709772 let acpi_rsdp_ptr = info. rsdp_addr ( ) ;
710773
@@ -736,27 +799,14 @@ pub fn efi_exec(
736799
737800 let mut stdin = console:: STDIN ;
738801 let mut stdout = console:: STDOUT ;
739- let mut st = efi:: SystemTable {
740- hdr : efi:: TableHeader {
741- signature : efi:: SYSTEM_TABLE_SIGNATURE ,
742- revision : efi:: SYSTEM_TABLE_REVISION_2_70 ,
743- header_size : core:: mem:: size_of :: < efi:: SystemTable > ( ) as u32 ,
744- crc32 : 0 , // TODO
745- reserved : 0 ,
746- } ,
747- firmware_vendor : core:: ptr:: null_mut ( ) , // TODO,
748- firmware_revision : 0 ,
749- console_in_handle : console:: STDIN_HANDLE ,
750- con_in : & mut stdin,
751- console_out_handle : console:: STDOUT_HANDLE ,
752- con_out : & mut stdout,
753- standard_error_handle : console:: STDERR_HANDLE ,
754- std_err : & mut stdout,
755- runtime_services : & mut rs,
756- boot_services : & mut bs,
757- number_of_table_entries : 1 ,
758- configuration_table : & mut ct,
759- } ;
802+ let mut st = unsafe { & mut ST } ;
803+ st. con_in = & mut stdin;
804+ st. con_out = & mut stdout;
805+ st. std_err = & mut stdout;
806+ st. runtime_services = unsafe { & mut RS } ;
807+ st. boot_services = unsafe { & mut BS } ;
808+ st. number_of_table_entries = 1 ;
809+ st. configuration_table = & mut ct;
760810
761811 populate_allocator ( info, loaded_address, loaded_size) ;
762812
@@ -801,7 +851,7 @@ pub fn efi_exec(
801851 proto : LoadedImageProtocol {
802852 revision : r_efi:: protocols:: loaded_image:: REVISION ,
803853 parent_handle : 0 as Handle ,
804- system_table : & mut st,
854+ system_table : & mut * st,
805855 device_handle : & wrapped_fs as * const _ as Handle ,
806856 file_path : & mut file_paths[ 0 ] . device_path , // Pointer to first path entry
807857 load_options_size : 0 ,
@@ -818,5 +868,5 @@ pub fn efi_exec(
818868 let ptr = address as * const ( ) ;
819869 let code: extern "win64" fn ( Handle , * mut efi:: SystemTable ) -> Status =
820870 unsafe { core:: mem:: transmute ( ptr) } ;
821- ( code) ( ( & image as * const _ ) as Handle , & mut st) ;
871+ ( code) ( ( & image as * const _ ) as Handle , & mut * st) ;
822872}
0 commit comments