poplar/caps.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Capability {
GetFramebuffer,
EarlyLogging,
ServiceProvider,
ServiceUser,
PciBusDriver,
}
pub const CAP_PADDING: u8 = 0x00;
pub const CAP_GET_FRAMEBUFFER: u8 = 0x01;
pub const CAP_EARLY_LOGGING: u8 = 0x02;
pub const CAP_SERVICE_PROVIDER: u8 = 0x03;
pub const CAP_SERVICE_USER: u8 = 0x04;
pub const CAP_PCI_BUS_DRIVER: u8 = 0x05;
/// `N` must be a multiple of 4, and padded with zeros, so the whole descriptor is aligned to a
/// 4-byte boundary.
///
/// This structure can be used to emit an ELF note section containing a list of capabilities. `N` must be a
/// multiple of 4 (padded with `CAP_PADDING`). You can define the capabilities of a task image like so:
/// ```
/// #[used]
/// #[link_section = ".caps"]
/// pub static mut CAPS: CapabilitiesRepr<4> = CapabilitiesRepr::new([CAP_EARLY_LOGGING,
/// CAP_GET_FRAMEBUFFER, CAP_PADDING, CAP_PADDING]);
/// ```
#[repr(C)]
pub struct CapabilitiesRepr<const N: usize> {
name_size: u32,
desc_size: u32,
entry_type: u32,
name: [u8; 8],
desc: [u8; N],
}
impl<const N: usize> CapabilitiesRepr<{ N }> {
pub const fn new(caps: [u8; N]) -> CapabilitiesRepr<{ N }> {
CapabilitiesRepr {
name_size: 6,
desc_size: N as u32,
entry_type: 0,
name: [b'P', b'O', b'P', b'L', b'A', b'R', 0x00, 0x00],
desc: caps,
}
}
}