|
2 | 2 | //!
|
3 | 3 | //! These functions will panic if called after exiting boot services.
|
4 | 4 |
|
5 |
| -pub use crate::table::boot::{ |
6 |
| - AllocateType, EventNotifyFn, LoadImageSource, OpenProtocolAttributes, OpenProtocolParams, |
7 |
| - ProtocolSearchKey, SearchType, TimerTrigger, |
8 |
| -}; |
9 | 5 | pub use uefi_raw::table::boot::{EventType, MemoryAttribute, MemoryDescriptor, MemoryType, Tpl};
|
10 | 6 |
|
11 | 7 | use crate::data_types::PhysicalAddress;
|
12 | 8 | use crate::mem::memory_map::{MemoryMapBackingMemory, MemoryMapKey, MemoryMapMeta, MemoryMapOwned};
|
13 | 9 | use crate::polyfill::maybe_uninit_slice_assume_init_ref;
|
14 |
| -use crate::proto::device_path::DevicePath; |
15 | 10 | #[cfg(doc)]
|
16 | 11 | use crate::proto::device_path::LoadedImageDevicePath;
|
| 12 | +use crate::proto::device_path::{DevicePath, FfiDevicePath}; |
17 | 13 | use crate::proto::loaded_image::LoadedImage;
|
18 | 14 | use crate::proto::media::fs::SimpleFileSystem;
|
19 |
| -use crate::proto::{Protocol, ProtocolPointer}; |
| 15 | +use crate::proto::{BootPolicy, Protocol, ProtocolPointer}; |
20 | 16 | use crate::runtime::{self, ResetType};
|
21 | 17 | use crate::table::Revision;
|
22 | 18 | use crate::util::opt_nonnull_to_ptr;
|
@@ -1438,3 +1434,206 @@ impl Drop for TplGuard {
|
1438 | 1434 | }
|
1439 | 1435 | }
|
1440 | 1436 | }
|
| 1437 | + |
| 1438 | +// OpenProtocolAttributes is safe to model as a regular enum because it |
| 1439 | +// is only used as an input. The attributes are bitflags, but all valid |
| 1440 | +// combinations are listed in the spec and only ByDriver and Exclusive |
| 1441 | +// can actually be combined. |
| 1442 | +// |
| 1443 | +// Some values intentionally excluded: |
| 1444 | +// |
| 1445 | +// ByHandleProtocol (0x01) excluded because it is only intended to be |
| 1446 | +// used in an implementation of `HandleProtocol`. |
| 1447 | +// |
| 1448 | +// TestProtocol (0x04) excluded because it doesn't actually open the |
| 1449 | +// protocol, just tests if it's present on the handle. Since that |
| 1450 | +// changes the interface significantly, that's exposed as a separate |
| 1451 | +// method: `BootServices::test_protocol`. |
| 1452 | + |
| 1453 | +/// Attributes for [`open_protocol`]. |
| 1454 | +#[repr(u32)] |
| 1455 | +#[derive(Debug)] |
| 1456 | +pub enum OpenProtocolAttributes { |
| 1457 | + /// Used by drivers to get a protocol interface for a handle. The |
| 1458 | + /// driver will not be informed if the interface is uninstalled or |
| 1459 | + /// reinstalled. |
| 1460 | + GetProtocol = 0x02, |
| 1461 | + |
| 1462 | + /// Used by bus drivers to show that a protocol is being used by one |
| 1463 | + /// of the child controllers of the bus. |
| 1464 | + ByChildController = 0x08, |
| 1465 | + |
| 1466 | + /// Used by a driver to gain access to a protocol interface. When |
| 1467 | + /// this mode is used, the driver's `Stop` function will be called |
| 1468 | + /// if the protocol interface is reinstalled or uninstalled. Once a |
| 1469 | + /// protocol interface is opened with this attribute, no other |
| 1470 | + /// drivers will be allowed to open the same protocol interface with |
| 1471 | + /// the `ByDriver` attribute. |
| 1472 | + ByDriver = 0x10, |
| 1473 | + |
| 1474 | + /// Used by a driver to gain exclusive access to a protocol |
| 1475 | + /// interface. If any other drivers have the protocol interface |
| 1476 | + /// opened with an attribute of `ByDriver`, then an attempt will be |
| 1477 | + /// made to remove them with `DisconnectController`. |
| 1478 | + ByDriverExclusive = 0x30, |
| 1479 | + |
| 1480 | + /// Used by applications to gain exclusive access to a protocol |
| 1481 | + /// interface. If any drivers have the protocol opened with an |
| 1482 | + /// attribute of `ByDriver`, then an attempt will be made to remove |
| 1483 | + /// them by calling the driver's `Stop` function. |
| 1484 | + Exclusive = 0x20, |
| 1485 | +} |
| 1486 | + |
| 1487 | +/// Parameters passed to [`open_protocol`]. |
| 1488 | +#[derive(Debug)] |
| 1489 | +pub struct OpenProtocolParams { |
| 1490 | + /// The handle for the protocol to open. |
| 1491 | + pub handle: Handle, |
| 1492 | + |
| 1493 | + /// The handle of the calling agent. For drivers, this is the handle |
| 1494 | + /// containing the `EFI_DRIVER_BINDING_PROTOCOL` instance. For |
| 1495 | + /// applications, this is the image handle. |
| 1496 | + pub agent: Handle, |
| 1497 | + |
| 1498 | + /// For drivers, this is the controller handle that requires the |
| 1499 | + /// protocol interface. For applications this should be set to |
| 1500 | + /// `None`. |
| 1501 | + pub controller: Option<Handle>, |
| 1502 | +} |
| 1503 | + |
| 1504 | +/// Used as a parameter of [`load_image`] to provide the image source. |
| 1505 | +#[derive(Debug)] |
| 1506 | +pub enum LoadImageSource<'a> { |
| 1507 | + /// Load an image from a buffer. The data will be copied from the |
| 1508 | + /// buffer, so the input reference doesn't need to remain valid |
| 1509 | + /// after the image is loaded. |
| 1510 | + FromBuffer { |
| 1511 | + /// Raw image data. |
| 1512 | + buffer: &'a [u8], |
| 1513 | + |
| 1514 | + /// If set, this path will be added as the file path of the |
| 1515 | + /// loaded image. This is not required to load the image, but |
| 1516 | + /// may be used by the image itself to load other resources |
| 1517 | + /// relative to the image's path. |
| 1518 | + file_path: Option<&'a DevicePath>, |
| 1519 | + }, |
| 1520 | + |
| 1521 | + /// Load an image via the [`SimpleFileSystem`] protocol. If there is |
| 1522 | + /// no instance of that protocol associated with the path then the |
| 1523 | + /// behavior depends on [`BootPolicy`]. If [`BootPolicy::BootSelection`], |
| 1524 | + /// attempt to load via the [`LoadFile`] protocol. If |
| 1525 | + /// [`BootPolicy::ExactMatch`], attempt to load via the [`LoadFile2`] |
| 1526 | + /// protocol, then fall back to [`LoadFile`]. |
| 1527 | + /// |
| 1528 | + /// [`LoadFile`]: crate::proto::media::load_file::LoadFile |
| 1529 | + /// [`LoadFile2`]: crate::proto::media::load_file::LoadFile2 |
| 1530 | + FromDevicePath { |
| 1531 | + /// The full device path from which to load the image. |
| 1532 | + /// |
| 1533 | + /// The provided path should be a full device path and not just the |
| 1534 | + /// file path portion of it. So for example, it must be (the binary |
| 1535 | + /// representation) |
| 1536 | + /// `PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0xFFFF,0x0)/HD(1,MBR,0xBE1AFDFA,0x3F,0xFBFC1)/\\EFI\\BOOT\\BOOTX64.EFI` |
| 1537 | + /// and not just `\\EFI\\BOOT\\BOOTX64.EFI`. |
| 1538 | + device_path: &'a DevicePath, |
| 1539 | + |
| 1540 | + /// The [`BootPolicy`] to use. |
| 1541 | + boot_policy: BootPolicy, |
| 1542 | + }, |
| 1543 | +} |
| 1544 | + |
| 1545 | +impl<'a> LoadImageSource<'a> { |
| 1546 | + /// Returns the raw FFI parameters for `load_image`. |
| 1547 | + #[must_use] |
| 1548 | + pub(crate) fn to_ffi_params( |
| 1549 | + &self, |
| 1550 | + ) -> ( |
| 1551 | + BootPolicy, |
| 1552 | + *const FfiDevicePath, |
| 1553 | + *const u8, /* buffer */ |
| 1554 | + usize, /* buffer length */ |
| 1555 | + ) { |
| 1556 | + let boot_policy; |
| 1557 | + let device_path; |
| 1558 | + let source_buffer; |
| 1559 | + let source_size; |
| 1560 | + match self { |
| 1561 | + LoadImageSource::FromBuffer { buffer, file_path } => { |
| 1562 | + // Boot policy is ignored when loading from source buffer. |
| 1563 | + boot_policy = BootPolicy::default(); |
| 1564 | + |
| 1565 | + device_path = file_path.map(|p| p.as_ffi_ptr()).unwrap_or(ptr::null()); |
| 1566 | + source_buffer = buffer.as_ptr(); |
| 1567 | + source_size = buffer.len(); |
| 1568 | + } |
| 1569 | + LoadImageSource::FromDevicePath { |
| 1570 | + device_path: d_path, |
| 1571 | + boot_policy: b_policy, |
| 1572 | + } => { |
| 1573 | + boot_policy = *b_policy; |
| 1574 | + device_path = d_path.as_ffi_ptr(); |
| 1575 | + source_buffer = ptr::null(); |
| 1576 | + source_size = 0; |
| 1577 | + } |
| 1578 | + }; |
| 1579 | + (boot_policy, device_path, source_buffer, source_size) |
| 1580 | + } |
| 1581 | +} |
| 1582 | + |
| 1583 | +/// Type of allocation to perform. |
| 1584 | +#[derive(Debug, Copy, Clone)] |
| 1585 | +pub enum AllocateType { |
| 1586 | + /// Allocate any possible pages. |
| 1587 | + AnyPages, |
| 1588 | + /// Allocate pages at any address below the given address. |
| 1589 | + MaxAddress(PhysicalAddress), |
| 1590 | + /// Allocate pages at the specified address. |
| 1591 | + Address(PhysicalAddress), |
| 1592 | +} |
| 1593 | + |
| 1594 | +/// The type of handle search to perform. |
| 1595 | +#[derive(Debug, Copy, Clone)] |
| 1596 | +pub enum SearchType<'guid> { |
| 1597 | + /// Return all handles present on the system. |
| 1598 | + AllHandles, |
| 1599 | + /// Returns all handles supporting a certain protocol, specified by its GUID. |
| 1600 | + /// |
| 1601 | + /// If the protocol implements the `Protocol` interface, |
| 1602 | + /// you can use the `from_proto` function to construct a new `SearchType`. |
| 1603 | + ByProtocol(&'guid Guid), |
| 1604 | + /// Return all handles that implement a protocol when an interface for that protocol |
| 1605 | + /// is (re)installed. |
| 1606 | + ByRegisterNotify(ProtocolSearchKey), |
| 1607 | +} |
| 1608 | + |
| 1609 | +impl<'guid> SearchType<'guid> { |
| 1610 | + /// Constructs a new search type for a specified protocol. |
| 1611 | + #[must_use] |
| 1612 | + pub const fn from_proto<P: ProtocolPointer + ?Sized>() -> Self { |
| 1613 | + SearchType::ByProtocol(&P::GUID) |
| 1614 | + } |
| 1615 | +} |
| 1616 | + |
| 1617 | +/// Event notification callback type. |
| 1618 | +pub type EventNotifyFn = unsafe extern "efiapi" fn(event: Event, context: Option<NonNull<c_void>>); |
| 1619 | + |
| 1620 | +/// Timer events manipulation. |
| 1621 | +#[derive(Debug)] |
| 1622 | +pub enum TimerTrigger { |
| 1623 | + /// Cancel event's timer |
| 1624 | + Cancel, |
| 1625 | + /// The event is to be signaled periodically. |
| 1626 | + /// Parameter is the period in 100ns units. |
| 1627 | + /// Delay of 0 will be signalled on every timer tick. |
| 1628 | + Periodic(u64), |
| 1629 | + /// The event is to be signaled once in 100ns units. |
| 1630 | + /// Parameter is the delay in 100ns units. |
| 1631 | + /// Delay of 0 will be signalled on next timer tick. |
| 1632 | + Relative(u64), |
| 1633 | +} |
| 1634 | + |
| 1635 | +/// Opaque pointer returned by [`register_protocol_notify`] to be used |
| 1636 | +/// with [`locate_handle`] via [`SearchType::ByRegisterNotify`]. |
| 1637 | +#[derive(Debug, Clone, Copy)] |
| 1638 | +#[repr(transparent)] |
| 1639 | +pub struct ProtocolSearchKey(pub(crate) NonNull<c_void>); |
0 commit comments