// Copyright 2016 The Fuchsia Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include #include #include #include #include #include #include xefi_global xefi_global_state; void xefi_init(efi_handle img, efi_system_table* sys) { gSys = sys; gImg = img; gBS = sys->BootServices; gConOut = sys->ConOut; } void xefi_wait_any_key(void) { efi_simple_text_input_protocol* sii = gSys->ConIn; efi_input_key key; while (sii->ReadKeyStroke(sii, &key) != EFI_SUCCESS) ; } void xefi_fatal(const char* msg, efi_status status) { printf("\nERROR: %s (%s)\n", msg, xefi_strerror(status)); xefi_wait_any_key(); gBS->Exit(gImg, 1, 0, NULL); } char16_t* xefi_devpath_to_str(efi_device_path_protocol* path) { efi_device_path_to_text_protocol* prot; efi_status status = gBS->LocateProtocol(&DevicePathToTextProtocol, NULL, (void**)&prot); if (EFI_ERROR(status)) { return NULL; } return prot->ConvertDevicePathToText(path, false, false); } int xefi_cmp_guid(efi_guid* guid1, efi_guid* guid2) { return memcmp(guid1, guid2, sizeof(efi_guid)); } char16_t* xefi_handle_to_str(efi_handle h) { efi_device_path_protocol* path; efi_status status = gBS->HandleProtocol(h, &DevicePathProtocol, (void*)&path); if (EFI_ERROR(status)) { char16_t* err; status = gBS->AllocatePool(EfiLoaderData, sizeof(L""), (void**)&err); if (EFI_ERROR(status)) { return NULL; } gBS->CopyMem(err, L"", sizeof(L"")); return err; } char16_t* str = xefi_devpath_to_str(path); if (str == NULL) { char16_t* err; status = gBS->AllocatePool(EfiLoaderData, sizeof(L""), (void**)&err); if (EFI_ERROR(status)) { return NULL; } gBS->CopyMem(err, L"", sizeof(L"")); return err; } return str; } efi_status xefi_open_protocol(efi_handle h, efi_guid* guid, void** ifc) { return gBS->OpenProtocol(h, guid, ifc, gImg, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); } efi_status xefi_close_protocol(efi_handle h, efi_guid* guid) { return gBS->CloseProtocol(h, guid, gImg, NULL); } const char *xefi_strerror(efi_status status) { switch (status) { #define ERR_ENTRY(x) \ case x: { \ return #x; \ } ERR_ENTRY(EFI_SUCCESS); ERR_ENTRY(EFI_LOAD_ERROR); ERR_ENTRY(EFI_INVALID_PARAMETER); ERR_ENTRY(EFI_UNSUPPORTED); ERR_ENTRY(EFI_BAD_BUFFER_SIZE); ERR_ENTRY(EFI_BUFFER_TOO_SMALL); ERR_ENTRY(EFI_NOT_READY); ERR_ENTRY(EFI_DEVICE_ERROR); ERR_ENTRY(EFI_WRITE_PROTECTED); ERR_ENTRY(EFI_OUT_OF_RESOURCES); ERR_ENTRY(EFI_VOLUME_CORRUPTED); ERR_ENTRY(EFI_VOLUME_FULL); ERR_ENTRY(EFI_NO_MEDIA); ERR_ENTRY(EFI_MEDIA_CHANGED); ERR_ENTRY(EFI_NOT_FOUND); ERR_ENTRY(EFI_ACCESS_DENIED); ERR_ENTRY(EFI_NO_RESPONSE); ERR_ENTRY(EFI_NO_MAPPING); ERR_ENTRY(EFI_TIMEOUT); ERR_ENTRY(EFI_NOT_STARTED); ERR_ENTRY(EFI_ALREADY_STARTED); ERR_ENTRY(EFI_ABORTED); ERR_ENTRY(EFI_ICMP_ERROR); ERR_ENTRY(EFI_TFTP_ERROR); ERR_ENTRY(EFI_PROTOCOL_ERROR); ERR_ENTRY(EFI_INCOMPATIBLE_VERSION); ERR_ENTRY(EFI_SECURITY_VIOLATION); ERR_ENTRY(EFI_CRC_ERROR); ERR_ENTRY(EFI_END_OF_MEDIA); ERR_ENTRY(EFI_END_OF_FILE); ERR_ENTRY(EFI_INVALID_LANGUAGE); ERR_ENTRY(EFI_COMPROMISED_DATA); ERR_ENTRY(EFI_IP_ADDRESS_CONFLICT); ERR_ENTRY(EFI_HTTP_ERROR); #undef ERR_ENTRY } return ""; } const char16_t* xefi_wstrerror(efi_status status) { switch (status) { #define ERR_ENTRY(x) \ case x: { \ return L"" #x; \ } ERR_ENTRY(EFI_SUCCESS); ERR_ENTRY(EFI_LOAD_ERROR); ERR_ENTRY(EFI_INVALID_PARAMETER); ERR_ENTRY(EFI_UNSUPPORTED); ERR_ENTRY(EFI_BAD_BUFFER_SIZE); ERR_ENTRY(EFI_BUFFER_TOO_SMALL); ERR_ENTRY(EFI_NOT_READY); ERR_ENTRY(EFI_DEVICE_ERROR); ERR_ENTRY(EFI_WRITE_PROTECTED); ERR_ENTRY(EFI_OUT_OF_RESOURCES); ERR_ENTRY(EFI_VOLUME_CORRUPTED); ERR_ENTRY(EFI_VOLUME_FULL); ERR_ENTRY(EFI_NO_MEDIA); ERR_ENTRY(EFI_MEDIA_CHANGED); ERR_ENTRY(EFI_NOT_FOUND); ERR_ENTRY(EFI_ACCESS_DENIED); ERR_ENTRY(EFI_NO_RESPONSE); ERR_ENTRY(EFI_NO_MAPPING); ERR_ENTRY(EFI_TIMEOUT); ERR_ENTRY(EFI_NOT_STARTED); ERR_ENTRY(EFI_ALREADY_STARTED); ERR_ENTRY(EFI_ABORTED); ERR_ENTRY(EFI_ICMP_ERROR); ERR_ENTRY(EFI_TFTP_ERROR); ERR_ENTRY(EFI_PROTOCOL_ERROR); ERR_ENTRY(EFI_INCOMPATIBLE_VERSION); ERR_ENTRY(EFI_SECURITY_VIOLATION); ERR_ENTRY(EFI_CRC_ERROR); ERR_ENTRY(EFI_END_OF_MEDIA); ERR_ENTRY(EFI_END_OF_FILE); ERR_ENTRY(EFI_INVALID_LANGUAGE); ERR_ENTRY(EFI_COMPROMISED_DATA); ERR_ENTRY(EFI_IP_ADDRESS_CONFLICT); ERR_ENTRY(EFI_HTTP_ERROR); #undef ERR_ENTRY } return L""; } size_t strlen_16(char16_t* str) { size_t len = 0; while (*(str + len) != '\0') { len++; } return len; }