Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add (Un)Installing Multiple Protocol Interfaces #675

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

HTGAzureX1212
Copy link
Contributor

@HTGAzureX1212 HTGAzureX1212 commented Mar 4, 2023

This (currently draft) PR proposes the addition for support for missing functions EFI_BOOT_SERVICES.InstallMultipleProtocolInterfaces() and EFI_BOOT_SERVICES.UninstallMultipleProtocolInterfaces().

This was previously blocked due to lack of support for varargs in EFIAPI. (Still need some assistance on the actual wrapper implementation).

Currently blocked on regular functions not supporting variadics, probably need to find a workaround for this.

Checklist

  • Sensible git history (for example, squash "typo" or "fix" commits). See the Rewriting History guide for help.
  • Update the changelog (if necessary)

/// * [`uefi::Status::ALREADY_STARTED`]
/// * [`uefi::Status::INVALID_PARAMETER`]
/// * [`uefi::Status::OUT_OF_RESOURCES`]
pub fn install_multiple_protocol_interfaces(&self, handle: Handle, mut args: ...) -> Result {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should either mark this as unsafe, as we do not guarantee any type-safety here, or do not support the UEFI function at all but build a custom solution around install_protocol_interface, which is well typed.

What do you think, @nicholasbishop ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to construct a VaList in Rust? I don't see a way after looking at the docs a bit but I'm not that familiar with the feature. Basically what I'm thinking is, we'd have the safe wrapper here take a slice of (&Guid, *mut c_void) pairs, then convert that into a valist for calling the underlying UEFI function.

If we can't do that, then I think marking this function unsafe is the right thing to do.

Incidentally, I have previously wondered why InstallMultipleProtocolInterfaces matters since it seems like you could just call InstallProtocolInterface multiple times. https://uefi.org/specs/UEFI/2.10/07_Services_Boot_Services.html#driver-model-boot-services says:

The third group of boot services is designed to help simplify the implementation of drivers, and produce drivers with smaller executable footprints. [...] The EFI_BOOT_SERVICES.InstallMultipleProtocolInterfaces() and EFI_BOOT_SERVICES.UninstallMultipleProtocolInterfaces() are very useful to driver writers. These boot services allow one or more protocol interfaces to be added or removed from a handle. In addition, InstallMultipleProtocolInterfaces() guarantees that a duplicate device path is never added to the handle database. This is very useful to bus drivers that can create one child handle at a time, because it guarantees that the bus driver will not inadvertently create two instances of the same child handle.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should either mark this as unsafe, as we do not guarantee any type-safety here, or do not support the UEFI function at all but build a custom solution around install_protocol_interface, which is well typed.

What do you think, @nicholasbishop ?

This can potentially a solution. But I will look into passing variadic arguments for this function.

@@ -58,7 +58,7 @@
//! [`uefi-services`]: https://crates.io/crates/uefi-services
//! [unstable features]: https://doc.rust-lang.org/unstable-book/

#![feature(abi_efiapi)]
#![feature(extended_varargs_abi_support)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be gated behind the unstable feature since we are looking to transition to the stable channel by default in 1.68. See the following cfg_attr line for what that looks like.

/// * [`uefi::Status::ALREADY_STARTED`]
/// * [`uefi::Status::INVALID_PARAMETER`]
/// * [`uefi::Status::OUT_OF_RESOURCES`]
pub fn install_multiple_protocol_interfaces(&self, handle: Handle, mut args: ...) -> Result {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to construct a VaList in Rust? I don't see a way after looking at the docs a bit but I'm not that familiar with the feature. Basically what I'm thinking is, we'd have the safe wrapper here take a slice of (&Guid, *mut c_void) pairs, then convert that into a valist for calling the underlying UEFI function.

If we can't do that, then I think marking this function unsafe is the right thing to do.

Incidentally, I have previously wondered why InstallMultipleProtocolInterfaces matters since it seems like you could just call InstallProtocolInterface multiple times. https://uefi.org/specs/UEFI/2.10/07_Services_Boot_Services.html#driver-model-boot-services says:

The third group of boot services is designed to help simplify the implementation of drivers, and produce drivers with smaller executable footprints. [...] The EFI_BOOT_SERVICES.InstallMultipleProtocolInterfaces() and EFI_BOOT_SERVICES.UninstallMultipleProtocolInterfaces() are very useful to driver writers. These boot services allow one or more protocol interfaces to be added or removed from a handle. In addition, InstallMultipleProtocolInterfaces() guarantees that a duplicate device path is never added to the handle database. This is very useful to bus drivers that can create one child handle at a time, because it guarantees that the bus driver will not inadvertently create two instances of the same child handle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants