Last active
July 2, 2022 08:49
-
-
Save xypron/74f4cfd54b6145aa315a2cea911e7c5a to your computer and use it in GitHub Desktop.
U-Boot: test reading via EFI_BLOCK_IO_PROTOCOL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: GPL-2.0+ | |
/* | |
* Copyright 2022, Heinrich Schuchardt <xypron.glpk@gmx.de> | |
* | |
* Read blocks | |
*/ | |
#include <common.h> | |
#include <efi_api.h> | |
#define efi_size_in_pages(size) (((size) + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT) | |
static struct efi_system_table *systable; | |
static struct efi_boot_services *bs; | |
static struct efi_simple_text_output_protocol *cerr; | |
static struct efi_simple_text_output_protocol *cout; | |
static struct efi_simple_text_input_protocol *cin; | |
static efi_guid_t guid_device_path_to_text_protocol = | |
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID; | |
static const efi_guid_t block_io_protocol_guid = EFI_BLOCK_IO_PROTOCOL_GUID; | |
static const efi_guid_t guid_device_path = EFI_DEVICE_PATH_PROTOCOL_GUID; | |
/** | |
* color() - set foreground color | |
* | |
* @color: foreground color | |
*/ | |
static void color(u8 color) | |
{ | |
cout->set_attribute(cout, color | EFI_BACKGROUND_BLACK); | |
} | |
/** | |
* print() - print string | |
* | |
* @string: text | |
*/ | |
static void print(u16 *string) | |
{ | |
cout->output_string(cout, string); | |
} | |
/** | |
* error() - print error string | |
* | |
* @string: error text | |
*/ | |
static void error(u16 *string) | |
{ | |
color(EFI_LIGHTRED); | |
print(string); | |
color(EFI_LIGHTBLUE); | |
} | |
/* | |
* printx() - print hexadecimal number | |
* | |
* @val: value to print; | |
* @prec: minimum number of digits to print | |
*/ | |
static void printx(u64 val, u32 prec) | |
{ | |
int i; | |
u16 c; | |
u16 buf[16]; | |
u16 *pos = buf; | |
for (i = 2 * sizeof(val) - 1; i >= 0; --i) { | |
c = (val >> (4 * i)) & 0x0f; | |
if (c || pos != buf || !i || i < prec) { | |
c += '0'; | |
if (c > '9') | |
c += 'a' - '9' - 1; | |
*pos++ = c; | |
} | |
} | |
*pos = 0; | |
print(buf); | |
} | |
/** | |
* efi_main() - entry point of the EFI application. | |
* | |
* @handle: handle of the loaded image | |
* @systab: system table | |
* Return: status code | |
*/ | |
efi_status_t EFIAPI efi_main(efi_handle_t image_handle, | |
struct efi_system_table *systab) | |
{ | |
efi_handle_t *buffer; | |
efi_uintn_t count; | |
efi_status_t ret; | |
size_t i; | |
struct efi_device_path_to_text_protocol *device_path_to_text; | |
systable = systab; | |
cerr = systable->std_err; | |
cout = systable->con_out; | |
cin = systable->con_in; | |
bs = systable->boottime; | |
ret = bs->locate_protocol(&guid_device_path_to_text_protocol, | |
NULL, (void **)&device_path_to_text); | |
if (ret != EFI_SUCCESS) { | |
error(u"Device path to text protocol is not available.\n"); | |
return ret; | |
} | |
ret = bs->locate_handle_buffer(BY_PROTOCOL, | |
&block_io_protocol_guid, NULL, | |
&count, &buffer); | |
for (i = 0; i < count; ++i) { | |
u16 *string; | |
efi_handle_t handle = buffer[i]; | |
struct efi_block_io *block_io_protocol; | |
u8 buf[512] __aligned(512); | |
struct efi_device_path *dp; | |
ret = bs->open_protocol(handle, &guid_device_path, | |
(void **)&dp, | |
NULL, NULL, | |
EFI_OPEN_PROTOCOL_GET_PROTOCOL); | |
if (ret != EFI_SUCCESS) { | |
error(u"Device path missing\n"); | |
continue; | |
} | |
string = device_path_to_text->convert_device_path_to_text( | |
dp, true, false); | |
if (!string) { | |
error(u"ConvertDevicePathToText failed\n"); | |
continue; | |
} | |
print(string); | |
print(u"\n"); | |
ret = bs->free_pool(string); | |
if (ret != EFI_SUCCESS) { | |
error(u"FreePool failed\n"); | |
return ret; | |
} | |
ret = bs->open_protocol(handle, &block_io_protocol_guid, | |
(void **)&block_io_protocol, NULL, NULL, | |
EFI_OPEN_PROTOCOL_GET_PROTOCOL); | |
if (ret != EFI_SUCCESS) { | |
error(u"Block IO protocol missing\n"); | |
continue; | |
} | |
ret = block_io_protocol->read_blocks(block_io_protocol, | |
block_io_protocol->media->media_id, | |
0, | |
block_io_protocol->media->block_size, | |
buf); | |
if (ret != EFI_SUCCESS) { | |
error(u"Reading block failed\n"); | |
continue; | |
} | |
for (size_t j = 0; j < block_io_protocol->media->block_size; j += 2) { | |
printx(buf[j], 2); | |
printx(buf[j + 1], 2); | |
print(u" "); | |
if (0x1e == (j & 0x1f)) | |
print(u"\n"); | |
} | |
print(u"\n"); | |
} | |
return EFI_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment