10. EFI_STATUS 타입 과 EFI_ERROR 매크로
UEFI 코드에서는 아래와 같은 구성의 코드를 일반적으로 사용한다.
if (!EFI_ERROR(Status) {
...
} else {
...
}
EFI_STATUS 기능의 내부 구현에 대해서 아래의 경로의 파일을 확인하면 된다. (MdePkg/Include/Uefi/UefiBaseType.h MdePkg/Include/Base.h)
#define EFI_ERROR(A) RETURN_ERROR(A)
...
/**
Returns TRUE if a specified RETURN_STATUS code is an error code.
This function returns TRUE if StatusCode has the high bit set. Otherwise, FALSE is returned.
@param StatusCode The status code value to evaluate.
@retval TRUE The high bit of StatusCode is set.
@retval FALSE The high bit of StatusCode is clear.
**/
#define RETURN_ERROR(StatusCode) (((INTN)(RETURN_STATUS)(StatusCode)) < 0)
...
//
// Status codes common to all execution phases
//
typedef UINTN RETURN_STATUS;
따라서 EFI_ERROR
매크로는 단순히 전달된 값이 음수인지 테스트를 하며 이는 signed integer
에 대해서도 마찬가지이다.
가능한 EFI_STATUS
의 값은 MdePkg/Include/Uefi/UefiBaseType.h에 명시되어 있다.
///
/// Enumeration of EFI_STATUS.
///@{
#define EFI_SUCCESS RETURN_SUCCESS
#define EFI_LOAD_ERROR RETURN_LOAD_ERROR
#define EFI_INVALID_PARAMETER RETURN_INVALID_PARAMETER
#define EFI_UNSUPPORTED RETURN_UNSUPPORTED
#define EFI_BAD_BUFFER_SIZE RETURN_BAD_BUFFER_SIZE
#define EFI_BUFFER_TOO_SMALL RETURN_BUFFER_TOO_SMALL
#define EFI_NOT_READY RETURN_NOT_READY
#define EFI_DEVICE_ERROR RETURN_DEVICE_ERROR
#define EFI_WRITE_PROTECTED RETURN_WRITE_PROTECTED
#define EFI_OUT_OF_RESOURCES RETURN_OUT_OF_RESOURCES
#define EFI_VOLUME_CORRUPTED RETURN_VOLUME_CORRUPTED
#define EFI_VOLUME_FULL RETURN_VOLUME_FULL
#define EFI_NO_MEDIA RETURN_NO_MEDIA
#define EFI_MEDIA_CHANGED RETURN_MEDIA_CHANGED
#define EFI_NOT_FOUND RETURN_NOT_FOUND
#define EFI_ACCESS_DENIED RETURN_ACCESS_DENIED
#define EFI_NO_RESPONSE RETURN_NO_RESPONSE
#define EFI_NO_MAPPING RETURN_NO_MAPPING
#define EFI_TIMEOUT RETURN_TIMEOUT
#define EFI_NOT_STARTED RETURN_NOT_STARTED
#define EFI_ALREADY_STARTED RETURN_ALREADY_STARTED
#define EFI_ABORTED RETURN_ABORTED
#define EFI_ICMP_ERROR RETURN_ICMP_ERROR
#define EFI_TFTP_ERROR RETURN_TFTP_ERROR
#define EFI_PROTOCOL_ERROR RETURN_PROTOCOL_ERROR
#define EFI_INCOMPATIBLE_VERSION RETURN_INCOMPATIBLE_VERSION
#define EFI_SECURITY_VIOLATION RETURN_SECURITY_VIOLATION
#define EFI_CRC_ERROR RETURN_CRC_ERROR
#define EFI_END_OF_MEDIA RETURN_END_OF_MEDIA
#define EFI_END_OF_FILE RETURN_END_OF_FILE
#define EFI_INVALID_LANGUAGE RETURN_INVALID_LANGUAGE
#define EFI_COMPROMISED_DATA RETURN_COMPROMISED_DATA
#define EFI_HTTP_ERROR RETURN_HTTP_ERROR
#define EFI_WARN_UNKNOWN_GLYPH RETURN_WARN_UNKNOWN_GLYPH
#define EFI_WARN_DELETE_FAILURE RETURN_WARN_DELETE_FAILURE
#define EFI_WARN_WRITE_FAILURE RETURN_WARN_WRITE_FAILURE
#define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL
#define EFI_WARN_STALE_DATA RETURN_WARN_STALE_DATA
#define EFI_WARN_FILE_SYSTEM RETURN_WARN_FILE_SYSTEM
만약 해당 값을 인코딩 하는 방법을 보려면 MdePkg\Include\Base.h를 확인하면 된다.
///
/// The operation completed successfully.
///
#define RETURN_SUCCESS 0
///
/// The image failed to load.
///
#define RETURN_LOAD_ERROR ENCODE_ERROR (1)
///
/// The parameter was incorrect.
///
#define RETURN_INVALID_PARAMETER ENCODE_ERROR (2)
<...>
/**
Produces a RETURN_STATUS code with the highest bit set.
@param StatusCode The status code value to convert into a warning code.
StatusCode must be in the range 0x00000000..0x7FFFFFFF.
@return The value specified by StatusCode with the highest bit set.
**/
#define ENCODE_ERROR(StatusCode) ((RETURN_STATUS)(MAX_BIT | (StatusCode)))
/**
Produces a RETURN_STATUS code with the highest bit clear.
@param StatusCode The status code value to convert into a warning code.
StatusCode must be in the range 0x00000000..0x7FFFFFFF.
@return The value specified by StatusCode with the highest bit clear.
**/
#define ENCODE_WARNING(StatusCode) ((RETURN_STATUS)(StatusCode))
이제 코드에서 EFI_ERROR
매크로를 사용하고 Print
의 %r
출력 옵션을 사용하여 에러가 출력되는지 확인 해보겠다.
ImageHandle
대신 NULL
포인터를 인자로 전달하여 오류 표시 테스트할 수 있다.
Print(L"________\n");
EFI_GUID **ProtocolGuidArray;
UINTN ArrayCount;
EFI_STATUS Status = gBS->ProtocolsPerHandle(NULL,
&ProtocolGuidArray,
&ArrayCount);
if (!EFI_ERROR(Status)) {
for (int i=0; i<ArrayCount; i++) {
Print(L"%g\n", ProtocolGuidArray[i]);
}
FreePool(ProtocolGuidArray);
} else {
Print(L"ProtocolsPerHandle error: %r\n", Status);
}
빌드 후 실행하면 아래와 같은 에러 문구를 볼 수 있다.
ProtocolsPerHandle error: Invalid Parameter
Last updated