From patchwork Fri Jul 14 05:44:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 702720 Delivered-To: patch@linaro.org Received: by 2002:adf:db4e:0:b0:314:25da:8dc4 with SMTP id f14csp906753wrj; Thu, 13 Jul 2023 22:48:15 -0700 (PDT) X-Google-Smtp-Source: APBJJlFE5Taupp5IxACbrLJjSoEDteCt2JS4jun4oLnbxhoSnWJMx0JJUNFO6yFPEMLheqXnSx0U X-Received: by 2002:a17:906:7a05:b0:993:dcca:9607 with SMTP id d5-20020a1709067a0500b00993dcca9607mr3397490ejo.2.1689313695490; Thu, 13 Jul 2023 22:48:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689313695; cv=none; d=google.com; s=arc-20160816; b=ZEUISl2VPZsgg8FpooJaYN9b7dAJbnTc06flnl//16VnDer5N5curL1y40fozV+Sd7 R3hb/a2/mA5a2A6to00oQz85rsd6UB6zgAdfCSgubhyblN2fncGFJO0v8OGBO+z1LY5L VTEZp2R56uwGVYa+N854qpM2hxVdrV6ztGR8de4cqb54Tk9uDbEyIQT+edttQUk71Eq4 7az+CJk6TM0RIsnBJvvETv5E0ED50vOUMzFTobhfC4JTBJk0Q0kc3ggbgBvYnk+YD5so BEqt0/FzdEA/rxJZmBTPJ3AcGF53MzSxmedAmDzVXN4qXHQi2ZysMhcjaQ6tiX2rjHc0 82yQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=nJfYSV3KtEu6wwaZAgeBAdh2YqYk06dljWME3Xxy/kk=; fh=xTN8zo5rzpABERcWHVpYCdCrcH4F7J76p6VSzZMpffc=; b=ENnts3Hr1eeoi9DSP+KXDnkw/LJMORFPWk+bsXTgTg5bHzbUVZw/ZjOEooBOOFdXWN m4d05Urn2eHaUv0EL1hdzrY4VJdvPDZoCK4a2YT+pB5Ci5WYf/1WL2sF4T86H53xPP1Z 5fdJr7fB7Sdst75neBkqtLffca6Kiwr++xFDWYWVU61f+3luzHVpkfxAzTATjFixKWqq Q7hITxGG+dKXUGCo5/rcgUN4EKRWhiQ/DECOQb4414ZcXk3dYYyqV0LzV91b7yQ2YtT7 Qb4SVyeQK7oVVxJGPldSJikstEKHt52HowRZiGPdMi8uyC5c08YhuwpuEYG8LfLA/0T7 XvzA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dm+ASQKe; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id l20-20020a1709066b9400b00992e0e54464si8737089ejr.254.2023.07.13.22.48.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Jul 2023 22:48:15 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dm+ASQKe; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D290A86D3D; Fri, 14 Jul 2023 07:47:42 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="dm+ASQKe"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A9D9F86D26; Fri, 14 Jul 2023 07:47:41 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 1DB9086D13 for ; Fri, 14 Jul 2023 07:47:38 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pf1-x435.google.com with SMTP id d2e1a72fcca58-666ed230c81so1510267b3a.0 for ; Thu, 13 Jul 2023 22:47:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689313656; x=1691905656; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nJfYSV3KtEu6wwaZAgeBAdh2YqYk06dljWME3Xxy/kk=; b=dm+ASQKeif0RwjyIyycvuMk1JjMiB8+3QZw6lH/ryW1g2gD8ihTvSybqvfqOY3Agz0 /BWZlV6BCCJes+fO3Rq3jYG9XCHWmdz+x8ubvXnfKM0GE4nUxPRM+2ooIgMLka1PzJdh QlQNEFA22yP1E+hsFvL67Tc8shcJe7jcBacAElclXJZuRlAYDED0qNgien7cLKV2Xe0P QYb/sNegg2Moah3XKW3VhpNT0fIzSWVBvzEadUn4oOywn9tlnJTkUJd6IA2hbgtdAH1P 61Mv+EIinTvdV3OdlgOEFT+j4+39NJC1uGKiXv+w2e1t05lKnyovVDW4Huq1ZUMraCVY oP4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689313656; x=1691905656; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nJfYSV3KtEu6wwaZAgeBAdh2YqYk06dljWME3Xxy/kk=; b=KzAdcbJfUqKkXHtXEXZsU2ZWkhjmbL7J8AX0lsK7/gU6L4+K7AY0xOrgdw42XX9wx/ OecF93QFzSSSbMx/27v1Rr+j4JtD/pn4QPZfdG73EyOYmhV7bn2H2ZgqQUIIePDA5xPx J9MONVZrHB2CA0qvjHtPCa4UHKEYCbiAs0bBg1xWqEa671hI4vMg/W6hMeLRVgeN6gJs Pxwd2G/zM5UYdLL370o3obqykW9gMF3Cfp3wztJoUbD571PPJz+LikZrPmgH2r50Rxgz BGAHfbc6UGbGgLFuuIpT72ayo9aiLEwcJmm7w6CNcq9CPP2mXcWkNYelWN7tYAmggDx/ fMVQ== X-Gm-Message-State: ABy/qLYorLxDFsTp2JR84x1PtYe+7sUWx869zS3Jn8ESf3S5D+g/+fxH v147CJFqwLdgH+7mdc0L/1AEXKdAeZvSLm13lF0= X-Received: by 2002:a05:6a00:2d19:b0:676:76ea:e992 with SMTP id fa25-20020a056a002d1900b0067676eae992mr4738879pfb.5.1689313656169; Thu, 13 Jul 2023 22:47:36 -0700 (PDT) Received: from localhost ([164.70.16.189]) by smtp.gmail.com with ESMTPSA id u22-20020aa78396000000b0068285a7f107sm6502320pfm.177.2023.07.13.22.47.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Jul 2023 22:47:35 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Masahisa Kojima Subject: [PATCH v2 6/6] efi_selftest: add EFI_RAM_DISK_PROTOCOL selftest Date: Fri, 14 Jul 2023 14:44:06 +0900 Message-Id: <20230714054406.761508-7-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230714054406.761508-1-masahisa.kojima@linaro.org> References: <20230714054406.761508-1-masahisa.kojima@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean This adds the selftest for the EFI_RAM_DISK_PROTOCOL. Signed-off-by: Masahisa Kojima --- No update since v1 lib/efi_selftest/Makefile | 1 + lib/efi_selftest/efi_selftest_ram_disk.c | 511 +++++++++++++++++++++++ 2 files changed, 512 insertions(+) create mode 100644 lib/efi_selftest/efi_selftest_ram_disk.c diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index e4d75420bf..899f2278d5 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -70,6 +70,7 @@ endif ifeq ($(CONFIG_BLK)$(CONFIG_DOS_PARTITION),yy) obj-y += efi_selftest_block_device.o +obj-$(CONFIG_EFI_RAM_DISK_PROTOCOL) += efi_selftest_ram_disk.o endif obj-$(CONFIG_EFI_ESRT) += efi_selftest_esrt.o diff --git a/lib/efi_selftest/efi_selftest_ram_disk.c b/lib/efi_selftest/efi_selftest_ram_disk.c new file mode 100644 index 0000000000..5d6ae1f44f --- /dev/null +++ b/lib/efi_selftest/efi_selftest_ram_disk.c @@ -0,0 +1,511 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * efi_selftest_ram_disk + * The disk image defined in efi_selftest_disk_image.h is + * used in this test. + * Most source code originates from efi_selftest_block_device.c. + * + * Copyright (c) 2023, Linaro Limited + */ + +#include +#include "efi_selftest_disk_image.h" +#include + +/* Block size of compressed disk image */ +#define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8 + +/* Binary logarithm of the block size */ +#define LB_BLOCK_SIZE 9 + +static struct efi_boot_services *boottime; + +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; +static const efi_guid_t guid_simple_file_system_protocol = + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; +static const efi_guid_t guid_file_system_info = EFI_FILE_SYSTEM_INFO_GUID; +static const efi_guid_t guid_ram_disk_protocol = EFI_RAM_DISK_PROTOCOL_GUID; +static efi_guid_t guid_virtual_disk = EFI_VIRTUAL_DISK_GUID; + +/* One 8 byte block of the compressed disk image */ +struct line { + size_t addr; + char *line; +}; + +/* Compressed disk image */ +struct compressed_disk_image { + size_t length; + struct line lines[]; +}; + +static const struct compressed_disk_image img = EFI_ST_DISK_IMG; + +/* Decompressed disk image */ +static u8 *image; +static u8 *image2; + +/* + * Decompress the disk image. + * + * @image decompressed disk image + * Return: status code + */ +static efi_status_t decompress(u8 **image) +{ + u8 *buf; + size_t i; + size_t addr; + size_t len; + efi_status_t ret; + + ret = boottime->allocate_pool(EFI_LOADER_DATA, img.length, + (void **)&buf); + if (ret != EFI_SUCCESS) { + efi_st_error("Out of memory\n"); + return ret; + } + boottime->set_mem(buf, img.length, 0); + + for (i = 0; ; ++i) { + if (!img.lines[i].line) + break; + addr = img.lines[i].addr; + len = COMPRESSED_DISK_IMAGE_BLOCK_SIZE; + if (addr + len > img.length) + len = img.length - addr; + boottime->copy_mem(buf + addr, img.lines[i].line, len); + } + *image = buf; + return ret; +} + +/* + * Setup unit test. + * + * @handle: handle of the loaded image + * @systable: system table + * Return: EFI_ST_SUCCESS for success + */ +static int setup(const efi_handle_t handle, + const struct efi_system_table *systable) +{ + boottime = systable->boottime; + + decompress(&image); + decompress(&image2); + + return EFI_ST_SUCCESS; +} + +/* + * Tear down unit test. + * + * Return: EFI_ST_SUCCESS for success + */ +static int teardown(void) +{ + efi_status_t r; + + if (image) { + r = boottime->free_pool(image); + if (r != EFI_SUCCESS) { + efi_st_error("Failed to free image\n"); + return EFI_ST_FAILURE; + } + } + if (image2) { + r = boottime->free_pool(image2); + if (r != EFI_SUCCESS) { + efi_st_error("Failed to free image\n"); + return EFI_ST_FAILURE; + } + } + return EFI_ST_SUCCESS; +} + +/* + * Get length of device path without end tag. + * + * @dp device path + * Return: length of device path in bytes + */ +static efi_uintn_t dp_size(struct efi_device_path *dp) +{ + struct efi_device_path *pos = dp; + + while (pos->type != DEVICE_PATH_TYPE_END) + pos = (struct efi_device_path *)((char *)pos + pos->length); + return (char *)pos - (char *)dp; +} + +/* + * Execute unit test. + * + * Return: EFI_ST_SUCCESS for success + */ +static int execute(void) +{ + efi_status_t ret; + struct efi_device_path *ram_disk_dp, *ram_disk_dp2; + struct efi_ram_disk_protocol *ram_disk = NULL; + efi_uintn_t no_handles, i, len; + efi_handle_t *handles; + efi_handle_t handle_partition = NULL; + struct efi_device_path *dp_partition; + struct efi_block_io *block_io_protocol; + struct efi_simple_file_system_protocol *file_system; + struct efi_file_handle *root, *file; + struct { + struct efi_file_system_info info; + u16 label[12]; + } system_info; + efi_uintn_t buf_size; + char buf[16] __aligned(ARCH_DMA_MINALIGN); + u32 part1_size; + u64 pos; + char block_io_aligned[1 << LB_BLOCK_SIZE] __aligned(1 << LB_BLOCK_SIZE); + + /* load first disk image */ + ret = boottime->locate_protocol(&guid_ram_disk_protocol, NULL, (void **)&ram_disk); + if (ret != EFI_SUCCESS || !ram_disk) { + efi_st_error("Failed to locate ram disk protocol\n"); + return EFI_ST_FAILURE; + } + ret = ram_disk->disk_register((u64)image, img.length, &guid_virtual_disk, + NULL, &ram_disk_dp); + if (ret != EFI_SUCCESS || !ram_disk_dp) { + efi_st_error("Failed to register ram disk image\n"); + return EFI_ST_FAILURE; + } + + /* Get the handle for the partition */ + ret = boottime->locate_handle_buffer( + BY_PROTOCOL, &guid_device_path, NULL, + &no_handles, &handles); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to locate handles\n"); + return EFI_ST_FAILURE; + } + len = dp_size(ram_disk_dp); + for (i = 0; i < no_handles; ++i) { + ret = boottime->open_protocol(handles[i], &guid_device_path, + (void **)&dp_partition, + NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to open device path protocol\n"); + return EFI_ST_FAILURE; + } + if (len >= dp_size(dp_partition)) + continue; + if (memcmp(ram_disk_dp, dp_partition, len)) + continue; + handle_partition = handles[i]; + break; + } + ret = boottime->free_pool(handles); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to free pool memory\n"); + return EFI_ST_FAILURE; + } + if (!handle_partition) { + efi_st_error("Partition handle not found\n"); + return EFI_ST_FAILURE; + } + + /* Open the block_io_protocol */ + ret = boottime->open_protocol(handle_partition, + &block_io_protocol_guid, + (void **)&block_io_protocol, NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to open block IO protocol\n"); + return EFI_ST_FAILURE; + } + /* Get size of first MBR partition */ + memcpy(&part1_size, image + 0x1ca, sizeof(u32)); + if (block_io_protocol->media->last_block != part1_size - 1) { + efi_st_error("Last LBA of partition %x, expected %x\n", + (unsigned int)block_io_protocol->media->last_block, + part1_size - 1); + return EFI_ST_FAILURE; + } + /* Open the simple file system protocol */ + ret = boottime->open_protocol(handle_partition, + &guid_simple_file_system_protocol, + (void **)&file_system, NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to open simple file system protocol\n"); + return EFI_ST_FAILURE; + } + + /* Open volume */ + ret = file_system->open_volume(file_system, &root); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to open volume\n"); + return EFI_ST_FAILURE; + } + buf_size = sizeof(system_info); + ret = root->getinfo(root, &guid_file_system_info, &buf_size, + &system_info); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to get file system info\n"); + return EFI_ST_FAILURE; + } + if (system_info.info.block_size != 512) { + efi_st_error("Wrong block size %u, expected 512\n", + system_info.info.block_size); + return EFI_ST_FAILURE; + } + if (efi_st_strcmp_16_8(system_info.info.volume_label, "U-BOOT TEST")) { + efi_st_todo( + "Wrong volume label '%ps', expected 'U-BOOT TEST'\n", + system_info.info.volume_label); + } + + /* Read file */ + ret = root->open(root, &file, u"hello.txt", EFI_FILE_MODE_READ, + 0); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to open file\n"); + return EFI_ST_FAILURE; + } + ret = file->setpos(file, 1); + if (ret != EFI_SUCCESS) { + efi_st_error("SetPosition failed\n"); + return EFI_ST_FAILURE; + } + buf_size = sizeof(buf) - 1; + ret = file->read(file, &buf_size, buf); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to read file\n"); + return EFI_ST_FAILURE; + } + if (buf_size != 12) { + efi_st_error("Wrong number of bytes read: %u\n", + (unsigned int)buf_size); + return EFI_ST_FAILURE; + } + if (memcmp(buf, "ello world!", 11)) { + efi_st_error("Unexpected file content\n"); + return EFI_ST_FAILURE; + } + ret = file->getpos(file, &pos); + if (ret != EFI_SUCCESS) { + efi_st_error("GetPosition failed\n"); + return EFI_ST_FAILURE; + } + if (pos != 13) { + efi_st_error("GetPosition returned %u, expected 13\n", + (unsigned int)pos); + return EFI_ST_FAILURE; + } + ret = file->close(file); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to close file\n"); + return EFI_ST_FAILURE; + } + + /* + * Test that read_blocks() can read same file data. + * + * In the test data, the partition starts at block 1 and the file + * hello.txt with the content 'Hello world!' is located at 0x5000 + * of the disk. Here we read block 0x27 (offset 0x4e00 of the + * partition) and expect the string 'Hello world!' to be at the + * start of block. + */ + ret = block_io_protocol->read_blocks(block_io_protocol, + block_io_protocol->media->media_id, + (0x5000 >> LB_BLOCK_SIZE) - 1, + block_io_protocol->media->block_size, + block_io_aligned); + if (ret != EFI_SUCCESS) { + efi_st_error("ReadBlocks failed\n"); + return EFI_ST_FAILURE; + } + + if (memcmp(block_io_aligned + 1, buf, 11)) { + efi_st_error("Unexpected block content\n"); + return EFI_ST_FAILURE; + } + +#ifdef CONFIG_FAT_WRITE + /* Write file */ + ret = root->open(root, &file, u"u-boot.txt", EFI_FILE_MODE_READ | + EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to open file\n"); + return EFI_ST_FAILURE; + } + buf_size = 7; + boottime->set_mem(buf, sizeof(buf), 0); + boottime->copy_mem(buf, "U-Boot", buf_size); + ret = file->write(file, &buf_size, buf); + if (ret != EFI_SUCCESS || buf_size != 7) { + efi_st_error("Failed to write file\n"); + return EFI_ST_FAILURE; + } + ret = file->getpos(file, &pos); + if (ret != EFI_SUCCESS) { + efi_st_error("GetPosition failed\n"); + return EFI_ST_FAILURE; + } + if (pos != 7) { + efi_st_error("GetPosition returned %u, expected 7\n", + (unsigned int)pos); + return EFI_ST_FAILURE; + } + ret = file->close(file); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to close file\n"); + return EFI_ST_FAILURE; + } + + /* Verify file */ + boottime->set_mem(buf, sizeof(buf), 0); + ret = root->open(root, &file, u"u-boot.txt", EFI_FILE_MODE_READ, + 0); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to open file\n"); + return EFI_ST_FAILURE; + } + buf_size = sizeof(buf) - 1; + ret = file->read(file, &buf_size, buf); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to read file\n"); + return EFI_ST_FAILURE; + } + if (buf_size != 7) { + efi_st_error("Wrong number of bytes read: %u\n", + (unsigned int)buf_size); + return EFI_ST_FAILURE; + } + if (memcmp(buf, "U-Boot", 7)) { + efi_st_error("Unexpected file content %s\n", buf); + return EFI_ST_FAILURE; + } + ret = file->close(file); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to close file\n"); + return EFI_ST_FAILURE; + } +#else + efi_st_todo("CONFIG_FAT_WRITE is not set\n"); +#endif /* CONFIG_FAT_WRITE */ + + /* Close volume */ + ret = root->close(root); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to close volume\n"); + return EFI_ST_FAILURE; + } + +#ifdef CONFIG_FAT_WRITE + /* load second disk image, then check the disk image is same as original */ + ret = ram_disk->disk_register((u64)image2, img.length, + &guid_virtual_disk, NULL, &ram_disk_dp2); + if (ret != EFI_SUCCESS || !ram_disk_dp2) { + efi_st_error("Failed to register ram disk image\n"); + return EFI_ST_FAILURE; + } + + /* Get the handle for the partition */ + ret = boottime->locate_handle_buffer(BY_PROTOCOL, &guid_device_path, + NULL, &no_handles, &handles); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to locate handles\n"); + return EFI_ST_FAILURE; + } + len = dp_size(ram_disk_dp2); + for (i = 0; i < no_handles; ++i) { + ret = boottime->open_protocol(handles[i], &guid_device_path, + (void **)&dp_partition, NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to open device path protocol\n"); + return EFI_ST_FAILURE; + } + if (len >= dp_size(dp_partition)) + continue; + if (memcmp(ram_disk_dp2, dp_partition, len)) + continue; + handle_partition = handles[i]; + break; + } + ret = boottime->free_pool(handles); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to free pool memory\n"); + return EFI_ST_FAILURE; + } + if (!handle_partition) { + efi_st_error("Partition handle not found\n"); + return EFI_ST_FAILURE; + } + + /* Open the block_io_protocol */ + ret = boottime->open_protocol(handle_partition, &block_io_protocol_guid, + (void **)&block_io_protocol, NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to open block IO protocol\n"); + return EFI_ST_FAILURE; + } + + /* Open the simple file system protocol */ + ret = boottime->open_protocol(handle_partition, + &guid_simple_file_system_protocol, + (void **)&file_system, NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to open simple file system protocol\n"); + return EFI_ST_FAILURE; + } + + /* Open volume */ + ret = file_system->open_volume(file_system, &root); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to open volume\n"); + return EFI_ST_FAILURE; + } + + boottime->set_mem(buf, sizeof(buf), 0); + ret = root->open(root, &file, u"u-boot.txt", EFI_FILE_MODE_READ, 0); + if (ret == EFI_SUCCESS) { + efi_st_error("wrong image loaded\n"); + return EFI_ST_FAILURE; + } + + /* Close volume */ + ret = root->close(root); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to close volume\n"); + return EFI_ST_FAILURE; + } + + /* unload disk images */ + ret = ram_disk->unregister(ram_disk_dp); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to unregister ramdisk\n"); + return EFI_ST_FAILURE; + } + ret = ram_disk->unregister(ram_disk_dp2); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to unregister ramdisk2\n"); + return EFI_ST_FAILURE; + } +#endif + return EFI_ST_SUCCESS; +} + +EFI_UNIT_TEST(ramdisk) = { + .name = "ramdisk", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .setup = setup, + .execute = execute, + .teardown = teardown, +};