uefi-rs icon indicating copy to clipboard operation
uefi-rs copied to clipboard

OpenProtocolAttributes missing EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL

Open ori-sky opened this issue 3 years ago • 2 comments

The OpenProtocolAttributes enum is currently missing a representation of the EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL value defined by UEFI. Without this, there doesn't seem to be a way to directly open a protocol from a specified handle non-exclusively. Some example code:

let boot_services = system_table.boot_services();

let search = SearchType::from_proto::<GraphicsOutput>();
let handle_buffer = boot_services.locate_handle_buffer(search)?;

for handle in handle_buffer.handles() {
    let params = OpenProtocolParams {
        handle: *handle,
        agent: image,
        controller: None
    };
    let attribs = unsafe { core::mem::transmute(1) };
    let gop = unsafe {
        boot_services.open_protocol::<GraphicsOutput>(params, attribs)?
    };

    let modeinfo = gop.current_mode_info();
    let (width, height) = modeinfo.resolution();
    uefi_services::println!("Graphics mode: {}x{}", width, height);
}

When attempting to open the GraphicsOutput protocol exclusively here, an error seems to be encountered, presumably either upon opening the protocol or somewhere in uefi_services::println!, so non-exclusivity seems to be required here. However, the code succeeds when performing the unsafe transmute from 1 (the value that EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL is defined to be).

ori-sky avatar Oct 04 '22 17:10 ori-sky

You can use OpenProtocolAttributes::GetProtocol for that. See https://github.com/rust-osdev/uefi-rs/blob/main/uefi-test-runner/src/proto/console/gop.rs#L5 for an example of this in action.

nicholasbishop avatar Oct 04 '22 17:10 nicholasbishop

It looks like GetProtocol will work in this circumstance so this ticket probably no longer affects me, although more generally GET_PROTOCOL does have the caveat that any notification events created to be signaled upon a protocol being reinstalled will not be notified in the case of the protocol having been opened via GET_PROTOCOL -- only if it has been opened via BY_HANDLE_PROTOCOL, if I'm understanding the UEFI spec correctly.

ori-sky avatar Oct 04 '22 17:10 ori-sky

I question whether anyone has been monitoring this issue, as the last comment was posted two years ago. Regardless, I would like to share my perspective.

only if it has been opened via BY_HANDLE_PROTOCOL, if I'm understanding the UEFI spec correctly.

As per the UEFI specification, BY_HANDLE_PROTOCOL is intended for use within the HandleProtocol() function of the EFI_BOOT_SERVICES. Its name suggests that it is meant to be employed specifically for this purpose.

In my view, the existance of attribute BY_HANDLE_PROTOCOL is intended to give the new API OpenProtocol() a chance to simulate the behavior of the OLD API HandleProtocol().

And the implemention in edk2 processes BY_HANDLE_PROTOCOL and GET_PROTOCOL the SAME way, meaning that there is no notification upon uninstallation/reinstallation of the protocol having been opened using BY_HANDLE_PROTOCOL.

Therefore, I concur with the comment for enum OpenProtocolAttributes:

// ByHandleProtocol (0x01) excluded because it is only intended to be // used in an implementation of HandleProtocol.

JeffLi01 avatar Jun 18 '24 12:06 JeffLi01

I question whether anyone has been monitoring this issue

I wasn't actively paying attention to this issue, but I do I get email notifications for all comments in the repo :)

I'll go ahead and close, it seems like GetHandle is sufficient.

nicholasbishop avatar Jun 19 '24 16:06 nicholasbishop