xref: /freebsd/contrib/llvm-project/libc/src/__support/OSUtil/uefi/error.h (revision bb722a7d0f1642bff6487f943ad0427799a6e5bf)
1 //===----------- UEFI implementation of error utils --------------*- C++-*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_UEFI_ERROR_H
10 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_UEFI_ERROR_H
11 
12 #include "hdr/errno_macros.h"
13 #include "include/llvm-libc-types/EFI_STATUS.h"
14 #include "src/__support/CPP/array.h"
15 #include "src/__support/CPP/limits.h"
16 #include "src/__support/macros/attributes.h"
17 #include "src/__support/macros/config.h"
18 
19 namespace LIBC_NAMESPACE_DECL {
20 
21 static constexpr int EFI_ERROR_MAX_BIT = cpp::numeric_limits<EFI_STATUS>::max();
22 
EFI_ENCODE_ERROR(int value)23 static constexpr int EFI_ENCODE_ERROR(int value) {
24   return EFI_ERROR_MAX_BIT | (EFI_ERROR_MAX_BIT >> 2) | (value);
25 }
26 
EFI_ENCODE_WARNING(int value)27 static constexpr int EFI_ENCODE_WARNING(int value) {
28   return (EFI_ERROR_MAX_BIT >> 2) | (value);
29 }
30 
31 struct UefiStatusErrnoEntry {
32   EFI_STATUS status;
33   int errno_value;
34 };
35 
36 static constexpr cpp::array<UefiStatusErrnoEntry, 43> UEFI_STATUS_ERRNO_MAP = {{
37     {EFI_SUCCESS, 0},
38     {EFI_ENCODE_ERROR(EFI_LOAD_ERROR), EINVAL},
39     {EFI_ENCODE_ERROR(EFI_INVALID_PARAMETER), EINVAL},
40     {EFI_ENCODE_ERROR(EFI_BAD_BUFFER_SIZE), EINVAL},
41     {EFI_ENCODE_ERROR(EFI_NOT_READY), EBUSY},
42     {EFI_ENCODE_ERROR(EFI_DEVICE_ERROR), EIO},
43     {EFI_ENCODE_ERROR(EFI_WRITE_PROTECTED), EPERM},
44     {EFI_ENCODE_ERROR(EFI_OUT_OF_RESOURCES), ENOMEM},
45     {EFI_ENCODE_ERROR(EFI_VOLUME_CORRUPTED), EROFS},
46     {EFI_ENCODE_ERROR(EFI_VOLUME_FULL), ENOSPC},
47     {EFI_ENCODE_ERROR(EFI_NO_MEDIA), ENODEV},
48     {EFI_ENCODE_ERROR(EFI_MEDIA_CHANGED), ENXIO},
49     {EFI_ENCODE_ERROR(EFI_NOT_FOUND), ENOENT},
50     {EFI_ENCODE_ERROR(EFI_ACCESS_DENIED), EACCES},
51     {EFI_ENCODE_ERROR(EFI_NO_RESPONSE), EBUSY},
52     {EFI_ENCODE_ERROR(EFI_NO_MAPPING), ENODEV},
53     {EFI_ENCODE_ERROR(EFI_TIMEOUT), EBUSY},
54     {EFI_ENCODE_ERROR(EFI_NOT_STARTED), EAGAIN},
55     {EFI_ENCODE_ERROR(EFI_ALREADY_STARTED), EINVAL},
56     {EFI_ENCODE_ERROR(EFI_ABORTED), EFAULT},
57     {EFI_ENCODE_ERROR(EFI_ICMP_ERROR), EIO},
58     {EFI_ENCODE_ERROR(EFI_TFTP_ERROR), EIO},
59     {EFI_ENCODE_ERROR(EFI_PROTOCOL_ERROR), EINVAL},
60     {EFI_ENCODE_ERROR(EFI_INCOMPATIBLE_VERSION), EINVAL},
61     {EFI_ENCODE_ERROR(EFI_SECURITY_VIOLATION), EPERM},
62     {EFI_ENCODE_ERROR(EFI_CRC_ERROR), EINVAL},
63     {EFI_ENCODE_ERROR(EFI_END_OF_MEDIA), EPIPE},
64     {EFI_ENCODE_ERROR(EFI_END_OF_FILE), EPIPE},
65     {EFI_ENCODE_ERROR(EFI_INVALID_LANGUAGE), EINVAL},
66     {EFI_ENCODE_ERROR(EFI_COMPROMISED_DATA), EINVAL},
67     {EFI_ENCODE_ERROR(EFI_IP_ADDRESS_CONFLICT), EINVAL},
68     {EFI_ENCODE_ERROR(EFI_HTTP_ERROR), EIO},
69     {EFI_ENCODE_WARNING(EFI_WARN_UNKNOWN_GLYPH), EINVAL},
70     {EFI_ENCODE_WARNING(EFI_WARN_DELETE_FAILURE), EROFS},
71     {EFI_ENCODE_WARNING(EFI_WARN_WRITE_FAILURE), EROFS},
72     {EFI_ENCODE_WARNING(EFI_WARN_BUFFER_TOO_SMALL), E2BIG},
73     {EFI_ENCODE_WARNING(EFI_WARN_STALE_DATA), EINVAL},
74     {EFI_ENCODE_WARNING(EFI_WARN_FILE_SYSTEM), EROFS},
75     {EFI_ENCODE_WARNING(EFI_WARN_RESET_REQUIRED), EINTR},
76 }};
77 
uefi_status_to_errno(EFI_STATUS status)78 LIBC_INLINE int uefi_status_to_errno(EFI_STATUS status) {
79   for (auto it = UEFI_STATUS_ERRNO_MAP.begin();
80        it != UEFI_STATUS_ERRNO_MAP.end(); it++) {
81     const struct UefiStatusErrnoEntry entry = *it;
82     if (entry.status == status)
83       return entry.errno_value;
84   }
85 
86   // Unknown type
87   return EINVAL;
88 }
89 
errno_to_uefi_status(int errno_value)90 LIBC_INLINE EFI_STATUS errno_to_uefi_status(int errno_value) {
91   for (auto it = UEFI_STATUS_ERRNO_MAP.begin();
92        it != UEFI_STATUS_ERRNO_MAP.end(); it++) {
93     const struct UefiStatusErrnoEntry entry = *it;
94     if (entry.errno_value == errno_value)
95       return entry.status;
96   }
97 
98   // Unknown type
99   return EFI_INVALID_PARAMETER;
100 }
101 
102 } // namespace LIBC_NAMESPACE_DECL
103 
104 #endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_UEFI_ERROR_H
105