diff options
| author | 许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com> | 2025-03-05 21:46:40 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-05 21:46:40 +0800 |
| commit | 24d481cc2927d12c343dffb0d103267f978db1bd (patch) | |
| tree | 19b2aa387708872c4743533ca76166be91b4bc0b /library/std/src | |
| parent | fde23c87a55fa82378e15fa2ad7069fced1f978b (diff) | |
| parent | 86aae8e2d626258104cae2725bcdd1a92e572daf (diff) | |
| download | rust-24d481cc2927d12c343dffb0d103267f978db1bd.tar.gz rust-24d481cc2927d12c343dffb0d103267f978db1bd.zip | |
Rollup merge of #137477 - Ayush1325:uefi-service-binding, r=Noratrieb
uefi: Add Service Binding Protocol abstraction - Some UEFI protocols such as TCP4, TCP6, UDP4, UDP6, etc are managed by service binding protocol. - A new instance of such protocols is created and destroyed using the corresponding service binding protocol. - This PR adds abstractions to make using such protocols simpler using Rust Drop trait. - The reason to add these abstractions in a seperate PR from TCP4 Protocol is to make review easier. [EFI_SERVICE_BINDING_PROTCOL](https://uefi.org/specs/UEFI/2.11/11_Protocols_UEFI_Driver_Model.html#efi-service-binding-protocol) cc ````@nicholasbishop````
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/sys/pal/uefi/helpers.rs | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index cb6aacd0063..cca2312c4f9 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -10,7 +10,7 @@ //! - More information about protocols can be found [here](https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/3_foundation/36_protocols_and_handles) use r_efi::efi::{self, Guid}; -use r_efi::protocols::{device_path, device_path_to_text, shell}; +use r_efi::protocols::{device_path, device_path_to_text, service_binding, shell}; use crate::ffi::{OsStr, OsString}; use crate::io::{self, const_error}; @@ -500,3 +500,62 @@ pub(crate) fn get_device_path_from_map(map: &Path) -> io::Result<BorrowedDeviceP Ok(BorrowedDevicePath::new(protocol)) } + +/// Helper for UEFI Protocols which are created and destroyed using +/// [EFI_SERVICE_BINDING_PROTCOL](https://uefi.org/specs/UEFI/2.11/11_Protocols_UEFI_Driver_Model.html#efi-service-binding-protocol) +pub(crate) struct ServiceProtocol { + service_guid: r_efi::efi::Guid, + handle: NonNull<crate::ffi::c_void>, + child_handle: NonNull<crate::ffi::c_void>, +} + +impl ServiceProtocol { + #[expect(dead_code)] + pub(crate) fn open(service_guid: r_efi::efi::Guid) -> io::Result<Self> { + let handles = locate_handles(service_guid)?; + + for handle in handles { + if let Ok(protocol) = open_protocol::<service_binding::Protocol>(handle, service_guid) { + let Ok(child_handle) = Self::create_child(protocol) else { + continue; + }; + + return Ok(Self { service_guid, handle, child_handle }); + } + } + + Err(io::const_error!(io::ErrorKind::NotFound, "no service binding protocol found")) + } + + #[expect(dead_code)] + pub(crate) fn child_handle(&self) -> NonNull<crate::ffi::c_void> { + self.child_handle + } + + fn create_child( + sbp: NonNull<service_binding::Protocol>, + ) -> io::Result<NonNull<crate::ffi::c_void>> { + let mut child_handle: r_efi::efi::Handle = crate::ptr::null_mut(); + // SAFETY: A new handle is allocated if a pointer to NULL is passed. + let r = unsafe { ((*sbp.as_ptr()).create_child)(sbp.as_ptr(), &mut child_handle) }; + + if r.is_error() { + Err(crate::io::Error::from_raw_os_error(r.as_usize())) + } else { + NonNull::new(child_handle) + .ok_or(const_error!(io::ErrorKind::Other, "null child handle")) + } + } +} + +impl Drop for ServiceProtocol { + fn drop(&mut self) { + if let Ok(sbp) = open_protocol::<service_binding::Protocol>(self.handle, self.service_guid) + { + // SAFETY: Child handle must be allocated by the current service binding protocol. + let _ = unsafe { + ((*sbp.as_ptr()).destroy_child)(sbp.as_ptr(), self.child_handle.as_ptr()) + }; + } + } +} |
