Skip to content

Commit 999bea7

Browse files
josephlrGabrielMajeri
authored andcommitted
Add support for locate_protocol
This fixes #79 and allows users to avoid allocating when they just want to find a single implementer of a protocol.
1 parent 02616ac commit 999bea7

File tree

7 files changed

+21
-38
lines changed

7 files changed

+21
-38
lines changed

src/table/boot.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,11 @@ pub struct BootServices {
103103
// Library services
104104
protocols_per_handle: usize,
105105
locate_handle_buffer: usize,
106-
locate_protocol: usize,
106+
locate_protocol: extern "win64" fn(
107+
proto: &Guid,
108+
registration: *mut c_void,
109+
out_proto: &mut *mut c_void,
110+
) -> Status,
107111
install_multiple_protocol_interfaces: usize,
108112
uninstall_multiple_protocol_interfaces: usize,
109113

@@ -446,6 +450,17 @@ impl BootServices {
446450
unsafe { (self.set_watchdog_timer)(timeout, watchdog_code, data_len, data) }.into()
447451
}
448452

453+
/// Returns a protocol implementation, if present on the system.
454+
///
455+
/// The caveats of `BootServices::handle_protocol()` also apply here.
456+
pub fn locate_protocol<P: Protocol>(&self) -> Result<&UnsafeCell<P>> {
457+
let mut ptr = ptr::null_mut();
458+
(self.locate_protocol)(&P::GUID, ptr::null_mut(), &mut ptr).into_with_val(|| {
459+
let ptr = ptr as *mut P as *mut UnsafeCell<P>;
460+
unsafe { &*ptr }
461+
})
462+
}
463+
449464
/// Copies memory from source to destination. The buffers can overlap.
450465
///
451466
/// This function is unsafe as it can be used to violate most safety

uefi-exts/src/boot.rs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use core::cell::UnsafeCell;
21
use uefi::proto::Protocol;
32
use uefi::table::boot::{BootServices, SearchType};
43
use uefi::{Handle, Result};
@@ -9,11 +8,6 @@ use crate::alloc::vec::Vec;
98
pub trait BootServicesExt {
109
/// Returns all the handles implementing a certain protocol.
1110
fn find_handles<P: Protocol>(&self) -> Result<Vec<Handle>>;
12-
13-
/// Returns a protocol implementation, if present on the system.
14-
///
15-
/// The caveats of `BootServices::handle_protocol()` also apply here.
16-
fn find_protocol<P: Protocol>(&self) -> Result<&UnsafeCell<P>>;
1711
}
1812

1913
impl BootServicesExt for BootServices {
@@ -44,23 +38,4 @@ impl BootServicesExt for BootServices {
4438
.into_with_val(|| buffer)
4539
.map(|completion| completion.with_status(status2))
4640
}
47-
48-
fn find_protocol<P: Protocol>(&self) -> Result<&UnsafeCell<P>> {
49-
// Retrieve all handles implementing this.
50-
let (status1, handles) = self.find_handles::<P>()?.split();
51-
52-
// There should be at least one, otherwise find_handles would have
53-
// aborted with a NOT_FOUND error.
54-
let handle = *handles.first().unwrap();
55-
56-
// Similarly, if the search is implemented properly, trying to open
57-
// the first output handle should always succeed
58-
// FIXME: Consider using the EFI 1.1 LocateProtocol API instead
59-
let (status2, protocol) = self.handle_protocol::<P>(handle)?.split();
60-
61-
// Emit output, with warnings
62-
status1
63-
.into_with_val(|| protocol)
64-
.map(|completion| completion.with_status(status2))
65-
}
6641
}

uefi-test-runner/src/main.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use core::mem;
1414
use uefi::prelude::*;
1515
use uefi::proto::console::serial::Serial;
1616
use uefi::table::boot::MemoryDescriptor;
17-
use uefi_exts::BootServicesExt;
1817

1918
mod boot;
2019
mod proto;
@@ -67,7 +66,7 @@ fn check_screenshot(bt: &BootServices, name: &str) {
6766
if cfg!(feature = "qemu") {
6867
// Access the serial port (in a QEMU environment, it should always be there)
6968
let serial = bt
70-
.find_protocol::<Serial>()
69+
.locate_protocol::<Serial>()
7170
.expect_success("Could not find serial port");
7271
let serial = unsafe { &mut *serial.get() };
7372

uefi-test-runner/src/proto/console/gop.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use uefi::prelude::*;
22
use uefi::proto::console::gop::{BltOp, BltPixel, FrameBuffer, GraphicsOutput, PixelFormat};
33
use uefi::table::boot::BootServices;
4-
use uefi_exts::BootServicesExt;
54

65
pub fn test(bt: &BootServices) {
76
info!("Running graphics output protocol test");
8-
if let Ok(gop) = bt.find_protocol::<GraphicsOutput>() {
7+
if let Ok(gop) = bt.locate_protocol::<GraphicsOutput>() {
98
let gop = gop.expect("Warnings encountered while opening GOP");
109
let gop = unsafe { &mut *gop.get() };
1110

uefi-test-runner/src/proto/console/pointer.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@ use uefi::prelude::*;
22
use uefi::proto::console::pointer::Pointer;
33
use uefi::table::boot::BootServices;
44

5-
use uefi_exts::BootServicesExt;
6-
75
pub fn test(bt: &BootServices) {
86
info!("Running pointer protocol test");
9-
if let Ok(pointer) = bt.find_protocol::<Pointer>() {
7+
if let Ok(pointer) = bt.locate_protocol::<Pointer>() {
108
let pointer = pointer.expect("Warnings encountered while opening pointer protocol");
119
let pointer = unsafe { &mut *pointer.get() };
1210

uefi-test-runner/src/proto/console/serial.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use uefi::prelude::*;
22
use uefi::proto::console::serial::{ControlBits, Serial};
33
use uefi::table::boot::BootServices;
4-
use uefi_exts::BootServicesExt;
54

65
pub fn test(bt: &BootServices) {
76
info!("Running serial protocol test");
8-
if let Ok(serial) = bt.find_protocol::<Serial>() {
7+
if let Ok(serial) = bt.locate_protocol::<Serial>() {
98
let serial = serial.expect("Warnings encountered while opening serial protocol");
109
let serial = unsafe { &mut *serial.get() };
1110

uefi-test-runner/src/proto/debug.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
use uefi::proto::debug::DebugSupport;
22
use uefi::table::boot::BootServices;
33

4-
use uefi_exts::BootServicesExt;
5-
64
pub fn test(bt: &BootServices) {
75
info!("Running UEFI debug connection protocol test");
8-
if let Ok(debug_support) = bt.find_protocol::<DebugSupport>() {
6+
if let Ok(debug_support) = bt.locate_protocol::<DebugSupport>() {
97
let debug_support =
108
debug_support.expect("Warnings encountered while opening debug support protocol");
119
let debug_support = unsafe { &mut *debug_support.get() };

0 commit comments

Comments
 (0)