diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-06-06 01:00:31 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-06-06 01:00:31 +0000 |
commit | 1723337b23e3f3e0af69241da43d4fe4cd31ea36 (patch) | |
tree | cb64391bb554b459d4b7b5107a5284e6e483a11a | |
parent | 87178cf7f51295a3d002733c9cf2851fa4ca9358 (diff) | |
parent | 037de99ca93c6da1bd68e92112705e0778848a20 (diff) | |
download | libbootloader-sdk-release.tar.gz |
Snap for 11933108 from 037de99ca93c6da1bd68e92112705e0778848a20 to sdk-releasesdk-release
Change-Id: If3a29a6f9d1d6a04d0237133e18f2b005b7ef91c
-rw-r--r-- | gbl/libefi/BUILD | 1 | ||||
-rw-r--r-- | gbl/libefi/defs/boot_service.h | 9 | ||||
-rw-r--r-- | gbl/libefi/defs/runtime_service.h | 41 | ||||
-rw-r--r-- | gbl/libefi/defs/system_table.h | 3 | ||||
-rw-r--r-- | gbl/libefi/defs/types.h | 56 | ||||
-rw-r--r-- | gbl/libefi/src/lib.rs | 44 |
6 files changed, 139 insertions, 15 deletions
diff --git a/gbl/libefi/BUILD b/gbl/libefi/BUILD index 5638114..639b361 100644 --- a/gbl/libefi/BUILD +++ b/gbl/libefi/BUILD @@ -43,6 +43,7 @@ cc_library( "defs/protocols/simple_network_protocol.h", "defs/protocols/simple_text_input_protocol.h", "defs/protocols/simple_text_output_protocol.h", + "defs/runtime_service.h", "defs/system_table.h", "defs/types.h", ], diff --git a/gbl/libefi/defs/boot_service.h b/gbl/libefi/defs/boot_service.h index 5959f00..8c0a9b3 100644 --- a/gbl/libefi/defs/boot_service.h +++ b/gbl/libefi/defs/boot_service.h @@ -50,15 +50,6 @@ typedef enum EFI_OPEN_PROTOCOL_ATTRIBUTE : uint32_t { } EfiOpenProtocolAttributes; typedef struct { - uint32_t memory_type; - uint32_t padding; - EfiPhysicalAddr physical_start; - EfiVirtualAddr virtual_start; - uint64_t number_of_pages; - uint64_t attributes; -} EfiMemoryDescriptor; - -typedef struct { EfiHandle agent_handle; EfiHandle controller_handle; uint32_t attributes; diff --git a/gbl/libefi/defs/runtime_service.h b/gbl/libefi/defs/runtime_service.h new file mode 100644 index 0000000..1d0aa2e --- /dev/null +++ b/gbl/libefi/defs/runtime_service.h @@ -0,0 +1,41 @@ +#ifndef __RUNTIME_SERVICE_H__ +#define __RUNTIME_SERVICE_H__ + +#include "types.h" + +typedef struct { + EfiTableHeader hdr; + EfiStatus (*get_time)(EfiTime* time, EfiTimeCapabilities* capabilities); + EfiStatus (*set_time)(EfiTime* time); + EfiStatus (*get_wakeup_time)(bool* enabled, bool* pending, EfiTime* time); + EfiStatus (*set_wakeup_time)(bool enable, EfiTime* time); + EfiStatus (*set_virtual_address_map)(size_t memory_map_size, + size_t descriptor_size, + uint32_t descriptor_version, + EfiMemoryDescriptor* virtual_map); + EfiStatus (*convert_pointer)(size_t debug_disposition, void** address); + EfiStatus (*get_variable)(const char16_t* variable_name, + const EfiGuid* vendor_guid, uint32_t* attributes, + size_t* data_size, void* data); + EfiStatus (*get_next_variable_name)(size_t* variable_name_size, + char16_t* variable_name, + EfiGuid* vendor_guid); + EfiStatus (*set_variable)(const char16_t* variable_name, + const EfiGuid* vendor_guid, uint32_t attributes, + size_t data_size, void* data); + EfiStatus (*get_next_high_monotonic_count)(uint32_t* high_count); + void (*reset_system)(EfiResetType reset_type, EfiStatus reset_status, + size_t data_size, void* reset_data); + EfiStatus (*update_capsule)(EfiCapsuleHeader** capsule_header_array, + size_t capsule_count, + EfiPhysicalAddr scatter_gather_list); + EfiStatus (*query_capsule_capabilities)( + EfiCapsuleHeader** capsule_header_array, size_t capsule_count, + uint64_t* maximum_capsule_size, EfiResetType* reset_type); + EfiStatus (*query_variable_info)(uint32_t attributes, + uint64_t* maximum_variable_storage_size, + uint64_t* remaining_variable_storage_size, + uint64_t* maximum_variable_size); +} EfiRuntimeService; + +#endif // __RUNTIME_SERVICE_H__
\ No newline at end of file diff --git a/gbl/libefi/defs/system_table.h b/gbl/libefi/defs/system_table.h index 92beb68..5319c98 100644 --- a/gbl/libefi/defs/system_table.h +++ b/gbl/libefi/defs/system_table.h @@ -22,6 +22,7 @@ #include "boot_service.h" #include "protocols/simple_text_output_protocol.h" +#include "runtime_service.h" typedef struct { EfiGuid vendor_guid; @@ -38,7 +39,7 @@ typedef struct EfiSystemTable { EfiSimpleTextOutputProtocol* con_out; EfiHandle standard_error_handle; EfiSimpleTextOutputProtocol* std_err; - void* runtime_service; + EfiRuntimeService* runtime_services; EfiBootService* boot_services; size_t number_of_table_entries; const EfiConfigurationTable* configuration_table; diff --git a/gbl/libefi/defs/types.h b/gbl/libefi/defs/types.h index 8f8f93d..41308f2 100644 --- a/gbl/libefi/defs/types.h +++ b/gbl/libefi/defs/types.h @@ -18,6 +18,13 @@ #ifndef __EFI_TYPES_H__ #define __EFI_TYPES_H__ +typedef void* EfiHandle; +typedef uint8_t char8_t; +typedef uint16_t char16_t; +typedef void* EfiEvent; +typedef uint64_t EfiPhysicalAddr; +typedef uint64_t EfiVirtualAddr; + typedef struct EfiTableHeader { uint64_t signature; uint32_t revision; @@ -33,11 +40,41 @@ typedef struct EfiGuid { uint8_t data4[8]; } EfiGuid; -typedef void* EfiHandle; -typedef uint16_t char16_t; -typedef void* EfiEvent; -typedef uint64_t EfiPhysicalAddr; -typedef uint64_t EfiVirtualAddr; +typedef struct EfiMemoryDescriptor { + uint32_t memory_type; + uint32_t padding; + EfiPhysicalAddr physical_start; + EfiVirtualAddr virtual_start; + uint64_t number_of_pages; + uint64_t attributes; +} EfiMemoryDescriptor; + +typedef struct EfiTime { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; + uint8_t pad1; + uint32_t nanosecond; + int16_t timezone; + uint8_t daylight; + uint8_t pad2; +} EfiTime; + +typedef struct EfiTimeCapabilities { + uint32_t resolution; + uint32_t accuracy; + bool sets_to_zero; +} EfiTimeCapabilities; + +typedef struct EfiCapsuleHeader { + EfiGuid CapsuleGuid; + uint32_t HeaderSize; + uint32_t Flags; + uint32_t CapsuleImageSize; +} EfiCapsuleHeader; typedef void (*EfiEventNotify)(EfiEvent event, void* ctx); @@ -80,6 +117,15 @@ typedef enum { typedef EFI_MEMORY_TYPE EfiMemoryType; +typedef enum { + EFI_RESET_COLD, + EFI_RESET_WARM, + EFI_RESET_SHUTDOWN, + EFI_RESET_PLATFORM_SPECIFIC +} EFI_RESET_TYPE; + +typedef EFI_RESET_TYPE EfiResetType; + #define EFI_ERROR_MASK ((uintptr_t)INTPTR_MAX + 1) #define EFI_ERR(x) (EFI_ERROR_MASK | (x)) diff --git a/gbl/libefi/src/lib.rs b/gbl/libefi/src/lib.rs index f2d0e84..3ad68cb 100644 --- a/gbl/libefi/src/lib.rs +++ b/gbl/libefi/src/lib.rs @@ -50,6 +50,9 @@ #![cfg_attr(not(test), no_std)] +extern crate alloc; +use alloc::vec::Vec; + use core::ptr::null_mut; use core::slice::from_raw_parts; #[cfg(not(test))] @@ -217,6 +220,14 @@ impl<'a> SystemTable<'a> { } } + /// Creates an instance of `RuntimeServices` + pub fn runtime_services(&self) -> RuntimeServices<'a> { + RuntimeServices { + // SAFETY: Pointers to UEFI data strucutres. + runtime_services: unsafe { self.table.runtime_services.as_ref() }.unwrap(), + } + } + /// Gets the `EFI_SYSTEM_TABLE.ConOut` field. pub fn con_out(&self) -> EfiResult<Protocol<'a, SimpleTextOutputProtocol>> { // SAFETY: `EFI_SYSTEM_TABLE.ConOut` is a pointer to EfiSimpleTextOutputProtocol structure @@ -467,6 +478,39 @@ impl<'a> BootServices<'a> { } } +/// `RuntimeServices` provides methods for accessing various EFI_RUNTIME_SERVICES interfaces. +#[derive(Clone, Copy)] +pub struct RuntimeServices<'a> { + runtime_services: &'a EfiRuntimeService, +} + +impl<'a> RuntimeServices<'a> { + /// Wrapper of `EFI_RUNTIME_SERVICES.GetVariable()`. + pub fn get_variable(&self, guid: &EfiGuid, name: &str, out: &mut [u8]) -> EfiResult<usize> { + let mut size = out.len(); + + let mut name_utf16: Vec<u16> = name.encode_utf16().collect(); + name_utf16.push(0); // null-terminator + + // SAFETY: + // * `&mut size` and `&mut out` are input/output params only and will not be retained + // * `&mut size` and `&mut out` are valid pointers and outlive the call + match unsafe { + efi_call!( + self.runtime_services.get_variable, + name_utf16.as_ptr(), + guid, + null_mut(), + &mut size, + out.as_mut_ptr() as *mut core::ffi::c_void + ) + } { + Ok(()) => Ok(size), + Err(e) => Err(e), + } + } +} + /// EFI Event type to pass to BootServicess::create_event; #[repr(u32)] pub enum EventType { |