Skip to content

Instantly share code, notes, and snippets.

@xypron
Last active July 2, 2022 08:49
Show Gist options
  • Save xypron/74f4cfd54b6145aa315a2cea911e7c5a to your computer and use it in GitHub Desktop.
Save xypron/74f4cfd54b6145aa315a2cea911e7c5a to your computer and use it in GitHub Desktop.
U-Boot: test reading via EFI_BLOCK_IO_PROTOCOL
// 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