From patchwork Mon Apr 16 05:59:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heinrich Schuchardt X-Patchwork-Id: 898475 X-Patchwork-Delegate: agraf@suse.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gmx.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 40PdCZ1TZ8z9s0t for ; Mon, 16 Apr 2018 16:05:30 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id CAA3AC21DD9; Mon, 16 Apr 2018 06:01:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 5E873C21E29; Mon, 16 Apr 2018 05:59:30 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id B5337C21BE5; Mon, 16 Apr 2018 05:59:20 +0000 (UTC) Received: from mout.gmx.net (mout.gmx.net [212.227.17.21]) by lists.denx.de (Postfix) with ESMTPS id 4F2BEC21D56 for ; Mon, 16 Apr 2018 05:59:20 +0000 (UTC) Received: from LPT2.fritz.box ([62.143.246.157]) by mail.gmx.com (mrgmx101 [212.227.17.174]) with ESMTPSA (Nemesis) id 0LvQkh-1eQwvE3pXn-010e7e; Mon, 16 Apr 2018 07:59:20 +0200 From: Heinrich Schuchardt To: Alexander Graf Date: Mon, 16 Apr 2018 07:59:10 +0200 Message-Id: <20180416055910.12611-9-xypron.glpk@gmx.de> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180416055910.12611-1-xypron.glpk@gmx.de> References: <20180416055910.12611-1-xypron.glpk@gmx.de> X-Provags-ID: V03:K1:B/VPjzDSP0OspbG0LQrZ0Pb0jHrn4umoMMcG9bx7JkmzX06LgrV rZ3QFa+WglAY9PnmVGzuPplIH/RcLMKqCx7YASlugWBWfcPjW5OjqHqaut8MBE2vX5qY9eK DeH/22p4zjr0WegzG5Hx8CYmkekrOkVj0LY2cOwNjlz2FwUMvEnKRmBvmzRfB6bUeYUKpDr KXat/wnWf1Zskk8styUZg== X-UI-Out-Filterresults: notjunk:1; V01:K0:/MrFFay3OyM=:+kAA3eKWG3PjL9Gv8/TdpX GJ3DBk9f1bHLgth4gt4P+CnhqiUDDBSd9svD65FwxVzgaB97P/K1o9OSGhV0wiq19L8HQOzAx vS1Mjxe7FVU9pDGYh2pyxfdCk/qnDxJAajDJlzt7/mFmExmYlS+Fi1nsXmVei5RGwSSuV+Wn0 ie1lTq/DSw5fzsZQzMRjKEhyTFXB4Z83H7Ve0LJTTNO426hOdW4XiCYVm1aczIbDy5Lg4j+qG Sxs6BMfnLyO+zSc7mYmG8Q+04SAGG5/HnzaDECxv579QAgHF+uQFr1u9mUnY2jSR8hWw/zY6D xckhvmtpJu/H/0eMWkVoa2NVjKhr9GQbA68dsTJpctbpqfWmABZ7P9cQ1Qj39nuhP2kK0p2Yk cVehwJvRyiJL1usYdAM86WZGtucLoWrKJvSbbUSzlM7ixfkFeYK0XjLw/sIYkbpnF2s1e9oDi nbzdAUNQevOtS3OSR+WhuSPHhEfEDJLWp/zWFIJOKxvP6qD9YU1ZKDw4ssMY7TOpRMOSUuF4e isHCUtV4zGp8NbgwUChLlXexfCLWWBHz26k3WPYlX2a4L1HBU5sZknQi+1AyEpzHcxcvbx4Q+ ehcEK2W9cmOQFCgeTux8B2hvlTyrEDvXauf1z/jllOnMBdOLtKS21MNdp2VZd4+hpt091Id6t iDFQ2UumF/h4YoGUkpa1ymjCwz3CBOuVgQF1d4y5iE+25Ek4tuuHE86mjiHrOqlwk7+zXGNt+ XzIlyaCppXJRzC++O0WWG+2v1scx5q4heGHBTU0M6PDjre8Vnxp7CAx4htbYpuN4viW8pXhkH tK8fX/rd8tav7Y2xF7vnw6mCrE38g== Cc: u-boot@lists.denx.de, Heinrich Schuchardt Subject: [U-Boot] [PATCH v2 8/8] efi_selftest: test EFI_DEVICE_PATH_UTILITIES_PROTOCOL X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Provide unit tests for the EFI_DEVICE_PATH_UTILITIES_PROTOCOL. Signed-off-by: Heinrich Schuchardt --- v2 add more comments, rename a variable --- lib/efi_selftest/Makefile | 1 + .../efi_selftest_devicepath_util.c | 286 ++++++++++++++++++ 2 files changed, 287 insertions(+) create mode 100644 lib/efi_selftest/efi_selftest_devicepath_util.c diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 2ca58cebe4..ddc2b87317 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -18,6 +18,7 @@ efi_selftest_bitblt.o \ efi_selftest_controllers.o \ efi_selftest_console.o \ efi_selftest_devicepath.o \ +efi_selftest_devicepath_util.o \ efi_selftest_events.o \ efi_selftest_event_groups.o \ efi_selftest_exitbootservices.o \ diff --git a/lib/efi_selftest/efi_selftest_devicepath_util.c b/lib/efi_selftest/efi_selftest_devicepath_util.c new file mode 100644 index 0000000000..2b5384f21b --- /dev/null +++ b/lib/efi_selftest/efi_selftest_devicepath_util.c @@ -0,0 +1,286 @@ +/* + * efi_selftest_devicepath_util + * + * Copyright (c) 2018 Heinrich Schuchardt + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This unit test checks the device path utilities protocol. + */ + +#include + +static struct efi_boot_services *boottime; + +static efi_guid_t guid_device_path_utilities_protocol = + EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID; + +struct efi_device_path_utilities_protocol *dpu; + +/* + * Setup unit test. + * + * Locate the device path utilities protocol. + * + * @handle: handle of the loaded image + * @systable: system table + */ +static int setup(const efi_handle_t img_handle, + const struct efi_system_table *systable) +{ + int ret; + + boottime = systable->boottime; + + ret = boottime->locate_protocol(&guid_device_path_utilities_protocol, + NULL, (void **)&dpu); + if (ret != EFI_SUCCESS) { + dpu = NULL; + efi_st_error( + "Device path to text protocol is not available.\n"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +/* + * Create a device path consisting of a single media device node followed by an + * end node. + * + * @length: length of the media device node + * @dp: device path + * @return: status code + */ +static int create_single_node_device_path(unsigned int length, + struct efi_device_path **dp) +{ + struct efi_device_path *node; + efi_uintn_t len; + int ret; + + node = dpu->create_device_node(DEVICE_PATH_TYPE_MEDIA_DEVICE, + DEVICE_PATH_SUB_TYPE_FILE_PATH, length); + if (!node) { + efi_st_error("CreateDeviceNode failed\n"); + return EFI_ST_FAILURE; + } + *dp = dpu->append_device_node(NULL, node); + if (!*dp) { + efi_st_error("AppendDeviceNode failed\n"); + return EFI_ST_FAILURE; + } + ret = boottime->free_pool(node); + if (ret != EFI_ST_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + len = dpu->get_device_path_size(*dp); + if (len != length + 4) { + efi_st_error("Wrong device path length %u, expected %u\n", + (unsigned int)len, length); + return EFI_ST_FAILURE; + } + return EFI_ST_SUCCESS; +} + +/* + * Execute unit test. + * + * In the test device paths are created, copied, and concatenated. The device + * path length is used as a measure of success. + */ +static int execute(void) +{ + struct efi_device_path *dp1; + struct efi_device_path *dp2; + struct efi_device_path *dp3; + + efi_uintn_t len; + int ret; + + /* IsDevicePathMultiInstance(NULL) */ + if (dpu->is_device_path_multi_instance(NULL)) { + efi_st_error("IsDevicePathMultiInstance(NULL) returned true\n"); + return EFI_ST_FAILURE; + } + /* GetDevicePathSize(NULL) */ + len = dpu->get_device_path_size(NULL); + if (len) { + efi_st_error("Wrong device path length %u, expected 0\n", + (unsigned int)len); + return EFI_ST_FAILURE; + } + /* DuplicateDevicePath(NULL) */ + dp1 = dpu->duplicate_device_path(NULL); + if (dp1) { + efi_st_error("DuplicateDevicePath(NULL) failed\n"); + return EFI_ST_FAILURE; + } + /* AppendDevicePath(NULL, NULL) */ + dp1 = dpu->append_device_path(NULL, NULL); + if (!dp1) { + efi_st_error("AppendDevicePath(NULL, NULL) failed\n"); + return EFI_ST_FAILURE; + } + len = dpu->get_device_path_size(dp1); + if (len != 4) { + efi_st_error("Wrong device path length %u, expected 4\n", + (unsigned int)len); + return EFI_ST_FAILURE; + } + ret = boottime->free_pool(dp1); + if (ret != EFI_ST_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + /* CreateDeviceNode */ + ret = create_single_node_device_path(21, &dp1); + if (ret != EFI_ST_SUCCESS) + return ret; + ret = create_single_node_device_path(17, &dp2); + if (ret != EFI_ST_SUCCESS) + return ret; + /* AppendDevicePath */ + dp3 = dpu->append_device_path(dp1, dp2); + if (!dp3) { + efi_st_error("AppendDevicePath failed\n"); + return EFI_ST_FAILURE; + } + if (dp3 == dp1 || dp3 == dp2) { + efi_st_error("AppendDevicePath reused buffer\n"); + return EFI_ST_FAILURE; + } + len = dpu->get_device_path_size(dp3); + /* 21 + 17 + 4 */ + if (len != 42) { + efi_st_error("Wrong device path length %u, expected 42\n", + (unsigned int)len); + return EFI_ST_FAILURE; + } + ret = boottime->free_pool(dp2); + if (ret != EFI_ST_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + /* AppendDeviceNode */ + dp2 = dpu->append_device_node(dp1, dp3); + if (!dp2) { + efi_st_error("AppendDevicePath failed\n"); + return EFI_ST_FAILURE; + } + len = dpu->get_device_path_size(dp2); + /* 21 + 21 + 4 */ + if (len != 46) { + printf("%s(%d) %s\n", __FILE__, __LINE__, __func__); + efi_st_error("Wrong device path length %u, expected 46\n", + (unsigned int)len); + return EFI_ST_FAILURE; + } + ret = boottime->free_pool(dp1); + if (ret != EFI_ST_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + /* IsDevicePathMultiInstance */ + if (dpu->is_device_path_multi_instance(dp2)) { + printf("%s(%d) %s\n", __FILE__, __LINE__, __func__); + efi_st_error("IsDevicePathMultiInstance returned true\n"); + return EFI_ST_FAILURE; + } + /* AppendDevicePathInstance */ + dp1 = dpu->append_device_path_instance(dp2, dp3); + if (!dp1) { + efi_st_error("AppendDevicePathInstance failed\n"); + return EFI_ST_FAILURE; + } + len = dpu->get_device_path_size(dp1); + /* 46 + 42 */ + if (len != 88) { + efi_st_error("Wrong device path length %u, expected 88\n", + (unsigned int)len); + return EFI_ST_FAILURE; + } + /* IsDevicePathMultiInstance */ + if (!dpu->is_device_path_multi_instance(dp1)) { + efi_st_error("IsDevicePathMultiInstance returned false\n"); + return EFI_ST_FAILURE; + } + ret = boottime->free_pool(dp2); + if (ret != EFI_ST_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + ret = boottime->free_pool(dp3); + if (ret != EFI_ST_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + /* GetNextDevicePathInstance */ + dp3 = dp1; + dp2 = dpu->get_next_device_path_instance(&dp1, &len); + if (!dp2) { + efi_st_error("GetNextDevicePathInstance failed\n"); + return EFI_ST_FAILURE; + } + if (!dp1) { + efi_st_error("GetNextDevicePathInstance no 2nd instance\n"); + return EFI_ST_FAILURE; + } + if (len != 46) { + efi_st_error("Wrong device path length %u, expected 46\n", + (unsigned int)len); + return EFI_ST_FAILURE; + } + len = dpu->get_device_path_size(dp1); + if (len != 42) { + efi_st_error("Wrong device path length %u, expected 42\n", + (unsigned int)len); + return EFI_ST_FAILURE; + } + ret = boottime->free_pool(dp2); + if (ret != EFI_ST_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + dp2 = dpu->get_next_device_path_instance(&dp1, &len); + if (!dp2) { + efi_st_error("GetNextDevicePathInstance failed\n"); + return EFI_ST_FAILURE; + } + if (len != 42) { + efi_st_error("Wrong device path length %u, expected 46\n", + (unsigned int)len); + return EFI_ST_FAILURE; + } + if (dp1) { + efi_st_error("GetNextDevicePathInstance did not signal end\n"); + return EFI_ST_FAILURE; + } + ret = boottime->free_pool(dp2); + if (ret != EFI_ST_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + + /* Clean up */ + ret = boottime->free_pool(dp2); + if (ret != EFI_ST_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + ret = boottime->free_pool(dp3); + if (ret != EFI_ST_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +EFI_UNIT_TEST(dputil) = { + .name = "device path utilities protocol", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .setup = setup, + .execute = execute, +};