From patchwork Wed Oct 5 12:18:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Barker X-Patchwork-Id: 1686325 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=sancloud.onmicrosoft.com header.i=@sancloud.onmicrosoft.com header.a=rsa-sha256 header.s=selector2-sancloud-onmicrosoft-com header.b=UnJaroOd; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4MjDDQ2x7yz1yqn for ; Wed, 5 Oct 2022 23:20:22 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 2B37084D7B; Wed, 5 Oct 2022 14:19:46 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=sancloud.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=sancloud.onmicrosoft.com header.i=@sancloud.onmicrosoft.com header.b="UnJaroOd"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D578984E37; Wed, 5 Oct 2022 14:19:12 +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=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from GBR01-LO2-obe.outbound.protection.outlook.com (mail-lo2gbr01on2090.outbound.protection.outlook.com [40.107.10.90]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id D95E384D6A for ; Wed, 5 Oct 2022 14:18:57 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=sancloud.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=paul.barker@sancloud.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=EJ7HI5T920H4n5rz3OeRUmpWFZycxEc1fKzR7vujE/8/NFAtOCeewfFhUMbg1RZj2TbgpVCSmV0xbxcwCl/Ov/TOzKlXH6wNGJUPghA7eNfNKEH6USIRpMOcIkQJo1NnUrEjfJniZK4Wx2tbHDkbyJydXyB+bfoU3Mle5tLr5ZltFH8zNtzBNwHShydLvq+G3o6y4W8C2W69n55aSiOOHvPXlncOAZ/EG6LnWhCO48bOOmzruZVmDUfFpnL+P+9w/tgUE+ZC7rB6HtdQ9QJhVbOetGWMndyAsYN79+tHvk+LUUJ9zAiowE2zoBOu0Y6CUHJwUT+BRzaAYJuuS5ZXmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=AEaGKbFzeSBkITc9EBUzfl/a8gkVnqMwSuskoc6WM4U=; b=KmF7Ded+RG94fJl8pEen70hBthfOBDrV/atZg0LfWRg2PA2DM0rIjwfc4Pxd0rac7qKwC0pzAt74zpyIpLM26mOy4H2Cc54OppQjbvyDcaZUTNhTforO4Km0NDCcnjg4se+kSSIyIwNqhaunnWR19iAk3UenhxYQrrtR6PiJVOuVmQ40hPEjraa2UWIAmMUoW+xZsysGCqUvrDfLhyKA97Bph7ODP4OzyPKGJTVQXjd4wS8cm/jK9UXZ1C2qaUAf97AWG2mc2azmp5kTEvCw5YJnBxnMzGAdR8h2qgcYiyqV7h5QaXjge3OFfuKQ/WQfK26nFBaI+FjF+Qr4gh+7HQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=sancloud.com; dmarc=pass action=none header.from=sancloud.com; dkim=pass header.d=sancloud.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sancloud.onmicrosoft.com; s=selector2-sancloud-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=AEaGKbFzeSBkITc9EBUzfl/a8gkVnqMwSuskoc6WM4U=; b=UnJaroOd/fofazMQRQEdux/vzSxPDc/gEXiSTLWEiA8xhglRL7W5akTYXtPR8HnGkmpaYS/D46tayY3O2ssQaorQfslDpOgH+ovi7bmhGz8ehcT1qoz2yaCpkGaWXrirtAFE+N6EMPia4ylwjezsTWrXalPHG4lekuzhLqcTN54= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=sancloud.com; Received: from CWLP123MB2241.GBRP123.PROD.OUTLOOK.COM (2603:10a6:401:61::19) by LO6P123MB6536.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:2b0::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5676.32; Wed, 5 Oct 2022 12:18:56 +0000 Received: from CWLP123MB2241.GBRP123.PROD.OUTLOOK.COM ([fe80::11d5:40af:9060:6b08]) by CWLP123MB2241.GBRP123.PROD.OUTLOOK.COM ([fe80::11d5:40af:9060:6b08%6]) with mapi id 15.20.5676.031; Wed, 5 Oct 2022 12:18:56 +0000 From: Paul Barker To: u-boot@lists.denx.de, Heinrich Schuchardt , Ilias Apalodimas , Tom Rini , Simon Glass Cc: Paul Barker Subject: [PATCH v4 4/6] efi_selftest: Add tests for SPI protocol support Date: Wed, 5 Oct 2022 13:18:37 +0100 Message-Id: <20221005121839.3938771-5-paul.barker@sancloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221005121839.3938771-1-paul.barker@sancloud.com> References: <20221005121839.3938771-1-paul.barker@sancloud.com> X-ClientProxiedBy: LO2P265CA0191.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:a::35) To CWLP123MB2241.GBRP123.PROD.OUTLOOK.COM (2603:10a6:401:61::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CWLP123MB2241:EE_|LO6P123MB6536:EE_ X-MS-Office365-Filtering-Correlation-Id: 8363db30-088a-4a00-ebb4-08daa6cbc67f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: PRTlJkzXUubc0t3C3zf3s4UrJugfP/WSW7KmzX1PJ6DLwMiCJWTJ51Td5N4oYaFGEFX+GQv21i3g6aN93TxDnEQbGhdYN6vlOMR/13N5UfCaVrHtn50hcpGxP9CBbCMzrw7mdu/Tu9aFeLy/bDtUyDRxkrMM1+O9bf1dqAyRyUujkUJIhNhZHgnq2tsSsRJhvAV1poNclock17arRe4HemBQ1yKwDl4OaEKJIJ5pj5XUW0eK7tivRi48dlhn/4JxZlnUfTGaVcnz+OLy3RH0sVhpSYJZXkteBsTfWgtS3oRjVsXuH/sD+4+zW1kVI70PTmPidl6rmfD1ivrUf0N3NL6JGqs7zsqby8FlA5CkNNFBFHEABbgZs6HGzruTr7HF7jGFrqVgyFh4HkNKXA1NLz1wAToBuNXiur5R078rd8W9m7jbYq8BwsNw/UgP26vqSwiMsi+6VtZvLtZPHAUjo1iZqMCDxh8p7C15pLWs/MfIzijVI9nY4lz50WO6v6eDJJWR34M6ntCrNhyAGu7WyJ0ogjTwKF+D/EBXABFnLPIYTS901Iua8oc2CArfOJdoX6sC5eLbUtLxsT9YbTfw8fnBCm5wsZSoZLzcPdeAtqVFpPsFX4G8DNhuVCXTKj5OrTd7CL2St4Vua6XsyPvhgu7WPuyjKLTpcpJhn4J05JdH4LbVSqMat9Gs5YkWQKJsp7zxTwvTr8N9gUDBNMlSh81py7Jo1wv5IZuKEJ/ZjCmXcePvs2wyryPxAVJ6KVtnMJQBdmVafmLBatPWNipfWbZGs8EJmBhuHmet7e9RisQBv7jhxwkKv+rCf8mVIaSU X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:CWLP123MB2241.GBRP123.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230022)(396003)(346002)(136003)(39830400003)(366004)(376002)(451199015)(36756003)(2906002)(6486002)(66556008)(66476007)(66946007)(8676002)(4326008)(38350700002)(41300700001)(478600001)(30864003)(8936002)(44832011)(110136005)(5660300002)(316002)(2616005)(1076003)(83380400001)(52116002)(86362001)(38100700002)(26005)(6506007)(6512007)(6666004)(107886003)(186003); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 47Wb2W8vEMDwz8jM7dGGsQyDtYNQuuAPPaLIf+1WCXjLjB2MJ3+GxnCp37pXm/Ml3OnCu8UAz9q8JxpsG6PZ/rSZABHrWqswBKKljYWEVJB8+rh0BSh7dO6Rf3qYc9vP7JBZgtm2jJ1BiF7NgiPD/3YR1e9dRiMpDUdzuLQ7df4Q8iMdI4fUTi7KdWUmFiYb9mPAIr5qNu9p7fA+9EdCcZ7NS6dNvstScwCSHO3icRhA5at5aQO/CjVM/3YEoEH40blHgAUClg5BX4sA72ZD3/QCGQUNsrZomK8+A9oeIozqUCEv5XTaxT29VeJ+bweq5aLp0hll/a3yWv19OCmW9unf8topaorCI8qmw1vERXSqqK8hRU9pk5++yyrgpQrnYLTLvrvGlc6Wf7ZnEnEpPPnT3JqL56lhqLhbBTEP7VuF/OpaqEyrD9mRK0SYqFZUTVh6FvXn3TgYUpu6QxxmxW7AZaAC8i1vIrefKbhqT8d2rVBrgzP0CfU6PxEynlEj31OKHrsvX5bhIACZy618KsvbrHNWBEF9X7RqPNwGNFP50qiIVEw0PDvz+p1jlqbGrXoXQRLeuQFBt5JYzMMy9JprpmFVMGHa/HqJEHRnKppA91bBoLeDS9SqVC7hgLeqVdu57hRExYvRUDk5V+28lAVPQrWymPBSvLG/HdqDchsOv46AF22vzcXBOJMCzF9W3dTnRm4fOtEUkyqVKEW6Ubbeviwm6H6Pj2aaWux7TaX+76MwOfnkeRozLH2NVd4/qJmob5vOqfWgyn1JkhSv1JjDhzaIErfbo/+HPRjX5hvC1RwSAq0ZKehqtQ/ziQFZuWVPfvIRmE/mk0A/HRWhKv9R8OsFiwyS1s4AGjsQtuazIaK89V5oxEJk2BAj+hHdwAFLvn2l1xHDG2VwvJj/2J0zkHJiaesLYYPhcHXUEuTGr2x8oFtby5QdYBy43NdML0Bb4+997xzphQFwHtQs1LvyNJ891DJ2GVLjWV1JX3GTIjEsALu0l+mnqcZ8l1Xsgizeq2hoJlCATJLUSO+cUr+wpmcJzg21KrbvLm3aR829EalF6qhPeOpaNEZvwfZi2VUq9B9qCIFeYNW1UTaxdS84Uqt0zS8fZWzOqsiOjygBufWdwwU05EWxmr41bJ1h/gztJEqkdmEiWj3yCBNEHNyBaKm2ZULjULBAnua7XiMtRQlkDs9b5gVqqor5YdQm7VklwduEIYvfOJVtuguDByoQFw24451/3qaODGrys47FD6PZuBqEVfWNd51ZFJjuFYX7OiZZE/e1dhbJkkflf/B2ql5tSboENnYh0MM4UwfEXnGAR8P53KFNqzluRxNiZ8tuWhm6IhsCyMzzFL4eyk0fn3VZciPUGIg8w2dsQgOdlYRPdi8uJp3vCg5iWT3rs0Q1ux8YOsjHJJGsdWa0BOMNGdPtpzeMIS/tcaAOdZNyFP+kqWz6aqtdiZ6mOeCkvTLfs7zWqZy+66PWEiCMQgzutHj99ZSTmZffahmSNFZ4DGlWFRgVM8E4UVD4WrLtzG0tGKzg1SNA74kQPksA16e1OHKsMdIBkEWtpVCwhIe33c/QbiYIVaeUoTU7mItPo0rcJWssJYh25sjUThMzfw== X-OriginatorOrg: sancloud.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8363db30-088a-4a00-ebb4-08daa6cbc67f X-MS-Exchange-CrossTenant-AuthSource: CWLP123MB2241.GBRP123.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Oct 2022 12:18:56.5971 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 840be37c-244a-450e-9bcc-2064862de1f4 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 63fXMhe2fyxpmgcvmmUseRLntcfvV0IdMI1kDbxJAG5/4a7xKV1Z7sAwgxGyPDZ5Wl1tMLBSVtjDfVHpe9CNq3UbE1eT26/GSBno70p8lIk= X-MS-Exchange-Transport-CrossTenantHeadersStamped: LO6P123MB6536 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.6 at phobos.denx.de X-Virus-Status: Clean These tests ensure that the new UEFI SPI I/O protocol support works as expected. They are intended to execute on the sandbox target. Signed-off-by: Paul Barker --- MAINTAINERS | 1 + arch/sandbox/dts/test.dts | 13 + lib/efi_selftest/Makefile | 1 + lib/efi_selftest/efi_selftest_spi_protocol.c | 284 +++++++++++++++++++ 4 files changed, 299 insertions(+) create mode 100644 lib/efi_selftest/efi_selftest_spi_protocol.c diff --git a/MAINTAINERS b/MAINTAINERS index 40b3f1c80daa..a58b2083a218 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -862,6 +862,7 @@ M: Paul Barker S: Maintained F: include/efi_spi_protocol.h F: lib/efi_loader/efi_spi_protocol.c +F: lib/efi_selftest/efi_selftest_spi_protocol.c EFI VARIABLES VIA OP-TEE M: Ilias Apalodimas diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 2761588f0dad..05c3e0377ac4 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1185,6 +1185,13 @@ compatible = "spansion,m25p16", "jedec,spi-nor"; spi-max-frequency = <40000000>; sandbox,filename = "spi.bin"; + + uefi-spi-vendor = "spansion"; + uefi-spi-part-number = "mt25p16"; + + /* GUID in UEFI format: b881eb5d-ad92-4a48-8fdd-fa75a8e4c6b8 */ + uefi-spi-io-guid = [5d eb 81 b8 92 ad 48 4a + 8f dd fa 75 a8 e4 c6 b8]; }; spi.bin@1 { reg = <1>; @@ -1193,6 +1200,12 @@ sandbox,filename = "spi.bin"; spi-cpol; spi-cpha; + + uefi-spi-vendor = "spansion"; + uefi-spi-part-number = "mt25p16"; + /* GUID in UEFI format: b6b39ecd-2b1f-a643-b8d7-3192d7cf7270 */ + uefi-spi-io-guid = [cd 9e b3 b6 1f 2b 43 a6 + b8 d7 31 92 d7 cf 72 70]; }; }; diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index daac6c396820..2790fcd784e0 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -63,6 +63,7 @@ obj-$(CONFIG_EFI_LOADER_HII) += efi_selftest_hii.o obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_selftest_rng.o obj-$(CONFIG_EFI_GET_TIME) += efi_selftest_rtc.o obj-$(CONFIG_EFI_TCG2_PROTOCOL) += efi_selftest_tcg2.o +obj-$(CONFIG_EFI_SPI_PROTOCOL) += efi_selftest_spi_protocol.o ifeq ($(CONFIG_GENERATE_ACPI_TABLE),) obj-y += efi_selftest_fdt.o diff --git a/lib/efi_selftest/efi_selftest_spi_protocol.c b/lib/efi_selftest/efi_selftest_spi_protocol.c new file mode 100644 index 000000000000..946d04dbb557 --- /dev/null +++ b/lib/efi_selftest/efi_selftest_spi_protocol.c @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2022 Micron Technology, Inc. + */ + +#include +#include + +static struct efi_boot_services *boottime; +static efi_guid_t efi_spi_configuration_guid = EFI_SPI_CONFIGURATION_GUID; + +static int setup(const efi_handle_t img_handle, + const struct efi_system_table *systable) +{ + boottime = systable->boottime; + return EFI_ST_SUCCESS; +} + +static int test_peripheral(struct efi_spi_peripheral *p, struct efi_spi_bus *bus) +{ + struct efi_spi_io_protocol *io_protocol; + u8 req[5], resp[5]; + efi_status_t ret; + + if (!p->friendly_name) { + efi_st_error("SPI peripheral lacks a friendly name\n"); + return EFI_ST_FAILURE; + } + + if (!p->spi_peripheral_driver_guid) { + efi_st_error("SPI peripheral lacks driver GUID\n"); + return EFI_ST_FAILURE; + } + + if (!p->spi_part) { + efi_st_error("SPI peripheral lacks SPI part definition\n"); + return EFI_ST_FAILURE; + } + + if (!p->max_clock_hz) { + efi_st_error("SPI peripheral has a max clock rate of zero\n"); + return EFI_ST_FAILURE; + } + + if (!p->spi_bus) { + efi_st_error("SPI peripheral lack pointer to SPI bus\n"); + return EFI_ST_FAILURE; + } + + if (p->spi_bus != bus) { + efi_st_error("SPI peripheral spi_bus pointer points to the wrong bus\n"); + return EFI_ST_FAILURE; + } + + if (!p->chip_select) { + efi_st_error("SPI peripheral lacks chip_select function\n"); + return EFI_ST_FAILURE; + } + + if (!p->spi_part->vendor) { + efi_st_error("SPI part lacks vendor string\n"); + return EFI_ST_FAILURE; + } + + if (!p->spi_part->part_number) { + efi_st_error("SPI part lacks part number string\n"); + return EFI_ST_FAILURE; + } + + if (p->spi_part->min_clock_hz > p->spi_part->max_clock_hz) { + efi_st_error("SPI part min clock rate is greater than max clock rate\n"); + return EFI_ST_FAILURE; + } + + if (p->spi_part->max_clock_hz != p->max_clock_hz) { + efi_st_error("SPI part max clock rate does not match peripheral max clock rate\n"); + return EFI_ST_FAILURE; + } + + ret = boottime->locate_protocol(p->spi_peripheral_driver_guid, + NULL, (void **)&io_protocol); + if (ret != EFI_SUCCESS) { + efi_st_error("SPI IO protocol not available\n"); + return EFI_ST_FAILURE; + } + + if (io_protocol->spi_peripheral != p) { + efi_st_error("SPI IO protocol spi_peripheral pointer points to the wrong peripheral\n"); + return EFI_ST_FAILURE; + } + + if (io_protocol->original_spi_peripheral != p) { + efi_st_error("SPI IO protocol original_spi_peripheral pointer points to the wrong peripheral\n"); + return EFI_ST_FAILURE; + } + + if (!io_protocol->maximum_transfer_bytes) { + efi_st_error("SPI IO protocol has zero maximum transfer size\n"); + return EFI_ST_FAILURE; + } + + if (!io_protocol->legacy_spi_protocol) { + efi_st_error("SPI IO protocol lacks legacy SPI protocol\n"); + return EFI_ST_FAILURE; + } + + if (!io_protocol->transaction) { + efi_st_error("SPI IO protocol lacks transaction function\n"); + return EFI_ST_FAILURE; + } + + if (!io_protocol->update_spi_peripheral) { + efi_st_error("SPI IO protocol lacks update_spi_peripheral function\n"); + return EFI_ST_FAILURE; + } + + if (!io_protocol->legacy_spi_protocol->erase_block_opcode) { + efi_st_error("SPI legacy controller protocol lacks erase_block_opcode function\n"); + return EFI_ST_FAILURE; + } + + if (io_protocol->legacy_spi_protocol->erase_block_opcode( + io_protocol->legacy_spi_protocol, + 0) != EFI_UNSUPPORTED) { + efi_st_error("Incorrect return value from SPI legacy controller protocol erase_block_opcode function\n"); + return EFI_ST_FAILURE; + } + + if (!io_protocol->legacy_spi_protocol->write_status_prefix) { + efi_st_error("SPI legacy controller protocol lacks write_status_prefix function\n"); + return EFI_ST_FAILURE; + } + + if (io_protocol->legacy_spi_protocol->write_status_prefix( + io_protocol->legacy_spi_protocol, + 0) != EFI_UNSUPPORTED) { + efi_st_error("Incorrect return value from SPI legacy controller protocol write_status_prefix function\n"); + return EFI_ST_FAILURE; + } + + if (!io_protocol->legacy_spi_protocol->bios_base_address) { + efi_st_error("SPI legacy controller protocol lacks bios_base_address function\n"); + return EFI_ST_FAILURE; + } + + if (io_protocol->legacy_spi_protocol->bios_base_address( + io_protocol->legacy_spi_protocol, + 0) != EFI_UNSUPPORTED) { + efi_st_error("Incorrect return value from SPI legacy controller protocol bios_base_address function\n"); + return EFI_ST_FAILURE; + } + + if (!io_protocol->legacy_spi_protocol->clear_spi_protect) { + efi_st_error("SPI legacy controller protocol lacks clear_spi_protect function\n"); + return EFI_ST_FAILURE; + } + + if (io_protocol->legacy_spi_protocol->clear_spi_protect( + io_protocol->legacy_spi_protocol) != EFI_UNSUPPORTED) { + efi_st_error("Incorrect return value from SPI legacy controller protocol clear_spi_protect function\n"); + return EFI_ST_FAILURE; + } + + if (!io_protocol->legacy_spi_protocol->is_range_protected) { + efi_st_error("SPI legacy controller protocol lacks is_range_protected function\n"); + return EFI_ST_FAILURE; + } + + if (io_protocol->legacy_spi_protocol->is_range_protected( + io_protocol->legacy_spi_protocol, + 0, 0)) { + efi_st_error("Incorrect return value from SPI legacy controller protocol is_range_protected function\n"); + return EFI_ST_FAILURE; + } + + if (!io_protocol->legacy_spi_protocol->protect_next_range) { + efi_st_error("SPI legacy controller protocol lacks protect_next_range function\n"); + return EFI_ST_FAILURE; + } + + if (io_protocol->legacy_spi_protocol->protect_next_range( + io_protocol->legacy_spi_protocol, + 0, 0) != EFI_UNSUPPORTED) { + efi_st_error("Incorrect return value from SPI legacy controller protocol protect_next_range function\n"); + return EFI_ST_FAILURE; + } + + if (!io_protocol->legacy_spi_protocol->lock_controller) { + efi_st_error("SPI legacy controller protocol lacks lock_controller function\n"); + return EFI_ST_FAILURE; + } + + if (io_protocol->legacy_spi_protocol->lock_controller( + io_protocol->legacy_spi_protocol) != EFI_UNSUPPORTED) { + efi_st_error("Incorrect return value from SPI legacy controller protocol lock_controller function\n"); + return EFI_ST_FAILURE; + } + + req[0] = 0x9f; + ret = io_protocol->transaction(io_protocol, + SPI_TRANSACTION_FULL_DUPLEX, + false, 0, 1, 8, + sizeof(req), req, + sizeof(resp), resp); + if (ret != EFI_SUCCESS) { + efi_st_error("SPI transaction failed\n"); + return EFI_ST_FAILURE; + } + + if ((resp[0] != 0xff) || (resp[1] != 0x20) || (resp[2] != 0x20) || (resp[3] != 0x15)) { + efi_st_error("Incorrect response from sandbox SPI flash emulator\n"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +static int test_bus(struct efi_spi_bus *bus) +{ + struct efi_spi_peripheral *p; + int status; + + if (!bus->friendly_name) { + efi_st_error("SPI bus lacks a friendly name\n"); + return EFI_ST_FAILURE; + } + + if (!bus->peripheral_list) { + efi_st_error("SPI bus has zero peripherals\n"); + return EFI_ST_FAILURE; + } + + if (!bus->clock) { + efi_st_error("SPI bus lacks clock function\n"); + return EFI_ST_FAILURE; + } + + for (p = bus->peripheral_list; p; p = p->next_spi_peripheral) { + status = test_peripheral(p, bus); + if (status) { + efi_st_error("Failed testing SPI peripheral\n"); + return status; + } + } + + return EFI_ST_SUCCESS; +} + +static int execute(void) +{ + struct efi_spi_configuration_protocol *spi; + efi_status_t ret; + int status; + u32 i; + + ret = boottime->locate_protocol(&efi_spi_configuration_guid, + NULL, (void **)&spi); + if (ret != EFI_SUCCESS) { + efi_st_error("SPI configuration protocol not available\n"); + return EFI_ST_FAILURE; + } + + if (!spi->bus_count) { + efi_st_error("SPI configuration protocol has zero busses\n"); + return EFI_ST_FAILURE; + } + + for (i = 0; i < spi->bus_count; i++) { + status = test_bus(spi->bus_list[i]); + if (status) { + efi_st_error("Failed testing SPI bus %d\n", i); + return status; + } + } + + return EFI_ST_SUCCESS; +} + +EFI_UNIT_TEST(spi_protocol) = { + .name = "SPI protocol", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .setup = setup, + .execute = execute, +};