uefi_specs/uefi/
common.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Common UEFI spec types.
5
6use core::fmt::Debug;
7use open_enum::open_enum;
8use zerocopy::FromBytes;
9use zerocopy::Immutable;
10use zerocopy::IntoBytes;
11use zerocopy::KnownLayout;
12use zerocopy::LittleEndian;
13use zerocopy::U64;
14
15open_enum! {
16    /// UEFI spec Appendix D - Status Codes
17    ///
18    /// Note that EFI_STATUS is encoded as a `UINTN` in UEFI, so it is either 32
19    /// or 64 bits wide (with the error bit always being the high bit). This
20    /// enum is defined as 64 bits wide so that it does not lose any (invalid)
21    /// high bits when taking a guest-provided 64-bit value.
22    ///
23    /// However, this type is not intended for direct sharing with the guest, so
24    /// it does not derive `IntoBytes`, etc. To be clear about intent when using
25    /// this value for communication with the guest via shared memory, use
26    /// [`EfiStatus64`] instead. If you are implementing a legacy protocol that
27    /// does not preserve the error bit, use
28    /// [`EfiStatus64NoErrorBit`](crate::hyperv::common::EfiStatus64NoErrorBit).
29    #[must_use]
30    pub enum EfiStatus: u64 {
31        SUCCESS =                   0,
32        LOAD_ERROR =                1 | Self::ERROR_BIT,
33        INVALID_PARAMETER =         2 | Self::ERROR_BIT,
34        UNSUPPORTED =               3 | Self::ERROR_BIT,
35        BAD_BUFFER_SIZE =           4 | Self::ERROR_BIT,
36        BUFFER_TOO_SMALL =          5 | Self::ERROR_BIT,
37        NOT_READY =                 6 | Self::ERROR_BIT,
38        DEVICE_ERROR =              7 | Self::ERROR_BIT,
39        WRITE_PROTECTED =           8 | Self::ERROR_BIT,
40        OUT_OF_RESOURCES =          9 | Self::ERROR_BIT,
41        VOLUME_CORRUPTED =          10 | Self::ERROR_BIT,
42        VOLUME_FULL =               11 | Self::ERROR_BIT,
43        NO_MEDIA =                  12 | Self::ERROR_BIT,
44        MEDIA_CHANGED =             13 | Self::ERROR_BIT,
45        NOT_FOUND =                 14 | Self::ERROR_BIT,
46        ACCESS_DENIED =             15 | Self::ERROR_BIT,
47        NO_RESPONSE =               16 | Self::ERROR_BIT,
48        NO_MAPPING =                17 | Self::ERROR_BIT,
49        TIMEOUT =                   18 | Self::ERROR_BIT,
50        NOT_STARTED =               19 | Self::ERROR_BIT,
51        ALREADY_STARTED =           20 | Self::ERROR_BIT,
52        ABORTED =                   21 | Self::ERROR_BIT,
53        ICMP_ERROR =                22 | Self::ERROR_BIT,
54        TFTP_ERROR =                23 | Self::ERROR_BIT,
55        PROTOCOL_ERROR =            24 | Self::ERROR_BIT,
56        INCOMPATIBLE_VERSION =      25 | Self::ERROR_BIT,
57        SECURITY_VIOLATION =        26 | Self::ERROR_BIT,
58        CRC_ERROR =                 27 | Self::ERROR_BIT,
59        END_OF_MEDIA =              28 | Self::ERROR_BIT,
60        END_OF_FILE =               31 | Self::ERROR_BIT,
61        INVALID_LANGUAGE =          32 | Self::ERROR_BIT,
62        COMPROMISED_DATA =          33 | Self::ERROR_BIT,
63        IP_ADDRESS_CONFLICT =       34 | Self::ERROR_BIT,
64        HTTP_ERROR =                35 | Self::ERROR_BIT,
65    }
66}
67
68impl Default for EfiStatus {
69    fn default() -> Self {
70        Self::SUCCESS
71    }
72}
73
74impl EfiStatus {
75    pub const ERROR_BIT: u64 = 1 << 63;
76}
77
78/// A 64-bit, unaligned, little-endian encoding of [`EfiStatus`], appropriate
79/// for sharing with the guest.
80#[repr(transparent)]
81#[derive(Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
82pub struct EfiStatus64(pub U64<LittleEndian>);
83
84impl Debug for EfiStatus64 {
85    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
86        EfiStatus::from(*self).fmt(f)
87    }
88}
89
90impl From<EfiStatus> for EfiStatus64 {
91    fn from(value: EfiStatus) -> Self {
92        Self(value.0.into())
93    }
94}
95
96impl From<EfiStatus64> for EfiStatus {
97    fn from(value: EfiStatus64) -> Self {
98        Self(value.0.get())
99    }
100}