From nobody Wed Oct 30 19:55:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+108789+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+108789+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1695050276; cv=none; d=zohomail.com; s=zohoarc; b=bPLYv8JIeGBv7Q0BDpb5hqw43O1e1bq5XFjIdZ/luSxQoKuD2d30s/yAin68QokTP22lsn/Q5vJM1TQcWZv2NnyTbThQyMzjmxFdT5Zl+24EHPOvjk64oRv8iYycPIPQkM654IEUO1mJAF5zWn6FdYwBmtiATczJasRlgMy18Ac= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1695050276; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=aavFhk2TSqfamGQ0JOCpEcTHUul47/vLJAJo52kvO5A=; b=Twtk5UqKnic7UVWM30E/+DmAOob0BmirkRH9Xm9fLyBw+SGpyQarTBP1qNkIM/GEr/2+6GkqtJEorTQx9YoOT0n+UAppAvEY1zrGrlaP0mFHe/Ai4Soxfczc8Alq98iaH/7Kf4fpyl1tdhvo8I9/Kyk71inEAcjk444TS3i4QcU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+108789+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1695050276655685.7603749591067; Mon, 18 Sep 2023 08:17:56 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=KAG7t1H+LNsrf4rmh+j2GjZxbt6CShv9Z3AOCYYiFnA=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1695050276; v=1; b=XQVgMAB/+YQCKVGypxMGPEDB8r5vvP+b7Dv753A2a/ljopltMP/o4QJZUQ580q/sYfxtJfDR Gq9R8v+X0f5NHxjIleEyzcUoesmkbwiQ1xxoP9cemKsK0CHr+/XmOfMXlrnuFILcFKmnijXtGOF J4Ho6UBKFwA9uuBCG3YYfclI= X-Received: by 127.0.0.2 with SMTP id 1fy4YY1788612x7eigL0vwZy; Mon, 18 Sep 2023 08:17:56 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web11.45986.1695019379286248808 for ; Sun, 17 Sep 2023 23:42:59 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10836"; a="369906065" X-IronPort-AV: E=Sophos;i="6.02,155,1688454000"; d="scan'208";a="369906065" X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Sep 2023 23:42:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10836"; a="869450508" X-IronPort-AV: E=Sophos;i="6.02,155,1688454000"; d="scan'208";a="869450508" X-Received: from juichenx-mobl3.gar.corp.intel.com ([10.227.107.41]) by orsmga004.jf.intel.com with ESMTP; 17 Sep 2023 23:42:39 -0700 From: brucex.wang@intel.com To: devel@edk2.groups.io Cc: brucex.wang@intel.com, Zhiguang Liu , Ard Biesheuvel , Jiewen Yao , Jordan Justen , Gerd Hoffmann , Anthony Perard , Julien Grall , Ray Ni Subject: [edk2-devel] [PATCH v4 1/4] OvmfPkg: Remove applicationProcessorEntryPoint Date: Mon, 18 Sep 2023 14:42:31 +0800 Message-Id: <20230918064235.1440-2-brucex.wang@intel.com> In-Reply-To: <20230918064235.1440-1-brucex.wang@intel.com> References: <20230918064235.1440-1-brucex.wang@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,brucex.wang@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: KqxH4IVLr0KkHPCBh6X6RAZRx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1695050278436100029 Content-Type: text/plain; charset="utf-8" From: Zhiguang Liu REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4494 Current reset vector uses 0xffffffe0 as AP waking vector, and expects GenFv generates code aligned on a 4k boundary which will jump to this location. However, some issues are listed below 1. GenFV doesn't generate code as the comment expects, because GenFv assumes no modifications are required to the VTF-0 'Volume Top File'. 2. Even if removing VFT0 signature and let GenFv to modify, Genfv is hard-code using another flash address 0xffffffd0. 3. In the same patch series, AP waking vector code is removed from GenFv, because no such usage anymore. The existing of first two issues also approve the usage is not available for a long time. Therefore, remove AP waking vector related code. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Anthony Perard Cc: Julien Grall Reviewed-by: Ray Ni Acked-by: Anthony PERARD Signed-off-by: Zhiguang Liu --- OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 15 +++------------ OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm | 16 +++------------- 2 files changed, 6 insertions(+), 25 deletions(-) diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVe= ctor/Ia16/ResetVectorVtf0.asm index 12f2cedd67..8f94da89f7 100644 --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm @@ -160,22 +160,13 @@ guidedStructureEnd: =20 ALIGN 16 =20 -applicationProcessorEntryPoint: ; -; Application Processors entry point +; 0xffffffe0 ; -; GenFv generates code aligned on a 4k boundary which will jump to this -; location. (0xffffffe0) This allows the Local APIC Startup IPI to be -; used to wake up the application processors. -; - jmp EarlyApInitReal16 - -ALIGN 8 - - DD 0 + DD 0, 0, 0 =20 ; -; The VTF signature +; The VTF signature (0xffffffec) ; ; VTF-0 means that the VTF (Volume Top File) code does not require ; any fixups. diff --git a/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/XenR= esetVector/Ia16/ResetVectorVtf0.asm index 56749bdbc9..67156d8252 100644 --- a/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm +++ b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm @@ -39,23 +39,13 @@ xenPVHEntryPoint: =20 BITS 16 ALIGN 16 - -applicationProcessorEntryPoint: -; -; Application Processors entry point ; -; GenFv generates code aligned on a 4k boundary which will jump to this -; location. (0xffffffe0) This allows the Local APIC Startup IPI to be -; used to wake up the application processors. +; 0xffffffe0 ; - jmp EarlyApInitReal16 - -ALIGN 8 - - DD 0 + DD 0, 0, 0 =20 ; -; The VTF signature +; The VTF signature (0xffffffec) ; ; VTF-0 means that the VTF (Volume Top File) code does not require ; any fixups. --=20 2.39.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#108789): https://edk2.groups.io/g/devel/message/108789 Mute This Topic: https://groups.io/mt/101435617/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Wed Oct 30 19:55:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+108790+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+108790+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1695050276; cv=none; d=zohomail.com; s=zohoarc; b=Ivv/rsyNj1n9imqpO5XT+UI8If3QII0QTV02f+5R6uO8GKB34285lFljVC2OEMlMX+PHk1w6+2eFf7/zhYp/tFlHuxdFb0VgGClYICVz53FAC+aNPrlnghCtoJo2UXGBwVnCZUQggBRW97H5gNLonUj98mZQz/W8delmkFuZNPs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1695050276; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=YYepfwvMJb4xqK1Td8qJ0qejxzI+Rs0juwvokpjKtEg=; b=fHplBnKAevuCoGmPD68LlOQMcOP1R49nZ71EbUsf7BvHb4UyexoE5bsOP1mAs5soJFpRNmMD3C3X4a3+jymoUCRuadZGLa+IjTL5ZZ/h5FJMFy4y2SA9MbbsS209BCAqqFZ8XdMMU4OYnlPlDCSZKYYj+CYOlHjmUE5hOHVCbXk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+108790+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1695050276972997.1660858115964; Mon, 18 Sep 2023 08:17:56 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=UOhGJW4FXv40VNArV7hOP+PV1GiwAM6r1XrzecCet0M=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1695050276; v=1; b=PO5B9yMp4UDBMhepnANgOBmnam51JD1BelXUzpWWO45PkUqoLbuuvl3no4t5ohvSnOd/Zqhm AqeFyLg1qUd2+9lkqfDyAWsoNhdzITUvWoApR6Hqg/avzLo2gNKBmDWAAkQVxFuiQ9POEiU2AVh HcibPdb6wSqbNNyKMJJeoZqQ= X-Received: by 127.0.0.2 with SMTP id LeHgYY1788612xewGNnC8mTL; Mon, 18 Sep 2023 08:17:56 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web11.45985.1695019378754549588 for ; Sun, 17 Sep 2023 23:42:59 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10836"; a="369906075" X-IronPort-AV: E=Sophos;i="6.02,155,1688454000"; d="scan'208";a="369906075" X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Sep 2023 23:42:44 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10836"; a="869450518" X-IronPort-AV: E=Sophos;i="6.02,155,1688454000"; d="scan'208";a="869450518" X-Received: from juichenx-mobl3.gar.corp.intel.com ([10.227.107.41]) by orsmga004.jf.intel.com with ESMTP; 17 Sep 2023 23:42:42 -0700 From: brucex.wang@intel.com To: devel@edk2.groups.io Cc: brucex.wang@intel.com, Zhiguang Liu , Eric Dong , Ray Ni , Rahul Kumar , Gerd Hoffmann Subject: [edk2-devel] [PATCH v4 2/4] UefiCpuPkg/ResetVector: Remove AP waking vector from ResetVector Date: Mon, 18 Sep 2023 14:42:32 +0800 Message-Id: <20230918064235.1440-3-brucex.wang@intel.com> In-Reply-To: <20230918064235.1440-1-brucex.wang@intel.com> References: <20230918064235.1440-1-brucex.wang@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,brucex.wang@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: 9ydHNLSkuY2vAR5J4aQzlGKmx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1695050277868100025 Content-Type: text/plain; charset="utf-8" From: Zhiguang Liu REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4494 Current reset vector uses 0xffffffe0 as AP waking vector, and expects GenFv generates code aligned on a 4k boundary which will jump to this location. However, some issues are listed below 1. GenFV doesn't generate code as the comment expects, because GenFv assumes no modifications are required to the VTF-0 'Volume Top File'. 2. Even if removing VFT0 signature and let GenFv to modify, Genfv is hard-code using another flash address 0xffffffd0. 3. In the same patch series, AP waking vector code is removed from GenFv, because no such usage anymore. The existing of first two issues also approve the usage is not available for a long time. Therefore, remove AP waking vector related code. Cc: Eric Dong Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Ray Ni Signed-off-by: Zhiguang Liu --- UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm | 7 ------- .../ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm | 15 +++------------ 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm b/UefiCpuPkg/Reset= Vector/Vtf0/Ia16/Init16.asm index cbdadee166..02b9a0303c 100644 --- a/UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm @@ -17,13 +17,6 @@ EarlyBspInitReal16: mov di, 'BP' jmp short Main16 =20 -; -; @param[out] DI 'AP' to indicate application processor -; -EarlyApInitReal16: - mov di, 'AP' - jmp short Main16 - ; ; Modified: EAX ; diff --git a/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm b/UefiCpu= Pkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm index fe5bbea803..384b1d4d98 100644 --- a/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm @@ -32,22 +32,13 @@ ALIGN 16 TIMES (0x1000 - 0x20) DB 0 %endif =20 -applicationProcessorEntryPoint: ; -; Application Processors entry point +; 0xffffffe0 ; -; GenFv generates code aligned on a 4k boundary which will jump to this -; location. (0xffffffe0) This allows the Local APIC Startup IPI to be -; used to wake up the application processors. -; - jmp EarlyApInitReal16 - -ALIGN 8 - - DD 0 + DD 0, 0, 0 =20 ; -; The VTF signature +; The VTF signature (0xffffffec) ; ; VTF-0 means that the VTF (Volume Top File) code does not require ; any fixups. --=20 2.39.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#108790): https://edk2.groups.io/g/devel/message/108790 Mute This Topic: https://groups.io/mt/101435618/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Wed Oct 30 19:55:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+108791+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+108791+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1695050276; cv=none; d=zohomail.com; s=zohoarc; b=VkL9MQbkc3Z9ltAxp8aHP50exr7a5LXHlnGc5T9toj2dPl5saDtVcBaVeeao55F7uZYUkcoM7EtfcjGIo7VMp81qRESAMX1JxSholwT1Jv0rask4FycBZbrrAQI7BqfPWAOn+/nPL5LPtA+s8di/buMqAjTj4Io/hB9j6rwBM80= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1695050276; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=Zeh29ulWWOl/pGLXY9lfugpjOViMju39eyNH2+UWhLg=; b=AaIxQOnR3rc5AnY/sxvQKWfdeXprTk73ku5z1xU+J9ElYYase76WwRQ/wYwhG+QgWI3G2cfGS2U3s1UXhJnXOAw/qGD/x9rI50I2o3MZSnZwXdSl1uLLs9Yp4cUscDKx//9+PCOA5qsuuCgxF4cs4QXoeySoa98Z887c+Y904Bs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+108791+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 169505027625693.2018882354472; Mon, 18 Sep 2023 08:17:56 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=XzrClMUNM98/LfeHti6FGZ3pJm1SP+8eOj0Tz2wrdq4=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1695050275; v=1; b=nNI/g6wFSuJjJinbTAd+fPaaPKT24PKbkb9tDXGrPWfZPn1aRLRBYNcWRtyEOD3TGcjNWAuA yYMKouRohHr6g1euEzVaWTnQu9odrKO1Zv0A0848lUqNY0F6I2GX/0rOVfIJKfC6VDH8HztHHEV qWTPLcDqqdXUsobTNi5A8vjY= X-Received: by 127.0.0.2 with SMTP id DfLiYY1788612x677IKqwpIr; Mon, 18 Sep 2023 08:17:55 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web11.45986.1695019379286248808 for ; Sun, 17 Sep 2023 23:42:59 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10836"; a="369906083" X-IronPort-AV: E=Sophos;i="6.02,155,1688454000"; d="scan'208";a="369906083" X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Sep 2023 23:42:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10836"; a="869450537" X-IronPort-AV: E=Sophos;i="6.02,155,1688454000"; d="scan'208";a="869450537" X-Received: from juichenx-mobl3.gar.corp.intel.com ([10.227.107.41]) by orsmga004.jf.intel.com with ESMTP; 17 Sep 2023 23:42:45 -0700 From: brucex.wang@intel.com To: devel@edk2.groups.io Cc: brucex.wang@intel.com, Benny Lin , Gua Guo , Chasel Chiu , James Lu Subject: [edk2-devel] [PATCH v4 3/4] MdePkg/BaseFdtLib: Add Fdt function. Date: Mon, 18 Sep 2023 14:42:33 +0800 Message-Id: <20230918064235.1440-4-brucex.wang@intel.com> In-Reply-To: <20230918064235.1440-1-brucex.wang@intel.com> References: <20230918064235.1440-1-brucex.wang@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,brucex.wang@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: Kf6UEUWI0uGrlLoPdbUjX1qKx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1695050277815100024 Content-Type: text/plain; charset="utf-8" From: "Brucex.Wang" Add FdtGetName() and FdtNodeDepth() function. Cc: Benny Lin Cc: Gua Guo Cc: Chasel Chiu Cc: James Lu Signed-off-by: BruceX Wang --- MdePkg/Include/Library/FdtLib.h | 34 +++++++++++++++++++++++++ MdePkg/Library/BaseFdtLib/FdtLib.c | 40 ++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/MdePkg/Include/Library/FdtLib.h b/MdePkg/Include/Library/FdtLi= b.h index cf5ceba9e9..d9300a18e3 100644 --- a/MdePkg/Include/Library/FdtLib.h +++ b/MdePkg/Include/Library/FdtLib.h @@ -398,4 +398,38 @@ FdtSetProp ( IN UINT32 Length ); =20 +/** + Returns the name of a given node. + + @param[in] Fdt The pointer to FDT blob. + @param[in] NodeOffse Offset of node to check. + @param[in] Length The pointer to an integer variable (will be ov= erwritten) or NULL. + + @return The pointer to the node's name. + +**/ +CONST CHAR8 * +EFIAPI +FdtGetName ( + IN VOID *Fdt, + IN INT32 NodeOffset, + IN UINT32 *Length + ); + +/** + FdtNodeDepth() finds the depth of a given node. The root node + has depth 0, its immediate subnodes depth 1 and so forth. + + @param[in] Fdt The pointer to FDT blob. + @param[in] NodeOffset Offset of node to check. + + @return Depth of the node at NodeOffset. +**/ +INT32 +EFIAPI +FdtNodeDepth ( + IN CONST VOID *Fdt, + IN INT32 NodeOffset + ); + #endif /* FDT_LIB_H_ */ diff --git a/MdePkg/Library/BaseFdtLib/FdtLib.c b/MdePkg/Library/BaseFdtLib= /FdtLib.c index 090b0b3fd4..1ef99ea882 100644 --- a/MdePkg/Library/BaseFdtLib/FdtLib.c +++ b/MdePkg/Library/BaseFdtLib/FdtLib.c @@ -402,3 +402,43 @@ FdtSetProp ( { return fdt_setprop (Fdt, NodeOffset, Name, Value, (int)Length); } + +/** + Returns the name of a given node. + + @param[in] Fdt The pointer to FDT blob. + @param[in] NodeOffset Offset of node to check. + @param[in] Length The pointer to an integer variable (will be ov= erwritten) or NULL. + + @return The pointer to the node's name. + +**/ +CONST CHAR8 * +EFIAPI +FdtGetName ( + IN VOID *Fdt, + IN INT32 NodeOffset, + IN UINT32 *Length + ) +{ + return fdt_get_name (Fdt, NodeOffset, (int *)Length); +} + +/** + FdtNodeDepth() finds the depth of a given node. The root node + has depth 0, its immediate subnodes depth 1 and so forth. + + @param[in] Fdt The pointer to FDT blob. + @param[in] NodeOffset Offset of node to check. + + @returns Depth of the node at NodeOffset. +**/ +INT32 +EFIAPI +FdtNodeDepth ( + IN CONST VOID *Fdt, + IN INT32 NodeOffset + ) +{ + return fdt_node_depth (Fdt, NodeOffset); +} --=20 2.39.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#108791): https://edk2.groups.io/g/devel/message/108791 Mute This Topic: https://groups.io/mt/101435619/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Wed Oct 30 19:55:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+108792+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+108792+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1695050279; cv=none; d=zohomail.com; s=zohoarc; b=aHzL1KIw+Q1bcc/x15bsuAgFI4YE60prgO+W1WDbqFaadxDz63fQL2yhNXa1UNuUkR2YnDwIVqcoHsZhvitWRbMHYZk947K89nImKEshOh33XV3T4L/qmMGwQ4B+W6jW2CzDd05qrrR18f+kosKWw4yYFNIMsy0+i4SsPjj7U+E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1695050279; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=pFwVSviDZmY8lb2HO/dmWNko0cpPKXMZ0cAT5/sq8Ss=; b=NeYIf1pJsvzS59uBEehJrLoOw67TmSI34czPtsjckNMZa1eI4iOHkXLBWeZQC6NL0u5ltJBEDSVqnDXsOsHasHnw9J7dbLI5paO0hwVI83I+wqK12kjzn4Y49XZO34syggJ/RFv3pNJ3qBXeMom6X1Sd8ybHDDh71AwTbP1JUKM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+108792+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1695050279965543.4678784548903; Mon, 18 Sep 2023 08:17:59 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=2V+3eT0Wz+Gc33ujUsjAEltY9WFtrfqdf4eoVHislko=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1695050277; v=1; b=aKqHCq0IpCAeotWyGcTP1tvBq8c4M6WpeiOOKXEqJUP7AJ9WRbCbJ9n3kuy6mgbxYWc9Otgf 0toJnXG0UrVQaKbmYAQrvrdUQuFCckJTUK0nU/cP31GnLCXQLpJC8zstboJEFpsCbNwJXOnmN1d QSB0vdFAHI44K3gRVfKsL+Aw= X-Received: by 127.0.0.2 with SMTP id FmOOYY1788612xotQ19zmVGe; Mon, 18 Sep 2023 08:17:57 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web10.45867.1695019380756545437 for ; Sun, 17 Sep 2023 23:43:00 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10836"; a="369906090" X-IronPort-AV: E=Sophos;i="6.02,155,1688454000"; d="scan'208";a="369906090" X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Sep 2023 23:42:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10836"; a="869450552" X-IronPort-AV: E=Sophos;i="6.02,155,1688454000"; d="scan'208";a="869450552" X-Received: from juichenx-mobl3.gar.corp.intel.com ([10.227.107.41]) by orsmga004.jf.intel.com with ESMTP; 17 Sep 2023 23:42:47 -0700 From: brucex.wang@intel.com To: devel@edk2.groups.io Cc: brucex.wang@intel.com, Guo Dong , Sean Rhodes , James Lu , Gua Guo Subject: [edk2-devel] [PATCH v4 4/4] UefiPayloadPkg: Add FIT support Date: Mon, 18 Sep 2023 14:42:34 +0800 Message-Id: <20230918064235.1440-5-brucex.wang@intel.com> In-Reply-To: <20230918064235.1440-1-brucex.wang@intel.com> References: <20230918064235.1440-1-brucex.wang@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,brucex.wang@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: eBzHB3sQUn49xRa5vl2ZmsaNx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1695050280978100039 Content-Type: text/plain; charset="utf-8" From: "Brucex.Wang" Provide Fit format for UniversalPayload, developer can use argument "--Fit" to build UniversalPayload.fit Cc: Guo Dong Cc: Sean Rhodes Cc: James Lu Cc: Gua Guo Signed-off-by: BruceX Wang --- .../Include/Guid/UniversalPayloadBase.h | 19 + UefiPayloadPkg/PayloadLoaderPeim/FitLib.h | 60 ++ .../PayloadLoaderPeim/FitLib/FitLib.c | 127 ++++ .../PayloadLoaderPeim/FitPayloadLoaderPeim.c | 150 ++++ .../FitPayloadLoaderPeim.inf | 59 ++ UefiPayloadPkg/Readme.md | 189 +++++ UefiPayloadPkg/Tools/MkFitImage.py | 272 ++++++++ .../FitUniversalPayloadEntry.c | 654 ++++++++++++++++++ .../FitUniversalPayloadEntry.inf | 98 +++ UefiPayloadPkg/UefiPayloadPkg.dec | 3 + UefiPayloadPkg/UefiPayloadPkg.dsc | 27 +- UefiPayloadPkg/UniversalPayloadBuild.py | 328 ++++++--- 12 files changed, 1890 insertions(+), 96 deletions(-) create mode 100644 UefiPayloadPkg/Include/Guid/UniversalPayloadBase.h create mode 100644 UefiPayloadPkg/PayloadLoaderPeim/FitLib.h create mode 100644 UefiPayloadPkg/PayloadLoaderPeim/FitLib/FitLib.c create mode 100644 UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c create mode 100644 UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.i= nf create mode 100644 UefiPayloadPkg/Readme.md create mode 100644 UefiPayloadPkg/Tools/MkFitImage.py create mode 100644 UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntr= y.c create mode 100644 UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntr= y.inf diff --git a/UefiPayloadPkg/Include/Guid/UniversalPayloadBase.h b/UefiPaylo= adPkg/Include/Guid/UniversalPayloadBase.h new file mode 100644 index 0000000000..60f2aa37dd --- /dev/null +++ b/UefiPayloadPkg/Include/Guid/UniversalPayloadBase.h @@ -0,0 +1,19 @@ +/** @file + Universal Payload general definitions. + +Copyright (c) 2023, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef UNIVERSAL_PAYLOAD_BASE_H_ +#define UNIVERSAL_PAYLOAD_BASE_H_ + +extern GUID gUniversalPayloadBaseGuid; + +typedef struct { + UNIVERSAL_PAYLOAD_GENERIC_HEADER Header; + EFI_PHYSICAL_ADDRESS Entry; +} UNIVERSAL_PAYLOAD_BASE; + +#endif // UNIVERSAL_PAYLOAD_BASE_H_ diff --git a/UefiPayloadPkg/PayloadLoaderPeim/FitLib.h b/UefiPayloadPkg/Pay= loadLoaderPeim/FitLib.h new file mode 100644 index 0000000000..0514d675a6 --- /dev/null +++ b/UefiPayloadPkg/PayloadLoaderPeim/FitLib.h @@ -0,0 +1,60 @@ +/** @file + FIT Load Image Support +Copyright (c) 2023, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef FIT_LIB_H_ +#define FIT_LIB_H_ + +#include +#include +#include + +typedef struct { + UINT64 RelocateType; + UINT64 Offset; +} FIT_RELOCATE_ITEM; + +typedef struct { + EFI_PHYSICAL_ADDRESS ImageBase; + EFI_PHYSICAL_ADDRESS PayloadBaseAddress; + UINT64 PayloadSize; + UINTN PayloadEntryOffset; + UINTN PayloadEntrySize; + EFI_PHYSICAL_ADDRESS PayloadEntryPoint; + UINTN RelocateTableOffset; + UINTN RelocateTableCount; + EFI_PHYSICAL_ADDRESS PayloadLoadAddress; +} FIT_IMAGE_CONTEXT; + +typedef struct { + UINT8 *Name; + UINT32 Offset; +} PROPERTY_DATA; + +#define IMAGE_BASE_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, ImageB= ase) +#define PAYLOAD_BASE_ADDR_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, Payloa= dBaseAddress) +#define PAYLOAD_BASE_SIZE_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, Payloa= dSize) +#define PAYLOAD_ENTRY_OFFSET_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, Payloa= dEntryOffset) +#define PAYLOAD_ENTRY_SIZE_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, Payloa= dEntrySize) +#define PAYLOAD_ENTRY_POINT_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, Payloa= dEntryPoint) +#define RELOCATE_TABLE_OFFSET_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, Reloca= teTableOffset) +#define RELOCATE_TABLE_COUNT_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, Reloca= teTableCount) +#define PAYLOAD_LOAD_ADDR_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, Payloa= dLoadAddress) + +/** + Parse the FIT image info. + @param[in] ImageBase Memory address of an image. + @param[out] Context The FIT image context pointer. + @retval EFI_UNSUPPORTED Unsupported binary type. + @retval EFI_SUCCESS FIT binary is loaded successfully. +**/ +EFI_STATUS +EFIAPI +ParseFitImage ( + IN VOID *ImageBase, + OUT FIT_IMAGE_CONTEXT *Context + ); + +#endif diff --git a/UefiPayloadPkg/PayloadLoaderPeim/FitLib/FitLib.c b/UefiPayload= Pkg/PayloadLoaderPeim/FitLib/FitLib.c new file mode 100644 index 0000000000..9d1d8a4f61 --- /dev/null +++ b/UefiPayloadPkg/PayloadLoaderPeim/FitLib/FitLib.c @@ -0,0 +1,127 @@ +/** @file + FIT Load Image Support +Copyright (c) 2023, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "FitLib.h" + +PROPERTY_DATA PropertyData32List[] =3D { + { "data-offset", PAYLOAD_ENTRY_OFFSET_OFFSET }, + { "data-size", PAYLOAD_ENTRY_SIZE_OFFSET }, + { "reloc-start", RELOCATE_TABLE_OFFSET_OFFSET } +}; + +PROPERTY_DATA PropertyData64List[] =3D { + { "entry-start", PAYLOAD_ENTRY_POINT_OFFSET }, + { "load", PAYLOAD_LOAD_ADDR_OFFSET } +}; + +/** + Parse the target firmware image info in FIT. + @param[in] Fdt Memory address of a fdt. + @param[in] Firmware Target name of an image. + @param[out] Context The FIT image context pointer. + @retval EFI_NOT_FOUND FIT node dose not find. + @retval EFI_SUCCESS FIT binary is loaded successfully. +**/ +EFI_STATUS +EFIAPI +FitParseFirmwarePropertyData ( + IN VOID *Fdt, + IN CHAR8 *Firmware, + OUT FIT_IMAGE_CONTEXT *Context + ) +{ + CONST FDT_PROPERTY *PropertyPtr; + INT32 ImageNode; + INT32 TianoNode; + INT32 TempLen; + UINT32 *Data32; + UINT64 *Data64; + UINT32 *ContextOffset32; + UINT64 *ContextOffset64; + INT32 Index; + + ImageNode =3D FdtSubnodeOffsetNameLen (Fdt, 0, "images", (INT32)AsciiStr= Len ("images")); + if (ImageNode <=3D 0) { + return EFI_NOT_FOUND; + } + + TianoNode =3D FdtSubnodeOffsetNameLen (Fdt, ImageNode, Firmware, (INT32)= AsciiStrLen (Firmware)); + if (TianoNode <=3D 0) { + return EFI_NOT_FOUND; + } + + for (Index =3D 0; Index < sizeof (PropertyData32List) / sizeof (PROPERTY= _DATA); Index++) { + PropertyPtr =3D FdtGetProperty (Fdt, TianoNode, PropertyData32Lis= t[Index].Name, &TempLen); + Data32 =3D (UINT32 *)(PropertyPtr->Data); + ContextOffset32 =3D (UINT32 *)((UINTN)Context + PropertyData32List[In= dex].Offset); + *ContextOffset32 =3D Fdt32ToCpu (*Data32); + } + + for (Index =3D 0; Index < sizeof (PropertyData64List)/sizeof (PROPERTY_D= ATA); Index++) { + PropertyPtr =3D FdtGetProperty (Fdt, TianoNode, PropertyData64Lis= t[Index].Name, &TempLen); + Data64 =3D (UINT64 *)(PropertyPtr->Data); + ContextOffset64 =3D (UINT64 *)((UINTN)Context + PropertyData64List[In= dex].Offset); + *ContextOffset64 =3D Fdt64ToCpu (*Data64); + } + + return EFI_SUCCESS; +} + +/** + Parse the FIT image info. + @param[in] ImageBase Memory address of an image. + @param[out] Context The FIT image context pointer. + @retval EFI_UNSUPPORTED Unsupported binary type. + @retval EFI_SUCCESS FIT binary is loaded successfully. +**/ +EFI_STATUS +EFIAPI +ParseFitImage ( + IN VOID *ImageBase, + OUT FIT_IMAGE_CONTEXT *Context + ) +{ + VOID *Fdt; + INT32 ConfigNode; + INT32 Config1Node; + CONST FDT_PROPERTY *PropertyPtr; + INT32 TempLen; + UINT32 *Data32; + UINT64 Value; + EFI_STATUS Status; + UINTN UplSize; + CHAR8 *Firmware; + + Status =3D FdtCheckHeader (ImageBase); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Fdt =3D ImageBase; + PropertyPtr =3D FdtGetProperty (Fdt, 0, "size", &TempLen); + Data32 =3D (UINT32 *)(PropertyPtr->Data); + UplSize =3D Value =3D Fdt32ToCpu (*Data32); + ConfigNode =3D FdtSubnodeOffsetNameLen (Fdt, 0, "configurations", (INT3= 2)AsciiStrLen ("configurations")); + if (ConfigNode <=3D 0) { + return EFI_NOT_FOUND; + } + + Config1Node =3D FdtSubnodeOffsetNameLen (Fdt, ConfigNode, "conf-1", (INT= 32)AsciiStrLen ("conf-1")); + if (Config1Node <=3D 0) { + return EFI_NOT_FOUND; + } + + PropertyPtr =3D FdtGetProperty (Fdt, Config1Node, "firmware", &TempLen); + Firmware =3D (CHAR8 *)(PropertyPtr->Data); + + FitParseFirmwarePropertyData (Fdt, Firmware, Context); + + Context->ImageBase =3D (EFI_PHYSICAL_ADDRESS)ImageBase; + Context->PayloadSize =3D UplSize; + Context->RelocateTableCount =3D (Context->PayloadEntrySize - (Context->R= elocateTableOffset - Context->PayloadEntryOffset)) / sizeof (FIT_RELOCATE_I= TEM); + + return EFI_SUCCESS; +} diff --git a/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c b/Uefi= PayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c new file mode 100644 index 0000000000..de33d49bd1 --- /dev/null +++ b/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c @@ -0,0 +1,150 @@ +/** @file + FIT Load Image Support +Copyright (c) 2023, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "FitLib.h" + +/** + The wrapper function of PeiLoadImageLoadImage(). + @param This - Pointer to EFI_PEI_LOAD_FILE_PPI. + @param FileHandle - Pointer to the FFS file header of the image. + @param ImageAddressArg - Pointer to PE/TE image. + @param ImageSizeArg - Size of PE/TE image. + @param EntryPoint - Pointer to entry point of specified image file = for output. + @param AuthenticationState - Pointer to attestation authentication state= of image. + @return Status of PeiLoadImageLoadImage(). +**/ +EFI_STATUS +EFIAPI +PeiLoadFileLoadPayload ( + IN CONST EFI_PEI_LOAD_FILE_PPI *This, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL, + OUT UINT64 *ImageSizeArg OPTIONAL, + OUT EFI_PHYSICAL_ADDRESS *EntryPoint, + OUT UINT32 *AuthenticationState + ) +{ + EFI_STATUS Status; + FIT_IMAGE_CONTEXT Context; + UINTN Instance; + VOID *Binary; + FIT_RELOCATE_ITEM *RelocateTable; + UNIVERSAL_PAYLOAD_BASE *PayloadBase; + UINTN Length; + UINTN Delta; + UINTN Index; + + Instance =3D 0; + do { + Status =3D PeiServicesFfsFindSectionData3 (EFI_SECTION_RAW, Instance++= , FileHandle, &Binary, AuthenticationState); + if (EFI_ERROR (Status)) { + return Status; + } + + ZeroMem (&Context, sizeof (Context)); + Status =3D ParseFitImage (Binary, &Context); + } while (EFI_ERROR (Status)); + + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + DEBUG (( + DEBUG_INFO, + "Before Rebase Payload File Base: 0x%08x, File Size: 0x%08X, EntryPoin= t: 0x%08x\n", + Context.PayloadBaseAddress, + Context.PayloadSize, + Context.PayloadEntryPoint + )); + Context.PayloadBaseAddress =3D (EFI_PHYSICAL_ADDRESS)AllocatePages (EFI_= SIZE_TO_PAGES (Context.PayloadSize)); + + RelocateTable =3D (FIT_RELOCATE_ITEM *)(UINTN)(Context.PayloadBaseAddres= s + Context.RelocateTableOffset); + CopyMem ((VOID *)Context.PayloadBaseAddress, Binary, Context.PayloadSize= ); + + if (Context.PayloadBaseAddress > Context.PayloadLoadAddress) { + Delta =3D Context.PayloadBaseAddress - Context.Pa= yloadLoadAddress; + Context.PayloadEntryPoint +=3D Delta; + for (Index =3D 0; Index < Context.RelocateTableCount; Index++) { + if ((RelocateTable[Index].RelocateType =3D=3D 10) || (RelocateTable[= Index].RelocateType =3D=3D 3)) { + *((UINT64 *)(Context.PayloadBaseAddress + RelocateTable[Index].Off= set)) =3D *((UINT64 *)(Context.PayloadBaseAddress + RelocateTable[Index].Of= fset)) + Delta; + } + } + } else { + Delta =3D Context.PayloadLoadAddress - Context.Pa= yloadBaseAddress; + Context.PayloadEntryPoint -=3D Delta; + for (Index =3D 0; Index < Context.RelocateTableCount; Index++) { + if ((RelocateTable[Index].RelocateType =3D=3D 10) || (RelocateTable[= Index].RelocateType =3D=3D 3)) { + *((UINT64 *)(Context.PayloadBaseAddress + RelocateTable[Index].Off= set)) =3D *((UINT64 *)(Context.PayloadBaseAddress + RelocateTable[Index].Of= fset)) - Delta; + } + } + } + + DEBUG (( + DEBUG_INFO, + "After Rebase Payload File Base: 0x%08x, File Size: 0x%08X, EntryPoint= : 0x%08x\n", + Context.PayloadBaseAddress, + Context.PayloadSize, + Context.PayloadEntryPoint + )); + + Length =3D sizeof (UNIVERSAL_PAYLOAD_BASE); + PayloadBase =3D BuildGuidHob ( + &gUniversalPayloadBaseGuid, + Length + ); + PayloadBase->Entry =3D (EFI_PHYSICAL_ADDRESS)Context.ImageBase; + + *ImageAddressArg =3D Context.PayloadBaseAddress; + *ImageSizeArg =3D Context.PayloadSize; + *EntryPoint =3D Context.PayloadEntryPoint; + + return EFI_SUCCESS; +} + +EFI_PEI_LOAD_FILE_PPI mPeiLoadFilePpi =3D { + PeiLoadFileLoadPayload +}; + +EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList =3D { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiLoadFilePpiGuid, + &mPeiLoadFilePpi +}; + +/** + Install Pei Load File PPI. + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + @retval EFI_SUCESS The entry point executes successfully. + @retval Others Some error occurs during the execution of this funct= ion. +**/ +EFI_STATUS +EFIAPI +InitializeFitPayloadLoaderPeim ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + Status =3D PeiServicesInstallPpi (&gPpiLoadFilePpiList); + + return Status; +} diff --git a/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf b/Ue= fiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf new file mode 100644 index 0000000000..cd0cb186e1 --- /dev/null +++ b/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf @@ -0,0 +1,59 @@ +## @file +# Produce LoadFile PPI for payload loading. +# +# Copyright (c) 2023, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D FitPayloadLoaderPeim + FILE_GUID =3D 55AC82C8-FC17-4C56-BCDA-990BB0A73E41 + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.0 + + ENTRY_POINT =3D InitializeFitPayloadLoaderPeim + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 +# + +[Sources] + FitPayloadLoaderPeim.c + FitLib.h + FitLib/FitLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + PcAtChipsetPkg/PcAtChipsetPkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec + +[LibraryClasses] + PcdLib + MemoryAllocationLib + BaseMemoryLib + PeiServicesLib + HobLib + BaseLib + PeimEntryPoint + DebugLib + FdtLib + +[Ppis] + gEfiPeiLoadFilePpiGuid ## PRODUCES + +[Pcd] + gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister + gPcAtChipsetPkgTokenSpaceGuid.PcdRtcTargetRegister + +[Guids] + gUniversalPayloadExtraDataGuid ## PRODUCES + gUniversalPayloadBaseGuid ## PRODUCES + +[Depex] + TRUE diff --git a/UefiPayloadPkg/Readme.md b/UefiPayloadPkg/Readme.md new file mode 100644 index 0000000000..cb7f39b3f7 --- /dev/null +++ b/UefiPayloadPkg/Readme.md @@ -0,0 +1,189 @@ +# UefiPayloadPkg +Provide UEFI Universal Payload for different bootloader to generate EFI en= vironment + +# Spec +UniversalPayload URL: https://universalscalablefirmware.github.io/document= ation/2_universal_payload.html +UniversalPayload URL: https://universalpayload.github.io/spec/ +ELF Format URL: https://refspecs.linuxfoundation.org/elf/elf.pdf +FIT Format URL: https://universalpayload.github.io/spec/chapter2-payload-i= mage-format.html + +# Uefi UniversalPayload Format + | Binary Format | HandOffPayload - HOB | + |---------------|----------------------| + | ELF | V (Default) | + | FIT | V | + +# Binary Format + - ELF + ``` + + +-----------------------+ + | | UniversalPayloadEntry | <----------- UefiPayloadPkg= \UefiPayloadEntry\UniversalPayloadEntry.c:_ModuleEntryPoint (HOB) + | +-----------------------+ + | | .upld_info | patch it directly + ELF Format | +-----------------------+ + | | .upld.uefi_fv | patch it directly + | +-----------------------+ + | | .upld.bds_fv | patch it directly + | +-----------------------+ + | | .upld._fv | patch it directly + + +-----------------------+ + ``` + + - FIT + ``` + + +-----------------------+ + FIT Data | | FIT Header | <----------- Generate by py= libfdt + + +-----------------------+ + PECOFF Format | | UniversalPayloadEntry | <----------- UefiPayloadPkg= \UefiPayloadEntry\FitUniversalPayloadEntry.c:_ModuleEntryPoint (HOB) + + +-----------------------+ + Relocate Data | | reloc-start | + + +-----------------------+ + | | uefi_fv | patch it directly + | +-----------------------+ + Multi Binary | | bds_fv | patch it directly + | +-----------------------+ + | | afp_xxx_fv | patch it directly + | +-----------------------+ + | | afp_xxx_fv | patch it directly + + +-----------------------+ + ``` + +# Environment + - ELF + ``` + Download and install https://github.com/llvm/llvm-project/releases/tag= /llvmorg-10.0.1 + ``` + - FIT + - Windows + ```powershell + Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.Servic= ePointManager]::SecurityProtocol =3D [System.Net.ServicePointManager]::Secu= rityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadStri= ng('https://chocolatey.org/install.ps1')) + choco install dtc-msys2 + pip3 install pefile + pip3 install swig + pip3 install pylibfdt + ``` + - Ubuntu + ```bash + sudo apt install -y u-boot-tools + pip3 install pefile + pip3 install swig + pip3 install pylibfdt + ``` +# How to build UEFI UniversalPayload + - Windows + - edksetup Rebuild + - Linux + - make -C BaseTools + - source edksetup.sh + + - UniversalPayload.elf + - python UefiPayloadPkg/UniversalPayloadBuild.py -t + - llvm-objdump -h Build/UefiPayloadPkgX64/UniversalPayload.elf + + - UniversalPayload.fit + - python UefiPayloadPkg/UniversalPayloadBuild.py -t -= -Fit + - fdtdump Build/UefiPayloadPkgX64/UniversalPayload.fit + +# Edk2boot + UefiUniversalPayload +ELF Edk2boot use below way to support compress and sign. + +- ELF Behavior - Edk2boot + UefiUniversalPayload.elf + ``` + Boot Flow + +-----------------------------------------------------------------------= --------------+------------------------------------------------------------= -----------------------------------------------+-------------------+ + | Platform Init = | Universal Loader Interface = | OS | + +-----------------------------------------------------------------------= --------------+------------------------------------------------------------= -----------------------------------------------+-------------------+ + = = HOBs + SEC -> PEI -> DXE -> DXE IPL -> UefiPayloadPkg\PayloadLoaderPeim\Payload= LoaderPeim.c --------------------------------------------------------------= ----------------------> Load UniversalPayload.elf -> Operation System + + + | Platform Initialize - Edk2 = = | UniversalPayload - Edk2 = | + +-----------------------------------------------------------------------= ---------------------------------------------------------------------------= -----------------------------------------------+---------------------------= -----+ + + Binary Format + + +-------------------+ + | BIOS.rom | + +-------------------+ + | Other Firmware | + +-------------------+ + | ... | FMMT = = UniversalPayloadBuild.py + +-------------------+<----------------+-----------------------+ GenFfs = +-----------------------+ Rsa2048Sha256 Sign +-----------------------+ = LzmaCompress +----------------------+ GenSec +---------------------------= -----+ + | | | EDK2 FFS Header |<--------= ---| Rsa2048Sha256 Hash |<--------------------| UniversalPayload.lzma |<= --------------| EDK2 SEC Header |<--------| UniversalPayload.elf = | + | RAW Data | +-----------------------+ = +-----------------------+ +-----------------------+ = +----------------------+ +---------------------------= -----+ + | | | Rsa2048Sha256 Hash | = | UniversalPayload.lzma | = | UniversalPayload.elf | | upld_info = | + | | +-----------------------+ = +-----------------------+ = +----------------------+ +---------------------------= -----+ + | | | UniversalPayload.lzma | = = | upld_info | | upld.uefi_fv = | + +-------------------+<----------------+-----------------------+ = = +----------------------+ +---------------------------= -----+ + | ... | = = | upld.uefi_fv | | upld.bds_fv = | + +-------------------+ = = +----------------------+ +---------------------------= -----+ + | Other Firmware | = = | upld.bds_fv | | upld.AFP1 = | + +-------------------+ = = +----------------------+ +---------------------------= -----+ + = = | upld.AFP1 | | upld.AFP2 = | + = = +----------------------+ +---------------------------= -----+ + = = | upld.AFP2 | | ... = | + = = +----------------------+ +---------------------------= -----+ + = = | ... | | upld.AFPn = | + = = +----------------------+ +---------------------------= -----+ + = = | upld.AFPn | + = = +----------------------+ + ``` + +FIT Edk2boot use below way to support compress and sign +- FIT Behavior - Edk2boot + UefiUniversalPayload.fit + ``` + Boot Flow + +-----------------------------------------------------------------------= --------------+------------------------------------------------------------= ------------+-------------------+ + | Platform Init = | Universal Loader Interface = | OS | + +-----------------------------------------------------------------------= --------------+------------------------------------------------------------= ------------+-------------------+ + = HOBs + SEC -> PEI -> DXE -> DXE IPL -> *UefiPayloadPkg\PayloadLoaderPeim\Payloa= dLoaderPeim.c ----------------------------------------------> Load Universa= lPayload.fit -> Operation System + + Binary Format + + | Platform Initialize - Edk2 = | UniversalPayload - Ed= k2 (UniversalPayloadBuild.py --Fit) | + +-----------------------------------------------------------------------= ----------------------------------------------------+----------------------= -------------------------------------------------------------------+ + + +-------------------+ + | BIOS.rom | + +-------------------+ + | Other Firmware | + +-------------------+ + | ... | FMMT = UniversalPayloadBuild.= py --Fit tianocore -> data-offset + +-------------------+<----------------+--------------------------------+= GenFfs +--------------------------------+ GenSec +----------------------= ----------+ tianocore -> reloc-start +--------------------------+ + | | | EDK2 FFS Header |= <--------| EDK2 SEC Header |<--------| FIT Header = |<-------------------------| UniversalPayload.pecoff | + | | +--------------------------------+= +--------------------------------+ | description =3D "Uefi= Payload"; | +--------------------------+ + | | | EDK2 SEC Header |= | FIT Header | | ... = | + | RAW Data | +--------------------------------+= | | | images { = | uefi-fv -> data-offset +--------------------------+ + | | | FIT Header |= | | | tianocore {...}; = |<-------------------------| uefi_fv | + | | | |= +--------------------------------+ | uefi-fv {...}; = | bds-fv -> data-offset +--------------------------+ + | | | |= | tianocore -> data | | bds-fv {...}; = |<-------------------------| bds_fv | + | | +--------------------------------+= +--------------------------------+ | afp1-fv {...}; = | AFP1 -> data-offset +--------------------------+ + | | | tianocore -> data |= | tianocore -> reloc-start | | ... = |<-------------------------| AFP1 | + | | +--------------------------------+= +--------------------------------+ | afpn-fv {...}; = | AFP2 -> data-offset +--------------------------+ + | | | tianocore -> reloc-start |= | uefi-fv -> data | | } = |<-------------------------| AFP2 | + | | +--------------------------------+= +--------------------------------+ | configurations { = | ... +--------------------------+ + | | | uefi-fv -> data |= | bds-fv -> data | | conf-1 {...} = |<-------------------------| ... | + | | +--------------------------------+= +--------------------------------+ | } = | AFPn -> data-offset +--------------------------+ + | | | bds-fv -> data |= | AFP1-fv -> data | | = |<-------------------------| AFPn | + | | +--------------------------------+= +--------------------------------+ | = | +--------------------------+ + | | | AFP1-fv -> data |= | AFP2-fv -> data | | = | + | | +--------------------------------+= +--------------------------------+ +----------------------= ----------+ + | | | AFP2-fv -> data |= | ... | | tianocore -> data = | + | | +--------------------------------+= +--------------------------------+ +----------------------= ----------+ + | | | ... |= | AFPn-fv -> data | | tianocore -> reloc-st= art | + | | +--------------------------------+= +--------------------------------+ +----------------------= ----------+ + | | | AFPn-fv -> data |= | uefi-fv -> data = | + +-------------------+<----------------+--------------------------------+= +----------------------= ----------+ + | ... | = | bds-fv -> data = | + +-------------------+ = +----------------------= ----------+ + | Other Firmware | = | AFP1-fv -> data = | + +-------------------+ = +----------------------= ----------+ + = | AFP2-fv -> data = | + = +----------------------= ----------+ + = | ... = | + = +----------------------= ----------+ + = | AFPn-fv -> data = | + = +----------------------= ----------+ + + ``` diff --git a/UefiPayloadPkg/Tools/MkFitImage.py b/UefiPayloadPkg/Tools/MkFi= tImage.py new file mode 100644 index 0000000000..82ab933d6d --- /dev/null +++ b/UefiPayloadPkg/Tools/MkFitImage.py @@ -0,0 +1,272 @@ +## @file +# This file is a script to build fit image. +# It generate a dtb header and combine a binary file after this header. +# +# Copyright (c) 2023, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +from os.path import exists +import libfdt +from ctypes import * +import time + +class FIT_IMAGE_INFO_HEADER: + """Class for user setting data to use MakeFitImage() + """ + _pack_ =3D 1 + _fields_ =3D [ + ('Compatible', str), + ('UplVersion', int), + ('Description', str), + ('Type', str), + ('Arch', str), + ('Compression', str), + ('Revision', int), + ('BuildType', str), + ('Capabilities', str), + ('Producer', str), + ('ImageId', str), + ('DataOffset', int), + ('DataSize', int), + ('RelocStart', int), + ('LoadAddr', int), + ('Entry', int), + ('Binary', str), + ('TargetPath', str), + ('UefifvPath', str), + ('BdsfvPath', str), + ('NetworkfvPath', str), + ('Project', str), + ] + + def __init__(self): + self.Compatible =3D 'universal-payload' + self.UplVersion =3D 0x0100 + self.TargetPath =3D 'mkimage.fit' + +def CreatFdt(Fdt): + FdtEmptyTree =3D libfdt.fdt_create_empty_tree(Fdt, len(Fdt)) + if FdtEmptyTree !=3D 0: + print('\n- Failed - Create Fdt failed!') + return False + return True + +def BuildConfNode(Fdt, ParentNode, MultiImage): + ConfNode1 =3D libfdt.fdt_add_subnode(Fdt, ParentNode, 'conf-1') + + libfdt.fdt_setprop(Fdt, ConfNode1, 'require-fit', b'', 0) + libfdt.fdt_setprop(Fdt, ConfNode1, 'firmware', bytes('tianocore', 'utf= -8'), len('tianocore') + 1) + +def BuildFvImageNode(Fdt, InfoHeader, ParentNode, DataOffset, DataSize, De= scription): + libfdt.fdt_setprop_u32(Fdt, ParentNode, 'data-size', DataSize) + libfdt.fdt_setprop_u32(Fdt, ParentNode, 'data-offset', DataOffset) + libfdt.fdt_setprop(Fdt, ParentNode, 'compression', bytes('none', = 'utf-8'), len('none') + 1) + libfdt.fdt_setprop(Fdt, ParentNode, 'project ', bytes('tianocore', = 'utf-8'), len('tianocore') + 1) + libfdt.fdt_setprop(Fdt, ParentNode, 'arch', bytes('x86_64', = 'utf-8'), len('x86_64') + 1) + libfdt.fdt_setprop(Fdt, ParentNode, 'type', bytes('flat-binary'= , 'utf-8'), len('flat-binary') + 1) + libfdt.fdt_setprop(Fdt, ParentNode, 'description', bytes(Description, = 'utf-8'), len(Description) + 1) + +def BuildTianoImageNode(Fdt, InfoHeader, ParentNode, DataOffset, DataSize,= Description): + # + # Set 'load' and 'data-offset' to reserve the memory first. + # They would be set again when Fdt completes or this function parses t= arget binary file. + # + if InfoHeader.LoadAddr is not None: + libfdt.fdt_setprop_u64(Fdt, ParentNode, 'load', InfoHeader.LoadAdd= r) + if InfoHeader.Entry is not None: + libfdt.fdt_setprop_u64(Fdt, ParentNode, 'entry-start', InfoHeader.= Entry) + if InfoHeader.RelocStart is not None: + libfdt.fdt_setprop_u32(Fdt, ParentNode, 'reloc-start', InfoHeader.= RelocStart) + if InfoHeader.DataSize is not None: + libfdt.fdt_setprop_u32(Fdt, ParentNode, 'data-size', DataSize) + if InfoHeader.DataOffset is not None: + libfdt.fdt_setprop_u32(Fdt, ParentNode, 'data-offset', DataOffset) + if InfoHeader.Producer is not None: + libfdt.fdt_setprop(Fdt, ParentNode, 'producer ', bytes(InfoHeader.= Producer, 'utf-8'), len(InfoHeader.Producer) + 1) + if InfoHeader.Capabilities is not None: + CapStrs =3D ','.join(InfoHeader.Capabilities) + libfdt.fdt_setprop(Fdt, ParentNode, 'capabilities ', bytes(CapStrs= , 'utf-8'), len(CapStrs) + 1) + if InfoHeader.Type is not None: + libfdt.fdt_setprop(Fdt, ParentNode, 'type ', bytes(InfoHeader.Type= , 'utf-8'), len(InfoHeader.Type) + 1) + if InfoHeader.Arch is not None: + libfdt.fdt_setprop(Fdt, ParentNode, 'arch ', bytes(InfoHeader.Arch= , 'utf-8'), len(InfoHeader.Arch) + 1) + if InfoHeader.Project is not None: + libfdt.fdt_setprop(Fdt, ParentNode, 'project ', bytes(InfoHeader.P= roject, 'utf-8'), len(InfoHeader.Project) + 1) + if InfoHeader.Description is not None: + libfdt.fdt_setprop(Fdt, ParentNode, 'description', bytes(Descripti= on, 'utf-8'), len(Description) + 1) + +# +# The subnode would be inserted from bottom to top of structure block. +# +def BuildFitImage(Fdt, InfoHeader): + MultiImage =3D [ + ["tianocore", InfoHeader.Binary, BuildTianoImageNode , In= foHeader.Description, None, 0 ], + ["uefi-fv", InfoHeader.UefifvPath, BuildFvImageNode, "U= EFI Firmware Volume", None, 0 ], + ["bds-fv", InfoHeader.BdsfvPath, BuildFvImageNode , "B= DS Firmware Volume", None, 0 ], + ["network-fv", InfoHeader.NetworkfvPath, BuildFvImageNode , "N= etwork Firmware Volume", None, 0 ], + ] + + # + # Set basic information + # + libfdt.fdt_setprop_u32(Fdt, 0, 'build-revision ', InfoHeader.Revision) + libfdt.fdt_setprop_u32(Fdt, 0, 'spec-version', InfoHeader.UplVersion) + + # + # Build configurations node + # + ConfNode =3D libfdt.fdt_add_subnode(Fdt, 0, 'configurations') + BuildConfNode(Fdt, ConfNode, MultiImage) + + # Build image + DataOffset =3D InfoHeader.DataOffset + for Index in range (0, len (MultiImage)): + _, Path, _, _, _, _ =3D MultiImage[Index] + if exists(Path) =3D=3D 1: + TempBinary =3D open(Path, 'rb') + BinaryData =3D TempBinary.read() + TempBinary.close() + MultiImage[Index][-2] =3D BinaryData + MultiImage[Index][-1] =3D DataOffset + DataOffset +=3D len (BinaryData) + libfdt.fdt_setprop_u32(Fdt, 0, 'size', DataOffset) + posix_time =3D int(time.time()) + libfdt.fdt_setprop_u32(Fdt, 0, 'timestamp', posix_time) + DescriptionFit =3D 'Uefi OS Loader' + libfdt.fdt_setprop(Fdt, 0, 'description', bytes(DescriptionFit, 'utf-8= '), len(DescriptionFit) + 1) + + ImageNode =3D libfdt.fdt_add_subnode(Fdt, 0, 'images') + for Item in reversed (MultiImage): + Name, Path, BuildFvNode, Description, BinaryData, DataOffset =3D I= tem + FvNode =3D libfdt.fdt_add_subnode(Fdt, ImageNode, Name) + BuildFvNode (Fdt, InfoHeader, FvNode, DataOffset, len(BinaryData),= Description) + + # + # Create new image file and combine all binary. + # + DtbFile =3D open(InfoHeader.TargetPath, "wb") + DtbFile.truncate() + DtbFile.write(Fdt) + for Item in MultiImage: + _, _, _, _, BinaryData, _ =3D Item + DtbFile.write(BinaryData) + DtbFile.close() + + return True + +def MakeFitImage(InfoHeader): + # + # Allocate fdt byte array. + # + Fdt =3D bytearray(InfoHeader.DataOffset) + + # + # Create fdt empty tree. + # + if CreatFdt(Fdt) is False: + return False + + # + # Parse args to build fit image. + # + return BuildFitImage(Fdt, InfoHeader) + +def ReplaceFv (UplBinary, SectionFvFile, SectionName): + try: + # + # Get Original Multi Fv + # + with open (UplBinary, "rb") as File: + Dtb =3D File.read () + Fit =3D libfdt.Fdt (Dtb) + NewFitHeader =3D bytearray(Dtb[0:Fit.totalsize()]) + FitSize =3D len(Dtb) + + LoadablesList =3D [] + ImagesNode =3D libfdt.fdt_subnode_offset(NewFitHeader, 0, 'imag= es') + FvNode =3D libfdt.fdt_subnode_offset(NewFitHeader, ImagesNo= de, 'uefi-fv') + NodeDepth =3D libfdt.fdt_node_depth (NewFitHeader, ImagesNode) + node_name =3D libfdt.fdt_get_name(NewFitHeader, FvNode) + FvNode =3D libfdt.fdt_next_node(NewFitHeader, FvNode, NodeD= epth) + + while node_name[0][-2:] =3D=3D 'fv': + LoadablesList.append (node_name[0]) + node_name =3D libfdt.fdt_get_name(NewFitHeader, FvNode[0]) + FvNode =3D libfdt.fdt_next_node(NewFitHeader, FvNode[0], NodeD= epth) + # + # Get current Fit Binary FV data + # + MultiFvList =3D [] + for Item in LoadablesList: + ImageNode =3D libfdt.fdt_subnode_offset(NewFitHeader, Image= sNode, Item) + ImageOffset =3D int.from_bytes (libfdt.fdt_getprop (NewFitHea= der, ImageNode, 'data-offset')[0], 'big') + ImageSize =3D int.from_bytes (libfdt.fdt_getprop (NewFitHea= der, ImageNode, 'data-size')[0], 'big') + MultiFvList.append ([Item, Dtb[ImageOffset:ImageOffset + Image= Size]]) + + IsFvExist =3D False + for Index in range (0, len (MultiFvList)): + if MultiFvList[Index][0] =3D=3D SectionName: + with open (SectionFvFile, 'rb') as File: + MultiFvList[Index][1] =3D File.read () + ImageNode =3D libfdt.fdt_subnode_offset(NewFitHeader, = ImagesNode, SectionName) + ImageSize =3D int.from_bytes (libfdt.fdt_getprop (NewF= itHeader, ImageNode, 'data-size')[0], 'big') + ReplaceOffset =3D int.from_bytes (libfdt.fdt_getprop (NewF= itHeader, ImageNode, 'data-offset')[0], 'big') + OffsetDelta =3D len(MultiFvList[Index][1]) - ImageSize + FitSize +=3D OffsetDelta + IsFvExist =3D True + libfdt.fdt_setprop_u32(NewFitHeader, ImageNode, 'data-size= ', len(MultiFvList[Index][1])) + + # + # Update new fit header + # + ImagesNode =3D libfdt.fdt_subnode_offset(NewFitHeader, 0, 'images') + if (IsFvExist =3D=3D False): + with open (SectionFvFile, 'rb') as File: + SectionFvFileBinary =3D File.read () + MultiFvList.append ([SectionName, SectionFvFileBinary]) + FvNode =3D libfdt.fdt_add_subnode(NewFitHeader, ImagesNode, Se= ctionName) + BuildFvImageNode (NewFitHeader, None, FvNode, FitSize, len(Sec= tionFvFileBinary), SectionName + " Firmware Volume") + FitSize +=3D len(SectionFvFileBinary) + else: + for Index in range (0, len (MultiFvList)): + ImageNode =3D libfdt.fdt_subnode_offset(NewFitHeader, I= magesNode, MultiFvList[Index][0]) + ImageOffset =3D int.from_bytes (libfdt.fdt_getprop (NewFi= tHeader, ImageNode, 'data-offset')[0], 'big') + if ImageOffset > ReplaceOffset: + libfdt.fdt_setprop_u32(NewFitHeader, ImageNode, 'data-= offset', ImageOffset + OffsetDelta) + + ConfNodes =3D libfdt.fdt_subnode_offset(NewFitHeader, 0, 'conf= igurations') + libfdt.fdt_setprop(NewFitHeader, ConfNodes, 'default ', bytes('con= f-1', 'utf-8'), len('conf-1') + 1) + ConfNode =3D libfdt.fdt_subnode_offset(NewFitHeader, ConfNode= s, 'conf-1') + + libfdt.fdt_setprop_u32(NewFitHeader, 0, 'size', FitSize) + + # + # Generate new fit image + # + ImagesNode =3D libfdt.fdt_subnode_offset(NewFitHeader, 0, 'imag= es') + TianoNode =3D libfdt.fdt_subnode_offset(NewFitHeader, ImagesNo= de, 'tianocore') + TianoOffset =3D int.from_bytes (libfdt.fdt_getprop (NewFitHeader= , TianoNode, 'data-offset')[0], 'big') + TianoSize =3D int.from_bytes (libfdt.fdt_getprop (NewFitHeader= , TianoNode, 'data-size')[0], 'big') + TianoBinary =3D Dtb[TianoOffset:TianoOffset + TianoSize] + + print("\nGenerate new fit image:") + NewUplBinary =3D bytearray(FitSize) + print("Update fit header\t to 0x0\t\t ~ " + str(hex(len(NewFitHead= er)))) + NewUplBinary[:len(NewFitHeader)] =3D NewFitHeader + print("Update tiano image\t to " + str(hex(len(NewFitHeader))) + "= \t ~ " + str(hex(len(NewFitHeader) + len(TianoBinary)))) + NewUplBinary[len(NewFitHeader):len(NewFitHeader) + len(TianoBinary= )] =3D TianoBinary + for Index in range (0, len (MultiFvList)): + ImageNode =3D libfdt.fdt_subnode_offset(NewFitHeader, Images= Node, MultiFvList[Index][0]) + ImageOffset =3D int.from_bytes (libfdt.fdt_getprop (NewFitHead= er, ImageNode, 'data-offset')[0], 'big') + ImageSize =3D int.from_bytes (libfdt.fdt_getprop (NewFitHead= er, ImageNode, 'data-size')[0], 'big') + NewUplBinary[ImageOffset:ImageOffset + ImageSize] =3D MultiFvL= ist[Index][1] + print("Update " + MultiFvList[Index][0] + "\t\t to " + str(hex= (ImageOffset)) + "\t ~ " + str(hex(ImageOffset + ImageSize))) + + with open (UplBinary, "wb") as File: + File.write (NewUplBinary) + + return 0 + except Exception as Ex: + print(Ex) + return 1 diff --git a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c b/U= efiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c new file mode 100644 index 0000000000..ad04ad7eb9 --- /dev/null +++ b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c @@ -0,0 +1,654 @@ +/** @file + Copyright (c) 2023, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "UefiPayloadEntry.h" +#include +#include + +#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT = | \ + EFI_RESOURCE_ATTRIBUTE_INITIALIZED = | \ + EFI_RESOURCE_ATTRIBUTE_TESTED = | \ + EFI_RESOURCE_ATTRIBUTE_READ_PROTECT= ED | \ + EFI_RESOURCE_ATTRIBUTE_WRITE_PROTEC= TED | \ + EFI_RESOURCE_ATTRIBUTE_EXECUTION_PR= OTECTED | \ + EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PR= OTECTED | \ + EFI_RESOURCE_ATTRIBUTE_16_BIT_IO = | \ + EFI_RESOURCE_ATTRIBUTE_32_BIT_IO = | \ + EFI_RESOURCE_ATTRIBUTE_64_BIT_IO = | \ + EFI_RESOURCE_ATTRIBUTE_PERSISTENT = ) + +#define TESTED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | = \ + EFI_RESOURCE_ATTRIBUTE_INITIALIZED = | \ + EFI_RESOURCE_ATTRIBUTE_TESTED ) + +extern VOID *mHobList; + +CHAR8 *mLineBuffer =3D NULL; + +/** + Print all HOBs info from the HOB list. + @return The pointer to the HOB list. +**/ +VOID +PrintHob ( + IN CONST VOID *HobStart + ); + +/** + Find the first substring. + @param String Point to the string where to find the substring. + @param CharSet Point to the string to be found. +**/ +UINTN +EFIAPI +AsciiStrSpn ( + IN CHAR8 *String, + IN CHAR8 *CharSet + ) +{ + UINTN Count; + CHAR8 *Str1; + CHAR8 *Str2; + + Count =3D 0; + + for (Str1 =3D String; *Str1 !=3D L'\0'; Str1++) { + for (Str2 =3D CharSet; *Str2 !=3D L'\0'; Str2++) { + if (*Str1 =3D=3D *Str2) { + break; + } + } + + if (*Str2 =3D=3D L'\0') { + return Count; + } + + Count++; + } + + return Count; +} + +/** + Searches a string for the first occurrence of a character contained in a + specified buffer. + @param String Point to the string where to find the substring. + @param CharSet Point to the string to be found. +**/ +CHAR8 * +EFIAPI +AsciiStrBrk ( + IN CHAR8 *String, + IN CHAR8 *CharSet + ) +{ + CHAR8 *Str1; + CHAR8 *Str2; + + for (Str1 =3D String; *Str1 !=3D L'\0'; Str1++) { + for (Str2 =3D CharSet; *Str2 !=3D L'\0'; Str2++) { + if (*Str1 =3D=3D *Str2) { + return (CHAR8 *)Str1; + } + } + } + + return NULL; +} + +/** + Find the next token after one or more specified characters. + @param String Point to the string where to find the substring. + @param CharSet Point to the string to be found. +**/ +CHAR8 * +EFIAPI +AsciiStrTokenLine ( + IN CHAR8 *String OPTIONAL, + IN CHAR8 *CharSet + ) +{ + CHAR8 *Begin; + CHAR8 *End; + + Begin =3D (String =3D=3D NULL) ? mLineBuffer : String; + if (Begin =3D=3D NULL) { + return NULL; + } + + Begin +=3D AsciiStrSpn (Begin, CharSet); + if (*Begin =3D=3D L'\0') { + mLineBuffer =3D NULL; + return NULL; + } + + End =3D AsciiStrBrk (Begin, CharSet); + if ((End !=3D NULL) && (*End !=3D L'\0')) { + *End =3D L'\0'; + End++; + } + + mLineBuffer =3D End; + return Begin; +} + +/** + Some bootloader may pass a pcd database, and UPL also contain a PCD data= base. + Dxe PCD driver has the assumption that the two PCD database can be caten= ated and + the local token number should be successive. + This function will fix up the UPL PCD database to meet that assumption. + @param[in] DxeFv The FV where to find the Universal PCD databa= se. + @retval EFI_SUCCESS If it completed successfully. + @retval other Failed to fix up. +**/ +EFI_STATUS +FixUpPcdDatabase ( + IN EFI_FIRMWARE_VOLUME_HEADER *DxeFv + ) +{ + EFI_STATUS Status; + EFI_FFS_FILE_HEADER *FileHeader; + VOID *PcdRawData; + PEI_PCD_DATABASE *PeiDatabase; + PEI_PCD_DATABASE *UplDatabase; + EFI_HOB_GUID_TYPE *GuidHob; + DYNAMICEX_MAPPING *ExMapTable; + UINTN Index; + + GuidHob =3D GetFirstGuidHob (&gPcdDataBaseHobGuid); + if (GuidHob =3D=3D NULL) { + // + // No fix-up is needed. + // + return EFI_SUCCESS; + } + + PeiDatabase =3D (PEI_PCD_DATABASE *)GET_GUID_HOB_DATA (GuidHob); + DEBUG ((DEBUG_INFO, "Find the Pei PCD data base, the total local token n= umber is %d\n", PeiDatabase->LocalTokenCount)); + + Status =3D FvFindFileByTypeGuid (DxeFv, EFI_FV_FILETYPE_DRIVER, PcdGetPt= r (PcdPcdDriverFile), &FileHeader); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D FileFindSection (FileHeader, EFI_SECTION_RAW, &PcdRawData); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + + UplDatabase =3D (PEI_PCD_DATABASE *)PcdRawData; + ExMapTable =3D (DYNAMICEX_MAPPING *)(UINTN)((UINTN)PcdRawData + UplData= base->ExMapTableOffset); + + for (Index =3D 0; Index < UplDatabase->ExTokenCount; Index++) { + ExMapTable[Index].TokenNumber +=3D PeiDatabase->LocalTokenCount; + } + + DEBUG ((DEBUG_INFO, "Fix up UPL PCD database successfully\n")); + return EFI_SUCCESS; +} + +/** + Add HOB into HOB list + @param[in] Hob The HOB to be added into the HOB list. +**/ +VOID +AddNewHob ( + IN EFI_PEI_HOB_POINTERS *Hob + ) +{ + EFI_PEI_HOB_POINTERS NewHob; + + if (Hob->Raw =3D=3D NULL) { + return; + } + + NewHob.Header =3D CreateHob (Hob->Header->HobType, Hob->Header->HobLengt= h); + + if (NewHob.Header !=3D NULL) { + CopyMem (NewHob.Header + 1, Hob->Header + 1, Hob->Header->HobLength - = sizeof (EFI_HOB_GENERIC_HEADER)); + } +} + +/** + Found the Resource Descriptor HOB that contains a range (Base, Top) + @param[in] HobList Hob start address + @param[in] Base Memory start address + @param[in] Top Memory end address. + @retval The pointer to the Resource Descriptor HOB. +**/ +EFI_HOB_RESOURCE_DESCRIPTOR * +FindResourceDescriptorByRange ( + IN VOID *HobList, + IN EFI_PHYSICAL_ADDRESS Base, + IN EFI_PHYSICAL_ADDRESS Top + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; + + for (Hob.Raw =3D (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw =3D G= ET_NEXT_HOB (Hob)) { + // + // Skip all HOBs except Resource Descriptor HOBs + // + if (GET_HOB_TYPE (Hob) !=3D EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + continue; + } + + // + // Skip Resource Descriptor HOBs that do not describe tested system me= mory + // + ResourceHob =3D Hob.ResourceDescriptor; + if (ResourceHob->ResourceType !=3D EFI_RESOURCE_SYSTEM_MEMORY) { + continue; + } + + if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) !=3D TEST= ED_MEMORY_ATTRIBUTES) { + continue; + } + + // + // Skip Resource Descriptor HOBs that do not contain the PHIT range Ef= iFreeMemoryBottom..EfiFreeMemoryTop + // + if (Base < ResourceHob->PhysicalStart) { + continue; + } + + if (Top > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) { + continue; + } + + return ResourceHob; + } + + return NULL; +} + +/** + Find the highest below 4G memory resource descriptor, except the input R= esource Descriptor. + @param[in] HobList Hob start address + @param[in] MinimalNeededSize Minimal needed size. + @param[in] ExceptResourceHob Ignore this Resource Descriptor. + @retval The pointer to the Resource Descriptor HOB. +**/ +EFI_HOB_RESOURCE_DESCRIPTOR * +FindAnotherHighestBelow4GResourceDescriptor ( + IN VOID *HobList, + IN UINTN MinimalNeededSize, + IN EFI_HOB_RESOURCE_DESCRIPTOR *ExceptResourceHob + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; + EFI_HOB_RESOURCE_DESCRIPTOR *ReturnResourceHob; + + ReturnResourceHob =3D NULL; + + for (Hob.Raw =3D (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw =3D G= ET_NEXT_HOB (Hob)) { + // + // Skip all HOBs except Resource Descriptor HOBs + // + if (GET_HOB_TYPE (Hob) !=3D EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + continue; + } + + // + // Skip Resource Descriptor HOBs that do not describe tested system me= mory + // + ResourceHob =3D Hob.ResourceDescriptor; + if (ResourceHob->ResourceType !=3D EFI_RESOURCE_SYSTEM_MEMORY) { + continue; + } + + if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) !=3D TEST= ED_MEMORY_ATTRIBUTES) { + continue; + } + + // + // Skip if the Resource Descriptor HOB equals to ExceptResourceHob + // + if (ResourceHob =3D=3D ExceptResourceHob) { + continue; + } + + // + // Skip Resource Descriptor HOBs that are beyond 4G + // + if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > BASE_= 4GB) { + continue; + } + + // + // Skip Resource Descriptor HOBs that are too small + // + if (ResourceHob->ResourceLength < MinimalNeededSize) { + continue; + } + + // + // Return the topest Resource Descriptor + // + if (ReturnResourceHob =3D=3D NULL) { + ReturnResourceHob =3D ResourceHob; + } else { + if (ReturnResourceHob->PhysicalStart < ResourceHob->PhysicalStart) { + ReturnResourceHob =3D ResourceHob; + } + } + } + + return ReturnResourceHob; +} + +/** + Check the HOB and decide if it is need inside Payload + Payload maintainer may make decision which HOB is need or needn't + Then add the check logic in the function. + @param[in] Hob The HOB to check + @retval TRUE If HOB is need inside Payload + @retval FALSE If HOB is needn't inside Payload +**/ +BOOLEAN +IsHobNeed ( + EFI_PEI_HOB_POINTERS Hob + ) +{ + if (Hob.Header->HobType =3D=3D EFI_HOB_TYPE_HANDOFF) { + return FALSE; + } + + if (Hob.Header->HobType =3D=3D EFI_HOB_TYPE_MEMORY_ALLOCATION) { + if (CompareGuid (&Hob.MemoryAllocationModule->MemoryAllocationHeader.N= ame, &gEfiHobMemoryAllocModuleGuid)) { + return FALSE; + } + } + + // Arrive here mean the HOB is need + return TRUE; +} + +/** + It will build Fv HOBs based on information from bootloaders. + @param[out] DxeFv The pointer to the DXE FV in memory. + @retval EFI_SUCCESS If it completed successfully. + @retval EFI_NOT_FOUND If it failed to find node in fit image. + @retval Others If it failed to build required HOBs. +**/ +EFI_STATUS +BuildFitLoadablesFvHob ( + OUT EFI_FIRMWARE_VOLUME_HEADER **DxeFv + ) +{ + EFI_STATUS Status; + VOID *Fdt; + UINT8 *GuidHob; + UNIVERSAL_PAYLOAD_BASE *PayloadBase; + INT32 ConfigNode; + INT32 Config1Node; + INT32 ImageNode; + INT32 FvNode; + INT32 Depth; + CONST FDT_PROPERTY *PropertyPtr; + INT32 TempLen; + CONST CHAR8 *Fvname; + UINT32 DataOffset; + UINT32 DataSize; + UINT32 *Data32; + + GuidHob =3D GetFirstGuidHob (&gUniversalPayloadBaseGuid); + if (GuidHob !=3D NULL) { + PayloadBase =3D (UNIVERSAL_PAYLOAD_BASE *)GET_GUID_HOB_DATA (GuidHob); + Fdt =3D (VOID *)(UINTN)PayloadBase->Entry; + DEBUG ((DEBUG_INFO, "PayloadBase Entry =3D 0x%08x\n", PayloadBase->Ent= ry)); + } + + Status =3D FdtCheckHeader (Fdt); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + ConfigNode =3D FdtSubnodeOffsetNameLen (Fdt, 0, "configurations", (INT32= )AsciiStrLen ("configurations")); + if (ConfigNode <=3D 0) { + return EFI_NOT_FOUND; + } + + Config1Node =3D FdtSubnodeOffsetNameLen (Fdt, ConfigNode, "conf-1", (INT= 32)AsciiStrLen ("conf-1")); + if (Config1Node <=3D 0) { + return EFI_NOT_FOUND; + } + + ImageNode =3D FdtSubnodeOffsetNameLen (Fdt, 0, "images", (INT32)AsciiStr= Len ("images")); + if (ImageNode <=3D 0) { + return EFI_NOT_FOUND; + } + + FvNode =3D FdtSubnodeOffsetNameLen (Fdt, ImageNode, "tianocore", (INT32)= AsciiStrLen ("tianocore")); + Depth =3D FdtNodeDepth (Fdt, FvNode); + FvNode =3D FdtNextNode (Fdt, FvNode, &Depth); + Fvname =3D FdtGetName (Fdt, FvNode, &TempLen); + while ((AsciiStrCmp ((Fvname + AsciiStrLen (Fvname) - 2), "fv") =3D=3D 0= )) { + if (FvNode <=3D 0) { + return EFI_NOT_FOUND; + } + + PropertyPtr =3D FdtGetProperty (Fdt, FvNode, "data-offset", &TempLen); + Data32 =3D (UINT32 *)(PropertyPtr->Data); + DataOffset =3D SwapBytes32 (*Data32); + + PropertyPtr =3D FdtGetProperty (Fdt, FvNode, "data-size", &TempLen); + Data32 =3D (UINT32 *)(PropertyPtr->Data); + DataSize =3D SwapBytes32 (*Data32); + + if (AsciiStrCmp (Fvname, "uefi-fv") =3D=3D 0) { + *DxeFv =3D (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)PayloadBase->Entry = + (UINTN)DataOffset); + ASSERT ((*DxeFv)->FvLength =3D=3D DataSize); + } else { + BuildFvHob (((UINTN)PayloadBase->Entry + (UINTN)DataOffset), DataSiz= e); + } + + DEBUG (( + DEBUG_INFO, + "UPL Multiple fv[%a], Base=3D0x%08x, size=3D0x%08x\n", + Fvname, + ((UINTN)PayloadBase->Entry + (UINTN)DataOffset), + DataSize, + DataOffset + )); + Depth =3D FdtNodeDepth (Fdt, FvNode); + FvNode =3D FdtNextNode (Fdt, FvNode, &Depth); + Fvname =3D FdtGetName (Fdt, FvNode, &TempLen); + } + + return EFI_SUCCESS; +} + +/** + It will build HOBs based on information from bootloaders. + @param[in] BootloaderParameter The starting memory address of bootloa= der parameter block. + @param[out] DxeFv The pointer to the DXE FV in memory. + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to build required HOBs. +**/ +EFI_STATUS +BuildHobs ( + IN UINTN BootloaderParameter, + OUT EFI_FIRMWARE_VOLUME_HEADER **DxeFv + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINTN MinimalNeededSize; + EFI_PHYSICAL_ADDRESS FreeMemoryBottom; + EFI_PHYSICAL_ADDRESS FreeMemoryTop; + EFI_PHYSICAL_ADDRESS MemoryBottom; + EFI_PHYSICAL_ADDRESS MemoryTop; + EFI_HOB_RESOURCE_DESCRIPTOR *PhitResourceHob; + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; + UINT8 *GuidHob; + EFI_HOB_FIRMWARE_VOLUME *FvHob; + UNIVERSAL_PAYLOAD_ACPI_TABLE *AcpiTable; + ACPI_BOARD_INFO *AcpiBoardInfo; + EFI_HOB_HANDOFF_INFO_TABLE *HobInfo; + + Hob.Raw =3D (UINT8 *)BootloaderParameter; + MinimalNeededSize =3D FixedPcdGet32 (PcdSystemMemoryUefiRegionSize); + + ASSERT (Hob.Raw !=3D NULL); + ASSERT ((UINTN)Hob.HandoffInformationTable->EfiFreeMemoryTop =3D=3D Hob.= HandoffInformationTable->EfiFreeMemoryTop); + ASSERT ((UINTN)Hob.HandoffInformationTable->EfiMemoryTop =3D=3D Hob.Hand= offInformationTable->EfiMemoryTop); + ASSERT ((UINTN)Hob.HandoffInformationTable->EfiFreeMemoryBottom =3D=3D H= ob.HandoffInformationTable->EfiFreeMemoryBottom); + ASSERT ((UINTN)Hob.HandoffInformationTable->EfiMemoryBottom =3D=3D Hob.H= andoffInformationTable->EfiMemoryBottom); + + // + // Try to find Resource Descriptor HOB that contains Hob range EfiMemory= Bottom..EfiMemoryTop + // + PhitResourceHob =3D FindResourceDescriptorByRange (Hob.Raw, Hob.HandoffI= nformationTable->EfiMemoryBottom, Hob.HandoffInformationTable->EfiMemoryTop= ); + if (PhitResourceHob =3D=3D NULL) { + // + // Boot loader's Phit Hob is not in an available Resource Descriptor, = find another Resource Descriptor for new Phit Hob + // + ResourceHob =3D FindAnotherHighestBelow4GResourceDescriptor (Hob.Raw, = MinimalNeededSize, NULL); + if (ResourceHob =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + MemoryBottom =3D ResourceHob->PhysicalStart + ResourceHob->Resourc= eLength - MinimalNeededSize; + FreeMemoryBottom =3D MemoryBottom; + FreeMemoryTop =3D ResourceHob->PhysicalStart + ResourceHob->Resourc= eLength; + MemoryTop =3D FreeMemoryTop; + } else if (PhitResourceHob->PhysicalStart + PhitResourceHob->ResourceLen= gth - Hob.HandoffInformationTable->EfiMemoryTop >=3D MinimalNeededSize) { + // + // New availiable Memory range in new hob is right above memory top in= old hob. + // + MemoryBottom =3D Hob.HandoffInformationTable->EfiFreeMemoryTop; + FreeMemoryBottom =3D Hob.HandoffInformationTable->EfiMemoryTop; + FreeMemoryTop =3D FreeMemoryBottom + MinimalNeededSize; + MemoryTop =3D FreeMemoryTop; + } else if (Hob.HandoffInformationTable->EfiMemoryBottom - PhitResourceHo= b->PhysicalStart >=3D MinimalNeededSize) { + // + // New availiable Memory range in new hob is right below memory bottom= in old hob. + // + MemoryBottom =3D Hob.HandoffInformationTable->EfiMemoryBottom - Mi= nimalNeededSize; + FreeMemoryBottom =3D MemoryBottom; + FreeMemoryTop =3D Hob.HandoffInformationTable->EfiMemoryBottom; + MemoryTop =3D Hob.HandoffInformationTable->EfiMemoryTop; + } else { + // + // In the Resource Descriptor HOB contains boot loader Hob, there is n= o enough free memory size for payload hob + // Find another Resource Descriptor Hob + // + ResourceHob =3D FindAnotherHighestBelow4GResourceDescriptor (Hob.Raw, = MinimalNeededSize, PhitResourceHob); + if (ResourceHob =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + MemoryBottom =3D ResourceHob->PhysicalStart + ResourceHob->Resourc= eLength - MinimalNeededSize; + FreeMemoryBottom =3D MemoryBottom; + FreeMemoryTop =3D ResourceHob->PhysicalStart + ResourceHob->Resourc= eLength; + MemoryTop =3D FreeMemoryTop; + } + + HobInfo =3D HobConstructor ((VOID *)(UINTN)MemoryBottom, (VOID= *)(UINTN)MemoryTop, (VOID *)(UINTN)FreeMemoryBottom, (VOID *)(UINTN)FreeMe= moryTop); + HobInfo->BootMode =3D Hob.HandoffInformationTable->BootMode; + // + // From now on, mHobList will point to the new Hob range. + // + + // + // Create an empty FvHob for the DXE FV that contains DXE core. + // + BuildFvHob ((EFI_PHYSICAL_ADDRESS)0, 0); + // + // Since payload created new Hob, move all hobs except PHIT from boot lo= ader hob list. + // + while (!END_OF_HOB_LIST (Hob)) { + if (IsHobNeed (Hob)) { + // Add this hob to payload HOB + AddNewHob (&Hob); + } + + Hob.Raw =3D GET_NEXT_HOB (Hob); + } + + BuildFitLoadablesFvHob (DxeFv); + + // + // Create guid hob for acpi board information + // + GuidHob =3D GetFirstGuidHob (&gUniversalPayloadAcpiTableGuid); + if (GuidHob !=3D NULL) { + AcpiTable =3D (UNIVERSAL_PAYLOAD_ACPI_TABLE *)GET_GUID_HOB_DATA (GuidH= ob); + GuidHob =3D GetFirstGuidHob (&gUefiAcpiBoardInfoGuid); + if (GuidHob =3D=3D NULL) { + AcpiBoardInfo =3D BuildHobFromAcpi ((UINT64)AcpiTable->Rsdp); + ASSERT (AcpiBoardInfo !=3D NULL); + } + } + + // + // Update DXE FV information to first fv hob in the hob list, which + // is the empty FvHob created before. + // + FvHob =3D GetFirstHob (EFI_HOB_TYPE_FV); + FvHob->BaseAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)*DxeFv; + FvHob->Length =3D (*DxeFv)->FvLength; + return EFI_SUCCESS; +} + +/** + Entry point to the C language phase of UEFI payload. + @param[in] BootloaderParameter The starting address of bootloader p= arameter block. + @retval It will not return if SUCCESS, and return error when passin= g bootloader parameter. +**/ +EFI_STATUS +EFIAPI +_ModuleEntryPoint ( + IN UINTN BootloaderParameter + ) +{ + EFI_STATUS Status; + PHYSICAL_ADDRESS DxeCoreEntryPoint; + EFI_PEI_HOB_POINTERS Hob; + EFI_FIRMWARE_VOLUME_HEADER *DxeFv; + + mHobList =3D (VOID *)BootloaderParameter; + DxeFv =3D NULL; + // Call constructor for all libraries + ProcessLibraryConstructorList (); + + DEBUG ((DEBUG_INFO, "Entering Universal Payload...\n")); + DEBUG ((DEBUG_INFO, "sizeof(UINTN) =3D 0x%x\n", sizeof (UINTN))); + + DEBUG_CODE ( + // + // Dump the Hobs from boot loader + // + PrintHob (mHobList); + ); + + // Initialize floating point operating environment to be compliant with = UEFI spec. + InitializeFloatingPointUnits (); + + // Build HOB based on information from Bootloader + Status =3D BuildHobs (BootloaderParameter, &DxeFv); + ASSERT_EFI_ERROR (Status); + + FixUpPcdDatabase (DxeFv); + Status =3D UniversalLoadDxeCore (DxeFv, &DxeCoreEntryPoint); + ASSERT_EFI_ERROR (Status); + + // + // Mask off all legacy 8259 interrupt sources + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF); + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF); + + Hob.HandoffInformationTable =3D (EFI_HOB_HANDOFF_INFO_TABLE *)GetFirstHo= b (EFI_HOB_TYPE_HANDOFF); + HandOffToDxeCore (DxeCoreEntryPoint, Hob); + + // Should not get here + CpuDeadLoop (); + return EFI_SUCCESS; +} diff --git a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf b= /UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf new file mode 100644 index 0000000000..01fb3aceb3 --- /dev/null +++ b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf @@ -0,0 +1,98 @@ +## @file +# This is the first module for UEFI payload. +# +# Copyright (c) 2023, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D FitUniversalPayloadEntry + FILE_GUID =3D CED5A8A9-B6EA-4D5A-8689-577EE88566CF + MODULE_TYPE =3D SEC + VERSION_STRING =3D 1.0 + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 +# + +[Sources] + FitUniversalPayloadEntry.c + LoadDxeCore.c + MemoryAllocation.c + PrintHob.c + AcpiTable.c + +[Sources.Ia32] + X64/VirtualMemory.h + X64/VirtualMemory.c + Ia32/DxeLoadFunc.c + Ia32/IdtVectorAsm.nasm + +[Sources.X64] + X64/VirtualMemory.h + X64/VirtualMemory.c + X64/DxeLoadFunc.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + BaseLib + SerialPortLib + IoLib + HobLib + PeCoffLib + CpuLib + FdtLib + +[Guids] + gEfiMemoryTypeInformationGuid + gEfiFirmwareFileSystem2Guid + gEfiGraphicsInfoHobGuid + gEfiGraphicsDeviceInfoHobGuid + gUefiAcpiBoardInfoGuid + gEfiSmbiosTableGuid + gUefiSerialPortInfoGuid + gUniversalPayloadExtraDataGuid + gUniversalPayloadBaseGuid + gPcdDataBaseHobGuid + gUniversalPayloadSmbiosTableGuid + gEfiHobMemoryAllocBspStoreGuid + gUniversalPayloadAcpiTableGuid + gUniversalPayloadPciRootBridgeInfoGuid + gUniversalPayloadSmbios3TableGuid + +[FeaturePcd.IA32] + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES + +[FeaturePcd.X64] + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables ## CONSUMES + + +[Pcd.IA32,Pcd.X64] + gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ##= SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ##= CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ##= CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ##= CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ##= CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ##= CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize ##= CONSUMES + + gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase + gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize + gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize + + gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIM= ES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIM= ES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIM= ES_CONSUMES diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayload= Pkg.dec index e2e4a79db3..2f1fd82487 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dec +++ b/UefiPayloadPkg/UefiPayloadPkg.dec @@ -24,6 +24,9 @@ # gUefiPayloadPkgTokenSpaceGuid =3D {0x1d127ea, 0xf6f1, 0x4ef6, {0x94, 0x= 15, 0x8a, 0x0, 0x0, 0x93, 0xf8, 0x9d}} =20 + ## Include/Guid/UniversalPayloadBase.h + gUniversalPayloadBaseGuid =3D { 0x03d4c61d, 0x2713, 0x4ec5, {0xa1, 0xcc,= 0x88, 0x3b, 0xe9, 0xdc, 0x18, 0xe5 } } + # # Gop Temp # diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayload= Pkg.dsc index 47812048dd..af9308ef8e 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -30,7 +30,6 @@ DEFINE PS2_KEYBOARD_ENABLE =3D FALSE DEFINE RAM_DISK_ENABLE =3D FALSE DEFINE SIO_BUS_ENABLE =3D FALSE - DEFINE UNIVERSAL_PAYLOAD =3D FALSE DEFINE SECURITY_STUB_ENABLE =3D TRUE DEFINE SMM_SUPPORT =3D FALSE DEFINE PLATFORM_BOOT_TIMEOUT =3D 3 @@ -44,6 +43,14 @@ DEFINE BOOTSPLASH_IMAGE =3D FALSE DEFINE NVME_ENABLE =3D TRUE DEFINE CAPSULE_SUPPORT =3D FALSE + # + # Setup Universal Payload + # + # ELF: Build UniversalPayload file as UniversalPayload.elf + # FIT: Build UniversalPayload file as UniversalPayload.fit + # + DEFINE UNIVERSAL_PAYLOAD =3D FALSE + DEFINE UNIVERSAL_PAYLOAD_FORMAT =3D ELF =20 # # NULL: NullMemoryTestDxe @@ -311,7 +318,7 @@ VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseV= ariableFlashInfoLib.inf CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeRepor= tStatusCodeLib.inf - + FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf [LibraryClasses.common] !if $(BOOTSPLASH_IMAGE) SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf @@ -600,14 +607,26 @@ !if "IA32" in "$(ARCH)" [Components.IA32] !if $(UNIVERSAL_PAYLOAD) =3D=3D TRUE - UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf + !if $(UNIVERSAL_PAYLOAD_FORMAT) =3D=3D "ELF" + UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf + !elseif $(UNIVERSAL_PAYLOAD_FORMAT) =3D=3D "FIT" + UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf + !else + UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf + !endif !else UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf !endif !else [Components.X64] !if $(UNIVERSAL_PAYLOAD) =3D=3D TRUE - UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf + !if $(UNIVERSAL_PAYLOAD_FORMAT) =3D=3D "ELF" + UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf + !elseif $(UNIVERSAL_PAYLOAD_FORMAT) =3D=3D "FIT" + UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf + !else + UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf + !endif !else UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf !endif diff --git a/UefiPayloadPkg/UniversalPayloadBuild.py b/UefiPayloadPkg/Unive= rsalPayloadBuild.py index 47f37b3377..9a83fc9e44 100644 --- a/UefiPayloadPkg/UniversalPayloadBuild.py +++ b/UefiPayloadPkg/UniversalPayloadBuild.py @@ -10,10 +10,22 @@ import subprocess import os import shutil import sys +import pathlib from ctypes import * -from Tools.ElfFv import ReplaceFv + sys.dont_write_bytecode =3D True =20 +class bcolors: + HEADER =3D '\033[95m' + OKBLUE =3D '\033[94m' + OKCYAN =3D '\033[96m' + OKGREEN =3D '\033[92m' + WARNING =3D '\033[93m' + FAIL =3D '\033[91m' + ENDC =3D '\033[0m' + BOLD =3D '\033[1m' + UNDERLINE =3D '\033[4m' + class UPLD_INFO_HEADER(LittleEndianStructure): _pack_ =3D 1 _fields_ =3D [ @@ -36,40 +48,114 @@ class UPLD_INFO_HEADER(LittleEndianStructure): self.ImageId =3D b'UEFI' self.ProducerId =3D b'INTEL' =20 -def BuildUniversalPayload(Args): - def RunCommand(cmd): - print(cmd) - p =3D subprocess.Popen(cmd, shell=3DTrue, stdout=3Dsubprocess.PIPE= , stderr=3Dsubprocess.STDOUT,cwd=3Dos.environ['WORKSPACE']) - while True: - line =3D p.stdout.readline() - if not line: - break - print(line.strip().decode(errors=3D'ignore')) - - p.communicate() - if p.returncode !=3D 0: - print("- Failed - error happened when run command: %s"%cmd) - raise Exception("ERROR: when run command: %s"%cmd) +def ValidateSpecRevision (Argument): + try: + (MajorStr, MinorStr) =3D Argument.split('.') + except: + raise argparse.ArgumentTypeError ('{} is not a valid SpecRevision = format (Major[8-bits].Minor[8-bits]).'.format (Argument)) + # + # Spec Revision Bits 15 : 8 - Major Version. Bits 7 : 0 - Minor Versio= n. + # + if len(MinorStr) > 0 and len(MinorStr) < 3: + try: + Minor =3D int(MinorStr, 16) if len(MinorStr) =3D=3D 2 else (in= t(MinorStr, 16) << 4) + except: + raise argparse.ArgumentTypeError ('{} Minor version of SpecRev= ision is not a valid integer value.'.format (Argument)) + else: + raise argparse.ArgumentTypeError ('{} is not a valid SpecRevision = format (Major[8-bits].Minor[8-bits]).'.format (Argument)) + + if len(MajorStr) > 0 and len(MajorStr) < 3: + try: + Major =3D int(MajorStr, 16) + except: + raise argparse.ArgumentTypeError ('{} Major version of SpecRev= ision is not a valid integer value.'.format (Argument)) + else: + raise argparse.ArgumentTypeError ('{} is not a valid SpecRevision = format (Major[8-bits].Minor[8-bits]).'.format (Argument)) + + return int('0x{0:02x}{1:02x}'.format(Major, Minor), 0) + +def Validate32BitInteger (Argument): + try: + Value =3D int (Argument, 0) + except: + raise argparse.ArgumentTypeError ('{} is not a valid integer value= .'.format (Argument)) + if Value < 0: + raise argparse.ArgumentTypeError ('{} is a negative value.'.format= (Argument)) + if Value > 0xffffffff: + raise argparse.ArgumentTypeError ('{} is larger than 32-bits.'.for= mat (Argument)) + return Value =20 +def ValidateAddFv (Argument): + Value =3D Argument.split ("=3D") + if len (Value) !=3D 2: + raise argparse.ArgumentTypeError ('{} is incorrect format with "xx= x_fv=3Dxxx.fv"'.format (Argument)) + if Value[0][-3:] !=3D "_fv": + raise argparse.ArgumentTypeError ('{} is incorrect format with "xx= x_fv=3Dxxx.fv"'.format (Argument)) + if Value[1][-3:].lower () !=3D ".fv": + raise argparse.ArgumentTypeError ('{} is incorrect format with "xx= x_fv=3Dxxx.fv"'.format (Argument)) + if os.path.exists (Value[1]) =3D=3D False: + raise argparse.ArgumentTypeError ('File {} is not found.'.format (= Value[1])) + return Value + +def RunCommand(cmd): + print(cmd) + p =3D subprocess.Popen(cmd, shell=3DTrue, stdout=3Dsubprocess.PIPE, st= derr=3Dsubprocess.STDOUT,cwd=3Dos.environ['WORKSPACE']) + while True: + line =3D p.stdout.readline() + if not line: + break + print(line.strip().decode(errors=3D'ignore')) + + p.communicate() + if p.returncode !=3D 0: + print("- Failed - error happened when run command: %s"%cmd) + raise Exception("ERROR: when run command: %s"%cmd) + +def BuildUniversalPayload(Args): BuildTarget =3D Args.Target ToolChain =3D Args.ToolChain Quiet =3D "--quiet" if Args.Quiet else "" - ElfToolChain =3D 'CLANGDWARF' - BuildDir =3D os.path.join(os.environ['WORKSPACE'], os.path.normpat= h("Build/UefiPayloadPkgX64")) - BuildModule =3D "" - BuildArch =3D "" =20 + if Args.Fit =3D=3D True: + PayloadEntryToolChain =3D ToolChain + Args.Macro.append("UNIVERSAL_PAYLOAD_FORMAT=3DFIT") + UpldEntryFile =3D "FitUniversalPayloadEntry" + else: + PayloadEntryToolChain =3D 'CLANGDWARF' + Args.Macro.append("UNIVERSAL_PAYLOAD_FORMAT=3DELF") + UpldEntryFile =3D "UniversalPayloadEntry" + + BuildDir =3D os.path.join(os.environ['WORKSPACE'], os.path.normpat= h("Build/UefiPayloadPkgX64")) if Args.Arch =3D=3D 'X64': BuildArch =3D "X64" - EntryOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ElfToolChain), os.path.normpath("X64/UefiPayloadPkg/UefiPayloadEntry/U= niversalPayloadEntry/DEBUG/UniversalPayloadEntry.dll")) + FitArch =3D "x86_64" + ObjCopyFlag =3D "elf64-x86-64" + EntryOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, PayloadEntryToolChain), os.path.normpath("X64/UefiPayloadPkg/UefiPaylo= adEntry/{}/DEBUG/{}.dll".format (UpldEntryFile, UpldEntryFile))) else: BuildArch =3D "IA32 -a X64" - EntryOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ElfToolChain), os.path.normpath("IA32/UefiPayloadPkg/UefiPayloadEntry/= UniversalPayloadEntry/DEBUG/UniversalPayloadEntry.dll")) + FitArch =3D "x86" + ObjCopyFlag =3D "elf32-i386" + EntryOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, PayloadEntryToolChain), os.path.normpath("IA32/UefiPayloadPkg/UefiPayl= oadEntry/{}/DEBUG/{}.dll".format (UpldEntryFile, UpldEntryFile))) =20 + EntryModuleInf =3D os.path.normpath("UefiPayloadPkg/UefiPayloadEntry/{= }.inf".format (UpldEntryFile)) DscPath =3D os.path.normpath("UefiPayloadPkg/UefiPayloadPkg.dsc") + DxeFvOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTarget,= ToolChain), os.path.normpath("FV/DXEFV.Fv")) + BdsFvOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTarget,= ToolChain), os.path.normpath("FV/BDSFV.Fv")) + NetworkFvOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/NETWORKFV.Fv")) + PayloadReportPath =3D os.path.join(BuildDir, "UefiUniversalPayload.txt= ") ModuleReportPath =3D os.path.join(BuildDir, "UefiUniversalPayloadEntry= .txt") UpldInfoFile =3D os.path.join(BuildDir, "UniversalPayloadInfo.bin") =20 + if "CLANG_BIN" in os.environ: + LlvmObjcopyPath =3D os.path.join(os.environ["CLANG_BIN"], "llvm-ob= jcopy") + else: + LlvmObjcopyPath =3D "llvm-objcopy" + try: + RunCommand('"%s" --version'%LlvmObjcopyPath) + except: + print("- Failed - Please check if LLVM is installed or if CLANG_BI= N is set correctly") + sys.exit(1) + Pcds =3D "" if (Args.pcd !=3D None): for PcdItem in Args.pcd: @@ -84,7 +170,6 @@ def BuildUniversalPayload(Args): # Building DXE core and DXE drivers as DXEFV. # if Args.BuildEntryOnly =3D=3D False: - PayloadReportPath =3D os.path.join(BuildDir, "UefiUniversalPayload= .txt") BuildPayload =3D "build -p {} -b {} -a X64 -t {} -y {} {}".format = (DscPath, BuildTarget, ToolChain, PayloadReportPath, Quiet) BuildPayload +=3D Pcds BuildPayload +=3D Defines @@ -93,94 +178,138 @@ def BuildUniversalPayload(Args): # Building Universal Payload entry. # if Args.PreBuildUplBinary is None: - EntryModuleInf =3D os.path.normpath("UefiPayloadPkg/UefiPayloadEnt= ry/UniversalPayloadEntry.inf") - BuildModule =3D "build -p {} -b {} -a {} -m {} -t {} -y {} {}".for= mat (DscPath, BuildTarget, BuildArch, EntryModuleInf, ElfToolChain, ModuleR= eportPath, Quiet) + BuildModule =3D "build -p {} -b {} -a {} -m {} -t {} -y {} {}".for= mat (DscPath, BuildTarget, BuildArch, EntryModuleInf, PayloadEntryToolChain= , ModuleReportPath, Quiet) BuildModule +=3D Pcds BuildModule +=3D Defines RunCommand(BuildModule) =20 if Args.PreBuildUplBinary is not None: - EntryOutputDir =3D os.path.join(BuildDir, "UniversalPayload.elf") + if Args.Fit =3D=3D False: + EntryOutputDir =3D os.path.join(BuildDir, "UniversalPayload.el= f") + else: + EntryOutputDir =3D os.path.join(BuildDir, "UniversalPayload.fi= t") shutil.copy (os.path.abspath(Args.PreBuildUplBinary), EntryOutputD= ir) =20 # - # Buid Universal Payload Information Section ".upld_info" + # Build Universal Payload Information Section ".upld_info" # - upld_info_hdr =3D UPLD_INFO_HEADER() - upld_info_hdr.SpecRevision =3D Args.SpecRevision - upld_info_hdr.Revision =3D Args.Revision - upld_info_hdr.ProducerId =3D Args.ProducerId.encode()[:16] - upld_info_hdr.ImageId =3D Args.ImageId.encode()[:16] - upld_info_hdr.Attribute |=3D 1 if BuildTarget =3D=3D "DEBUG" else 0 - fp =3D open(UpldInfoFile, 'wb') - fp.write(bytearray(upld_info_hdr)) - fp.close() + if Args.Fit =3D=3D False: + upld_info_hdr =3D UPLD_INFO_HEADER() + upld_info_hdr.SpecRevision =3D Args.SpecRevision + upld_info_hdr.Revision =3D Args.Revision + upld_info_hdr.ProducerId =3D Args.ProducerId.encode()[:16] + upld_info_hdr.ImageId =3D Args.ImageId.encode()[:16] + upld_info_hdr.Attribute |=3D 1 if BuildTarget =3D=3D "DEBUG" else 0 + fp =3D open(UpldInfoFile, 'wb') + fp.write(bytearray(upld_info_hdr)) + fp.close() + + if Args.BuildEntryOnly =3D=3D False: + import Tools.ElfFv as ElfFv + ElfFv.ReplaceFv (EntryOutputDir, UpldInfoFile, '.upld_info', A= lignment =3D 4) + if Args.Fit =3D=3D False: + shutil.copy (EntryOutputDir, os.path.join(BuildDir, 'UniversalPayl= oad.elf')) + else: + shutil.copy (EntryOutputDir, os.path.join(BuildDir, 'UniversalPayl= oad.fit')) =20 MultiFvList =3D [] if Args.BuildEntryOnly =3D=3D False: MultiFvList =3D [ - ['uefi_fv', os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/DXEFV.Fv")) ], - ['bds_fv', os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/BDSFV.Fv")) ], - ['network_fv', os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/NETWORKFV.Fv")) ], + ['uefi_fv', os.path.join(BuildDir, "{}_{}".format (Buil= dTarget, ToolChain), os.path.normpath("FV/DXEFV.Fv")) ], + ['bds_fv', os.path.join(BuildDir, "{}_{}".format (Buil= dTarget, ToolChain), os.path.normpath("FV/BDSFV.Fv")) ], + ['network_fv', os.path.join(BuildDir, "{}_{}".format (Buil= dTarget, ToolChain), os.path.normpath("FV/NETWORKFV.Fv"))], ] - AddSectionName =3D '.upld_info' - ReplaceFv (EntryOutputDir, UpldInfoFile, AddSectionName, Alignment= =3D 4) =20 - if Args.PreBuildUplBinary is None: - shutil.copy (EntryOutputDir, os.path.join(BuildDir, 'UniversalPayl= oad.elf')) =20 - return MultiFvList, os.path.join(BuildDir, 'UniversalPayload.elf') + if Args.Fit =3D=3D True: + import Tools.MkFitImage as MkFitImage + import pefile + fit_image_info_header =3D MkFitImage.FIT_IMAGE_INFO_= HEADER() + fit_image_info_header.Description =3D 'Uefi Universal Payload' + fit_image_info_header.UplVersion =3D Args.SpecRevision + fit_image_info_header.Type =3D 'flat-binary' + fit_image_info_header.Arch =3D FitArch + fit_image_info_header.Compression =3D 'none' + fit_image_info_header.Revision =3D Args.Revision + fit_image_info_header.BuildType =3D Args.Target.lower() + fit_image_info_header.Capabilities =3D None + fit_image_info_header.Producer =3D Args.ProducerId.lower() + fit_image_info_header.ImageId =3D Args.ImageId.lower() + fit_image_info_header.Binary =3D os.path.join(BuildDir, 'Un= iversalPayload.fit') + fit_image_info_header.TargetPath =3D os.path.join(BuildDir, 'Un= iversalPayload.fit') + fit_image_info_header.UefifvPath =3D DxeFvOutputDir + fit_image_info_header.BdsfvPath =3D BdsFvOutputDir + fit_image_info_header.NetworkfvPath =3D NetworkFvOutputDir + fit_image_info_header.DataOffset =3D 0x1000 + fit_image_info_header.LoadAddr =3D Args.LoadAddress + fit_image_info_header.Project =3D 'tianocore' + + TargetRebaseFile =3D fit_image_info_header.Binary.replace (pathlib= .Path(fit_image_info_header.Binary).suffix, ".pecoff") + TargetRebaseEntryFile =3D fit_image_info_header.Binary.replace (pa= thlib.Path(fit_image_info_header.Binary).suffix, ".entry") + =20 -def main(): - def ValidateSpecRevision (Argument): - try: - (MajorStr, MinorStr) =3D Argument.split('.') - except: - raise argparse.ArgumentTypeError ('{} is not a valid SpecRevis= ion format (Major[8-bits].Minor[8-bits]).'.format (Argument)) # - # Spec Revision Bits 15 : 8 - Major Version. Bits 7 : 0 - Minor Ve= rsion. + # Rebase PECOFF to load address # - if len(MinorStr) > 0 and len(MinorStr) < 3: - try: - Minor =3D int(MinorStr, 16) if len(MinorStr) =3D=3D 2 else= (int(MinorStr, 16) << 4) - except: - raise argparse.ArgumentTypeError ('{} Minor version of Spe= cRevision is not a valid integer value.'.format (Argument)) - else: - raise argparse.ArgumentTypeError ('{} is not a valid SpecRevis= ion format (Major[8-bits].Minor[8-bits]).'.format (Argument)) + RunCommand ( + "GenFw -e SEC -o {} {}".format ( + TargetRebaseFile, + fit_image_info_header.Binary + )) + RunCommand ( + "GenFw --rebase 0x{:02X} -o {} {} ".format ( + fit_image_info_header.LoadAddr + fit_image_info_header.DataO= ffset, + TargetRebaseFile, + TargetRebaseFile, + )) =20 - if len(MajorStr) > 0 and len(MajorStr) < 3: - try: - Major =3D int(MajorStr, 16) - except: - raise argparse.ArgumentTypeError ('{} Major version of Spe= cRevision is not a valid integer value.'.format (Argument)) - else: - raise argparse.ArgumentTypeError ('{} is not a valid SpecRevis= ion format (Major[8-bits].Minor[8-bits]).'.format (Argument)) + # + # Open PECOFF relocation table binary. + # + RelocBinary =3D b'' + PeCoff =3D pefile.PE (TargetRebaseFile) + for reloc in PeCoff.DIRECTORY_ENTRY_BASERELOC: + for entry in reloc.entries: + if (entry.type =3D=3D 0): + continue + Type =3D entry.type + Offset =3D entry.rva + fit_image_info_header.DataOffset + RelocBinary +=3D Type.to_bytes (8, 'little') + Offset.to_b= ytes (8, 'little') + RelocBinary +=3D b'\x00' * (0x1000 - (len(RelocBinary) % 0x1000)) =20 - return int('0x{0:02x}{1:02x}'.format(Major, Minor), 0) + # + # Output UniversalPayload.entry + # + TempBinary =3D open (TargetRebaseFile, 'rb') + TianoBinary =3D TempBinary.read () + TempBinary.close () =20 - def Validate32BitInteger (Argument): - try: - Value =3D int (Argument, 0) - except: - raise argparse.ArgumentTypeError ('{} is not a valid integer v= alue.'.format (Argument)) - if Value < 0: - raise argparse.ArgumentTypeError ('{} is a negative value.'.fo= rmat (Argument)) - if Value > 0xffffffff: - raise argparse.ArgumentTypeError ('{} is larger than 32-bits.'= .format (Argument)) - return Value - - def ValidateAddFv (Argument): - Value =3D Argument.split ("=3D") - if len (Value) !=3D 2: - raise argparse.ArgumentTypeError ('{} is incorrect format with= "xxx_fv=3Dxxx.fv"'.format (Argument)) - if Value[0][-3:] !=3D "_fv": - raise argparse.ArgumentTypeError ('{} is incorrect format with= "xxx_fv=3Dxxx.fv"'.format (Argument)) - if Value[1][-3:].lower () !=3D ".fv": - raise argparse.ArgumentTypeError ('{} is incorrect format with= "xxx_fv=3Dxxx.fv"'.format (Argument)) - if os.path.exists (Value[1]) =3D=3D False: - raise argparse.ArgumentTypeError ('File {} is not found.'.form= at (Value[1])) - return Value + TianoEntryBinary =3D TianoBinary + RelocBinary + TianoEntryBinary +=3D (b'\x00' * (0x1000 - (len(TianoBinary) % 0x1= 000))) + TianoEntryBinarySize =3D len (TianoEntryBinary) + + TempBinary =3D open(TargetRebaseEntryFile, "wb") + TempBinary.truncate() + TempBinary.write(TianoEntryBinary) + TempBinary.close() + + # + # Calculate entry and update relocation table start address and da= ta-size. + # + fit_image_info_header.Entry =3D PeCoff.OPTIONAL_HEADER.ImageB= ase + PeCoff.OPTIONAL_HEADER.AddressOfEntryPoint + fit_image_info_header.RelocStart =3D fit_image_info_header.DataOff= set + len(TianoBinary) + fit_image_info_header.DataSize =3D TianoEntryBinarySize + fit_image_info_header.Binary =3D TargetRebaseEntryFile + + if MkFitImage.MakeFitImage(fit_image_info_header) is True: + print('\nSuccessfully build Fit Image') + else: + sys.exit(1) + return MultiFvList, os.path.join(BuildDir, 'UniversalPayload.fit') + else: + return MultiFvList, os.path.join(BuildDir, 'UniversalPayload.elf') =20 +def main(): parser =3D argparse.ArgumentParser(description=3D'For building Univers= al Payload') parser.add_argument('-t', '--ToolChain') parser.add_argument('-b', '--Target', default=3D'DEBUG') @@ -192,13 +321,16 @@ def main(): parser.add_argument("-s", "--SpecRevision", type=3DValidateSpecRevisio= n, default =3D'0.7', help=3D'Indicates compliance with a revision of this s= pecification in the BCD format.') parser.add_argument("-r", "--Revision", type=3DValidate32BitInteger, d= efault =3D'0x0000010105', help=3D'Revision of the Payload binary. Major.Min= or.Revision.Build') parser.add_argument("-o", "--ProducerId", default =3D'INTEL', help=3D'= A null-terminated OEM-supplied string that identifies the payload producer = (16 bytes maximal).') + parser.add_argument("-e", "--BuildEntryOnly", action=3D'store_true', h= elp=3D'Build UniversalPayload Entry file') + parser.add_argument("-pb", "--PreBuildUplBinary", default=3DNone, help= =3D'Specify the UniversalPayload file') parser.add_argument("-sk", "--SkipBuild", action=3D'store_true', help= =3D'Skip UniversalPayload build') parser.add_argument("-af", "--AddFv", type=3DValidateAddFv, action=3D'= append', help=3D'Add or replace specific FV into payload, Ex: uefi_fv=3DXXX= .fv') - command_group =3D parser.add_mutually_exclusive_group() - command_group.add_argument("-e", "--BuildEntryOnly", action=3D'store_t= rue', help=3D'Build UniversalPayload Entry file') - command_group.add_argument("-pb", "--PreBuildUplBinary", default=3DNon= e, help=3D'Specify the UniversalPayload file') + parser.add_argument("-f", "--Fit", action=3D'store_true', help=3D'Buil= d UniversalPayload file as UniversalPayload.fit', default=3DFalse) + parser.add_argument('-l', "--LoadAddress", type=3Dint, help=3D'Specify= payload load address', default =3D0x000800000) + args =3D parser.parse_args() =20 + MultiFvList =3D [] UniversalPayloadBinary =3D args.PreBuildUplBinary if (args.SkipBuild =3D=3D False): @@ -208,12 +340,24 @@ def main(): for (SectionName, SectionFvFile) in args.AddFv: MultiFvList.append ([SectionName, SectionFvFile]) =20 + def ReplaceFv (UplBinary, SectionFvFile, SectionName): + print (bcolors.OKGREEN + "Patch {}=3D{} into {}".format (SectionNa= me, SectionFvFile, UplBinary) + bcolors.ENDC) + if (args.Fit =3D=3D False): + import Tools.ElfFv as ElfFv + return ElfFv.ReplaceFv (UplBinary, SectionFvFile, '.upld.{}'.f= ormat (SectionName)) + else: + import Tools.MkFitImage as MkFitImage + return MkFitImage.ReplaceFv (UplBinary, SectionFvFile, Section= Name) + if (UniversalPayloadBinary !=3D None): for (SectionName, SectionFvFile) in MultiFvList: if os.path.exists (SectionFvFile) =3D=3D False: continue - print ("Patch {}=3D{} into {}".format (SectionName, SectionFvF= ile, UniversalPayloadBinary)) - ReplaceFv (UniversalPayloadBinary, SectionFvFile, '.upld.{}'.f= ormat (SectionName)) + + status =3D ReplaceFv (UniversalPayloadBinary, SectionFvFile, S= ectionName.replace ("_", "-")) + if status !=3D 0: + print (bcolors.FAIL + "[Fail] Patch {}=3D{}".format (Secti= onName, SectionFvFile) + bcolors.ENDC) + return status =20 print ("\nSuccessfully build Universal Payload") =20 --=20 2.39.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#108792): https://edk2.groups.io/g/devel/message/108792 Mute This Topic: https://groups.io/mt/101435620/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-