From patchwork Sun Nov 12 14:02:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heinrich Schuchardt X-Patchwork-Id: 837190 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=) Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3yZbSJ2Rclz9s9Y for ; Mon, 13 Nov 2017 01:17:04 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id B55B2C21E43; Sun, 12 Nov 2017 14:06: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_MSPIKE_H3, RCVD_IN_MSPIKE_WL 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 C0D1DC21E3B; Sun, 12 Nov 2017 14:04:30 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 7BEB2C21E70; Sun, 12 Nov 2017 14:04:00 +0000 (UTC) Received: from mout.gmx.net (mout.gmx.net [212.227.15.18]) by lists.denx.de (Postfix) with ESMTPS id 234FCC21D95 for ; Sun, 12 Nov 2017 14:03:55 +0000 (UTC) Received: from LPT2.fritz.box ([94.114.42.150]) by mail.gmx.com (mrgmx003 [212.227.17.184]) with ESMTPSA (Nemesis) id 0Lfjxq-1eynOP0h4M-00pHt7; Sun, 12 Nov 2017 15:03:03 +0100 From: Heinrich Schuchardt To: Alexander Graf Date: Sun, 12 Nov 2017 15:02:35 +0100 Message-Id: <20171112140247.26532-7-xypron.glpk@gmx.de> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171112140247.26532-1-xypron.glpk@gmx.de> References: <20171112140247.26532-1-xypron.glpk@gmx.de> X-Provags-ID: V03:K0:VoXlqBUmeVHlqyRSADf+TyGNAIIYKEV+1hXgP6ruCxz4rdEITEv vLCdNRrhcEXr3jNC5IaWg32oXhEt3oil4uyyfuvH1z6HQ+zIjxcedLvP5KrItW70FsCYmlG J7Mf83zHsvFGVlgLQnUPzK9Xz+zylY3/TD7ZThljNyjyxOVc1IKPy56nxyuNHWzhmESYyrP SAXvCY052byCh+Nx9A2Cw== X-UI-Out-Filterresults: notjunk:1; V01:K0:3sfrYlqyVrw=:K1fZhA+gcybkeNR3+LJlg0 lwjPfHOzg1apQlTFBRiNld2+7qu1h8n9QBegezihX1XLjGZcItfHYkWZtokvpFg+3z/wXT2DK XBA0f7SgLgW1EKjbbx0RXlRZJUkcW/M2DeYqlpC0fs5RuldMDODzZnHVc+8ykd1QTPL5wv/o8 9rqMZe8wENRVPJI4CWe0GWC0Z6JokNSUkq7e482acRQlov8A+ArkzGhlrPEPnIEK7hrSc5MSp ni2bc0dx6UqP8jvYv9ViWllNTQetpcw8kQ6dq8uKBGZ9ccy2PgO0JKuoFX9woTKLqU8h7weth NWGGkc/CgfTJ8u6Wni88PYGHxM5BsNfLRhZSu/8leiyiOdovVl6wKzc2AvcZlZLmDu/U1nfzs upCpNs5i+A8qmIbZ35eNzuzorTGW26tAcAgNlrjmWYp/+YVsFhP46PLx5aZwqGASo0Mi4Lku2 5KTmqcBKg3yR8Dfw4ZcU1we9qxS7rxIQh8xcEH5ke2+6tfG2726iSJ98cJzP1i9Pd8ZgldX5+ QyCEel2DFdZ19PkVG/Z/94fgz9FmzIDXSX46FkdJOkclCDeciB4KEboXlS5SHyr/i/4PxK8ac TRRddiqP7aJV7wzML2U3jyYPC6lXIyinWkx6URt9JkX09GWDYVnoqnhlo1N+gr05iIO1W8TH+ lrmqf1FTY3zfXcbjoThm7CgGFcIbupPClbOQNhd3+0DV5AxtgT6EO/QkCj+vHjZUtH57sKMU3 j6mbTr/UKE5teUOuSuS8CVK+fdgsyAiaZT+8iRJ85RdFO/48yv4iBiJB6QsKkgYvNzR4sbziA 4CTmQKd1nousR6ken4VIP+cnPnyGQ== Cc: Heinrich Schuchardt , u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 06/18] efi_selftest: test EFI_DEVICE_PATH_TO_TEXT_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 a test for the EFI_DEVICE_PATH_TO_TEXT_PROTOCOL protocol. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- v2 no change --- lib/efi_selftest/Makefile | 3 + lib/efi_selftest/efi_selftest_devicepath.c | 340 +++++++++++++++++++++++++++++ 2 files changed, 343 insertions(+) create mode 100644 lib/efi_selftest/efi_selftest_devicepath.c diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 1851c17db6..d280eca5c3 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -11,6 +11,8 @@ CFLAGS_efi_selftest.o := $(CFLAGS_EFI) CFLAGS_REMOVE_efi_selftest.o := $(CFLAGS_NON_EFI) CFLAGS_efi_selftest_console.o := $(CFLAGS_EFI) CFLAGS_REMOVE_efi_selftest_console.o := $(CFLAGS_NON_EFI) +CFLAGS_efi_selftest_devicepathe.o := $(CFLAGS_EFI) +CFLAGS_REMOVE_efi_selftest_devicepath.o := $(CFLAGS_NON_EFI) CFLAGS_efi_selftest_events.o := $(CFLAGS_EFI) CFLAGS_REMOVE_efi_selftest_events.o := $(CFLAGS_NON_EFI) CFLAGS_efi_selftest_exitbootservices.o := $(CFLAGS_EFI) @@ -33,6 +35,7 @@ CFLAGS_REMOVE_efi_selftest_watchdog.o := $(CFLAGS_NON_EFI) obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += \ efi_selftest.o \ efi_selftest_console.o \ +efi_selftest_devicepath.o \ efi_selftest_events.o \ efi_selftest_exitbootservices.o \ efi_selftest_gop.o \ diff --git a/lib/efi_selftest/efi_selftest_devicepath.c b/lib/efi_selftest/efi_selftest_devicepath.c new file mode 100644 index 0000000000..6c6185c050 --- /dev/null +++ b/lib/efi_selftest/efi_selftest_devicepath.c @@ -0,0 +1,340 @@ +/* + * efi_selftest_devicepath + * + * Copyright (c) 2017 Heinrich Schuchardt + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This unit test checks the following protocol services: + * DevicePathToText + */ + +#include + +static struct efi_boot_services *boottime; + +static efi_handle_t handle1; +static efi_handle_t handle2; +static efi_handle_t handle3; + +struct interface { + void (EFIAPI * inc)(void); +} interface; + +static efi_guid_t guid_protocol = + EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d, + 0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xbb, 0x7d); + +static efi_guid_t guid_vendor1 = + EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d, + 0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xbb, 0xb1); + +static efi_guid_t guid_vendor2 = + EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d, + 0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xbb, 0xa2); + +static efi_guid_t guid_vendor3 = + EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d, + 0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xbb, 0xc3); + +static u8 *dp1; +static u8 *dp2; +static u8 *dp3; + +struct efi_device_path_to_text_protocol *device_path_to_text; + +/* + * Setup unit test. + * + * Create three handles. Install a new protocol on two of them and + * provice device paths. + * + * handle1 + * guid interface + * handle2 + * guid interface + * handle3 + * + * @handle: handle of the loaded image + * @systable: system table + */ +static int setup(const efi_handle_t img_handle, + const struct efi_system_table *systable) +{ + struct efi_device_path_vendor vendor_node; + struct efi_device_path end_node; + efi_status_t ret; + + boottime = systable->boottime; + + ret = boottime->locate_protocol(&efi_guid_device_path_to_text_protocol, + NULL, (void **)&device_path_to_text); + if (ret != EFI_SUCCESS) { + device_path_to_text = NULL; + efi_st_printf( + "Device path to text protocol is not available.\n"); + return EFI_ST_FAILURE; + } + + ret = boottime->allocate_pool(EFI_LOADER_DATA, + sizeof(struct efi_device_path_vendor) + + sizeof(struct efi_device_path), + (void **)&dp1); + if (ret != EFI_SUCCESS) + goto out_of_memory; + + ret = boottime->allocate_pool(EFI_LOADER_DATA, 2 * + sizeof(struct efi_device_path_vendor) + + sizeof(struct efi_device_path), + (void **)&dp2); + if (ret != EFI_SUCCESS) + goto out_of_memory; + + ret = boottime->allocate_pool(EFI_LOADER_DATA, 3 * + sizeof(struct efi_device_path_vendor) + + sizeof(struct efi_device_path), + (void **)&dp3); + if (ret != EFI_SUCCESS) + goto out_of_memory; + + vendor_node.dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE; + vendor_node.dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR; + vendor_node.dp.length = sizeof(struct efi_device_path_vendor); + + boottime->copy_mem(&vendor_node.guid, &guid_vendor1, + sizeof(efi_guid_t)); + boottime->copy_mem(dp1, &vendor_node, + sizeof(struct efi_device_path_vendor)); + boottime->copy_mem(dp2, &vendor_node, + sizeof(struct efi_device_path_vendor)); + boottime->copy_mem(dp3, &vendor_node, + sizeof(struct efi_device_path_vendor)); + + boottime->copy_mem(&vendor_node.guid, &guid_vendor2, + sizeof(efi_guid_t)); + boottime->copy_mem(dp2 + sizeof(struct efi_device_path_vendor), + &vendor_node, sizeof(struct efi_device_path_vendor)); + boottime->copy_mem(dp3 + sizeof(struct efi_device_path_vendor), + &vendor_node, sizeof(struct efi_device_path_vendor)); + + boottime->copy_mem(&vendor_node.guid, &guid_vendor3, + sizeof(efi_guid_t)); + boottime->copy_mem(dp3 + 2 * sizeof(struct efi_device_path_vendor), + &vendor_node, sizeof(struct efi_device_path_vendor)); + + end_node.type = DEVICE_PATH_TYPE_END; + end_node.sub_type = DEVICE_PATH_SUB_TYPE_END; + end_node.length = sizeof(struct efi_device_path); + boottime->copy_mem(dp1 + sizeof(struct efi_device_path_vendor), + &end_node, sizeof(struct efi_device_path)); + boottime->copy_mem(dp2 + 2 * sizeof(struct efi_device_path_vendor), + &end_node, sizeof(struct efi_device_path)); + boottime->copy_mem(dp3 + 3 * sizeof(struct efi_device_path_vendor), + &end_node, sizeof(struct efi_device_path)); + + ret = boottime->install_protocol_interface(&handle1, + &efi_guid_device_path, + EFI_NATIVE_INTERFACE, + dp1); + if (ret != EFI_SUCCESS) { + efi_st_error("InstallProtocolInterface failed\n"); + return EFI_ST_FAILURE; + } + ret = boottime->install_protocol_interface(&handle1, + &guid_protocol, + EFI_NATIVE_INTERFACE, + &interface); + if (ret != EFI_SUCCESS) { + efi_st_error("InstallProtocolInterface failed\n"); + return EFI_ST_FAILURE; + } + ret = boottime->install_protocol_interface(&handle2, + &efi_guid_device_path, + EFI_NATIVE_INTERFACE, + dp2); + if (ret != EFI_SUCCESS) { + efi_st_error("InstallProtocolInterface failed\n"); + return EFI_ST_FAILURE; + } + ret = boottime->install_protocol_interface(&handle2, + &guid_protocol, + EFI_NATIVE_INTERFACE, + &interface); + if (ret != EFI_SUCCESS) { + efi_st_error("InstallProtocolInterface failed\n"); + return EFI_ST_FAILURE; + } + ret = boottime->install_protocol_interface(&handle3, + &efi_guid_device_path, + EFI_NATIVE_INTERFACE, + dp3); + if (ret != EFI_SUCCESS) { + efi_st_error("InstallProtocolInterface failed\n"); + return EFI_ST_FAILURE; + } + return EFI_ST_SUCCESS; + +out_of_memory: + efi_st_error("Out of memory\n"); + return EFI_ST_FAILURE; +} + +/* + * Tear down unit test. + * + */ +static int teardown(void) +{ + efi_status_t ret; + + ret = boottime->uninstall_protocol_interface(&handle1, + &efi_guid_device_path, + dp1); + if (ret != EFI_SUCCESS) + efi_st_todo("UninstallProtocolInterface failed\n"); + ret = boottime->uninstall_protocol_interface(&handle1, + &guid_protocol, + &interface); + if (ret != EFI_SUCCESS) + efi_st_todo("UninstallProtocolInterface failed\n"); + ret = boottime->uninstall_protocol_interface(&handle2, + &efi_guid_device_path, + dp2); + if (ret != EFI_SUCCESS) + efi_st_todo("UninstallProtocolInterface failed\n"); + ret = boottime->uninstall_protocol_interface(&handle2, + &guid_protocol, + &interface); + if (ret != EFI_SUCCESS) + efi_st_todo("UninstallProtocolInterface failed\n"); + ret = boottime->uninstall_protocol_interface(&handle3, + &efi_guid_device_path, + dp3); + if (ret != EFI_SUCCESS) + efi_st_todo("UninstallProtocolInterface failed\n"); + if (dp1) { + ret = boottime->free_pool(dp1); + if (ret != EFI_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + } + if (dp2) { + ret = boottime->free_pool(dp2); + if (ret != EFI_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + } + if (dp3) { + ret = boottime->free_pool(dp3); + if (ret != EFI_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + } + return EFI_ST_SUCCESS; +} + +/* + * Execute unit test. + * + */ +static int execute(void) +{ + struct efi_device_path *remaining_dp; + void *handle; + /* + * This device path node ends with the letter 't' of 'u-boot'. + * The following '.bin' does not belong to the node but is + * helps to test the correct truncation. + */ + struct { + struct efi_device_path dp; + u16 text[12]; + } __packed dp_node = { + { DEVICE_PATH_TYPE_MEDIA_DEVICE, + DEVICE_PATH_SUB_TYPE_FILE_PATH, + sizeof(struct efi_device_path) + 12}, + L"u-boot.bin", + }; + u16 *string; + efi_status_t ret; + + /* Test ConvertDevicePathToText */ + string = device_path_to_text->convert_device_path_to_text( + (struct efi_device_path *)dp2, true, false); + if (!string) { + efi_st_error("ConvertDevicePathToText failed\n"); + return EFI_ST_FAILURE; + } + efi_st_printf("dp2: %ps\n", string); + if (efi_st_strcmp_16_8( + string, + "/VenHw(dbca4c98-6cb0-694d-0872-819c650cbbb1)/VenHw(dbca4c98-6cb0-694d-0872-819c650cbba2)") + ) { + efi_st_error("Incorrect text from ConvertDevicePathToText\n"); + return EFI_ST_FAILURE; + } + + ret = boottime->free_pool(string); + if (ret != EFI_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + + /* Test ConvertDeviceNodeToText */ + string = device_path_to_text->convert_device_node_to_text( + (struct efi_device_path *)&dp_node, true, false); + if (!string) { + efi_st_error("ConvertDeviceNodeToText failed\n"); + return EFI_ST_FAILURE; + } + efi_st_printf("dp_node: %ps\n", string); + ret = boottime->free_pool(string); + if (ret != EFI_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + if (efi_st_strcmp_16_8(string, "u-boot")) { + efi_st_error( + "Incorrect conversion by ConvertDeviceNodeToText\n"); + return EFI_ST_FAILURE; + } + + /* Test LocateDevicePath */ + remaining_dp = (struct efi_device_path *)dp3; + ret = boottime->locate_device_path(&guid_protocol, &remaining_dp, + &handle); + if (ret != EFI_SUCCESS) { + efi_st_error("LocateDevicePath failed\n"); + return EFI_ST_FAILURE; + } + if (handle != handle2) { + efi_st_error("LocateDevicePath returned wrong handle\n"); + return EFI_ST_FAILURE; + } + string = device_path_to_text->convert_device_path_to_text(remaining_dp, + true, false); + if (!string) { + efi_st_error("ConvertDevicePathToText failed\n"); + return EFI_ST_FAILURE; + } + efi_st_printf("remaining device path: %ps\n", string); + if (efi_st_strcmp_16_8(string, + "/VenHw(dbca4c98-6cb0-694d-0872-819c650cbbc3)") + ) { + efi_st_error("LocateDevicePath: wrong remaining device path\n"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +EFI_UNIT_TEST(devicepath) = { + .name = "device path", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .setup = setup, + .execute = execute, + .teardown = teardown, +};