uefi_specs/hyperv/
common.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Types shared between multiple parts of the Hyper-V UEFI protocols.
5
6use crate::uefi::common::EfiStatus;
7use core::fmt::Debug;
8use zerocopy::FromBytes;
9use zerocopy::Immutable;
10use zerocopy::IntoBytes;
11use zerocopy::KnownLayout;
12use zerocopy::LittleEndian;
13use zerocopy::U64;
14
15/// A 64-bit, unaligned, little-endian encoding of [`EfiStatus`] that does not
16/// include the error bit.
17///
18/// This should be used for the Hyper-V NVRAM and crypto protocols only.
19///
20/// This encoding cannot be round tripped, nor can it be used to return warnings
21/// to the guest. UEFI warning values (non-zero status values that do not have
22/// the error bit set) will be turned into errors.
23///
24/// Luckily, such warnings statuses are rare in practice and are unused by
25/// Hyper-V UEFI protocols.
26#[repr(transparent)]
27#[derive(Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
28pub struct EfiStatus64NoErrorBit(pub U64<LittleEndian>);
29
30impl From<EfiStatus> for EfiStatus64NoErrorBit {
31    fn from(value: EfiStatus) -> Self {
32        Self((value.0 & !EfiStatus::ERROR_BIT).into())
33    }
34}
35
36impl From<EfiStatus64NoErrorBit> for EfiStatus {
37    fn from(value: EfiStatus64NoErrorBit) -> Self {
38        if value.0.get() == 0 {
39            Self::SUCCESS
40        } else {
41            Self(value.0.get() | Self::ERROR_BIT)
42        }
43    }
44}
45
46impl Debug for EfiStatus64NoErrorBit {
47    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
48        EfiStatus::from(*self).fmt(f)
49    }
50}