Skip to content

Commit

Permalink
test-runner: Improve uninstall_protocol_interface example
Browse files Browse the repository at this point in the history
If a protocol is installed with a data pointer, you have to pass that same
pointer in when uninstalling the interface. Update the test runner to
demonstrate how to do this by opening the protocol and converting the
ScopedProtocol to a raw pointer.
  • Loading branch information
nicholasbishop authored and phip1611 committed Nov 12, 2023
1 parent f8168f7 commit 4e43642
Showing 1 changed file with 40 additions and 4 deletions.
44 changes: 40 additions & 4 deletions uefi-test-runner/src/boot/misc.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
use core::ffi::c_void;
use core::ptr::{self, NonNull};

use core::mem;
use uefi::proto::unsafe_protocol;
use uefi::table::boot::{BootServices, EventType, MemoryType, SearchType, TimerTrigger, Tpl};
use uefi::table::boot::{
BootServices, EventType, MemoryType, OpenProtocolAttributes, OpenProtocolParams, SearchType,
TimerTrigger, Tpl,
};
use uefi::table::{Boot, SystemTable};
use uefi::{guid, Event, Guid, Identify};

Expand Down Expand Up @@ -84,7 +88,9 @@ fn test_watchdog(bt: &BootServices) {

/// Dummy protocol for tests
#[unsafe_protocol("1a972918-3f69-4b5d-8cb4-cece2309c7f5")]
struct TestProtocol {}
struct TestProtocol {
data: u32,
}

unsafe extern "efiapi" fn _test_notify(_event: Event, _context: Option<NonNull<c_void>>) {
info!("Protocol was (re)installed and this function notified.")
Expand All @@ -109,8 +115,17 @@ fn test_register_protocol_notify(bt: &BootServices) {
fn test_install_protocol_interface(bt: &BootServices) {
info!("Installing TestProtocol");

let alloc: *mut TestProtocol = bt
.allocate_pool(
MemoryType::BOOT_SERVICES_DATA,
mem::size_of::<TestProtocol>(),
)
.unwrap()
.cast();
unsafe { alloc.write(TestProtocol { data: 123 }) };

let _ = unsafe {
bt.install_protocol_interface(None, &TestProtocol::GUID, ptr::null_mut())
bt.install_protocol_interface(None, &TestProtocol::GUID, alloc.cast())
.expect("Failed to install protocol interface")
};

Expand All @@ -137,13 +152,34 @@ fn test_reinstall_protocol_interface(bt: &BootServices) {

fn test_uninstall_protocol_interface(bt: &BootServices) {
info!("Uninstalling TestProtocol");

let handle = bt
.locate_handle_buffer(SearchType::from_proto::<TestProtocol>())
.expect("Failed to find protocol to uninstall")[0];

unsafe {
bt.uninstall_protocol_interface(handle, &TestProtocol::GUID, ptr::null_mut())
// Uninstalling a protocol interface requires knowing the interface
// pointer. Open the protocol to get that pointer, making sure to drop
// the `ScopedProtocol` _before_ uninstalling the protocol interface.
let interface_ptr: *mut TestProtocol = {
let mut sp = bt
.open_protocol::<TestProtocol>(
OpenProtocolParams {
handle,
agent: bt.image_handle(),
controller: None,
},
OpenProtocolAttributes::GetProtocol,
)
.unwrap();
assert_eq!(sp.data, 123);
&mut *sp
};

bt.uninstall_protocol_interface(handle, &TestProtocol::GUID, interface_ptr.cast())
.expect("Failed to uninstall protocol interface");

bt.free_pool(interface_ptr.cast()).unwrap();
}
}

Expand Down

0 comments on commit 4e43642

Please sign in to comment.