From patchwork Fri Jul 7 04:00:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 700013 Delivered-To: patch@linaro.org Received: by 2002:adf:fcc5:0:0:0:0:0 with SMTP id f5csp3663394wrs; Thu, 6 Jul 2023 21:01:46 -0700 (PDT) X-Google-Smtp-Source: APBJJlHGKmgYay8/gKfyvcyC1nZnwWlIG8cCIF2ylAGSXQSaJo0Y48/8Fkyj1PlY2gF6/6oapz4E X-Received: by 2002:a6b:e009:0:b0:786:2a1e:4e1f with SMTP id z9-20020a6be009000000b007862a1e4e1fmr5315935iog.10.1688702506720; Thu, 06 Jul 2023 21:01:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688702506; cv=none; d=google.com; s=arc-20160816; b=O8xgS0WdItNS+TLHNfHLrFdsUrxr6Vi0rfM1zTVEaL/RwvJ97cMd2EMxEpCMAyG4S+ pfueE7K3qwhPlZ9gjxCKHP7ezZEUZB1wZNtRDbYKi3DYeUOcxkY3jMrHaO9jgiSU5yuB 0IabDkCMfXW5zmqWqc2tnDH1JPCKx5muVgseFv/rxZ4SaHUHDU49Hkd/Ean4eYNKsUel hrNkDyy4LloNM5haQmszqFGlc9ywYpsm+WH2w1GtS0bgBMWqkPQ1GxED8RvN4SZOIdHV JkxVzplM9qdwCdh/P+g8SKzNIOmaW7LJgCZA6937R7gYseAV13LiGg3sOSK6oCQbZ42u z14Q== 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=TaxBuyANh3GRzNUNGq5DXNK9Ok7IJeiYHBAOstodDu4=; fh=UqK/4Wc1IgH8GVyLylIZPdO/qWI3a/IzA+fwLs4tfXk=; b=tcPiiENwsCBKw/zB+SP35cPSXft9mKqMl2Cdx0pB2RiayxeRR/Nj3zFvuN5lXvzt8L EIcjLUBaPyDcV91zs11qXqv3OYHdyI5FPhUP5VpXikFYqfzKb8BhO+AF1qmqUPCsf3KZ pV7X8O8L5iOCakqrf2AlMMJyzH5uKVWMaBIMzEjjYlQH16tHpkhSjz3/KR6/aAlIGD44 6iM6X2txvceszhOwmYO1X5vFr2yLlZkAhP2pbtAdZjFUjZhmoM520ERUpzANI02BFBS9 6HMm6ma7f9wNA7ml7O2NGoVZ03H0hytoCZc5Fr+ikJqUZQuqVhKmD0SSapfD9jBoNJ6e n5hg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Fc4Slizx; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id f12-20020a6bdd0c000000b00778356abcecsi1103148ioc.96.2023.07.06.21.01.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Jul 2023 21:01:46 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Fc4Slizx; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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 517F1863C2; Fri, 7 Jul 2023 06:01:37 +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="Fc4Slizx"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 9E27B863C9; Fri, 7 Jul 2023 06:01:35 +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-oa1-x30.google.com (mail-oa1-x30.google.com [IPv6:2001:4860:4864:20::30]) (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 2EC9D863C2 for ; Fri, 7 Jul 2023 06:01:33 +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-oa1-x30.google.com with SMTP id 586e51a60fabf-1b0606bee45so1448875fac.3 for ; Thu, 06 Jul 2023 21:01:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1688702491; x=1691294491; 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=TaxBuyANh3GRzNUNGq5DXNK9Ok7IJeiYHBAOstodDu4=; b=Fc4Slizx/WbhPyjCdkkNww8xYkyIN/MjyECR4iGdr9Yfns1ucq4/3W4H6ZMdU3oTgn 9pu3ljLbv6wKn1xfDdHPwLUuIoHT83AAs5NA081eAJuN6IYo449iSFR0ZjhkGLOcSJQS Uq/bG9MxV8I/oHk2hU+teEQsToDer2yveSICY9eyAH0ro7zchAm7wg7u48nDICcgwb8+ 40ngSE0WT7WjHnWrcWaKQ8niBh6+7oINwo4bx4D4JDnag3u9UMYCJFxYv4C+oPCJynqY lVPLKg+RKZN4S6RbxsOW9MNFxY4jBtRhj3saXdtarEBKaP54EHPhgmMgUrdUxZPdF1Cv Bp2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688702491; x=1691294491; 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=TaxBuyANh3GRzNUNGq5DXNK9Ok7IJeiYHBAOstodDu4=; b=RdLuUvkhQEHMJGc4FcO2XRiflicKrD9QyDZc3oImuQPnDhqBK+SQKvk9tHfQl0Jmkp 39HxOTupvWwJunulwvj2OpXc/8JrUXLh+Xcc5vS3FB33AOFzSYDON3UG8zSMOSm8Kyc5 AsldUSKLmKwuU1ake0xDX2fQpX7MoqV6cn4vSQwn7ay9riFMEOwhlQXj0NUxa153K2nc rEy/hBXyZHuVUa7flENORGTcUYRxudsn5y3Uj0W1XllfxXm+wrc2Ygc7UHDKbjrOtAs3 nNyCt2PhU1nK1bbzRjC7MSmJHMZONz3mjMbZ7qD2JR+jY1HHviwJxjoYpojxCNSHU9j7 JzUg== X-Gm-Message-State: ABy/qLbm89bmHXwiL1SatVggdPxzY4AtAc/toex0Ii7NLnTrm4TsbCN8 ep7n6b6+yIyG8tupMQ8UvB2B8IVXjZBe5USZJiw= X-Received: by 2002:a05:6870:82a0:b0:1b0:3e84:1dc5 with SMTP id q32-20020a05687082a000b001b03e841dc5mr4909234oae.54.1688702491559; Thu, 06 Jul 2023 21:01:31 -0700 (PDT) Received: from localhost ([164.70.16.189]) by smtp.gmail.com with ESMTPSA id 30-20020a17090a1a5e00b0025930e50e28sm569722pjl.41.2023.07.06.21.01.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Jul 2023 21:01:31 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , AKASHI Takahiro , Masahisa Kojima Subject: [PATCH 1/4] efi_loader: add RAM disk device path Date: Fri, 7 Jul 2023 13:00:41 +0900 Message-Id: <20230707040045.485790-2-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230707040045.485790-1-masahisa.kojima@linaro.org> References: <20230707040045.485790-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 is a preparation to add the EFI_RAM_DISK_PROTOCOL. This commit adds the RAM disk device path structure and text conversion to Device Path to Text Protocol. Signed-off-by: Masahisa Kojima --- include/efi_api.h | 19 +++++++++++++++++++ lib/efi_loader/efi_device_path_to_text.c | 14 ++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/include/efi_api.h b/include/efi_api.h index 55a4c989fc..4ee4a1b5e9 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -682,6 +682,7 @@ struct efi_device_path_uri { # define DEVICE_PATH_SUB_TYPE_CDROM_PATH 0x02 # define DEVICE_PATH_SUB_TYPE_VENDOR_PATH 0x03 # define DEVICE_PATH_SUB_TYPE_FILE_PATH 0x04 +# define DEVICE_PATH_SUB_TYPE_RAM_DISK_PATH 0x09 struct efi_device_path_hard_drive_path { struct efi_device_path dp; @@ -705,6 +706,24 @@ struct efi_device_path_file_path { u16 str[]; } __packed; +/* This GUID defines a RAM Disk supporting a raw disk format in volatile memory */ +#define EFI_VIRTUAL_DISK_GUID \ + EFI_GUID(0x77ab535a, 0x45fc, 0x624b, \ + 0x55, 0x60, 0xf7, 0xb2, 0x81, 0xd1, 0xf9, 0x6e) + +/* This GUID defines a RAM Disk supporting an ISO image in volatile memory */ +#define EFI_VIRTUAL_CD_GUID \ + EFI_GUID(0x3d5abd30, 0x4175, 0x87ce, \ + 0x6d, 0x64, 0xd2, 0xad, 0xe5, 0x23, 0xc4, 0xbb) + +struct efi_device_path_ram_disk_path { + struct efi_device_path dp; + u64 starting_address; + u64 ending_address; + efi_guid_t disk_type_guid; + u16 disk_instance; +} __packed; + #define EFI_BLOCK_IO_PROTOCOL_GUID \ EFI_GUID(0x964e5b21, 0x6459, 0x11d2, \ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b) diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index 8c76d8be60..4395e79f33 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -324,6 +324,20 @@ static char *dp_media(char *s, struct efi_device_path *dp) free(buffer); break; } + case DEVICE_PATH_SUB_TYPE_RAM_DISK_PATH: { + struct efi_device_path_ram_disk_path *rddp = + (struct efi_device_path_ram_disk_path *)dp; + u64 start; + u64 end; + + /* Copy from packed structure to aligned memory */ + memcpy(&start, &rddp->starting_address, sizeof(start)); + memcpy(&end, &rddp->ending_address, sizeof(end)); + + s += sprintf(s, "RamDisk(0x%llx,%llx,%pUl,0x%x)", start, end, + &rddp->disk_type_guid, rddp->disk_instance); + break; + } default: s = dp_unknown(s, dp); break; From patchwork Fri Jul 7 04:00:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 700014 Delivered-To: patch@linaro.org Received: by 2002:ab3:710f:0:b0:238:a68b:2c7d with SMTP id n15csp1717670lte; Thu, 6 Jul 2023 21:01:59 -0700 (PDT) X-Google-Smtp-Source: APBJJlHjLVakmIyeP9U92BiYtTvENdckpTTI4emmyWsw/waccn49iP9a96cGIZZiTOIcJ0Ujd5Jo X-Received: by 2002:a92:d092:0:b0:341:fdd4:9acb with SMTP id h18-20020a92d092000000b00341fdd49acbmr3923892ilh.14.1688702518897; Thu, 06 Jul 2023 21:01:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688702518; cv=none; d=google.com; s=arc-20160816; b=at/9Ab5ZNaNbDsKHUnvyu4o2FIcaR2JAD9/B3f/imgzO8U5gl6Z6+JzDkX90SSLtcO 3oxOPVD/ko3DRbCukA307Kwn3TBPE+cZAsk3IgdeT/W2HnEwTYLcgaw5VTLjed9YeUB8 XRxaufzvpzDEnuH3TdB3+AbuNL0KoJsHB32QQO/lHWivefIhA0VYe8T1dZQJb3/kgyKN wFMMbRT1pOtoevhs1pkqIEgkHtP9OfGV235d0yxJPZvW+HeOAsTYFH/FVuTQiSMZA1rA VaexDrIA6qYCPytEerdCUbStwegueBmg5xZQluzS3kQtB1XOc9tnh+XzEpyyQETvNxmp cosA== 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=z45djteDPV2ZH+S0mdpp3t0P1Qe2g9TdyhC2kEar2mc=; fh=RF61Sdo7Z9vPdEXjtBUxOV6kGajVxCA/ZkXy91yx00o=; b=tcNCHtymt8D7km9fnWA8oxUzjeU/DgsYKXF7p2c4WWrpjITvo/b4yAZz9C3wi2sZfX KtpHMZlPQPTtdNxB33S9HTkqBq5fqbmKm/d0ClRiR9ET8LSkRfSjjFhispZ3MHRcth1g YPnfuoWkWllJlrNJQj6/GzpPqu3hPqUimw2fGiPipfCtSpk5CCwYhd+qmQCzjbbx1Q1L XEAl2STUlJIamo/aMQE624mL4wB+4Hf7o3Dngp965ISyCt/5B5DJEXrA2fp7WD3MhLf/ Jj5aq9QWdI1AbU38omTEPDLi14uk26ezCd77E/8mlE7A77N/CjWFpKbKjQBKhQ93ANnn JzBA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wJkdwoAW; 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 c27-20020a023b1b000000b0042b64cb1212si1140201jaa.119.2023.07.06.21.01.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Jul 2023 21:01:58 -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=wJkdwoAW; 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 41123863ED; Fri, 7 Jul 2023 06:01: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="wJkdwoAW"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 1424A863E9; Fri, 7 Jul 2023 06:01: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-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) (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 578E6863C7 for ; Fri, 7 Jul 2023 06:01:37 +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-pg1-x52f.google.com with SMTP id 41be03b00d2f7-55767141512so863432a12.3 for ; Thu, 06 Jul 2023 21:01:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1688702495; x=1691294495; 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=z45djteDPV2ZH+S0mdpp3t0P1Qe2g9TdyhC2kEar2mc=; b=wJkdwoAWyJvc41m+23AIrhG8luU70V9bzFkSeHJ9+i775C+Mftf4kMu4hRX0Kr8LSp 5fjEm9cQAbzdXFdUB0fF7GW9SbJZddZD3LvtFTGF0kvs7a2OmapXD9cpDOhxHb+2wKJs RdPYETwbU4KXEj2qs37Su0Dn5uATfeCmJJS2qk6bvvjHLC+aGNHLjACqOa6OSF2PDuTt reBszV1FjdTGQW1f1oGTEYpkKflu2ML+SZiVHZEWAVgtKxhRzgigQbNRjnuQQ8hau4n2 WdbQICjX2I70W1AodhXmVZIhzDkvWnHHJjAIs+a+ThJihYEQb1q0Yo5m1jXzjskJkXM9 8CEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688702495; x=1691294495; 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=z45djteDPV2ZH+S0mdpp3t0P1Qe2g9TdyhC2kEar2mc=; b=Jkuyla++OoHAOIeJ2iN+pUUQ3oEv8kZxWlTAwPiVbJuekJz3HnKrVzMkkwedBrgwI3 toO/E5Z815OmzGPpp5tXtQLEIKWK6iNRGN4T2+1E4lUJh4iRHqhJH1eb77hvBiq9NucM 7J17rB/WSKFm3cAbOaI93LiwmSCHN7xWUGtXPapNz4SX4QiBXkr1oxDBNn6qgdSJ6o10 F/M9e/MYMTszfISb78UYbzBN7amT8UiG5Dn5l4Oj2AGrsp8xZqsnM6REjWk3uvy/i/wI FFajeXPf+MnyPgyZK5B0B/+uGyLhQZ+kk24SThnknFq/Ttesv335r67I0QSMph1enxXA iZxg== X-Gm-Message-State: ABy/qLYI8v5/DmmxtCVvDmIKWoaqT+sVHSoMTNxg1b4rio2GitzxVqNA CvMwS1iPrMEi4B+KvuoS0HoeWvSOp2Q8Be8TI8w= X-Received: by 2002:a05:6a20:138c:b0:126:a5e3:3927 with SMTP id hn12-20020a056a20138c00b00126a5e33927mr2910554pzc.8.1688702495348; Thu, 06 Jul 2023 21:01:35 -0700 (PDT) Received: from localhost ([164.70.16.189]) by smtp.gmail.com with ESMTPSA id n11-20020a170902e54b00b001aaecc0b6ffsm2131114plf.160.2023.07.06.21.01.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Jul 2023 21:01:34 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , AKASHI Takahiro , Masahisa Kojima , Simon Glass , Jose Marinho Subject: [PATCH 2/4] efi_loader: add EFI_RAM_DISK_PROTOCOL implementation Date: Fri, 7 Jul 2023 13:00:42 +0900 Message-Id: <20230707040045.485790-3-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230707040045.485790-1-masahisa.kojima@linaro.org> References: <20230707040045.485790-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 commit adds the EFI_RAM_DISK_PROTOCOL implementation. User can mount the distro installer by registering the memory mapped ISO image through EFI_RAM_DISK_PROTOCOL. Note that the installation process may not proceed after the distro installer calls ExitBootServices() since there is no hand-off process for the block device of memory mapped ISO image. Signed-off-by: Masahisa Kojima --- include/efi_api.h | 13 ++ include/efi_loader.h | 4 + lib/efi_driver/efi_uclass.c | 7 +- lib/efi_loader/Kconfig | 6 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_ram_disk.c | 334 ++++++++++++++++++++++++++++++++++ lib/efi_loader/efi_setup.c | 6 + lib/uuid.c | 4 + 8 files changed, 373 insertions(+), 2 deletions(-) create mode 100644 lib/efi_loader/efi_ram_disk.c diff --git a/include/efi_api.h b/include/efi_api.h index 4ee4a1b5e9..3982ab89bc 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -764,6 +764,19 @@ struct efi_block_io { efi_status_t (EFIAPI *flush_blocks)(struct efi_block_io *this); }; +#define EFI_RAM_DISK_PROTOCOL_GUID \ + EFI_GUID(0xab38a0df, 0x6873, 0x44a9, \ + 0x87, 0xe6, 0xd4, 0xeb, 0x56, 0x14, 0x84, 0x49) + +struct efi_ram_disk_protocol { + /* "register" is a reserved keyword in C, use "disk_register" instead */ + efi_status_t(EFIAPI *disk_register)( + u64 ram_disk_base, u64 ram_disk_size, efi_guid_t *ram_disk_type, + struct efi_device_path *parent_device_path, + struct efi_device_path **device_path); + efi_status_t (EFIAPI *unregister)(struct efi_device_path *device_path); +}; + struct simple_text_output_mode { s32 max_mode; s32 mode; diff --git a/include/efi_loader.h b/include/efi_loader.h index 604fd765f7..70c8c83099 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -333,6 +333,8 @@ extern const efi_guid_t smbios_guid; /*GUID of console */ extern const efi_guid_t efi_guid_text_input_protocol; extern const efi_guid_t efi_guid_text_output_protocol; +/* GUID of Ram Disk protocol */ +extern const efi_guid_t efi_guid_ram_disk_protocol; extern char __efi_runtime_start[], __efi_runtime_stop[]; extern char __efi_runtime_rel_start[], __efi_runtime_rel_stop[]; @@ -1159,4 +1161,6 @@ efi_status_t efi_disk_get_device_name(const efi_handle_t handle, char *buf, int */ void efi_add_known_memory(void); +efi_status_t efi_ram_disk_register(void); + #endif /* _EFI_LOADER_H */ diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c index 45f9351988..f7597811b7 100644 --- a/lib/efi_driver/efi_uclass.c +++ b/lib/efi_driver/efi_uclass.c @@ -44,8 +44,11 @@ static efi_status_t check_node_type(efi_handle_t handle) /* Get the last node */ const struct efi_device_path *node = efi_dp_last_node(dp); /* We do not support partitions as controller */ - if (!node || node->type == DEVICE_PATH_TYPE_MEDIA_DEVICE) - ret = EFI_UNSUPPORTED; + if (!node || node->type == DEVICE_PATH_TYPE_MEDIA_DEVICE) { + /* We support RAM disk as controller */ + if (node->sub_type != DEVICE_PATH_SUB_TYPE_RAM_DISK_PATH) + ret = EFI_UNSUPPORTED; + } } return ret; } diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index c5835e6ef6..1a81b65688 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -433,4 +433,10 @@ config EFI_RISCV_BOOT_PROTOCOL replace the transfer via the device-tree. The latter is not possible on systems using ACPI. +config EFI_RAM_DISK_PROTOCOL + bool "EFI_RAM_DISK_PROTOCOL support" + depends on PARTITIONS + help + Provide a EFI_RAM_DISK_PROTOCOL implementation to register the + RAM disk and create the block device. endif diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 1a8c8d7cab..4197f594a2 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -86,6 +86,7 @@ obj-$(CONFIG_EFI_RISCV_BOOT_PROTOCOL) += efi_riscv.o obj-$(CONFIG_EFI_LOAD_FILE2_INITRD) += efi_load_initrd.o obj-$(CONFIG_EFI_SIGNATURE_SUPPORT) += efi_signature.o obj-$(CONFIG_EFI_ECPT) += efi_conformance.o +obj-$(CONFIG_EFI_RAM_DISK_PROTOCOL) += efi_ram_disk.o EFI_VAR_SEED_FILE := $(subst $\",,$(CONFIG_EFI_VAR_SEED_FILE)) $(obj)/efi_var_seed.o: $(srctree)/$(EFI_VAR_SEED_FILE) diff --git a/lib/efi_loader/efi_ram_disk.c b/lib/efi_loader/efi_ram_disk.c new file mode 100644 index 0000000000..10a6944aea --- /dev/null +++ b/lib/efi_loader/efi_ram_disk.c @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * RAM Disk Protocol + * + * Copyright (c) 2023, Linaro Limited + */ + +#include +#include +#include +#include + +#define MEM_BLOCK_SIZE_SHIFT 9 /* 512 bytes */ + +const efi_guid_t efi_guid_ram_disk_protocol = EFI_RAM_DISK_PROTOCOL_GUID; +static struct list_head obj_list; + +/** + * struct efi_ram_disk_obj - ram disk protocol object + * + * @ops: EFI disk I/O protocol interface + * @media: block I/O media information + * @dp: device path + * @image: image base address + * @image_size: image size + * @list: list structure + */ +struct efi_ram_disk_obj { + struct efi_block_io ops; + struct efi_block_io_media media; + struct efi_device_path *dp; + u8 *image; + u64 image_size; + struct list_head list; +}; + +/* + * reset - Reset service of the block IO protocol + * + * @this: pointer to the BLOCK_IO_PROTOCOL + * @extended_verification: extended verification + * Return: status code + */ +static efi_status_t EFIAPI reset(struct efi_block_io *this, + char extended_verification) +{ + return EFI_SUCCESS; +} + +/* + * read_blocks - Read service of the block IO protocol + * + * @this: pointer to the BLOCK_IO_PROTOCOL + * @media_id: id of the medium to be read from + * @lba: starting logical block for reading + * @buffer_size: size of the read buffer + * @buffer: pointer to the destination buffer + * Return: status code + */ +static efi_status_t EFIAPI read_blocks(struct efi_block_io *this, u32 media_id, + u64 lba, efi_uintn_t buffer_size, + void *buffer) +{ + u8 *start; + struct efi_ram_disk_obj *ram_disk_obj; + + if (!this || !buffer) + return EFI_INVALID_PARAMETER; + + if (!buffer_size) + return EFI_SUCCESS; + + /* TODO: check for media changes */ + if (media_id != this->media->media_id) + return EFI_MEDIA_CHANGED; + + if (!this->media->media_present) + return EFI_NO_MEDIA; + + EFI_ENTRY("%p, %x, %llx, %zx, %p", this, media_id, lba, + buffer_size, buffer); + + ram_disk_obj = container_of(this, struct efi_ram_disk_obj, ops); + + if ((lba << MEM_BLOCK_SIZE_SHIFT) + buffer_size > + ram_disk_obj->image_size) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + start = ram_disk_obj->image + (lba << MEM_BLOCK_SIZE_SHIFT); + memmove(buffer, start, buffer_size); + + return EFI_EXIT(EFI_SUCCESS); +} + +/* + * write_blocks - Write service of the block IO protocol + * + * @this: pointer to the BLOCK_IO_PROTOCOL + * @media_id: id of the medium to be written to + * @lba: starting logical block for writing + * @buffer_size: size of the write buffer + * @buffer: pointer to the source buffer + * Return: status code + */ +static efi_status_t EFIAPI write_blocks(struct efi_block_io *this, u32 media_id, + u64 lba, efi_uintn_t buffer_size, + void *buffer) +{ + u8 *start; + struct efi_ram_disk_obj *ram_disk_obj; + + if (!this || !buffer) + return EFI_INVALID_PARAMETER; + + if (this->media->read_only) + return EFI_WRITE_PROTECTED; + + if (!buffer_size) + return EFI_SUCCESS; + + /* TODO: check for media changes */ + if (media_id != this->media->media_id) + return EFI_MEDIA_CHANGED; + + if (!this->media->media_present) + return EFI_NO_MEDIA; + + EFI_ENTRY("%p, %x, %llx, %zx, %p", this, media_id, lba, + buffer_size, buffer); + + ram_disk_obj = container_of(this, struct efi_ram_disk_obj, ops); + + if ((lba << MEM_BLOCK_SIZE_SHIFT) + buffer_size > + ram_disk_obj->image_size) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + start = ram_disk_obj->image + (lba << MEM_BLOCK_SIZE_SHIFT); + memmove(start, buffer, buffer_size); + + return EFI_EXIT(EFI_SUCCESS); +} + +/* + * flush_blocks - Flush service of the block IO protocol + * + * @this: pointer to the BLOCK_IO_PROTOCOL + * Return: status code + */ +static efi_status_t EFIAPI flush_blocks(struct efi_block_io *this) +{ + return EFI_SUCCESS; +} + +/* + * ram_disk_register - Register service of the RAM disk protocol + * + * @ram_disk_base: The base address of registered RAM disk + * @ram_disk_size: The size of registered RAM disk + * @ram_disk_type: The type of registered RAM disk + * @parent_device_path: Pointer to the parent device path + * @device_path: Pointer to the device path + * Return: status code + */ +static efi_status_t EFIAPI +ram_disk_register(u64 ram_disk_base, u64 ram_disk_size, + efi_guid_t *ram_disk_type, + struct efi_device_path *parent_device_path, + struct efi_device_path **device_path) +{ + efi_status_t ret; + efi_handle_t disk_handle = NULL; + struct efi_device_path *dp; + struct efi_device_path end_node; + struct efi_ram_disk_obj *ram_disk_obj; + struct efi_device_path_ram_disk_path ram_disk_node; + + EFI_ENTRY("%llu %llu %pUs %p, %p", ram_disk_base, ram_disk_size, + ram_disk_type, parent_device_path, device_path); + + if (!ram_disk_size || !ram_disk_type || !device_path) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + *device_path = NULL; + + ram_disk_obj = calloc(1, sizeof(*ram_disk_obj)); + if (!ram_disk_obj) + return EFI_EXIT(EFI_OUT_OF_RESOURCES); + + ram_disk_obj->image = (u8 *)ram_disk_base; + ram_disk_obj->image_size = ram_disk_size; + ram_disk_obj->ops.media = &ram_disk_obj->media; + + ram_disk_obj->ops.media->block_size = 1 << MEM_BLOCK_SIZE_SHIFT; + ram_disk_obj->ops.media->last_block = + (ram_disk_size >> MEM_BLOCK_SIZE_SHIFT) - 1; + ram_disk_obj->ops.media->media_present = 1; + + ram_disk_obj->ops.reset = reset; + ram_disk_obj->ops.read_blocks = read_blocks; + ram_disk_obj->ops.write_blocks = write_blocks; + ram_disk_obj->ops.flush_blocks = flush_blocks; + + dp = calloc(1, sizeof(struct efi_device_path_ram_disk_path) + + sizeof(struct efi_device_path)); + if (!dp) { + free(ram_disk_obj); + return EFI_EXIT(EFI_OUT_OF_RESOURCES); + } + + ram_disk_node.dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; + ram_disk_node.dp.sub_type = DEVICE_PATH_SUB_TYPE_RAM_DISK_PATH; + ram_disk_node.dp.length = sizeof(struct efi_device_path_ram_disk_path); + put_unaligned_le64(ram_disk_base, &ram_disk_node.starting_address); + put_unaligned_le64(ram_disk_base + ram_disk_size - 1, &ram_disk_node.ending_address); + guidcpy(&ram_disk_node.disk_type_guid, ram_disk_type); + ram_disk_node.disk_instance = 0; + memcpy(dp, &ram_disk_node, sizeof(struct efi_device_path_ram_disk_path)); + + end_node.type = DEVICE_PATH_TYPE_END; + end_node.sub_type = DEVICE_PATH_SUB_TYPE_END; + end_node.length = sizeof(struct efi_device_path); + memcpy((char *)dp + sizeof(struct efi_device_path_ram_disk_path), + &end_node, sizeof(struct efi_device_path)); + + ram_disk_obj->dp = efi_dp_append(parent_device_path, dp); + free(dp); + if (!ram_disk_obj->dp) { + free(ram_disk_obj); + return EFI_EXIT(EFI_OUT_OF_RESOURCES); + } + + if (efi_dp_find_obj(ram_disk_obj->dp, NULL, NULL)) { + log_err("Already Started\n"); + ret = EFI_ALREADY_STARTED; + goto err; + } + + ret = efi_install_multiple_protocol_interfaces( + &disk_handle, &efi_guid_device_path, ram_disk_obj->dp, + &efi_block_io_guid, &ram_disk_obj->ops, NULL); + if (ret != EFI_SUCCESS) { + log_err("InstallProtocolInterface failed\n"); + goto err; + } + + ret = EFI_CALL(systab.boottime->connect_controller(disk_handle, NULL, + NULL, 1)); + if (ret != EFI_SUCCESS) { + log_err("ConnectController failed\n"); + goto err; + } + + *device_path = ram_disk_obj->dp; + list_add(&ram_disk_obj->list, &obj_list); + + return EFI_EXIT(ret); +err: + efi_free_pool(ram_disk_obj->dp); + free(ram_disk_obj); + + return EFI_EXIT(ret); +} + +/* + * ram_disk_unregister - Unregister service of the RAM disk protocol + * + * @device_path: Pointer to the device path + * Return: status code + */ +static efi_status_t EFIAPI +ram_disk_unregister(struct efi_device_path *device_path) +{ + int ret; + efi_handle_t disk_handle; + struct list_head *pos, *n; + struct efi_ram_disk_obj *entry; + struct efi_ram_disk_obj *ram_disk_obj = NULL; + + EFI_ENTRY("%p", device_path); + + if (!device_path) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + list_for_each_safe(pos, n, &obj_list) { + entry = list_entry(pos, struct efi_ram_disk_obj, list); + if (!efi_dp_match(device_path, entry->dp)) { + ram_disk_obj = entry; + break; + } + } + + if (!ram_disk_obj) + return EFI_EXIT(EFI_NOT_FOUND); + + disk_handle = efi_dp_find_obj(device_path, &efi_block_io_guid, NULL); + if (!disk_handle) + return EFI_EXIT(EFI_NOT_FOUND); + + ret = efi_uninstall_multiple_protocol_interfaces( + disk_handle, &efi_guid_device_path, ram_disk_obj->dp, + &efi_block_io_guid, &ram_disk_obj->ops, NULL); + if (ret != EFI_SUCCESS) + log_err("UninstallProtocolInterface failed\n"); + + list_del(&ram_disk_obj->list); + efi_free_pool(ram_disk_obj->dp); + free(ram_disk_obj); + + return EFI_EXIT(ret); +} + +static const struct efi_ram_disk_protocol efi_ram_disk_protocol = { + .disk_register = ram_disk_register, + .unregister = ram_disk_unregister, +}; + +/** + * efi_ram_disk_register() - register EFI_RAM_DISK_PROTOCOL + * + * Return: status code + */ +efi_status_t efi_ram_disk_register(void) +{ + efi_status_t ret; + + ret = efi_add_protocol(efi_root, &efi_guid_ram_disk_protocol, + (void *)&efi_ram_disk_protocol); + if (ret != EFI_SUCCESS) + log_err("Cannot install EFI_RAM_DISK_PROTOCOL\n"); + + INIT_LIST_HEAD(&obj_list); + + return ret; +} diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 877f3878d6..8c430d4a9c 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -344,6 +344,12 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; + if (IS_ENABLED(CONFIG_EFI_RAM_DISK_PROTOCOL)) { + ret = efi_ram_disk_register(); + if (ret != EFI_SUCCESS) + goto out; + } + /* Initialize EFI runtime services */ ret = efi_reset_system_init(); if (ret != EFI_SUCCESS) diff --git a/lib/uuid.c b/lib/uuid.c index 96e1af3c8b..9827588186 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -195,6 +195,10 @@ static const struct { "Firmware Management", EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID }, + { + "Ram Disk", + EFI_RAM_DISK_PROTOCOL_GUID + }, /* Configuration table GUIDs */ { "ACPI table", From patchwork Fri Jul 7 04:00:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 700015 Delivered-To: patch@linaro.org Received: by 2002:ab3:710f:0:b0:238:a68b:2c7d with SMTP id n15csp1717771lte; Thu, 6 Jul 2023 21:02:11 -0700 (PDT) X-Google-Smtp-Source: APBJJlEo2O/Y5DWfnZAVLY/P3PnDWN7ELgjfIW1WcXw2khE7R4ux1RcY2ltuOHSYYhIYpJblhPv9 X-Received: by 2002:a6b:dc16:0:b0:783:74a5:b73f with SMTP id s22-20020a6bdc16000000b0078374a5b73fmr4009509ioc.13.1688702531249; Thu, 06 Jul 2023 21:02:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688702531; cv=none; d=google.com; s=arc-20160816; b=IOqd1bsIGmNr/hQjQ9J1YQR6G1E0M2t0PHVBFJv5K0srklrHwQBMUyKt1p2pxTETK3 Q4Mu1nRnK4xLrE8bgnttQjUhD1MpJc401AtoQGdiKlJSGpgnqEVq0liXNLpBhy1rpxLo PzmEGz2zBbpLrOBTwernkSjp7Sl/vRiMTKsmq9oxpdAIWHR8GxDO5jYKbJ3nZ9no3/EV OqZ+t6jbBpbqG41LAd22BiUUWK8HUE7UwlZIX1dZvBYYj7K1ozQPbldbagpq/QwFw8tP CjH+mywCoPkB71BiO6tTZkd1WYjBvrpJuGDKEZywyER/yEHNXFJhGO/2+SVYu9nE06Ka FSzw== 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=EY1QPDVQku2nwBLXHfn67UCpf37ADO4x0TeMnlmebXY=; fh=UqK/4Wc1IgH8GVyLylIZPdO/qWI3a/IzA+fwLs4tfXk=; b=ne9mtSdQQhYMbme5Tnlah/rimhKDPZ/4W5MVtP9BWOkVPvmQ6fegsj5NCRTWHQ9ZbF +XQsboUwXG3OrB02RqKVHc/G2W0Ttr47ZJvpAzpjVX4QflyYmwDdTPLAITgFCLHUpI3F 5FhTguYXb0r1SFzeIFrf2i330RlksbpYNvy3SGxpUNExnnNwg76qrhifZLInGzV8m96X lXPnMueASBP+8Co3SXPt8FBbS311buUfjWSlNtoN7aXRaBTrs5yyKHoS2y5pZkylLb16 L7ju6HmdEXlH5bq8LSAkm/NaT+6gy8ohs48AGOwbZgyj/kg7plDODCqKOnBf0fxRBI2S sfpg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VzqPdg6G; 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 i11-20020a6b7e0b000000b00786ea00bf58si62899iom.102.2023.07.06.21.02.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Jul 2023 21:02:11 -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=VzqPdg6G; 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 52069863E6; Fri, 7 Jul 2023 06:01:46 +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="VzqPdg6G"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 4D63E863B2; Fri, 7 Jul 2023 06:01:44 +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-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) (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 349D7863D5 for ; Fri, 7 Jul 2023 06:01:41 +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-pj1-x1034.google.com with SMTP id 98e67ed59e1d1-262ef07be72so819225a91.1 for ; Thu, 06 Jul 2023 21:01:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1688702499; x=1691294499; 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=EY1QPDVQku2nwBLXHfn67UCpf37ADO4x0TeMnlmebXY=; b=VzqPdg6GAhIdh/I0BrhsSHbn8ozgU4J/B/JYsz7AwqwSMmKqMBggIsryFn8ikpVTOy xJBvUMpxBp9zXu1hcS64EPZfqWTJwB5xbrd/p4x6qBe27/apJ+CuCbZ8wY+/pUfN+h5d pKVzBUvqljWQojixU9zKrFLVHCWcMx1owsHLhO04Gef0irH7mm4thWeh3T7Ml3FuoSR/ 0U6uuvR3Lud3EHB+E4hnW75QCmS0qY+Epg0shqbT+mTm6n41QD4A2OIs7gMzg33HCcBb uijnp3/tiU++whMntPMNK/UIa2k2ggnFPZrxhaOnl4S/s5cgFWX35vbBNmNAHCT+m9dH mBmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688702499; x=1691294499; 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=EY1QPDVQku2nwBLXHfn67UCpf37ADO4x0TeMnlmebXY=; b=gLenCGfbutazWx4CngL7pcR/8U9HkQvlw4ody745EWYC2mLvK3UuNmGtMlrgftdJZw C0bpPCkzcYGxrZRCNEDnBloF/oQjLVfJwfCzpekGsSWAblpRcPM4L1VDXL+A/pPn4cA/ e36cn0NBfQAV+1cVD3rLcQp+BwHM++1MG7Rmyd7wtHqTvPaob6W7LdV1Cnivs5fsjWch N+qEx9eGFnHyxjNzEP2RpLJcNvh7GjW7skUjQ6LnbHKQql43n2467J20flPogaVTx2hG XPYjiTiCbys9Hy2V0D18BnvngqAYXJEejlYQIXEIqp+h0aihbbQbYnK3zZbeOrRjOmYF f37g== X-Gm-Message-State: ABy/qLbyS1sscbw1pXMinSFnX2AnbPCrAKM16n6F83fhRp7Amc7pT4/d nKuItYZhssTzJjUx4eKyMOadIDIggOxZYuIO6a4= X-Received: by 2002:a17:90b:1d10:b0:263:8c2:6290 with SMTP id on16-20020a17090b1d1000b0026308c26290mr3018208pjb.43.1688702499252; Thu, 06 Jul 2023 21:01:39 -0700 (PDT) Received: from localhost ([164.70.16.189]) by smtp.gmail.com with ESMTPSA id h13-20020a17090a3d0d00b00262eb0d141esm576430pjc.28.2023.07.06.21.01.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Jul 2023 21:01:38 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , AKASHI Takahiro , Masahisa Kojima Subject: [PATCH 3/4] cmd: efidebug: add RAM disk mount command Date: Fri, 7 Jul 2023 13:00:43 +0900 Message-Id: <20230707040045.485790-4-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230707040045.485790-1-masahisa.kojima@linaro.org> References: <20230707040045.485790-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 commit implements the test commands for EFI_RAM_DISK_PROTOCOL. With the disk load/unload commands, user can mount the ISO image in the volatile memory through EFI_RAM_DISK_PROTOCOL. Currently the load command can load only one image at a time even if UEFI specification does not limit the number of images. Anyway one image is enough for testing. Signed-off-by: Masahisa Kojima --- cmd/efidebug.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/cmd/efidebug.c b/cmd/efidebug.c index 9622430c47..3466ae7e32 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -1421,6 +1421,113 @@ static int do_efi_query_info(struct cmd_tbl *cmdtp, int flag, return CMD_RET_SUCCESS; } +#ifdef CONFIG_EFI_RAM_DISK_PROTOCOL +static struct efi_device_path *ram_disk_dp; +static efi_guid_t virtual_cd_guid = EFI_VIRTUAL_CD_GUID; + +static int do_efi_disk_load(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + u64 addr, size; + efi_status_t ret; + struct efi_ram_disk_protocol *ram_disk = NULL; + + if (ram_disk_dp) { + printf("Only one image can be loaded\n"); + return CMD_RET_FAILURE; + } + + argc--; + argv++; + + if (argc != 2) + return CMD_RET_USAGE; + + addr = hextoul(argv[0], NULL); + size = hextoul(argv[1], NULL); + + ret = EFI_CALL(BS->locate_protocol(&efi_guid_ram_disk_protocol, NULL, + (void **)&ram_disk)); + if (ret != EFI_SUCCESS || !ram_disk) { + printf("No EFI_RAM_DISK_PROTOCOL found(ret = %lu)\n", + ret & ~EFI_ERROR_MASK); + return CMD_RET_FAILURE; + } + + ret = EFI_CALL(ram_disk->disk_register(addr, size, &virtual_cd_guid, NULL, + &ram_disk_dp)); + if (ret != EFI_SUCCESS || !ram_disk_dp) { + printf("RAM DISK register failed(ret = %lu)\n", + ret & ~EFI_ERROR_MASK); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +static int do_efi_disk_unload(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + efi_status_t ret; + struct efi_ram_disk_protocol *ram_disk = NULL; + + ret = EFI_CALL(BS->locate_protocol(&efi_guid_ram_disk_protocol, NULL, + (void **)&ram_disk)); + if (ret != EFI_SUCCESS || !ram_disk) { + printf("No EFI_RAM_DISK_PROTOCOL found(ret = %lu)\n", + ret & ~EFI_ERROR_MASK); + return CMD_RET_FAILURE; + } + + ret = EFI_CALL(ram_disk->unregister(ram_disk_dp)); + if (ret != EFI_SUCCESS) { + printf("RAM DISK unregister failed(ret = %lu)\n", + ret & ~EFI_ERROR_MASK); + return CMD_RET_FAILURE; + } + + ram_disk_dp = NULL; + + return CMD_RET_SUCCESS; +} + +static struct cmd_tbl cmd_efidebug_disk_sub[] = { + U_BOOT_CMD_MKENT(load, CONFIG_SYS_MAXARGS, 1, do_efi_disk_load, "", ""), + U_BOOT_CMD_MKENT(unload, CONFIG_SYS_MAXARGS, 1, do_efi_disk_unload, "", ""), +}; + +/** + * do_efi_disk() - manage UEFI ram disk device + * + * @cmdtp: Command table + * @flag: Command flag + * @argc: Number of arguments + * @argv: Argument array + * Return: CMD_RET_SUCCESS on success, + * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure + * + * Implement efidebug "disk" sub-command. + */ +static int do_efi_disk(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct cmd_tbl *cp; + + if (argc < 2) + return CMD_RET_USAGE; + + argc--; + argv++; + + cp = find_cmd_tbl(argv[0], cmd_efidebug_disk_sub, + ARRAY_SIZE(cmd_efidebug_disk_sub)); + if (!cp) + return CMD_RET_USAGE; + + return cp->cmd(cmdtp, flag, argc, argv); +} +#endif + static struct cmd_tbl cmd_efidebug_sub[] = { U_BOOT_CMD_MKENT(boot, CONFIG_SYS_MAXARGS, 1, do_efi_boot_opt, "", ""), #ifdef CONFIG_EFI_HAVE_CAPSULE_SUPPORT @@ -1441,6 +1548,10 @@ static struct cmd_tbl cmd_efidebug_sub[] = { "", ""), U_BOOT_CMD_MKENT(query, CONFIG_SYS_MAXARGS, 1, do_efi_query_info, "", ""), +#ifdef CONFIG_EFI_RAM_DISK_PROTOCOL + U_BOOT_CMD_MKENT(disk, CONFIG_SYS_MAXARGS, 1, do_efi_disk, + "", ""), +#endif }; /** @@ -1526,6 +1637,12 @@ static char efidebug_help_text[] = " - show UEFI memory map\n" "efidebug tables\n" " - show UEFI configuration tables\n" +#ifdef CONFIG_EFI_RAM_DISK_PROTOCOL + "efidebug disk load
\n" + " - load ISO image\n" + "efidebug disk unload\n" + " - unload ISO image\n" +#endif #ifdef CONFIG_CMD_BOOTEFI_BOOTMGR "efidebug test bootmgr\n" " - run simple bootmgr for test\n" From patchwork Fri Jul 7 04:00:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 700016 Delivered-To: patch@linaro.org Received: by 2002:ab3:710f:0:b0:238:a68b:2c7d with SMTP id n15csp1717867lte; Thu, 6 Jul 2023 21:02:24 -0700 (PDT) X-Google-Smtp-Source: APBJJlFV55/1q1YH9+VfsZ6QfoKEpVhKYwJHttp9rOcWC9sUM8tTdD9eMTwTuD/77ODfBxfa4gb4 X-Received: by 2002:a6b:c8d8:0:b0:780:c92c:38ed with SMTP id y207-20020a6bc8d8000000b00780c92c38edmr4714263iof.0.1688702544019; Thu, 06 Jul 2023 21:02:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688702544; cv=none; d=google.com; s=arc-20160816; b=0HeP6DxqhSe/SNYwOdYXsS/qU3LXvMUPSFQUl1v+hCxwnGt8/jouRglZfjnkwcKeqY zWIrLcNf839HVFkuFzhEE9PlHlKTsIVmnKdI+aRNQgSvkYk4RA8p7K++lWD5PpDeekJc MnToNxJPxhRt6CwNQLE/brVYXTEtASSRuI7MBNLuwlFtPsMZpkEG5IPhJGsu/z32AwIa 5XtohAo4nZUfqcNLDZvbDqxekpwf2n5prmqYVeFSWw/enAlfCjQ6hqgXjBXX5HZvTUnN sNYe6vFYXr3NzIJ8FXAOZ6QFE+RdBsKYPmSgwi8arjqDAXhdg527s+hkIqV6FRe9g4eT kvWA== 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=whqeMeNxvL7otDns61Nd0TCdnHR9tJbuK1RqT7aeuv0=; fh=UqK/4Wc1IgH8GVyLylIZPdO/qWI3a/IzA+fwLs4tfXk=; b=JuIJnMHJ+VATgAR3SPBWCJOKLGm7NjtbuMr199s1jojMLaXD7c/Bip8PYPz4+qYdwK djAtvC0+tsVoGIQATJCBTG4lZbzQlALYl/7rFVZ42JDB8kZiDra/bYj8YdLzAzzydUop XsXKfR1RRd6sT7/IDzrOFMvU57b1Ng2LBo/YkaL69Q+BOHs6jJ30SVQqVo+6Iov4d4SY A61RfTVY4fL6UUdSu2bpF2efL4IvmjOsuntLa4OTBR6e6QWDfzjqqZw9A4mPPDq2LR1k d6EU2Mx1zfgKYyVbkWSW2BjUXcU8WH0w83vor33nXkUJb2QzbFjSogE6SSxLOxlj6fzg GLQA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=vmErOWvp; 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 g10-20020a05663816ca00b0042b461902d4si1178487jat.148.2023.07.06.21.02.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Jul 2023 21:02:23 -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=vmErOWvp; 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 DB06D863C7; Fri, 7 Jul 2023 06:01:49 +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="vmErOWvp"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 77CE6863EA; Fri, 7 Jul 2023 06:01:48 +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-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) (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 B6B22863B2 for ; Fri, 7 Jul 2023 06:01:44 +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-pl1-x62a.google.com with SMTP id d9443c01a7336-1b9c368f4b5so1040835ad.0 for ; Thu, 06 Jul 2023 21:01:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1688702503; x=1691294503; 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=whqeMeNxvL7otDns61Nd0TCdnHR9tJbuK1RqT7aeuv0=; b=vmErOWvpWQcC/TujHhXKb3fDgEjU9cd9TTc5XpImpOCPjlXQzoRyrraurUSB7PJPIS vMzTTn13VwSQwkz2cX5XLYETDvm7Kts/qDUfhZ5jgZG9vVBoDVvQuEmid2tXmlWz98ho OpohEkgH7AXBuQQBlf89cvJvu10q1TpriVJEnRLaiwc+9wWMHNpIZWr9h6eNF2I6PsCY VBifCNXGWPqxcVNrGaxZmA84RD/CQJJ/zdGPptdzzD0X/yc5Kt+2zIL83rSs4D1r0O+S +5lVntJzIhDjMAVAzUC5YkhVVQj1mPlSTqKFkFApUwXH5iaDxH8ZXOayx++mjAZKIkmr LfvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688702503; x=1691294503; 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=whqeMeNxvL7otDns61Nd0TCdnHR9tJbuK1RqT7aeuv0=; b=kq6hd/1cCGrpQhJq9QGzjxXCvM4MkDSf8BQdrUGuYNIJQvVdrSwffvTWhXEIasggbU EQfmzQKlB3fNXfSf3SatzsAFEW9bMGY6gM/tPpxujK55/aaHy/mN1Ce1e6YCYp6lfI4p BlFyHW6uNp0kSZ2LLreAYCNgAF054UqGPAlDEdwOZ7euly32Wdj6mkIX/rzQaEugujm2 36x0rv/+FQon3IvPdOt6UAiRbJLvCxvJN0skWeJ2v2+sdPw+Y7nRlt7Lx+xEz0Slkscs kvS0piE3ny+tej6uAoTEAOSKiwwImlyy7hb7oU2ooajQ6Zc6l2erz1CmJiJ1ljfam7u9 NXaw== X-Gm-Message-State: ABy/qLYDGF+hzi9QVHUf42kKE2Vg1xlNTvDJFacUb/6D2D5KhWgOwdAq PpfPGrGsSXzK96hAiI453yeAHNO5O2wt4Krh6eo= X-Received: by 2002:a17:902:d481:b0:1b8:2adc:8358 with SMTP id c1-20020a170902d48100b001b82adc8358mr6032137plg.11.1688702502736; Thu, 06 Jul 2023 21:01:42 -0700 (PDT) Received: from localhost ([164.70.16.189]) by smtp.gmail.com with ESMTPSA id f11-20020a17090274cb00b0019f3cc463absm2160256plt.0.2023.07.06.21.01.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Jul 2023 21:01:42 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , AKASHI Takahiro , Masahisa Kojima Subject: [PATCH 4/4] efi_selftest: add EFI_RAM_DISK_PROTOCOL selftest Date: Fri, 7 Jul 2023 13:00:44 +0900 Message-Id: <20230707040045.485790-5-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230707040045.485790-1-masahisa.kojima@linaro.org> References: <20230707040045.485790-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 --- 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, +};