From b4c36e9c11d93b365cd807209dbc561b9970fb49 Mon Sep 17 00:00:00 2001 From: aticu <15schnic@gmail.com> Date: Tue, 11 Sep 2018 22:41:36 +0200 Subject: [PATCH] Added more documentation, updated edition to 2018. The documentation was added according to http://www.uefi.org/sites/default/files/resources/UEFI%20Spec%202_7_A%20Sept%206.pdf with minor changes to fit the context better. --- Cargo.toml | 3 + src/block_io.rs | 55 ++++++++- src/boot.rs | 224 +++++++++++++++++++++++++++-------- src/capsule.rs | 3 +- src/config.rs | 22 +++- src/device.rs | 3 +- src/fs.rs | 42 ++++--- src/graphics.rs | 205 +++++++++++++++++++++----------- src/guid.rs | 282 +++++++++++++++++++++++++++++++++++++------- src/lib.rs | 42 ++++++- src/loaded_image.rs | 27 ++++- src/memory.rs | 65 +++++----- src/pointer.rs | 61 +++++++++- src/reset.rs | 13 ++ src/runtime.rs | 117 +++++++++--------- src/shell.rs | 14 ++- src/status.rs | 74 +++++++++++- src/system.rs | 58 +++++++-- src/text.rs | 39 +++++- src/time.rs | 89 +++++++++++++- 20 files changed, 1129 insertions(+), 309 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 040996b..70c20b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,6 @@ +cargo-features = ["edition"] + [package] name = "uefi" version = "0.1.0" +edition = "2018" \ No newline at end of file diff --git a/src/block_io.rs b/src/block_io.rs index 0678f9c..57f4751 100644 --- a/src/block_io.rs +++ b/src/block_io.rs @@ -1,24 +1,71 @@ -use status::Status; +//! This protocol provides control over block devices. +use crate::status::Status; +/// Represents block IO media information. #[repr(C)] pub struct BlockIoMedia { + /// The current media ID. If the media changes, this value is + /// changed. pub MediaId: u32, + /// TRUE if the media is removable; otherwise, FALSE. pub RemovableMedia: bool, + /// TRUE if there is a media current ly present in the device; + /// otherwise, FALSE. This field shows the media present status as of + /// the most recent ReadBlocks() or WriteBlocks() call. pub MediaPresent: bool, + /// TRUE if the EFI_BLOCK_IO_PROTOCOL was produced to abstract + /// partition structures on the disk. FALSE if the BLOCK_IO protocol + /// was produced to abstract the logical blocks on a hardware + /// device. pub LogicalPartition: bool, + /// TRUE if the media is marked read-only otherwise, FALSE. This + /// field shows the read-only status as of the most recent + /// WriteBlocks() call. pub ReadOnly: bool, + /// TRUE if the WriteBlocks() function caches write data. pub WriteCaching: bool, + /// The intrinsic block size of the device. If the media changes, then + /// this field is updated.Returns the number of bytes per logical + /// block. For ATA devices, this is reported in IDENTIFY DEVICE data + /// words 117-118 (i.e., Words per Logical Sector) (see ATA8-ACS). + /// For SCSI devices, this is reported in the READ CAPACITY (16) + /// parameter data Logical Block Length In Bytes field (see SBC-3). pub BlockSize: u32, + /// Supplies the alignment requirement for any buffer used in a data + /// transfer. IoAlign values of 0 and 1 mean that the buffer can be + /// placed anywhere in memory. Otherwise, IoAlign must be a + /// power of 2, and the requirement is that the start address of a + /// buffer must be evenly divisible by IoAlign with no remainder. pub IoAlign: u32, - pub LastBlock: u64 + /// The last LBA on the device. If the media changes, then this field is + /// updated. For ATA devices, this is reported in IDENTIFY DEVICE + /// data words 60-61 (i.e., Total number of user addressable logical + /// sectors) (see ATA8-ACS) minus one. For SCSI devices, this is + /// reported in the READ CAPACITY (16) parameter data Returned + /// Logical Block Address field (see SBC-3) minus one. + pub LastBlock: u64, } +/// This protocol provides control over block devices. #[repr(C)] pub struct BlockIo { + /// The revision to which the block IO interface adheres. All future + /// revisions must be backwards compatible. If a future version is + /// not back wards compatible it is not the same GUID. pub Revision: u64, + /// A pointer to the EFI_BLOCK_IO_MEDIA data for this device. pub Media: &'static BlockIoMedia, + /// Resets the block device hardware. pub Reset: extern "win64" fn(&BlockIo, ExtendedVerification: bool) -> Status, - pub ReadBlocks: extern "win64" fn(&BlockIo, MediaId: u32, LBA: u64, BufferSize: usize, Buffer: *mut u8) -> Status, - pub WriteBlocks: extern "win64" fn(&BlockIo, MediaId: u32, LBA: u64, BufferSize: usize, Buffer: *const u8) -> Status, + /// Reads the requested number of blocks from the device. + pub ReadBlocks: + extern "win64" fn(&BlockIo, MediaId: u32, LBA: u64, BufferSize: usize, Buffer: *mut u8) + -> Status, + /// Writes the requested number of blocks to the device. + pub WriteBlocks: + extern "win64" fn(&BlockIo, MediaId: u32, LBA: u64, BufferSize: usize, Buffer: *const u8) + -> Status, + /// Flushes any cache blocks. This function is optional and only + /// needs to be supported on block devices that cache writes. pub FlushBlocks: extern "win64" fn(&BlockIo) -> Status, } diff --git a/src/boot.rs b/src/boot.rs index 11fd5dd..08c383b 100644 --- a/src/boot.rs +++ b/src/boot.rs @@ -1,68 +1,198 @@ -use ::{Event, Handle, TableHeader}; -use guid::Guid; -use memory::{MemoryDescriptor, MemoryType}; -use status::Status; +//! UEFI uses the EFI Boot Services Table, which contains a table header and pointers to all of the boot +//! services. The definition for this table is shown in the following code fragments. Except for the table +//! header, all elements in the EFI Boot Services Tables are prototypes of function pointers to functions +//! as defined in Section 7. The function pointers in this table are not valid after the operating system +//! has taken control of the platform with a call to EFI_BOOT_SERVICES.ExitBootServices(). +use crate::{ + guid::Guid, + memory::{MemoryDescriptor, MemoryType}, + status::Status, + Event, Handle, TableHeader, +}; + +/// Indicates whether Interface is supplied in native form. #[repr(C)] pub enum InterfaceType { - Native + /// Interface is supplied in native form. + Native, } +/// Specifies which handle(s) are to be returned. #[repr(C)] pub enum LocateSearchType { /// Retrieve all the handles in the handle database. AllHandles, - /// Retrieve the next handle fron a RegisterProtocolNotify() event. + /// SearchKey supplies the Registration value returned by + /// EFI_BOOT_SERVICES.RegisterProtocolNotify(). The + /// function returns the next handle that is new for the registration. + /// Only one handle is returned at a time, starting with the first, and the + /// caller must loop until no more handles are returned. Protocol is + /// ignored for this search type. ByRegisterNotify, - /// Retrieve the set of handles from the handle database that support a specified protocol. - ByProtocol + /// All handles that support Protocol are returned. SearchKey is ignored + /// for this search type. + ByProtocol, } +/// Contains a table header and pointers to all of the boot services. #[repr(C)] pub struct BootServices { + /// The table header for the EFI Boot Services Table. This header + /// contains the EFI_BOOT_SERVICES_SIGNATURE and + /// EFI_BOOT_SERVICES_REVISION values along with the size of + /// the EFI_BOOT_SERVICES structure and a 32-bit CRC to verify + /// that the contents of the EFI Boot Services Table are valid. pub Hdr: TableHeader, + /// Raises the task priority level. RaiseTpl: extern "win64" fn(NewTpl: usize) -> usize, + /// Restores/lowers the task priority level. RestoreTpl: extern "win64" fn(OldTpl: usize), - pub AllocatePages: extern "win64" fn(AllocType: usize, MemoryType: MemoryType, Pages: usize, Memory: &mut usize) -> Status, + /// Allocates pages of a particular type. + pub AllocatePages: extern "win64" fn( + AllocType: usize, + MemoryType: MemoryType, + Pages: usize, + Memory: &mut usize, + ) -> Status, + /// Frees allocated pages. pub FreePages: extern "win64" fn(Memory: usize, Pages: usize) -> Status, - pub GetMemoryMap: extern "win64" fn(MemoryMapSize: &mut usize, MemoryMap: *mut MemoryDescriptor, MapKey: &mut usize, DescriptorSize: &mut usize, DescriptorVersion: &mut u32) -> Status, - pub AllocatePool: extern "win64" fn(PoolType: MemoryType, Size: usize, Buffer: &mut usize) -> Status, + /// Returns the current boot services memory map and memory map key. + pub GetMemoryMap: extern "win64" fn( + MemoryMapSize: &mut usize, + MemoryMap: *mut MemoryDescriptor, + MapKey: &mut usize, + DescriptorSize: &mut usize, + DescriptorVersion: &mut u32, + ) -> Status, + /// Allocates a pool of a particular type. + pub AllocatePool: + extern "win64" fn(PoolType: MemoryType, Size: usize, Buffer: &mut usize) -> Status, + /// Frees allocated pool. pub FreePool: extern "win64" fn(Buffer: usize) -> Status, - CreateEvent: extern "win64" fn (), - SetTimer: extern "win64" fn (), - pub WaitForEvent: extern "win64" fn (NumberOfEvents: usize, Event: *const Event, Index: &mut usize) -> Status, - SignalEvent: extern "win64" fn (), - CloseEvent: extern "win64" fn (), - CheckEvent: extern "win64" fn (), - pub InstallProtocolInterface: extern "win64" fn (Handle: &mut Handle, Protocol: &Guid, InterfaceType: InterfaceType, Interface: usize) -> Status, - ReinstallProtocolInterface: extern "win64" fn (), - pub UninstallProtocolInterface: extern "win64" fn (Handle: Handle, Protocol: &Guid, Interface: usize) -> Status, - pub HandleProtocol: extern "win64" fn (Handle: Handle, Protocol: &Guid, Interface: &mut usize) -> Status, + /// Creates a general-purpose event structure. + CreateEvent: extern "win64" fn(), + /// Sets an event to be signaled at a particular time. + SetTimer: extern "win64" fn(), + /// Stops execution until an event is signaled. + pub WaitForEvent: + extern "win64" fn(NumberOfEvents: usize, Event: *const Event, Index: &mut usize) -> Status, + /// Signals an event. + SignalEvent: extern "win64" fn(), + /// Closes and frees an event structure. + CloseEvent: extern "win64" fn(), + /// Checks whether an event is in the signaled state. + CheckEvent: extern "win64" fn(), + /// Installs a protocol interface on a device handle. + pub InstallProtocolInterface: extern "win64" fn( + Handle: &mut Handle, + Protocol: &Guid, + InterfaceType: InterfaceType, + Interface: usize, + ) -> Status, + /// Reinstalls a protocol interface on a device handle. + ReinstallProtocolInterface: extern "win64" fn(), + /// Removes a protocol interface from a device handle. + pub UninstallProtocolInterface: + extern "win64" fn(Handle: Handle, Protocol: &Guid, Interface: usize) -> Status, + /// Queries a handle to determine if it supports a specified protocol. + pub HandleProtocol: + extern "win64" fn(Handle: Handle, Protocol: &Guid, Interface: &mut usize) -> Status, + /// Reserved. Must be NULL. _rsvd: usize, - RegisterProtocolNotify: extern "win64" fn (), - pub LocateHandle: extern "win64" fn (SearchType: LocateSearchType, Protocol: &Guid, SearchKey: usize, BufferSize: &mut usize, Buffer: *mut Handle) -> Status, - LocateDevicePath: extern "win64" fn (), - InstallConfigurationTable: extern "win64" fn (), - pub LoadImage: extern "win64" fn (BootPolicy: bool, ParentImageHandle: Handle, DevicePath: usize /*TODO*/, SourceBuffer: *const u8, SourceSize: usize, ImageHandle: &mut Handle) -> Status, - pub StartImage: extern "win64" fn (ImageHandle: Handle, ExitDataSize: &mut usize, ExitData: &mut *mut u16) -> Status, - pub Exit: extern "win64" fn (ImageHandle: Handle, ExitStatus: isize, ExitDataSize: usize, ExitData: *const u16) -> Status, - UnloadImage: extern "win64" fn (), - pub ExitBootServices: extern "win64" fn (ImageHandle: Handle, MapKey: usize) -> Status, - GetNextMonotonicCount: extern "win64" fn (), - pub Stall: extern "win64" fn (Microseconds: usize) -> Status, - pub SetWatchdogTimer: extern "win64" fn (Timeout: usize, WatchdogCode: u64, DataSize: usize, WatchdogData: *const u16) -> Status, - ConnectController: extern "win64" fn (), - DisconnectController: extern "win64" fn (), - OpenProtocol: extern "win64" fn (), - CloseProtocol: extern "win64" fn (), - OpenProtocolInformation: extern "win64" fn (), - pub ProtocolsPerHandle: extern "win64" fn (Handle: Handle, ProtocolBuffer: *mut Guid, ProtocolBufferCount: usize) -> Status, - LocateHandleBuffer: extern "win64" fn (SearchType: LocateSearchType, Protocol: &Guid, SearchKey: usize, NoHandles: &mut usize, Buffer: &mut *mut Handle), - pub LocateProtocol: extern "win64" fn (Protocol: &Guid, Registration: usize, Interface: &mut usize) -> Status, - InstallMultipleProtocolInterfaces: extern "win64" fn (), - UninstallMultipleProtocolInterfaces: extern "win64" fn (), - CalculateCrc32: extern "win64" fn (), - CopyMem: extern "win64" fn (), - SetMem: extern "win64" fn (), - CreateEventEx: extern "win64" fn (), + /// Registers an event that is to be signaled whenever an interface is + /// installed for a specified protocol. + RegisterProtocolNotify: extern "win64" fn(), + /// Returns an array of handles that support a specified protocol. + pub LocateHandle: extern "win64" fn( + SearchType: LocateSearchType, + Protocol: &Guid, + SearchKey: usize, + BufferSize: &mut usize, + Buffer: *mut Handle, + ) -> Status, + /// Locates all devices on a device path that support a specified + /// protocol and returns the handle to the device that is closest to + /// the path. + LocateDevicePath: extern "win64" fn(), + /// Adds, updates, or removes a configuration table from the EFI + /// System Table. + InstallConfigurationTable: extern "win64" fn(), + /// Loads an EFI image into memory. + pub LoadImage: extern "win64" fn( + BootPolicy: bool, + ParentImageHandle: Handle, + DevicePath: usize, /*TODO*/ + SourceBuffer: *const u8, + SourceSize: usize, + ImageHandle: &mut Handle, + ) -> Status, + /// Transfers control to a loaded image’s entry point. + pub StartImage: + extern "win64" fn(ImageHandle: Handle, ExitDataSize: &mut usize, ExitData: &mut *mut u16) + -> Status, + /// Exits the image’s entry point. + pub Exit: extern "win64" fn( + ImageHandle: Handle, + ExitStatus: isize, + ExitDataSize: usize, + ExitData: *const u16, + ) -> Status, + /// Unloads an image. + UnloadImage: extern "win64" fn(), + /// Terminates boot services. + pub ExitBootServices: extern "win64" fn(ImageHandle: Handle, MapKey: usize) -> Status, + /// Returns a monotonically increasing count for the platform. + GetNextMonotonicCount: extern "win64" fn(), + /// Stalls the processor. + pub Stall: extern "win64" fn(Microseconds: usize) -> Status, + /// Resets and sets a watchdog timer used during boot services time. + pub SetWatchdogTimer: extern "win64" fn( + Timeout: usize, + WatchdogCode: u64, + DataSize: usize, + WatchdogData: *const u16, + ) -> Status, + /// Uses a set of precedence rules to find the best set of drivers to + /// manage a controller. + ConnectController: extern "win64" fn(), + /// Informs a set of drivers to stop managing a controller. + DisconnectController: extern "win64" fn(), + /// Adds elements to the list of agents consuming a protocol interface. + OpenProtocol: extern "win64" fn(), + /// Removes elements from the list of agents consuming a protocol + /// interface. + CloseProtocol: extern "win64" fn(), + /// Retrieve the list of agents that are currently consuming a + /// protocol interface. + OpenProtocolInformation: extern "win64" fn(), + /// Retrieves the list of protocols installed on a handle. The return + /// buffer is automatically allocated. + pub ProtocolsPerHandle: + extern "win64" fn(Handle: Handle, ProtocolBuffer: *mut Guid, ProtocolBufferCount: usize) + -> Status, + /// Retrieves the list of handles from the handle database that meet + /// the search criteria. The return buffer is automatically allocated. + LocateHandleBuffer: extern "win64" fn( + SearchType: LocateSearchType, + Protocol: &Guid, + SearchKey: usize, + NoHandles: &mut usize, + Buffer: &mut *mut Handle, + ), + /// Finds the first handle in the handle database the supports the requested protocol. + pub LocateProtocol: + extern "win64" fn(Protocol: &Guid, Registration: usize, Interface: &mut usize) -> Status, + /// Installs one or more protocol interfaces onto a handle. + InstallMultipleProtocolInterfaces: extern "win64" fn(), + /// Uninstalls one or more protocol interfaces from a handle. + UninstallMultipleProtocolInterfaces: extern "win64" fn(), + /// Computes and returns a 32-bit CRC for a data buffer. + CalculateCrc32: extern "win64" fn(), + /// Copies the contents of one buffer to another buffer. + CopyMem: extern "win64" fn(), + /// Fills a buffer with a specified value. + SetMem: extern "win64" fn(), + /// Creates an event structure as part of an event group. + CreateEventEx: extern "win64" fn(), } diff --git a/src/capsule.rs b/src/capsule.rs index 62353a8..4219d1b 100644 --- a/src/capsule.rs +++ b/src/capsule.rs @@ -1,5 +1,4 @@ -use guid::Guid; -use memory::PhysicalAddress; +use crate::{guid::Guid, memory::PhysicalAddress}; pub const CAPSULE_FLAGS_PERSIST_ACROSS_RESET: u32 = 0x00010000; pub const CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE: u32 = 0x00020000; diff --git a/src/config.rs b/src/config.rs index 1a1815b..15545db 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,7 +1,25 @@ -use guid::Guid; +//! The EFI Configuration Table is the ConfigurationTable field in the EFI System Table. This table +//! contains a set of GUID/pointer pairs. Each element of this table is described by the +//! EFI_CONFIGURATION_TABLE structure below. The number of types of configuration tables is +//! expected to grow over time. This is why a GUID is used to identify the configuration table type. The +//! EFI Configuration Table may contain at most once instance of each table type. +use crate::guid::Guid; + +/// Contains a set of GUID/pointer pairs comprised of the ConfigurationTable field in the EFI +/// System Table. #[repr(C)] pub struct ConfigurationTable { + /// The 128-bit GUID value that uniquely identifies the system + /// configuration table. pub VendorGuid: Guid, - pub VendorTable: usize + /// A pointer to the table associated with VendorGuid. Whether + /// this pointer is a physical address or a virtual address during + /// runtime is determined by the VendorGuid. The VendorGuid + /// associated with a given VendorTable pointer defines whether + /// or not a particular address reported in the table gets fixed up + /// when a call to SetVirtualAddressMap() is made. It is the + /// responsibility of the specification defining the VendorTable to + /// specify whether to convert the addresses reported in the table. + pub VendorTable: usize, } diff --git a/src/device.rs b/src/device.rs index 711b8d0..7a161c3 100644 --- a/src/device.rs +++ b/src/device.rs @@ -1,4 +1,4 @@ -use guid::Guid; +use crate::guid::Guid; #[repr(C)] pub enum DevicePathType { @@ -61,7 +61,6 @@ pub enum DevicePathBbsType { Bbs = 0x01, } - #[repr(C)] pub enum DevicePathEndType { Instance = 0x01, diff --git a/src/fs.rs b/src/fs.rs index 7c8c962..1f205b4 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -1,6 +1,4 @@ -use guid::Guid; -use status::Status; -use time::Time; +use crate::{guid::Guid, status::Status, time::Time}; // Open modes pub const FILE_MODE_READ: u64 = 0x0000000000000001; @@ -18,7 +16,7 @@ pub const FILE_ARCHIVE: u64 = 0x20; #[repr(C)] pub struct SimpleFileSystem { pub Revision: u64, - pub OpenVolume: extern "win64" fn (&mut SimpleFileSystem, Root: &mut *mut File) -> Status, + pub OpenVolume: extern "win64" fn(&mut SimpleFileSystem, Root: &mut *mut File) -> Status, } #[repr(C)] @@ -51,14 +49,30 @@ impl Default for FileInfo { #[repr(C)] pub struct File { pub Revision: u64, - pub Open: extern "win64" fn (&mut File, NewHandle: &mut *mut File, FileName: *const u16, OpenMode: u64, Attributes: u64) -> Status, - pub Close: extern "win64" fn (&mut File) -> Status, - pub Delete: extern "win64" fn (&mut File) -> Status, - pub Read: extern "win64" fn (&mut File, BufferSize: &mut usize, Buffer: *mut u8) -> Status, - pub Write: extern "win64" fn (&mut File, BufferSize: &mut usize, Buffer: *const u8) -> Status, - pub SetPosition: extern "win64" fn (&mut File, Position: u64) -> Status, - pub GetPosition: extern "win64" fn (&mut File, Position: &mut u64) -> Status, - pub GetInfo: extern "win64" fn (&mut File, InformationType: &Guid, BufferSize: &mut usize, Buffer: *mut u8) -> Status, - pub SetInfo: extern "win64" fn (&mut File, InformationType: &Guid, BufferSize: &mut usize, Buffer: *const u8) -> Status, - pub Flush: extern "win64" fn (&mut File) -> Status, + pub Open: extern "win64" fn( + &mut File, + NewHandle: &mut *mut File, + FileName: *const u16, + OpenMode: u64, + Attributes: u64, + ) -> Status, + pub Close: extern "win64" fn(&mut File) -> Status, + pub Delete: extern "win64" fn(&mut File) -> Status, + pub Read: extern "win64" fn(&mut File, BufferSize: &mut usize, Buffer: *mut u8) -> Status, + pub Write: extern "win64" fn(&mut File, BufferSize: &mut usize, Buffer: *const u8) -> Status, + pub SetPosition: extern "win64" fn(&mut File, Position: u64) -> Status, + pub GetPosition: extern "win64" fn(&mut File, Position: &mut u64) -> Status, + pub GetInfo: extern "win64" fn( + &mut File, + InformationType: &Guid, + BufferSize: &mut usize, + Buffer: *mut u8, + ) -> Status, + pub SetInfo: extern "win64" fn( + &mut File, + InformationType: &Guid, + BufferSize: &mut usize, + Buffer: *const u8, + ) -> Status, + pub Flush: extern "win64" fn(&mut File) -> Status, } diff --git a/src/graphics.rs b/src/graphics.rs index 4d4e9dd..7e540a6 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -1,112 +1,173 @@ -use status::Status; +//! Provides a basic abstraction to set video modes and copy pixels to and from the graphics +//! controller’s frame buffer. The linear address of the hardware frame buffer is also exposed so +//! software can write directly to the video hardware. +use crate::status::Status; + +/// Represents a pixel when doing a Blt. +/// +/// Blt stands for BLock Transfer. #[derive(Copy, Clone, Debug)] #[repr(C)] pub struct GraphicsBltPixel { + /// The blue part of the pixel. pub Blue: u8, + /// The green part of the pixel. pub Green: u8, + /// The red part of the pixel. pub Red: u8, - pub Reserved: u8 + /// The reserved part of the pixel. + pub Reserved: u8, } +/// Describes the BltOperations that are supported on rectangles. Rectangles have +/// coordinates (left, upper) (right, bottom). #[derive(Copy, Clone, Debug)] #[repr(C)] pub enum GraphicsBltOp { - // Write data from the first buffer pixel to every pixel of the display + /// Write data from the BltBuffer pixel (0,0) directly to every pixel of + /// the video display rectangle (DestinationX, DestinationY) + /// (DestinationX + Width, DestinationY + Height). Only one + /// pixel will be used from the BltBuffer. Delta is NOT used. VideoFill, - // Copy from the display to the buffer + /// Read data from the video display rectangle (SourceX, SourceY) + /// (SourceX + Width, SourceY + Height) and place it in the + /// BltBuffer rectangle (DestinationX, DestinationY) + /// (DestinationX + Width, DestinationY + Height). If + /// DestinationX or DestinationY is not zero then Delta must + /// be set to the length in bytes of a row in the BltBuffer. VideoToBuffer, - // Copy from the buffer to the display + /// Write data from the BltBuffer rectangle (SourceX, SourceY) + /// (SourceX + Width, SourceY + Height) directly to the video + /// display rectangle (DestinationX, DestinationY) + /// (DestinationX + Width, DestinationY + Height). If + /// SourceX or SourceY is not zero then Delta must be set to the + /// length in bytes of a row in the BltBuffer. BufferToVideo, - // Copy from the display to the display - VideoToVideo + /// Copy from the video display rectangle (SourceX, SourceY) + /// (SourceX + Width, SourceY + Height) to the video display + /// rectangle (DestinationX, DestinationY) ( DestinationX + + /// Width, DestinationY + Height). The BltBuffer and Delta + /// are not used in this mode. There is no limitation on the overlapping of + /// the source and destination rectangles. + VideoToVideo, } +/// Defines various pixel formats. #[derive(Copy, Clone, Debug)] #[repr(C)] pub enum GraphicsPixelFormat { - /// - /// A pixel is 32-bits and byte zero represents red, byte one represents green, - /// byte two represents blue, and byte three is reserved. This is the definition - /// for the physical frame buffer. The byte values for the red, green, and blue - /// components represent the color intensity. This color intensity value range - /// from a minimum intensity of 0 to maximum intensity of 255. - /// - PixelRedGreenBlueReserved8BitPerColor, - /// - /// A pixel is 32-bits and byte zero represents blue, byte one represents green, - /// byte two represents red, and byte three is reserved. This is the definition - /// for the physical frame buffer. The byte values for the red, green, and blue - /// components represent the color intensity. This color intensity value range - /// from a minimum intensity of 0 to maximum intensity of 255. - /// - PixelBlueGreenRedReserved8BitPerColor, - /// - /// The Pixel definition of the physical frame buffer. - /// - PixelBitMask, - /// - /// This mode does not support a physical frame buffer. - /// - PixelBltOnly, - /// - /// Valid EFI_GRAPHICS_PIXEL_FORMAT enum values are less than this value. - /// - PixelFormatMax + /// A pixel is 32-bits and byte zero represents red, byte one represents green, + /// byte two represents blue, and byte three is reserved. This is the definition + /// for the physical frame buffer. The byte values for the red, green, and blue + /// components represent the color intensity. This color intensity value range + /// from a minimum intensity of 0 to maximum intensity of 255. + PixelRedGreenBlueReserved8BitPerColor, + /// A pixel is 32-bits and byte zero represents blue, byte one represents green, + /// byte two represents red, and byte three is reserved. This is the definition + /// for the physical frame buffer. The byte values for the red, green, and blue + /// components represent the color intensity. This color intensity value range + /// from a minimum intensity of 0 to maximum intensity of 255. + PixelBlueGreenRedReserved8BitPerColor, + /// The pixel definition of the physical frame buffer is defined by EFI_PIXEL_BITMASK. + PixelBitMask, + /// This mode does not support a physical frame buffer. + PixelBltOnly, + /// Valid EFI_GRAPHICS_PIXEL_FORMAT enum values are less than this value. + PixelFormatMax, } +/// If a bit is set in RedMask, GreenMask, or BlueMask then those bits of the pixel represent the +/// corresponding color. Bits in RedMask, GreenMask, BlueMask, and ReserverdMask must not over +/// lap bit positions. The values for the red, green, and blue components in the bit mask represent the +/// color intensity. The color intensities must increase as the color values for a each color mask +/// increase with a minimum intensity of all bits in a color mask clear to a maximum intensity of all bits +/// in a color mask set. #[derive(Copy, Clone, Debug)] #[repr(C)] pub struct GraphicsPixelBitmask { - pub RedMask: u32, - pub GreenMask: u32, - pub BlueMask: u32, - pub ReservedMask: u32, + /// The bits which represent red in the pixel layout of the physical frame buffer. + pub RedMask: u32, + /// The bits which represent green in the pixel layout of the physical frame buffer. + pub GreenMask: u32, + /// The bits which represent blue in the pixel layout of the physical frame buffer. + pub BlueMask: u32, + /// The bits which are reserved in the pixel layout of the physical frame buffer. + pub ReservedMask: u32, } +/// Provides information about the graphics output mode. #[derive(Copy, Clone, Debug)] #[repr(C)] pub struct GraphicsOutputModeInfo { - /// The version of this data structure. A value of zero represents the - /// EFI_GRAPHICS_OUTPUT_MODE_INFORMATION structure as defined in this specification. - pub Version: u32, - /// The size of video screen in pixels in the X dimension. - pub HorizontalResolution: u32, - /// The size of video screen in pixels in the Y dimension. - pub VerticalResolution: u32, - /// Enumeration that defines the physical format of the pixel. A value of PixelBltOnly - /// implies that a linear frame buffer is not available for this mode. - pub PixelFormat: GraphicsPixelFormat, - /// This bit-mask is only valid if PixelFormat is set to PixelPixelBitMask. - /// A bit being set defines what bits are used for what purpose such as Red, Green, Blue, or Reserved. - pub PixelInformation: GraphicsPixelBitmask, - /// Defines the number of pixel elements per video memory line. - pub PixelsPerScanLine: u32, + /// The version of this data structure. A value of zero represents the + /// EFI_GRAPHICS_OUTPUT_MODE_INFORMATION structure as defined in this specification. + /// Future version of this specification may extend this data structure in a + /// backwards compatible way and increase the value of Version. + pub Version: u32, + /// The size of video screen in pixels in the X dimension. + pub HorizontalResolution: u32, + /// The size of video screen in pixels in the Y dimension. + pub VerticalResolution: u32, + /// Enumeration that defines the physical format of the pixel. A value of PixelBltOnly + /// implies that a linear frame buffer is not available for this mode. + pub PixelFormat: GraphicsPixelFormat, + /// This bit-mask is only valid if PixelFormat is set to PixelPixelBitMask. + /// A bit being set defines what bits are used for what purpose such as Red, Green, Blue, or Reserved. + pub PixelInformation: GraphicsPixelBitmask, + /// Defines the number of pixel elements per video memory line. + pub PixelsPerScanLine: u32, } +/// The EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE is read-only and values are only changed by using +/// the appropriate interface functions. #[derive(Debug)] #[repr(C)] pub struct GraphicsOutputMode { - /// The number of modes supported by QueryMode() and SetMode(). - pub MaxMode: u32, - /// Current Mode of the graphics device. Valid mode numbers are 0 to MaxMode -1. - pub Mode: u32, - /// Pointer to read-only EFI_GRAPHICS_OUTPUT_MODE_INFORMATION data. - pub Info: &'static GraphicsOutputModeInfo, - /// Size of Info structure in bytes. - pub SizeOfInfo: usize, - /// Base address of graphics linear frame buffer. - /// Offset zero in FrameBufferBase represents the upper left pixel of the display. - pub FrameBufferBase: usize, - /// Amount of frame buffer needed to support the active mode as defined by - /// PixelsPerScanLine xVerticalResolution x PixelElementSize. - pub FrameBufferSize: usize, + /// The number of modes supported by QueryMode() and SetMode(). + pub MaxMode: u32, + /// Current Mode of the graphics device. Valid mode numbers are 0 to MaxMode -1. + pub Mode: u32, + /// Reference to read-only EFI_GRAPHICS_OUTPUT_MODE_INFORMATION data. + pub Info: &'static GraphicsOutputModeInfo, + /// Size of Info structure in bytes. Future versions of this specification + /// may increase the size of the EFI_GRAPHICS_OUTPUT_MODE_INFORMATION data. + pub SizeOfInfo: usize, + /// Base address of graphics linear frame buffer. Info contains + /// information required to allow software to draw directly to the + /// frame buffer without using Blt().Offset zero in FrameBufferBase + /// represents the upper left pixel of the display. + pub FrameBufferBase: usize, + /// Amount of frame buffer needed to support the active mode as defined by + /// PixelsPerScanLine x VerticalResolution x PixelElementSize. + pub FrameBufferSize: usize, } +/// Provides a basic abstraction to set video modes and copy pixels to and from the graphics +/// controller’s frame buffer. The linear address of the hardware frame buffer is also exposed so +/// software can write directly to the video hardware. #[repr(C)] pub struct GraphicsOutput { - pub QueryMode: extern "win64" fn (&mut GraphicsOutput, u32, &mut usize, &mut *mut GraphicsOutputModeInfo) -> Status, - pub SetMode: extern "win64" fn (&mut GraphicsOutput, u32) -> Status, - pub Blt: extern "win64" fn (&mut GraphicsOutput, *mut GraphicsBltPixel, GraphicsBltOp, usize, usize, usize, usize, usize, usize, usize) -> Status, - pub Mode: &'static mut GraphicsOutputMode + /// Returns information for an available graphics mode that the graphics + /// device and the set of active video output devices supports. + pub QueryMode: + extern "win64" fn(&mut GraphicsOutput, u32, &mut usize, &mut *mut GraphicsOutputModeInfo) + -> Status, + /// Set the video device into the specified mode and clears the visible portions of the output display to black. + pub SetMode: extern "win64" fn(&mut GraphicsOutput, u32) -> Status, + /// Software abstraction to draw on the video device’s frame buffer. + pub Blt: extern "win64" fn( + &mut GraphicsOutput, + *mut GraphicsBltPixel, + GraphicsBltOp, + usize, + usize, + usize, + usize, + usize, + usize, + usize, + ) -> Status, + /// Reference to EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE data. + pub Mode: &'static mut GraphicsOutputMode, } diff --git a/src/guid.rs b/src/guid.rs index ee07ebc..cbca7a9 100644 --- a/src/guid.rs +++ b/src/guid.rs @@ -1,43 +1,239 @@ use core::fmt; -pub const NULL_GUID : Guid = Guid(0x00000000, 0x0000, 0x0000, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); -pub const MPS_TABLE_GUID : Guid = Guid(0xeb9d2d2f, 0x2d88, 0x11d3, [0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d]); -pub const ACPI_TABLE_GUID : Guid = Guid(0xeb9d2d30, 0x2d88, 0x11d3, [0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d]); -pub const ACPI_20_TABLE_GUID : Guid = Guid(0x8868e871, 0xe4f1, 0x11d3, [0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81]); -pub const SMBIOS_TABLE_GUID : Guid = Guid(0xeb9d2d31, 0x2d88, 0x11d3, [0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d]); -pub const SMBIOS3_TABLE_GUID : Guid = Guid(0xf2fd1544, 0x9794, 0x4a2c, [0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94]); -pub const SAL_SYSTEM_TABLE_GUID : Guid = Guid(0xeb9d2d32, 0x2d88, 0x11d3, [0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d]); -pub const HCDP_TABLE_GUID : Guid = Guid(0xf951938d, 0x620b, 0x42ef, [0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98]); -pub const UGA_IO_PROTOCOL_GUID : Guid = Guid(0x61a4d49e, 0x6f68, 0x4f1b, [0xb9, 0x22, 0xa8, 0x6e, 0xed, 0x0b, 0x07, 0xa2]); -pub const SIMPLE_TEXT_OUTPUT_GUID : Guid = Guid(0x387477c2, 0x69c7, 0x11d2, [0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b]); -pub const GLOBAL_VARIABLE_GUID : Guid = Guid(0x8be4df61, 0x93ca, 0x11d2, [0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c]); -pub const UV_SYSTEM_TABLE_GUID : Guid = Guid(0x3b13a7d4, 0x633e, 0x11dd, [0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93]); -pub const LINUX_EFI_CRASH_GUID : Guid = Guid(0xcfc8fc79, 0xbe2e, 0x4ddc, [0x97, 0xf0, 0x9f, 0x98, 0xbf, 0xe2, 0x98, 0xa0]); -pub const LOADED_IMAGE_PROTOCOL_GUID : Guid = Guid(0x5b1b31a1, 0x9562, 0x11d2, [0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b]); -pub const GRAPHICS_OUTPUT_PROTOCOL_GUID : Guid = Guid(0x9042a9de, 0x23dc, 0x4a38, [0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a]); -pub const UGA_PROTOCOL_GUID : Guid = Guid(0x982c298b, 0xf4fa, 0x41cb, [0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39]); -pub const PCI_IO_PROTOCOL_GUID : Guid = Guid(0x4cf5b200, 0x68b8, 0x4ca5, [0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x02, 0x9a]); -pub const FILE_INFO_ID : Guid = Guid(0x09576e92, 0x6d3f, 0x11d2, [0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b]); -pub const SYSTEM_RESOURCE_TABLE_GUID : Guid = Guid(0xb122a263, 0x3661, 0x4f68, [0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80]); -pub const BLOCK_IO_GUID : Guid = Guid(0x964e5b21, 0x6459, 0x11d2, [0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b]); -pub const FILE_SYSTEM_GUID : Guid = Guid(0x964e5b22, 0x6459, 0x11d2, [0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b]); -pub const LOAD_FILE_GUID : Guid = Guid(0x56ec3091, 0x954c, 0x11d2, [0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b]); -pub const DEVICE_PATH_GUID : Guid = Guid(0x09576e91, 0x6d3f, 0x11d2, [0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b]); -pub const DEVICE_TREE_GUID : Guid = Guid(0xb1b621d5, 0xf19c, 0x41a5, [0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0]); -pub const PROPERTIES_TABLE_GUID : Guid = Guid(0x880aaca3, 0x4adc, 0x4a04, [0x90, 0x79, 0xb7, 0x47, 0x34, 0x08, 0x25, 0xe5]); -pub const RNG_PROTOCOL_GUID : Guid = Guid(0x3152bca5, 0xeade, 0x433d, [0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44]); -pub const RNG_ALGORITHM_RAW : Guid = Guid(0xe43176d7, 0xb6e8, 0x4827, [0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61]); -pub const MEMORY_ATTRIBUTES_TABLE_GUID : Guid = Guid(0xdcfa911d, 0x26eb, 0x469f, [0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20]); -pub const CONSOLE_OUT_DEVICE_GUID : Guid = Guid(0xd3b36f2c, 0xd551, 0x11d4, [0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d]); -pub const SECTION_TIANO_COMPRESS_GUID : Guid = Guid(0xa31280ad, 0x481e, 0x41b6, [0x95, 0xe8, 0x12, 0x7f, 0x4c, 0x98, 0x47, 0x79]); -pub const SECTION_LZMA_COMPRESS_GUID : Guid = Guid(0xee4e5898, 0x3914, 0x4259, [0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf]); -pub const DXE_SERVICES_TABLE_GUID : Guid = Guid(0x05ad34ba, 0x6f02, 0x4214, [0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9]); -pub const HOB_LIST_GUID : Guid = Guid(0x7739f24c, 0x93d7, 0x11d4, [0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d]); -pub const MEMORY_TYPE_INFORMATION_GUID : Guid = Guid(0x4c19049f, 0x4137, 0x4dd3, [0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa]); -pub const DEBUG_IMAGE_INFO_TABLE_GUID : Guid = Guid(0x49152e77, 0x1ada, 0x4764, [0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b]); -pub const SHELL_GUID : Guid = Guid(0x6302d008, 0x7f9b, 0x4f30, [0x87, 0xac, 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e]); -pub const SHELL_PARAMETERS_GUID : Guid = Guid(0x752f3136, 0x4e16, 0x4fdc, [0xa2, 0x2a, 0xe5, 0xf4, 0x68, 0x12, 0xf4, 0xca]); -pub const SIMPLE_POINTER_GUID : Guid = Guid(0x31878c87, 0x0b75, 0x11d5, [0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d]); +pub const NULL_GUID: Guid = Guid( + 0x00000000, + 0x0000, + 0x0000, + [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], +); +pub const MPS_TABLE_GUID: Guid = Guid( + 0xeb9d2d2f, + 0x2d88, + 0x11d3, + [0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d], +); +pub const ACPI_TABLE_GUID: Guid = Guid( + 0xeb9d2d30, + 0x2d88, + 0x11d3, + [0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d], +); +pub const ACPI_20_TABLE_GUID: Guid = Guid( + 0x8868e871, + 0xe4f1, + 0x11d3, + [0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81], +); +pub const SMBIOS_TABLE_GUID: Guid = Guid( + 0xeb9d2d31, + 0x2d88, + 0x11d3, + [0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d], +); +pub const SMBIOS3_TABLE_GUID: Guid = Guid( + 0xf2fd1544, + 0x9794, + 0x4a2c, + [0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94], +); +pub const SAL_SYSTEM_TABLE_GUID: Guid = Guid( + 0xeb9d2d32, + 0x2d88, + 0x11d3, + [0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d], +); +pub const HCDP_TABLE_GUID: Guid = Guid( + 0xf951938d, + 0x620b, + 0x42ef, + [0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98], +); +pub const UGA_IO_PROTOCOL_GUID: Guid = Guid( + 0x61a4d49e, + 0x6f68, + 0x4f1b, + [0xb9, 0x22, 0xa8, 0x6e, 0xed, 0x0b, 0x07, 0xa2], +); +pub const SIMPLE_TEXT_OUTPUT_GUID: Guid = Guid( + 0x387477c2, + 0x69c7, + 0x11d2, + [0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b], +); +pub const GLOBAL_VARIABLE_GUID: Guid = Guid( + 0x8be4df61, + 0x93ca, + 0x11d2, + [0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c], +); +pub const UV_SYSTEM_TABLE_GUID: Guid = Guid( + 0x3b13a7d4, + 0x633e, + 0x11dd, + [0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93], +); +pub const LINUX_EFI_CRASH_GUID: Guid = Guid( + 0xcfc8fc79, + 0xbe2e, + 0x4ddc, + [0x97, 0xf0, 0x9f, 0x98, 0xbf, 0xe2, 0x98, 0xa0], +); +/// Can be used on any image handle to obtain information about the loaded image. +pub const LOADED_IMAGE_PROTOCOL_GUID: Guid = Guid( + 0x5b1b31a1, + 0x9562, + 0x11d2, + [0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b], +); +/// Provides a basic abstraction to set video modes and copy pixels to and from the graphics +/// controller’s frame buffer. The linear address of the hardware frame buffer is also exposed so +/// software can write directly to the video hardware. +pub const GRAPHICS_OUTPUT_PROTOCOL_GUID: Guid = Guid( + 0x9042a9de, + 0x23dc, + 0x4a38, + [0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a], +); +pub const UGA_PROTOCOL_GUID: Guid = Guid( + 0x982c298b, + 0xf4fa, + 0x41cb, + [0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39], +); +pub const PCI_IO_PROTOCOL_GUID: Guid = Guid( + 0x4cf5b200, + 0x68b8, + 0x4ca5, + [0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x02, 0x9a], +); +pub const FILE_INFO_ID: Guid = Guid( + 0x09576e92, + 0x6d3f, + 0x11d2, + [0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b], +); +pub const SYSTEM_RESOURCE_TABLE_GUID: Guid = Guid( + 0xb122a263, + 0x3661, + 0x4f68, + [0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80], +); +/// This protocol provides control over block devices. +pub const BLOCK_IO_GUID: Guid = Guid( + 0x964e5b21, + 0x6459, + 0x11d2, + [0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b], +); +pub const FILE_SYSTEM_GUID: Guid = Guid( + 0x964e5b22, + 0x6459, + 0x11d2, + [0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b], +); +pub const LOAD_FILE_GUID: Guid = Guid( + 0x56ec3091, + 0x954c, + 0x11d2, + [0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b], +); +pub const DEVICE_PATH_GUID: Guid = Guid( + 0x09576e91, + 0x6d3f, + 0x11d2, + [0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b], +); +pub const DEVICE_TREE_GUID: Guid = Guid( + 0xb1b621d5, + 0xf19c, + 0x41a5, + [0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0], +); +pub const PROPERTIES_TABLE_GUID: Guid = Guid( + 0x880aaca3, + 0x4adc, + 0x4a04, + [0x90, 0x79, 0xb7, 0x47, 0x34, 0x08, 0x25, 0xe5], +); +pub const RNG_PROTOCOL_GUID: Guid = Guid( + 0x3152bca5, + 0xeade, + 0x433d, + [0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44], +); +pub const RNG_ALGORITHM_RAW: Guid = Guid( + 0xe43176d7, + 0xb6e8, + 0x4827, + [0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61], +); +pub const MEMORY_ATTRIBUTES_TABLE_GUID: Guid = Guid( + 0xdcfa911d, + 0x26eb, + 0x469f, + [0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20], +); +pub const CONSOLE_OUT_DEVICE_GUID: Guid = Guid( + 0xd3b36f2c, + 0xd551, + 0x11d4, + [0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d], +); +pub const SECTION_TIANO_COMPRESS_GUID: Guid = Guid( + 0xa31280ad, + 0x481e, + 0x41b6, + [0x95, 0xe8, 0x12, 0x7f, 0x4c, 0x98, 0x47, 0x79], +); +pub const SECTION_LZMA_COMPRESS_GUID: Guid = Guid( + 0xee4e5898, + 0x3914, + 0x4259, + [0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf], +); +pub const DXE_SERVICES_TABLE_GUID: Guid = Guid( + 0x05ad34ba, + 0x6f02, + 0x4214, + [0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9], +); +pub const HOB_LIST_GUID: Guid = Guid( + 0x7739f24c, + 0x93d7, + 0x11d4, + [0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d], +); +pub const MEMORY_TYPE_INFORMATION_GUID: Guid = Guid( + 0x4c19049f, + 0x4137, + 0x4dd3, + [0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa], +); +pub const DEBUG_IMAGE_INFO_TABLE_GUID: Guid = Guid( + 0x49152e77, + 0x1ada, + 0x4764, + [0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b], +); +pub const SHELL_GUID: Guid = Guid( + 0x6302d008, + 0x7f9b, + 0x4f30, + [0x87, 0xac, 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e], +); +pub const SHELL_PARAMETERS_GUID: Guid = Guid( + 0x752f3136, + 0x4e16, + 0x4fdc, + [0xa2, 0x2a, 0xe5, 0xf4, 0x68, 0x12, 0xf4, 0xca], +); +/// Provides services that allow information about a pointer device to be retrieved. +pub const SIMPLE_POINTER_GUID: Guid = Guid( + 0x31878c87, + 0x0b75, + 0x11d5, + [0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d], +); #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[repr(C)] @@ -58,12 +254,17 @@ pub enum GuidKind { SimpleTextOutput, UvSystem, LinuxEfiCrash, + /// Can be used on any image handle to obtain information about the loaded image. LoadedImage, + /// Provides a basic abstraction to set video modes and copy pixels to and from the graphics + /// controller’s frame buffer. The linear address of the hardware frame buffer is also exposed so + /// software can write directly to the video hardware. GraphicsOutput, Uga, PciIo, FileInfo, SystemResource, + /// This protocol provides control over block devices. BlockIo, FileSystem, LoadFile, @@ -82,8 +283,9 @@ pub enum GuidKind { DebugImageInfo, Shell, ShellParameters, + /// Provides services that allow information about a pointer device to be retrieved. SimplePointer, - Unknown + Unknown, } impl Guid { @@ -127,7 +329,7 @@ impl Guid { SHELL_GUID => GuidKind::Shell, SHELL_PARAMETERS_GUID => GuidKind::ShellParameters, SIMPLE_POINTER_GUID => GuidKind::SimplePointer, - _ => GuidKind::Unknown + _ => GuidKind::Unknown, } } } diff --git a/src/lib.rs b/src/lib.rs index 1c879f1..257e5c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,7 @@ +//! A library to write code that interacts with the UEFI firmware. +//! +//! The documentation is based on UEFI version 2.7A which can be found +//! [here](http://www.uefi.org/sites/default/files/resources/UEFI%20Spec%202_7_A%20Sept%206.pdf). #![allow(dead_code)] #![allow(non_snake_case)] #![no_std] @@ -22,17 +26,53 @@ pub mod system; pub mod text; pub mod time; +/// Handle to an event structure. +/// +/// Type VOID *. #[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[repr(transparent)] pub struct Event(pub usize); +/// A collection of related interfaces. +/// +/// Type VOID *. #[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[repr(transparent)] pub struct Handle(pub usize); +/// Data structure that precedes all of the standard EFI table types. #[repr(C)] pub struct TableHeader { + /// A 64-bit signature that identifies the type of table that follows. + /// Unique signatures have been generated for the EFI System + /// Table, the EFI Boot Services Table, and the EFI Runtime Services + /// Table. Signature: u64, + /// The revision of the EFI Specification to which this table + /// conforms. The upper 16 bits of this field contain the major + /// revision value, and the lower 16 bits contain the minor revision + /// value. The minor revision values are binary coded decimals and + /// are limited to the range of 00..99. + /// + /// When printed or displayed UEFI spec revision is referred as + /// (Major revision).(Minor revision upper decimal).(Minor revision + /// lower decimal) or (Major rev ision).(Minor revision upper + /// decimal) in case Minor revision lower decimal is set to 0. For + /// example: + /// + /// A specification with the revision value ((2<<16) | (30)) would + /// be referred as 2.3; + /// + /// A specification with the revision value ((2<<16) | (31)) would + /// be referred as 2.3.1 Revision: u32, + /// The size, in bytes, of the entire table including the + /// EFI_TABLE_HEADER. HeaderSize: u32, + ///The 32-bit CRC for the entire table. This value is computed by + /// setting this field to 0, and co mputing the 32-bit CRC for + /// HeaderSize bytes. CRC32: u32, - Reserved: u32 + /// Reserved field that must be set to 0. + Reserved: u32, } diff --git a/src/loaded_image.rs b/src/loaded_image.rs index 585de4d..1d8336a 100644 --- a/src/loaded_image.rs +++ b/src/loaded_image.rs @@ -1,21 +1,40 @@ -use ::Handle; -use memory::MemoryType; -use status::Status; -use system::SystemTable; +//! Can be used on any image handle to obtain information about the loaded image. +use crate::{memory::MemoryType, status::Status, system::SystemTable, Handle}; + +/// Each loaded image has an image handle that supports EFI_LOADED_IMAGE_PROTOCOL. When an +/// image is started, it is passed the image handle for itself. The image can use the handle to obtain its +/// relevant image data stored in the EFI_LOADED_IMAGE_PROTOCOL structure, such as its load options. #[repr(C)] pub struct LoadedImage { + /// Defines the revision of the EFI_LOADED_IMAGE_PROTOCOL + /// structure. All future revisions will be backward compatible + /// to the current revision. pub Revision: u32, + /// Parent image’s image handle. NULL if the image is loaded + /// directly from the firmware’s boot manager. pub ParentHandle: Handle, + /// The image’s EFI system table pointer. pub SystemTable: &'static mut SystemTable, + /// The device handle that the EFI Image was loaded from. pub DeviceHandle: Handle, + /// A pointer to the file path portion specific to DeviceHandle + /// that the EFI Image was loaded from. pub FilePath: usize, + /// Reserved. DO NOT USE. pub Reserved: usize, + /// The size in bytes of LoadOptions. pub LoadOptionsSize: u32, + /// A pointer to the image’s binary load options. pub LoadOptions: *const u16, + /// The base address at which the image was loaded. pub ImageBase: usize, + /// The size in bytes of the loaded image. pub ImageSize: u64, + /// The memory type that the code sections were loaded as. pub ImageCodeType: MemoryType, + /// The memory type that the data sections were loaded as. pub ImageDataType: MemoryType, + /// Function that unloads the image. pub Unload: extern "win64" fn(ImageHandle: Handle) -> Status, } diff --git a/src/memory.rs b/src/memory.rs index 4650eb1..35b6329 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -1,88 +1,77 @@ +/// Handles the memory management specific functionality of UEFI. + +/// Represents a physical address. #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct PhysicalAddress(pub u64); +/// Represents a virtual address. #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct VirtualAddress(pub u64); +/// Describes the different areas of memory in the memory map. #[derive(Clone, Copy, Debug, Default)] #[repr(C)] pub struct MemoryDescriptor { + /// Type of the memory region. pub Type: u32, + /// Physical address of the first byte in the memory region. + /// PhysicalStart must be aligned on a 4 KiB boundary, and must + /// not be above 0xfffffffffffff000. pub PhysicalStart: PhysicalAddress, + /// Virtual address of the first byte in the memory region. + /// VirtualStart must be aligned on a 4 KiB boundary, and must not + /// be above 0xfffffffffffff000. pub VirtualStart: VirtualAddress, + /// Number of 4 KiB pages in the memory region. + /// NumberOfPages must not be 0, and must not be any value that + /// would represent a memory page with a start address, either physical + /// or virtual, above 0xfffffffffffff000. pub NumberOfPages: u64, + /// Attributes of the memory region that describe the bit mask of + /// capabilities for that memory region, and not necessarily the current + /// settings for that memory region. pub Attribute: u64, } +/// Represents the different types memory can have. #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[repr(C)] pub enum MemoryType { - /// - /// Not used. - /// + /// Not usable. EfiReservedMemoryType, - /// /// The code portions of a loaded application. - /// (Note that UEFI OS loaders are UEFI applications.) - /// EfiLoaderCode, - /// /// The data portions of a loaded application and the default data allocation /// type used by an application to allocate pool memory. - /// EfiLoaderData, - /// - /// The code portions of a loaded Boot Services Driver. - /// + /// The code portions of a loaded Boot Service Driver. EfiBootServicesCode, - /// - /// The data portions of a loaded Boot Serves Driver, and the default data + /// The data portions of a loaded Boot Serve Driver, and the default data /// allocation type used by a Boot Services Driver to allocate pool memory. - /// EfiBootServicesData, - /// - /// The code portions of a loaded Runtime Services Driver. - /// + /// The code portions of a loaded Runtime Driver. EfiRuntimeServicesCode, - /// - /// The data portions of a loaded Runtime Services Driver and the default - /// data allocation type used by a Runtime Services Driver to allocate pool memory. - /// + /// The data portions of a loaded Runtime Driver and the default + /// data allocation type used by a Runtime Driver to allocate pool memory. EfiRuntimeServicesData, - /// /// Free (unallocated) memory. - /// EfiConventionalMemory, - /// /// Memory in which errors have been detected. - /// EfiUnusableMemory, - /// /// Memory that holds the ACPI tables. - /// EfiACPIReclaimMemory, - /// /// Address space reserved for use by the firmware. - /// EfiACPIMemoryNVS, - /// /// Used by system firmware to request that a memory-mapped IO region /// be mapped by the OS to a virtual address so it can be accessed by EFI runtime services. - /// EfiMemoryMappedIO, - /// /// System memory-mapped IO region that is used to translate memory /// cycles to IO cycles by the processor. - /// EfiMemoryMappedIOPortSpace, - /// /// Address space reserved by the firmware for code that is part of the processor. - /// EfiPalCode, - /// /// A memory region that operates as EfiConventionalMemory, /// however it happens to also support byte-addressable non-volatility. - /// EfiPersistentMemory, - EfiMaxMemoryType + EfiMaxMemoryType, } diff --git a/src/pointer.rs b/src/pointer.rs index 55f9a0a..05773a0 100644 --- a/src/pointer.rs +++ b/src/pointer.rs @@ -1,30 +1,83 @@ -use ::Event; -use status::Status; +//! This section defines the Simple Pointer Protocol and a detailed description of the +//! EFI_SIMPLE_POINTER_PROTOCOL. The intent of this section is to specify a simple method for +//! accessing pointer devices. This would include devices such as mice and trackballs. +//! +//! The EFI_SIMPLE_POINTER_PROTOCOL allows information about a pointer device to be retrieved. +//! This would include the status of buttons and the motion of the pointer device since the last time it +//! was accessed. This protocol is attached the device handle of a pointer device, and can be used for +//! input from the user in the preboot environment. +use crate::{status::Status, Event}; + +/// The following data values in the EFI_SIMPLE_POINTER_MODE interface are read-only and are +/// changed by using the appropriate interface functions. #[derive(Clone, Copy, Debug)] #[repr(C)] pub struct SimplePointerMode { + /// The resolution of the pointer device on the x-axis in counts/mm. If 0, + ///then the pointer device does not support an x-axis. pub ResolutionX: u64, + /// The resolution of the pointer device on the y-axis in counts/mm. If 0, + /// then the pointer device does not support a y-axis. pub ResolutionY: u64, + /// The resolution of the pointer device on the z-axis in counts/mm. If 0, + /// then the pointer device does not support a z-axis. pub ResolutionZ: u64, + /// TRUE if a left button is present on the pointer device. Otherwise FALSE. pub LeftButton: bool, + /// TRUE if a right button is present on the pointer device. Otherwise FALSE. pub RightButton: bool, } +/// The current state of a pointer device. +/// +/// This includes information on the buttons associated with the pointer device and the distance +/// that each of the axes associated with the pointer device has been moved. #[derive(Clone, Copy, Debug, Default)] #[repr(C)] pub struct SimplePointerState { + /// The signed distance in counts that the pointer device has been + /// moved along the x-axis. The actual distance moved is + /// RelativeMovementX / ResolutionX millimeters. If the ResolutionX + /// field of the EFI_SIMPLE_POINTER_MODE structure is 0, then this + /// pointer device does not support an x-axis, and this field must be + /// ignored. pub RelativeMovementX: i32, + /// The signed distance in counts that the pointer device has been + /// moved along the y-axis. The actual distance moved is + /// RelativeMovementY / ResolutionY millimeters. If the ResolutionY + /// field of the EFI_SIMPLE_POINTER_MODE structure is 0, then this + /// pointer device does not support a y-axis, and this field must be + /// ignored. pub RelativeMovementY: i32, + /// The signed distance in counts that the pointer device has been + /// moved along the z-axis. The actual distance moved is + /// RelativeMovementZ / ResolutionZ millimeters. If the ResolutionZ + /// field of the EFI_SIMPLE_POINTER_MODE structure is 0, then this + /// pointer device does not support a z-axis, and this field must be + /// ignored. pub RelativeMovementZ: i32, + /// If TRUE, then the left button of the pointer device is being pressed. + /// If FALSE , then the left button of the pointer device is not being + /// pressed. If the LeftButton field of the EFI_SIMPLE_POINTER_MODE + /// structure is FALSE, then this field is not valid, and must be ignored. pub LeftButton: bool, + /// If TRUE, then the right button of the pointer device is being pressed. + /// If FALSE, then the right button of the pointer device is not being + /// pressed. If the RightButton field of the EFI_SIMPLE_POINTER_MODE + /// structure is FALSE, then this field is not valid, and must be ignored. pub RightButton: bool, } +/// Provides services that allow information about a pointer device to be retrieved. #[repr(C)] pub struct SimplePointer { - pub Reset: extern "win64" fn (&mut SimplePointer, ExtendedVerification: bool) -> Status, - pub GetState: extern "win64" fn (&mut SimplePointer, State: &mut SimplePointerState) -> Status, + /// Resets the pointer device. + pub Reset: extern "win64" fn(&mut SimplePointer, ExtendedVerification: bool) -> Status, + /// Retrieves the current state of the pointer device. + pub GetState: extern "win64" fn(&mut SimplePointer, State: &mut SimplePointerState) -> Status, + /// Event to use with EFI_BOOT_SERVICES.WaitForEvent() to wait for input from the pointer device. pub WaitForInput: Event, + /// Pointer to EFI_SIMPLE_POINTER_MODE data. pub Mode: &'static mut SimplePointerMode, } diff --git a/src/reset.rs b/src/reset.rs index d2723a0..484a7a1 100644 --- a/src/reset.rs +++ b/src/reset.rs @@ -1,7 +1,20 @@ +//! Provides types for dealing with resets. + +/// The types of reset that UEFI supports. #[derive(Clone, Copy, Debug)] #[repr(C)] pub enum ResetType { + /// EfiResetCold causes a system-wide reset. This sets all + /// circuitry within the system to its initial state. This type of reset is asynchronous to system operation + /// and operates without regard to cycle boundaries. EfiResetCold is tantamount to a system + /// power cycle. Cold, + /// EfiResetWarm causes a system-wide initialization. The + /// processors are set to their in itial state, and pending cycles are not corrupted. If the system does not + /// support this reset type, then an EfiResetCold must be performed. Warm, + /// EfiResetShutdown causes the system to enter a power + /// state equivalent to the ACPI G2/S5 or G3 states. If the system does not support this reset type, then + /// when the system is rebooted, it should exhibit the EfiResetCold attributes. Shutdown, } diff --git a/src/runtime.rs b/src/runtime.rs index 23e75c4..4eff49c 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -1,97 +1,100 @@ -use ::TableHeader; -use capsule::CapsuleHeader; -use guid::Guid; -use memory::{PhysicalAddress, MemoryDescriptor}; -use reset::ResetType; -use status::Status; -use time::{Time, TimeCapabilities}; +//! UEFI uses the EFI Runtime Services Table, which contains a table header and pointers to all of the +//! runtime services. The definition for this table is shown in the following code fragments. Except for +//! the table header, all elements in the EFI Runtime Services Tables are prototypes of function +//! pointers to functions as defined in Section 8. Unlike the EFI Boot Services Table, this table, and the +//! function pointers it contains are valid after the UEFI OS loader and OS have taken control of the +//! platform with a call to EFI_BOOT_SERVICES.ExitBootServices(). If a call to SetVirtualAddressMap() +//! is made by the OS, then the function pointers in this table are fixed up +//! to point to the new virtually mapped entry points. +use crate::{ + capsule::CapsuleHeader, + guid::Guid, + memory::{MemoryDescriptor, PhysicalAddress}, + reset::ResetType, + status::Status, + time::{Time, TimeCapabilities}, + TableHeader, +}; + +/// Contains a table header and pointers to all of the runtime services. #[repr(C)] pub struct RuntimeServices { pub Hdr: TableHeader, - - pub GetTime: extern "win64" fn( - Time: &mut Time, - Capabilities: *mut TimeCapabilities - ) -> Status, - - pub SetTime: extern "win64" fn( - Time: &Time - ) -> Status, - - pub GetWakeupTime: extern "win64" fn( - Enabled: &mut bool, - Pending: &mut bool, - Time: &mut Time - ) -> Status, - - pub SetWakeupTime: extern "win64" fn( - Enable: bool, - Time: *const Time - ) -> Status, - + /// Returns the current time and date information, and the time-keeping capabilities of the hardware + /// platform. + pub GetTime: extern "win64" fn(Time: &mut Time, Capabilities: *mut TimeCapabilities) -> Status, + /// Sets the current local time and date information. + pub SetTime: extern "win64" fn(Time: &Time) -> Status, + /// Returns the current wakeup alarm clock setting. + pub GetWakeupTime: + extern "win64" fn(Enabled: &mut bool, Pending: &mut bool, Time: &mut Time) -> Status, + /// Sets the system wakeup alarm clock time. + pub SetWakeupTime: extern "win64" fn(Enable: bool, Time: *const Time) -> Status, + /// Changes the runtime addressing mode of EFI firmware from physical to virtual. SetVirtualAddressMap: extern "win64" fn( MemoryMapSize: usize, DescriptorSize: usize, DescriptorVersion: u32, - VirtualMap: *const MemoryDescriptor - ) -> Status, - - pub ConvertPointer: extern "win64" fn( - DebugDisposition: usize, - Address: &mut usize + VirtualMap: *const MemoryDescriptor, ) -> Status, - + /// Determines the new virtual address that is to be used on subsequent memory accesses. + pub ConvertPointer: extern "win64" fn(DebugDisposition: usize, Address: &mut usize) -> Status, + /// Returns the value of a variable. pub GetVariable: extern "win64" fn( VariableName: *const u16, VendorGuid: &Guid, Attributes: *mut u32, DataSize: &mut usize, - Data: *mut u8 + Data: *mut u8, ) -> Status, - + /// Enumerates the current variable names. pub GetNextVariableName: extern "win64" fn( VariableNameSize: &mut usize, VariableName: *mut u16, - VendorGuid: &mut Guid + VendorGuid: &mut Guid, ) -> Status, - + /// Sets the value of a variable. pub SetVariable: extern "win64" fn( VariableName: *const u16, VendorGuid: &Guid, Attributes: u32, DataSize: usize, - Data: *const u8 + Data: *const u8, ) -> Status, - - pub GetNextHighMonotonicCount: extern "win64" fn( - HighCount: &mut u32 - ) -> Status, - + /// Returns the next high 32 bits of the platform’s monotonic counter. + pub GetNextHighMonotonicCount: extern "win64" fn(HighCount: &mut u32) -> Status, + /// Resets the entire platform. If the platform supports EFI_RESET_NOTIFICATION_PROTOCOL, + /// then prior to completing the reset of the platform, all of the pending notifications must be called. pub ResetSystem: extern "win64" fn( ResetType: ResetType, ResetStatus: Status, DataSize: usize, - ResetData: *const u8 + ResetData: *const u8, ) -> !, - + /// Passes capsules to the firmware with both virtual and physical mapping. Depending on the + /// intended consumption, the firmware may process the capsule immediately. If the payload should + /// persist across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities + /// must be passed into ResetSystem() and will cause the capsule to be processed by the firmware + /// as part of the reset process. pub UpdateCapsule: extern "win64" fn( CapsuleHeaderArray: *const *const CapsuleHeader, CapsuleCount: usize, - ScatterGatherList: PhysicalAddress - ) -> Status, - - pub QueryCapsuleCapabilities: extern "win64" fn( - CapsuleHeaderArray: *const *const CapsuleHeader, - CapsuleCount: usize, - MaximumCapsuleSize: &mut u64, - ResetType: &mut ResetType + ScatterGatherList: PhysicalAddress, ) -> Status, - + /// Returns if the capsule can be supported via UpdateCapsule(). + pub QueryCapsuleCapabilities: + extern "win64" fn( + CapsuleHeaderArray: *const *const CapsuleHeader, + CapsuleCount: usize, + MaximumCapsuleSize: &mut u64, + ResetType: &mut ResetType, + ) -> Status, + /// Returns information about the EFI variables. pub QueryVariableInfo: extern "win64" fn( Attributes: u32, MaximumVariableStorageSize: &mut u64, RemainingVariableStorageSize: &mut u64, - MaximumVariableSize: &mut u64 + MaximumVariableSize: &mut u64, ) -> Status, } diff --git a/src/shell.rs b/src/shell.rs index 45ed0a1..fc7e4df 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -1,17 +1,21 @@ -use ::Handle; -use status::Status; +use crate::{status::Status, Handle}; #[repr(C)] pub struct Shell { - pub Execute: extern "win64" fn(ImageHandle: &Handle, CommandLine: *const u16, Environment: *const *const u16, Status: *mut Status) -> Status, + pub Execute: extern "win64" fn( + ImageHandle: &Handle, + CommandLine: *const u16, + Environment: *const *const u16, + Status: *mut Status, + ) -> Status, //TODO } #[repr(C)] pub struct ShellParameters { - pub Argv: * const * const u16, + pub Argv: *const *const u16, pub Argc: usize, pub StdIn: Handle, pub StdOut: Handle, - pub StdErr: Handle + pub StdErr: Handle, } diff --git a/src/status.rs b/src/status.rs index 9aa5d70..1eafacf 100644 --- a/src/status.rs +++ b/src/status.rs @@ -1,47 +1,113 @@ +//! Handles UEFI status codes. + use core::ops::Try; +/// The hig bit of a status code to indicate an error. +#[cfg(target_pointer_width = "128")] +pub const ERROR_BIT: usize = 1 << 127; + +/// The high bit of a status code to indicate an error. +#[cfg(target_pointer_width = "64")] pub const ERROR_BIT: usize = 1 << 63; +/// The high bit of a status code to indicate an error. +#[cfg(target_pointer_width = "32")] +pub const ERROR_BIT: usize = 1 << 31; + +/// The high bit of a status code to indicate an error. +#[cfg(target_pointer_width = "16")] +pub const ERROR_BIT: usize = 1 << 15; + +/// The high bit of a status code to indicate an error. +#[cfg(target_pointer_width = "8")] +pub const ERROR_BIT: usize = 1 << 7; + +/// Represents an error in a UEFI status code. #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[repr(usize)] pub enum Error { + /// The operation completed successfully. Success, + /// The image failed to load. LoadError, + /// A parameter was incorrect. InvalidParameter, + /// The operation is not supported. Unsupported, + /// The buffer was not the proper size for the request. BadBufferSize, + /// The buffer is not large enough to hold the requested data. The + /// required buffer size is returned in the appropriate parameter + /// when this error occurs. BufferTooSmall, + /// There is no data pending upon return. NotReady, + /// The physical device reported an error while attempting the + /// operation. DeviceError, + /// The device cannot be written to. WriteProtected, + /// A resource has run out. OutOfResources, + /// An inconstancy was detected on the file system causing the + /// operation to fail. VolumeCorrupted, + /// There is no more space on the file system. VolumeFull, + /// The device does not contain any medium to perform the + /// operation. NoMedia, + /// The medium in the device has changed since the last access. MediaChanged, + /// The item was not found. NotFound, + /// Access was denied. AccessDenied, + /// The server was not found or did not respond to the request. NoResponse, + /// A mapping to a device does not exist. NoMapping, + /// The timeout time expired. Timeout, + /// The protocol has not been started. NotStarted, + /// The protocol has already been started. AlreadyStarted, + /// The operation was aborted. Aborted, + /// An ICMP error occurred during the network operation. IcmpError, + /// A TFTP error occurred during the network operation. TftpError, + /// A protocol error occurred during the network operation. ProtocolError, + /// The function encountered an internal version that was + /// incompatible with a version requested by the caller. IncompatibleVersion, + /// The function was not performed due to a security violation. SecurityViolation, + /// A CRC error was detected. CrcError, + /// Beginning or end of media was reached. EndOfMedia, + /// Error code 29 is not defined as of UEFI version 2.7A. Error29, + /// Error code 29 is not defined as of UEFI version 2.7A. Error30, + /// The end of the file was reached. EndOfFile, + /// The language specified was invalid. InvalidLanguage, + /// The security status of the data is unknown or compromised and + /// the data must be updated or replaced to restore a valid security + /// status. CompromisedData, + /// There is an address conflict address allocation. Error34, + /// A HTTP error occurred during the network operation. HttpError, - Unknown + /// There is an unknown error. + Unknown, } impl From for Error { @@ -84,15 +150,19 @@ impl From for Error { 33 => CompromisedData, 34 => Error34, 35 => HttpError, - _ => Unknown + _ => Unknown, } } } +/// Represents a result with an UEFI status code as error. pub type Result = ::core::result::Result; +/// Success, error, and warning codes returned by boot services and runtime services +/// functions. #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[must_use] +#[repr(transparent)] pub struct Status(pub usize); impl Status { diff --git a/src/system.rs b/src/system.rs index 07251e1..dce65b8 100644 --- a/src/system.rs +++ b/src/system.rs @@ -1,32 +1,72 @@ +//! UEFI uses the EFI System Table, which contains pointers to the runtime and boot services tables. +//! The definition for this table is shown in the following code fragments. Except for the table header, +//! all elements in the service tables are pointers to functions as defined in Section 7 and Section 8. +//! Prior to a call to EFI_BOOT_SERVICES.ExitBootServices(), all of the fields of the EFI System +//! Table are valid. After an operating system has taken control of the platform with a call to +//! ExitBootServices(), only the Hdr, FirmwareVendor, FirmwareRevision, +//! RuntimeServices, NumberOfTableEntries, and ConfigurationTable fields are valid. + use core::slice; -use ::{Handle, TableHeader}; -use boot::BootServices; -use config::ConfigurationTable; -use runtime::RuntimeServices; -use text::{TextInput, TextOutput}; +use crate::{ + boot::BootServices, + config::ConfigurationTable, + runtime::RuntimeServices, + text::{TextInput, TextOutput}, + Handle, TableHeader, +}; +/// Contains pointers to the runtime and boot services tables. #[repr(C)] pub struct SystemTable { + /// The table header for the EFI System Table. This header contains the + /// EFI_SYSTEM_TABLE_SIGNATURE and + /// EFI_SYSTEM_TABLE_REVISION values along with the size of + /// the EFI_SYSTEM_TABLE structure and a 32-bit CRC to verify + /// that the contents of the EFI System Table are valid. pub Hdr: TableHeader, + /// A pointer to a null terminated string that identifies the vendor + /// that produces the system firmware for the platform. pub FirmwareVendor: *const u16, + /// A firmware vendor specific value that identifies the revision of + /// the system firmware for the platform. pub FirmwareRevision: u32, + /// The handle for the active console input device. This handle must + /// support EFI_SIMPLE_TEXT_INPUT_PROTOCOL and + /// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL. pub ConsoleInHandle: Handle, + /// A reference to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL + /// interface that is associated with `ConsoleInHandle`. pub ConsoleIn: &'static mut TextInput, + /// The handle for the active console output device. This handle + /// must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL. pub ConsoleOutHandle: Handle, + /// A reference to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL + /// interface that is associated with `ConsoleOutHandle`. pub ConsoleOut: &'static mut TextOutput, + /// The handle for the active standard error console device. This + /// handle must support the + /// EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL. pub ConsoleErrorHandle: Handle, + /// A reference to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL + /// interface that is associated with `ConsoleErrorHandle`. pub ConsoleError: &'static mut TextOutput, + /// A reference to the EFI Runtime Services Table. See Section 4.5. pub RuntimeServices: &'static mut RuntimeServices, + /// A reference to the EFI Boot Services Table. See Section 4.4. pub BootServices: &'static mut BootServices, + /// The number of system configuration tables in the buffer + /// `ConfigurationTables`. Entries: usize, - ConfigurationTables: *const ConfigurationTable + /// A pointer to the system configuration tables. The number of + /// entries in the table is `Entries`. + ConfigurationTables: *const ConfigurationTable, } impl SystemTable { + /// Returns a slice to all the configuration tables available. pub fn config_tables(&self) -> &'static [ConfigurationTable] { - unsafe { - slice::from_raw_parts(self.ConfigurationTables, self.Entries) - } + // This is safe under the assumption that the firmware supplied valid values. + unsafe { slice::from_raw_parts(self.ConfigurationTables, self.Entries) } } } diff --git a/src/text.rs b/src/text.rs index 5f10558..e8a48f1 100644 --- a/src/text.rs +++ b/src/text.rs @@ -1,41 +1,76 @@ -use ::Event; -use status::Status; +//! This protocol is used to handle input and output of +//! text-based information intended for the system user during the operation of code in the boot +//! services environment. Also included here are the definitions of three console devices: one for input +//! and one each for normal output and errors. +use crate::{status::Status, Event}; + +/// Keystroke information for the key that was pressed. #[derive(Clone, Copy, Debug, Default)] #[repr(C)] pub struct TextInputKey { + /// If there is a pending keystroke, then ScanCode is the EFI scan code defined in + /// Table 104. pub ScanCode: u16, + /// The UnicodeChar is the actual printable + /// character or is zero if the key does not represent a printable + /// character (control key, function key, etc.). pub UnicodeChar: u16, } +/// This protocol is used to obtain input from the ConsoleIn device. The EFI specification requires that +/// the EFI_SIMPLE_TEXT_INPUT_PROTOCOL supports the same languages as the corresponding +/// EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL. #[repr(C)] pub struct TextInput { + /// Reset the ConsoleIn device. pub Reset: extern "win64" fn(&TextInput, bool) -> Status, + /// Returns the next input character. pub ReadKeyStroke: extern "win64" fn(&TextInput, &mut TextInputKey) -> Status, + /// Event to use with EFI_BOOT_SERVICES.WaitForEvent() to wait for a key to be available. pub WaitForKey: Event, } +/// The following data values in the SIMPLE_TEXT_OUTPUT_MODE interface are read-only and are +/// changed by using the appropriate interface functions. #[derive(Clone, Copy, Debug)] #[repr(C)] pub struct TextOutputMode { + /// The number of modes supported by QueryMode() and SetMode(). pub MaxMode: i32, + /// The text mode of the output device(s). pub Mode: i32, + /// The current character output attribute. pub Attribute: i32, + /// The cursor’s column. pub CursorColumn: i32, + /// The cursor’s row. pub CursorRow: i32, + /// The cursor is currently visible or not. pub CursorVisible: bool, } +/// This protocol is used to control text-based output devices. #[repr(C)] pub struct TextOutput { + /// Reset the ConsoleOut device. pub Reset: extern "win64" fn(&TextOutput, bool) -> Status, + /// Displays the string on the device at the current cursor location. pub OutputString: extern "win64" fn(&TextOutput, *const u16) -> Status, + /// Tests to see if the ConsoleOut device supports this string. pub TestString: extern "win64" fn(&TextOutput, *const u16) -> Status, + /// Queries information concerning the output device’s supported text mode. pub QueryMode: extern "win64" fn(&TextOutput, usize, &mut usize, &mut usize) -> Status, + /// Sets the current mode of the output device. pub SetMode: extern "win64" fn(&TextOutput, usize) -> Status, + /// Sets the foreground and background color of the text that is output. pub SetAttribute: extern "win64" fn(&TextOutput, usize) -> Status, + /// Clears the screen with the currently set background color. pub ClearScreen: extern "win64" fn(&TextOutput) -> Status, + /// Sets the current cursor position. pub SetCursorPosition: extern "win64" fn(&TextOutput, usize, usize) -> Status, + /// Turns the visibility of the cursor on/off. pub EnableCursor: extern "win64" fn(&TextOutput, bool) -> Status, + /// Reference to SIMPLE_TEXT_OUTPUT_MODE data. pub Mode: &'static TextOutputMode, } diff --git a/src/time.rs b/src/time.rs index cc83b4e..42c0817 100644 --- a/src/time.rs +++ b/src/time.rs @@ -1,23 +1,104 @@ +/// This represents the current time information. #[derive(Copy, Clone, Debug, Default)] #[repr(C)] pub struct Time { + /// The current local date. pub Year: u16, + /// The current local date. pub Month: u8, + /// The current local date. pub Day: u8, + /// The current local time. Nanoseconds report the current + /// fraction of a second in the device. The format of the time is + /// hh:mm:ss.nnnnnnnnn. A battery backed real time clock + /// device maintains the date and time. pub Hour: u8, + /// The current local time. Nanoseconds report the current + /// fraction of a second in the device. The format of the time is + /// hh:mm:ss.nnnnnnnnn. A battery backed real time clock + /// device maintains the date and time. pub Minute: u8, + /// The current local time. Nanoseconds report the current + /// fraction of a second in the device. The format of the time is + /// hh:mm:ss.nnnnnnnnn. A battery backed real time clock + /// device maintains the date and time. pub Second: u8, _Pad1: u8, + /// The current local time. Nanoseconds report the current + /// fraction of a second in the device. The format of the time is + /// hh:mm:ss.nnnnnnnnn. A battery backed real time clock + /// device maintains the date and time. pub Nanosecond: u32, + /// The time's offset in minutes from UTC. If the value is + /// EFI_UNSPECIFIED_TIMEZONE, then the time is interpreted + /// as a local time. The TimeZone is the number of minutes + /// that the local time is relative to UTC. To calculate the + /// TimeZone value, follow this equation: Localtime = UTC - + /// TimeZone. + /// + /// To further illustrate this, an example is given below: + /// PST (Pacific Standard Time is 12PM) = UTC (8PM) - 8 + /// hours (480 minutes) + /// + /// In this case, the value for Timezone would be 480 if + /// referencing PST. pub TimeZone: u16, + /// A bitmask containing the daylight savings time + /// information for the time. + /// + /// The EFI_TIME_ADJUST_DAYLIGHT bit indicates if the time + /// is affected by daylight savings time or not. This value does + /// not indicate that the time has been adjusted for daylight + /// savings time. It indicates only that it should be adjusted + /// when the EFI_TIME enters daylight savings time. + /// + /// If EFI_TIME_IN_DAYLIGHT is set, the time has been + /// adjusted for daylight savings time. + /// + /// All other bits must be zero. + /// When entering daylight saving time, if the time is affected, + /// but hasn't been adjusted (DST = 1), use the new + /// calculation: + ///  + /// 1. The date/time should be increased by the appropriate + /// amount. + /// 2. The TimeZone should be decreased by the appropriate + /// amount (EX: +480 changes to +420 when moving from + /// PST to PDT). + /// 3. The Daylight value changes to 3. + ///  + /// When exiting daylight saving time, if the time is affected + /// and has been adjusted (DST = 3), use the new calculation: + /// + /// 1. The date/time should be decreased by the appropriate + /// amount. + /// 2. The TimeZone should be increased by the appropriate + /// amount. + /// 3. The Daylight value changes to 1. pub Daylight: u8, - _Pad2: u8 + _Pad2: u8, } +/// This provides the capabilities of the +/// real time clock device as exposed through the EFI interfaces. #[derive(Copy, Clone, Debug, Default)] #[repr(C)] pub struct TimeCapabilities { - pub Resolution: u32, - pub Accuracy: u32, - pub SetsToZero: bool, + /// Provides the reporting resolution of the real-time clock + /// device in counts per second. For a normal PC-AT CMOS + /// RTC device, this value would be 1 Hz, or 1, to indicate that + /// the device only reports the time to the resolution of 1 + /// second. + pub Resolution: u32, + /// Provides the timekeeping accuracy of the real-time clock + /// in an error rate of 1E-6 parts per million. For a clock with + /// an accuracy of 50 parts per million, the value in this field + /// would be 50,000,000. + pub Accuracy: u32, + /// A TRUE indicates that a time set operation clears the + /// device’s time below the Resolution reporting level. A + /// FALSE indicates that the state below the Resolution level + /// of the device is not cleared when the time is set. Normal + /// PC-AT CMOS RTC devices set this value to FALSE. + pub SetsToZero: bool, } -- GitLab