From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (NAM10-BN7-obe.outbound.protection.outlook.com [40.107.92.121]) by mx.groups.io with SMTP id smtpd.web11.275.1623775740327304338 for ; Tue, 15 Jun 2021 09:49:00 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@os.amperecomputing.com header.s=selector2 header.b=H7w3C7SX; spf=pass (domain: os.amperecomputing.com, ip: 40.107.92.121, mailfrom: nhi@os.amperecomputing.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=T+NSPqk0QHRCQyDUTI9xIAwqpDqJmABt6TKUqXslS9FUv1lHgaeN5Pn+kFASyhWbP4bO7TZ/1IwqtFuGJP6q+ZjwocdesWBOljb29WMmUSyUnCarJ7PcmoQW4l/i3Bo7PLnwJHrWGZWSzzjZT9Ya1Z7zTYGGYXqGTWdvg/R4BZQSxIDUMKBza1ya/5MHLpmwtNzkxxhLd1TqG9tlwoP8Yxw2SpQMbMvzrueQEjUaI1FGTEeQZlX3QlLHxx8gusZ53rFX+dxk7obMvpdi3TeoHfUg87NuwPmi2hxh+PQw9YRIiWqzE6ZHjD9rxXtvogfJvOU/Fk6wsruqkc/1B19Rpg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=PSM2vClH428anQGvStfBaADUStDVk+hO6gytq+7Dt1s=; b=hqpEfDf9237TyijzYkTjN80crvMEpmlH8m0XQifQpY/wVGtqc+2/0BfcLmwzJWv6YmUTesvaGYplIhrI7i7cIT9iDDGYiYD1vBlzkJxxlLP6LsNeEb4nLoNzhewbcS7scxj9rcY6U10lQFWDgNYdcs3YLS8xhVZSMxTmI6vovlBqD1UucG5avSEPjXzx8xDABslVlWThpbUaT1sE8bl+yaEe+xPluHtHmRQ5UPXMbka+gnCwMOWAF3IxHsiIQQFtlCwQpEpewfDOudjC6/eqvuJI9bDFrW8eVcM0nZgSlxTRgB68XD6y71xiqMkeZNIGWkyX1XMj69nzzd7wKb98ow== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=os.amperecomputing.com; dmarc=pass action=none header.from=os.amperecomputing.com; dkim=pass header.d=os.amperecomputing.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=os.amperecomputing.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=PSM2vClH428anQGvStfBaADUStDVk+hO6gytq+7Dt1s=; b=H7w3C7SXTE1pCX0gpRVS4HCUSS+IVm2fGZHk6b+aeTU2ZaXXEoNaEvoRj0O7ZLRIU7LTrotQU1K4859C3lnx+5SkXkdlA3aUe6UsB3V4l8bGNpAALw1YZsOuoo8wqDRNE92LmVzh3L4/OXXE5gtwy6ZhkVJOLD5jW2fjoTce70E= Authentication-Results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=os.amperecomputing.com; Received: from DM6PR01MB5849.prod.exchangelabs.com (2603:10b6:5:205::20) by DM6PR01MB4732.prod.exchangelabs.com (2603:10b6:5:6d::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4219.24; Tue, 15 Jun 2021 16:48:57 +0000 Received: from DM6PR01MB5849.prod.exchangelabs.com ([fe80::4d8d:74e3:6747:75a2]) by DM6PR01MB5849.prod.exchangelabs.com ([fe80::4d8d:74e3:6747:75a2%7]) with mapi id 15.20.4219.025; Tue, 15 Jun 2021 16:48:57 +0000 Subject: Re: [edk2-platforms][PATCH v2 09/32] AmpereAltraPkg: Support non-volatile variables To: Leif Lindholm Cc: devel@edk2.groups.io, Vu Nguyen , Thang Nguyen , Chuong Tran , Phong Vo , Michael D Kinney , Ard Biesheuvel , Nate DeSimone References: <20210526100724.5359-1-nhi@os.amperecomputing.com> <20210526100724.5359-11-nhi@os.amperecomputing.com> <20210604233613.hltqv7uyytfzu23e@leviathan> From: "Nhi Pham" Message-ID: <5d30dba4-0580-edca-2d5f-17294df1bbee@os.amperecomputing.com> Date: Tue, 15 Jun 2021 23:48:47 +0700 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 In-Reply-To: <20210604233613.hltqv7uyytfzu23e@leviathan> X-Originating-IP: [116.110.40.240] X-ClientProxiedBy: HK2PR06CA0024.apcprd06.prod.outlook.com (2603:1096:202:2e::36) To DM6PR01MB5849.prod.exchangelabs.com (2603:10b6:5:205::20) Return-Path: nhi@os.amperecomputing.com MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from [192.168.1.7] (116.110.40.240) by HK2PR06CA0024.apcprd06.prod.outlook.com (2603:1096:202:2e::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4242.16 via Frontend Transport; Tue, 15 Jun 2021 16:48:54 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b2fb0226-e2c8-431b-7d38-08d9301d7793 X-MS-TrafficTypeDiagnostic: DM6PR01MB4732: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:10000; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: IXiMlMrx13EZvVFjJcFgKqh9pAWT48SPbJ7HcVXuC8fwt+WLxPuaiRySARhb0Mq4eMYDv3g8gNbF29S6SHTzkjfetiSSk/HwiqI9y6nM+DIHbOO9MNMGAVCZMSlocPH/8RgY5OgF0Ayu9lIkZGVWZDATpZzSV5msEl4M+MDNYXheuSt9gF/EyCHTw3mKyLkexGzI8aE2sCMgJJSyvGdqsypipf9ODWUdaOfLN7mV10XQOgQ9cIhlt1qgw3pq+jzswnZgD6L+ICeNzKuzsI/gge7iXeFfqq3uJkucq0sJL6LHHXRc/eEjsCXpJH3m+koPe+FhWJLgVY2MpQeoQflDPvUvi1+yObinZmTza7M1twvGY6R1MkfiQKg/aBZjXpEbx4SDR2TXlMpwY7CZhUdrG6C21bLD2DkF712rZJZgWwFnauB0bMu9G13vWZOZAI0yShchEikr9VL2/C3qC95cokZr3N2j1x9hhXaICe6vNDYxLRUrQ7aKiSBzaYU5fa1Q3Ceni0oqPYtQMdAZGKKgx7aFIzewbdq1WwAAe9/CQDlqmhb8jy5z0MJ0JDZBdGSESITRHobc4a0wyZf/PvcZksJ5wXwFDi4DS+8ujDyWbwMp5z08XSUHvK3grbrF3skbL+U7pEMVisTIPnK4hw7hyQzVAE03BlZDc2Mb4R/M15KkGz3NelHv/UHJRliDCfVytrAM5fVNPul1wKg98qbLanYj2UDVi76OHMzcbYjCcw4KjOnPNUWf+EL/hgPbeF5P X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM6PR01MB5849.prod.exchangelabs.com;PTR:;CAT:NONE;SFS:(4636009)(136003)(396003)(39840400004)(366004)(376002)(346002)(86362001)(316002)(4326008)(8936002)(5660300002)(16576012)(19627235002)(66946007)(54906003)(83380400001)(31686004)(53546011)(66476007)(6666004)(66556008)(6916009)(30864003)(52116002)(16526019)(956004)(2616005)(8676002)(186003)(6486002)(478600001)(38350700002)(31696002)(38100700002)(2906002)(26005)(43740500002)(45980500001)(559001)(579004)(44824005);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?OENXbVNlWDZoNXdaZ2JjRFRtWlNBdGRrVmlKOUlVQXFtSjh5Y0hYdzgvMjVs?= =?utf-8?B?dk1EM0w3ZG5CMm5naElLaUk0M0tTTkpvN2VlTWU0TFVVbGJWZVUrbGsxOGg3?= =?utf-8?B?M09mRXJBTXVRMS8xUFVGWTRtMUxUUTF3aGRONjJBdk0yaWt1djBCK1ZYTUxX?= =?utf-8?B?cDQweithOFkrTTg3UmFWcVpweFIyTGJweE1wb0RvWjNjdXN5RTE1Y3AwUldN?= =?utf-8?B?a3hGNk5RbUFJRVJuc2RUTXlXY2lwRFJxRjVPcnV5Zi9sT0NyT0RUSUZQampK?= =?utf-8?B?UzV2V1dEdHdBcGxPQXdoSUxuNnFPNmV2TWFId1J2OFoxTlZkZ2xwemUwWExR?= =?utf-8?B?Skt2bmpkRlVGa2NhN25Zc0hiZFo2Z2ozU0pNc1cvVFQvY2FaV2lhSDJPMFln?= =?utf-8?B?VXMzNzNuWVFnbHJkNDJuTVZ2SEpoenlYZGZIYi9MUS9hODdNeVJUaVlMOE40?= =?utf-8?B?NEpRTEk5YzY4dit0ekJlYzM3R2NuNndFTit1bWtKQ2ZjazJOUzh4T1dVTUxr?= =?utf-8?B?eXVUREtOVW5FUGNnRW9yMUtIcG0xVGVKUlVVV3ZSRDE1UVliVGkvcFNXRHNk?= =?utf-8?B?K2hqSGZmeUZMUm5seGpPUjhINXcwQ012WnFJN1psNDFycXdRSDVtS2hxdlpZ?= =?utf-8?B?RmtrNEx2NjJqVnNBN0dFNTkwNjdpdG4wV2JrazlCYVVVa25NbTVRaXhJL3Ba?= =?utf-8?B?VE9Eb2JIbVdrMFA0KzV3Z0pFZjMweWJZdEFhS2MvcUl0dDFNZXd6TWZOa0NB?= =?utf-8?B?b3RIT0oyaG9XSFRxZU8rVDNXUkdNdTlLQlJ3VnQ1N2N3SUYySlFzMFVkdlov?= =?utf-8?B?WndCOWxnSG9JbVorVjNJSmNMSzArS3dXY3lWNncxVDhHWWcwdG1UdlViYUxX?= =?utf-8?B?NWZGakxpY1F1dEk2Z3YzQkZHR1ZlZzhVallrdzBVNlM4Z21COUNNTVFUSzRM?= =?utf-8?B?NlBHb2RJUDBsQUZtOFRGZ3d5YWdXcVpkblYwcXdVME1BWnJNbS9aRWtIZFYz?= =?utf-8?B?aUhTanI3MndTeFY0SXF2cUFXWjFhRHA3K00zVVBPVzVoakx6bGM0NEIzWHJ1?= =?utf-8?B?NTFzK2lOQ0NvWE5lRU9ydEk1Q2xKWFRGem9jWlBWWWlxNFRQYmk0MFd5Q2VH?= =?utf-8?B?d01LanN6N3Awd2crZ1dpMW00WUREYSt6c3plWi9MemRGNXppZWk2Z1AzOTJS?= =?utf-8?B?NFJRSGMzR0MrY2dCRWdoUkFtUEV1NTNEcjJTQS84d250clhrSmRZNDl0ODlz?= =?utf-8?B?bE9la25Td1ppYWdxVG5xdmRjODVIT2d4WVBDekRxdzFxZUlOdkFYRFhJVUUy?= =?utf-8?B?RDFsS0FxMXNtUFdFWTdRd2Rtbjd0L1dsZlJ4b2Y4MnZaYkZLc0RCNW1mZVIx?= =?utf-8?B?NEZGc1pUSFVzY3FLSXUxRmhMYk9INkpaa1lnc1k2NG84dVRlS1JvbWw1ZExI?= =?utf-8?B?TEJuT0xwaFgzeVRNbGo0VE54QUdWKzIxQUc1YzQwY1NyMG5GZ1lrazlpeEtH?= =?utf-8?B?ODJ4dHpZdmEvdnluZDBMRWZpdlo3cjN0aW5UQmFsRkxTajZDZHlwM2NFREpU?= =?utf-8?B?NjY5ck45R3J5Um5IcEMyQVlld0REa2ZKVkhsOXVuelI2NGtNaUVsTy9yQjRh?= =?utf-8?B?OUg5QTgzZzRlTk5Pb0ZTMDJ3NjdhNlV1SkdsUWFLTVgvR09iby9YdVBtN2Za?= =?utf-8?B?UmpoWXQ4Z090ZG5WTzlJOTJRS0tlZWRjLy9DQ3FXNmdYbFZ0bG9vTklMTnhN?= =?utf-8?Q?YoT6r3N50+Iv+8TgHSr8ZkOiyiW50YYkcuVyPQs?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: b2fb0226-e2c8-431b-7d38-08d9301d7793 X-MS-Exchange-CrossTenant-AuthSource: DM6PR01MB5849.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Jun 2021 16:48:57.3052 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3bc2b170-fd94-476d-b0ce-4229bdc904a7 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: j4bCM8cd/1fLCOcLF6Pg5A7yRoEMrb99vt14hBtJDdwhnaCUUiBf3ofBpqOr9K5OOVP9zxudBlOsmNErenGuUZJ+xfidQ/TCHqgZQpxyUdw= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR01MB4732 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-Language: en-US On 6/5/21 06:36, Leif Lindholm wrote: > On Wed, May 26, 2021 at 17:07:01 +0700, Nhi Pham wrote: >> From: Vu Nguyen >> >> Non-volatile variables now can be stored on flash. MM communication >> protocol is used to access storage on flash. >> >> Included in this change are: >> * FlashPei module is used to compare saved UUID with firmware's >> UEFI_UUID on each boot. If UUIDs match, data is stored to RAM. >> Otherwise fill the storage with default value from NVRAM FV. >> * FlashLib provide APIs to access flash through MM Communication >> protocol >> * FlashFvbDxe installs gEfiFirmwareVolumeBlock protocol which will be >> used by the variable services to get/set variables. >> >> Cc: Thang Nguyen >> Cc: Chuong Tran >> Cc: Phong Vo >> Cc: Leif Lindholm >> Cc: Michael D Kinney >> Cc: Ard Biesheuvel >> Cc: Nate DeSimone >> >> Signed-off-by: Vu Nguyen >> --- >> Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec | 3 + >> Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec | 3 + >> Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc | 11 +- >> Platform/Ampere/JadePkg/Jade.dsc | 1 + >> Platform/Ampere/JadePkg/Jade.fdf | 62 ++- >> Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf | 54 ++ >> Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf | 51 ++ >> Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf | 36 ++ >> Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h | 42 ++ >> Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c | 525 ++++++++++++++++++++ >> Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c | 283 +++++++++++ >> Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c | 358 +++++++++++++ >> 12 files changed, 1425 insertions(+), 4 deletions(-) >> >> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec >> index be827dd19a96..d5b12a81e9bf 100644 >> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec >> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec >> @@ -37,6 +37,9 @@ [LibraryClasses] >> ## @libraryclass Defines a set of methods to communicate with secure parition over MM interface. >> MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h >> >> + ## @libraryclass Defines a set of methods to access flash memory. >> + FlashLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h >> + >> ## @libraryclass Defines a set of methods to generate random numbers by using Hardware RNG. >> TrngLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h >> >> diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec >> index 6ebdf7db0a57..26e020715290 100755 >> --- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec >> +++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec >> @@ -44,3 +44,6 @@ [PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx] >> # Firmware Volume Pcds >> # >> gAmpereTokenSpaceGuid.PcdFvBlockSize|0|UINT32|0xB0000001 >> + >> + # NVRam Pcds >> + gAmpereTokenSpaceGuid.PcdNvramErased|FALSE|BOOLEAN|0xB0000009 >> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc >> index 9f75da6f05ad..65973569a41d 100755 >> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc >> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc >> @@ -14,6 +14,7 @@ [BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] >> >> [BuildOptions] >> GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG >> + GCC:*_*_*_CC_FLAGS = -DUEFI_UUID=$(UEFI_UUID) > This isn't obvious enough. I'm a bear of very little brain, and I > could possibly figure out what's happening here, given time, but > please put a proper description in commit message (and possibly here? > whatever makes sense). Thanks, Leif. I will use a PCD instead of build option flag like above and will update the commit message to explain how it works. Best regards, Nhi > >> >> [LibraryClasses.common] >> !if $(TARGET) == RELEASE >> @@ -224,6 +225,7 @@ [LibraryClasses.common.DXE_DRIVER] >> SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf >> PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf >> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf >> + FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf >> >> [LibraryClasses.common.UEFI_APPLICATION] >> UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiTianoCustomDecompressLib.inf >> @@ -254,6 +256,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] >> >> EfiResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf >> ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf >> + FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf >> >> [LibraryClasses.ARM,LibraryClasses.AARCH64] >> # >> @@ -500,6 +503,8 @@ [PcdsDynamicDefault.common] >> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0x0 >> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0x0 >> >> + gAmpereTokenSpaceGuid.PcdNvramErased|FALSE >> + >> ################################################################################ >> # >> # Component Section - list of all EDK II Component Entries defined by this Platform >> @@ -520,8 +525,10 @@ [Components.common] >> Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf >> Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf >> Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf >> + Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf >> ArmPkg/Drivers/CpuPei/CpuPei.inf >> UefiCpuPkg/CpuIoPei/CpuIoPei.inf >> + MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf >> MdeModulePkg/Universal/Variable/Pei/VariablePei.inf >> MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf { >> >> @@ -575,9 +582,9 @@ [Components.common] >> # >> # Environment Variables Protocol >> # >> + Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf >> + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf >> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { >> - >> - gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE >> >> BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf >> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf >> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc >> index f37ab1a92e44..9b9a5d0bad0f 100755 >> --- a/Platform/Ampere/JadePkg/Jade.dsc >> +++ b/Platform/Ampere/JadePkg/Jade.dsc >> @@ -52,6 +52,7 @@ [Defines] >> DEFINE EDK2_SKIP_PEICORE = TRUE >> DEFINE SECURE_BOOT_ENABLE = FALSE >> DEFINE INCLUDE_TFTP_COMMAND = TRUE >> + DEFINE UEFI_UUID = 84BC921F-9D4A-4D1D-A1A1-1AE13EDD07E5 > This is a horrible name for a UUID. What is it meant to identify? > >> # >> # Network definition >> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf >> index 1857296a8ea5..375455086d0b 100755 >> --- a/Platform/Ampere/JadePkg/Jade.fdf >> +++ b/Platform/Ampere/JadePkg/Jade.fdf >> @@ -26,7 +26,7 @@ [FD.BL33_JADE_UEFI] >> ErasePolarity = 1 >> >> # This one is tricky, it must be: BlockSize * NumBlocks = Size >> -BlockSize = 0x10000 >> +BlockSize = 0x10000|gAmpereTokenSpaceGuid.PcdFvBlockSize >> NumBlocks = 0x7C >> >> ################################################################################ >> @@ -56,8 +56,61 @@ [FD.BL33_JADE_UEFI] >> >> # >> # NV Variables >> -# T.B.D > Ah. If I can make a retroactive comment - could this be introduced as > "Placeholder" rather than "T.B.D."? > > / > Leif > >> +# Offset: 0x00740000 >> +# Size: 0x00080000 >> # >> +0x00740000|0x00030000 >> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize >> +DATA = { >> + ## This is the EFI_FIRMWARE_VOLUME_HEADER >> + # ZeroVector [] >> + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >> + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >> + # FileSystemGuid: gEfiSystemNvDataFvGuid = >> + # { 0xFFF12B8D, 0x7696, 0x4C8B, >> + # { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }} >> + 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C, >> + 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50, >> + # FvLength: 0x80000 >> + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, >> + # Signature "_FVH" # Attributes >> + 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00, >> + # HeaderLength # CheckSum # ExtHeaderOffset #Reserved #Revision >> + 0x48, 0x00, 0x2D, 0x09, 0x00, 0x00, 0x00, 0x02, >> + # Blockmap[0]: 0x2 Blocks * 0x40000 Bytes / Block >> + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, >> + # Blockmap[1]: End >> + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >> + ## This is the VARIABLE_STORE_HEADER >> + # It is compatible with SECURE_BOOT_ENABLE == FALSE as well. >> + # Signature: gEfiAuthenticatedVariableGuid = >> + # { 0xaaf32c78, 0x947b, 0x439a, >> + # { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }} >> + 0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43, >> + 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92, >> + # Size: 0x30000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - >> + # 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x2FFB8 >> + # This can speed up the Variable Dispatch a bit. >> + 0xB8, 0xFF, 0x02, 0x00, >> + # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32 >> + 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 >> +} >> + >> +0x00770000|0x00010000 >> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize >> +DATA = { >> + # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid = >> + # { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95 }} >> + 0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49, >> + 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95, >> + # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved >> + 0x2c, 0xaf, 0x2c, 0x64, 0xFE, 0xFF, 0xFF, 0xFF, >> + # WriteQueueSize: UINT64 Size: 0x10000 - 0x20 (FTW_WORKING_HEADER) = 0xFFE0 >> + 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 >> +} >> + >> +0x00780000|0x00040000 >> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize >> >> ################################################################################ >> # >> @@ -102,9 +155,11 @@ [FV.FVMAIN_COMPACT] >> INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf >> INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf >> INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf >> + INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf >> INF Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf >> INF ArmPkg/Drivers/CpuPei/CpuPei.inf >> INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf >> + INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf >> INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf >> INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf >> INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf >> @@ -144,6 +199,7 @@ [FV.FvMain] >> INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf >> INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf >> INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf >> + INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf >> } >> >> INF MdeModulePkg/Core/Dxe/DxeMain.inf >> @@ -173,6 +229,8 @@ [FV.FvMain] >> # Environment Variables Protocol >> # >> INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf >> + INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf >> + INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf >> >> # >> # Multiple Console IO support >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf >> new file mode 100644 >> index 000000000000..782278615094 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf >> @@ -0,0 +1,54 @@ >> +## @file >> +# >> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
>> +# >> +# SPDX-License-Identifier: BSD-2-Clause-Patent >> +# >> +## >> + >> +[Defines] >> + INF_VERSION = 0x0001001B >> + BASE_NAME = FlashFvbDxe >> + FILE_GUID = 9E6EA240-DF80-11EA-8B6E-0800200C9A66 >> + MODULE_TYPE = DXE_RUNTIME_DRIVER >> + VERSION_STRING = 0.1 >> + ENTRY_POINT = FlashFvbDxeInitialize >> + >> +[Sources] >> + FlashFvbDxe.c >> + >> +[Packages] >> + ArmPkg/ArmPkg.dec >> + MdeModulePkg/MdeModulePkg.dec >> + MdePkg/MdePkg.dec >> + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec >> + Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec >> + >> +[LibraryClasses] >> + DebugLib >> + FlashLib >> + PcdLib >> + UefiBootServicesTableLib >> + UefiDriverEntryPoint >> + UefiRuntimeLib >> + >> +[FixedPcd] >> + gAmpereTokenSpaceGuid.PcdFvBlockSize >> + >> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize >> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize >> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize >> + >> +[Pcd] >> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 >> + >> +[Guids] >> + gEfiEventVirtualAddressChangeGuid >> + gSpiNorMmGuid >> + >> +[Protocols] >> + gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES >> + gEfiMmCommunicationProtocolGuid ## CONSUMES >> + >> +[Depex] >> + gEfiMmCommunicationProtocolGuid >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf >> new file mode 100644 >> index 000000000000..a4eaf5039bb0 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf >> @@ -0,0 +1,51 @@ >> +## @file >> +# >> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
>> +# >> +# SPDX-License-Identifier: BSD-2-Clause-Patent >> +# >> +## >> + >> +[Defines] >> + INF_VERSION = 0x0001001B >> + BASE_NAME = FlashPei >> + FILE_GUID = 967CFBD0-DF81-11EA-8B6E-0800200C9A66 >> + MODULE_TYPE = PEIM >> + VERSION_STRING = 1.0 >> + ENTRY_POINT = FlashPeiEntryPoint >> + >> +[Sources] >> + FlashPei.c >> + >> +[Packages] >> + ArmPkg/ArmPkg.dec >> + MdeModulePkg/MdeModulePkg.dec >> + MdePkg/MdePkg.dec >> + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec >> + Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec >> + >> +[LibraryClasses] >> + ArmSmcLib >> + BaseMemoryLib >> + DebugLib >> + MmCommunicationLib >> + PcdLib >> + PeimEntryPoint >> + >> +[Guids] >> + gSpiNorMmGuid >> + >> +[FixedPcd] >> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize >> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize >> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize >> + >> +[Pcd] >> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 >> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 >> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 >> + >> + gAmpereTokenSpaceGuid.PcdNvramErased >> + >> +[Depex] >> + TRUE >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf >> new file mode 100644 >> index 000000000000..2d5003d1af17 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf >> @@ -0,0 +1,36 @@ >> +## @file >> +# >> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
>> +# >> +# SPDX-License-Identifier: BSD-2-Clause-Patent >> +# >> +## >> + >> +[Defines] >> + INF_VERSION = 0x0001001B >> + BASE_NAME = FlashLib >> + FILE_GUID = 9E9D093D-6484-45AE-BA49-0745AA0BB481 >> + MODULE_TYPE = DXE_DRIVER >> + VERSION_STRING = 0.1 >> + LIBRARY_CLASS = FlashLib >> + CONSTRUCTOR = FlashLibConstructor >> + >> +[Sources.common] >> + FlashLib.c >> + >> +[Packages] >> + ArmPkg/ArmPkg.dec >> + ArmPlatformPkg/ArmPlatformPkg.dec >> + MdePkg/MdePkg.dec >> + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec >> + >> +[LibraryClasses] >> + BaseMemoryLib >> + DebugLib >> + MemoryAllocationLib >> + >> +[Guids] >> + gSpiNorMmGuid >> + >> +[Protocols] >> + gEfiMmCommunicationProtocolGuid >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h >> new file mode 100644 >> index 000000000000..9207dee643a5 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h >> @@ -0,0 +1,42 @@ >> +/** @file >> + >> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#ifndef FLASH_LIB_H_ >> +#define FLASH_LIB_H_ >> + >> +EFI_STATUS >> +EFIAPI >> +FlashGetNvRamInfo ( >> + OUT UINT64 *NvRamBase, >> + OUT UINT32 *NvRamSize >> + ); >> + >> +EFI_STATUS >> +EFIAPI >> +FlashEraseCommand ( >> + IN UINT8 *pBlockAddress, >> + IN UINT32 Length >> + ); >> + >> +EFI_STATUS >> +EFIAPI >> +FlashProgramCommand ( >> + IN UINT8 *pByteAddress, >> + IN UINT8 *Byte, >> + IN OUT UINTN *Length >> + ); >> + >> +EFI_STATUS >> +EFIAPI >> +FlashReadCommand ( >> + IN UINT8 *pByteAddress, >> + OUT UINT8 *Byte, >> + IN OUT UINTN *Length >> + ); >> + >> +#endif /* FLASH_LIB_H_ */ >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c >> new file mode 100644 >> index 000000000000..dcd92151b7d2 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c >> @@ -0,0 +1,525 @@ >> +/** @file >> + >> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +// >> +// These temporary buffers are used to calculate and convert linear virtual >> +// to physical address >> +// >> +STATIC UINT64 mNvFlashBase; >> +STATIC UINT32 mNvFlashSize; >> +STATIC UINT32 mFlashBlockSize; >> +STATIC UINT64 mNvStorageBase; >> +STATIC UINT64 mNvStorageSize; >> + >> +/** >> + Fixup internal data so that EFI can be call in virtual mode. >> + Call the passed in Child Notify event and convert any pointers in >> + lib to virtual mode. >> + >> + @param[in] Event The Event that is being processed >> + @param[in] Context Event Context >> +**/ >> +VOID >> +EFIAPI >> +FlashFvbAddressChangeEvent ( >> + IN EFI_EVENT Event, >> + IN VOID *Context >> + ) >> +{ >> + EfiConvertPointer (0x0, (VOID **)&mNvStorageBase); >> +} >> + >> +/** >> + The GetAttributes() function retrieves the attributes and >> + current settings of the block. >> + >> + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. >> + >> + @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the >> + attributes and current settings are >> + returned. Type EFI_FVB_ATTRIBUTES_2 is defined >> + in EFI_FIRMWARE_VOLUME_HEADER. >> + >> + @retval EFI_SUCCESS The firmware volume attributes were >> + returned. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +FlashFvbDxeGetAttributes ( >> + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, >> + OUT EFI_FVB_ATTRIBUTES_2 *Attributes >> + ) >> +{ >> + ASSERT (Attributes != NULL); >> + >> + *Attributes = EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled >> + EFI_FVB2_READ_STATUS | // Reads are currently enabled >> + EFI_FVB2_WRITE_STATUS | // Writes are currently enabled >> + EFI_FVB2_WRITE_ENABLED_CAP | // Writes may be enabled >> + EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY >> + EFI_FVB2_MEMORY_MAPPED | // It is memory mapped >> + EFI_FVB2_ALIGNMENT | >> + EFI_FVB2_ERASE_POLARITY; // After erasure all bits take this value (i.e. '1') >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + The SetAttributes() function sets configurable firmware volume >> + attributes and returns the new settings of the firmware volume. >> + >> + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. >> + >> + @param Attributes On input, Attributes is a pointer to >> + EFI_FVB_ATTRIBUTES_2 that contains the >> + desired firmware volume settings. On >> + successful return, it contains the new >> + settings of the firmware volume. Type >> + EFI_FVB_ATTRIBUTES_2 is defined in >> + EFI_FIRMWARE_VOLUME_HEADER. >> + >> + @retval EFI_SUCCESS The firmware volume attributes were returned. >> + >> + @retval EFI_INVALID_PARAMETER The attributes requested are in >> + conflict with the capabilities >> + as declared in the firmware >> + volume header. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +FlashFvbDxeSetAttributes ( >> + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, >> + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes >> + ) >> +{ >> + return EFI_SUCCESS; // ignore for now >> +} >> + >> +/** >> + The GetPhysicalAddress() function retrieves the base address of >> + a memory-mapped firmware volume. This function should be called >> + only for memory-mapped firmware volumes. >> + >> + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. >> + >> + @param Address Pointer to a caller-allocated >> + EFI_PHYSICAL_ADDRESS that, on successful >> + return from GetPhysicalAddress(), contains the >> + base address of the firmware volume. >> + >> + @retval EFI_SUCCESS The firmware volume base address was returned. >> + >> + @retval EFI_UNSUPPORTED The firmware volume is not memory mapped. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +FlashFvbDxeGetPhysicalAddress ( >> + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, >> + OUT EFI_PHYSICAL_ADDRESS *Address >> + ) >> +{ >> + ASSERT (Address != NULL); >> + >> + *Address = (EFI_PHYSICAL_ADDRESS)mNvStorageBase; >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + The GetBlockSize() function retrieves the size of the requested >> + block. It also returns the number of additional blocks with >> + the identical size. The GetBlockSize() function is used to >> + retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER). >> + >> + >> + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. >> + >> + @param Lba Indicates the block for which to return the size. >> + >> + @param BlockSize Pointer to a caller-allocated UINTN in which >> + the size of the block is returned. >> + >> + @param NumberOfBlocks Pointer to a caller-allocated UINTN in >> + which the number of consecutive blocks, >> + starting with Lba, is returned. All >> + blocks in this range have a size of >> + BlockSize. >> + >> + >> + @retval EFI_SUCCESS The firmware volume base address was returned. >> + >> + @retval EFI_INVALID_PARAMETER The requested LBA is out of range. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +FlashFvbDxeGetBlockSize ( >> + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, >> + IN EFI_LBA Lba, >> + OUT UINTN *BlockSize, >> + OUT UINTN *NumberOfBlocks >> + ) >> +{ >> + UINTN TotalNvStorageBlocks; >> + >> + ASSERT (BlockSize != NULL); >> + ASSERT (NumberOfBlocks != NULL); >> + >> + TotalNvStorageBlocks = mNvStorageSize / mFlashBlockSize; >> + >> + if (TotalNvStorageBlocks <= (UINTN)Lba) { >> + DEBUG ((DEBUG_ERROR, "The requested LBA is out of range\n")); >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + *NumberOfBlocks = TotalNvStorageBlocks - (UINTN)Lba; >> + *BlockSize = mFlashBlockSize; >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Reads the specified number of bytes into a buffer from the specified block. >> + >> + The Read() function reads the requested number of bytes from the >> + requested block and stores them in the provided buffer. >> + Implementations should be mindful that the firmware volume >> + might be in the ReadDisabled state. If it is in this state, >> + the Read() function must return the status code >> + EFI_ACCESS_DENIED without modifying the contents of the >> + buffer. The Read() function must also prevent spanning block >> + boundaries. If a read is requested that would span a block >> + boundary, the read must read up to the boundary but not >> + beyond. The output parameter NumBytes must be set to correctly >> + indicate the number of bytes actually read. The caller must be >> + aware that a read may be partially completed. >> + >> + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. >> + >> + @param Lba The starting logical block index >> + from which to read. >> + >> + @param Offset Offset into the block at which to begin reading. >> + >> + @param NumBytes Pointer to a UINTN. At entry, *NumBytes >> + contains the total size of the buffer. At >> + exit, *NumBytes contains the total number of >> + bytes read. >> + >> + @param Buffer Pointer to a caller-allocated buffer that will >> + be used to hold the data that is read. >> + >> + @retval EFI_SUCCESS The firmware volume was read successfully, >> + and contents are in Buffer. >> + >> + @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA >> + boundary. On output, NumBytes >> + contains the total number of bytes >> + returned in Buffer. >> + >> + @retval EFI_ACCESS_DENIED The firmware volume is in the >> + ReadDisabled state. >> + >> + @retval EFI_DEVICE_ERROR The block device is not >> + functioning correctly and could >> + not be read. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +FlashFvbDxeRead ( >> + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, >> + IN EFI_LBA Lba, >> + IN UINTN Offset, >> + IN OUT UINTN *NumBytes, >> + IN OUT UINT8 *Buffer >> + ) >> +{ >> + EFI_STATUS Status; >> + >> + ASSERT (NumBytes != NULL); >> + ASSERT (Buffer != NULL); >> + >> + if (Offset + *NumBytes > mFlashBlockSize) { >> + return EFI_BAD_BUFFER_SIZE; >> + } >> + >> + Status = FlashReadCommand ( >> + (UINT8 *)(mNvFlashBase + Lba * mFlashBlockSize + Offset), >> + Buffer, >> + NumBytes >> + ); >> + >> + if (EFI_ERROR (Status)) { >> + DEBUG ((DEBUG_ERROR, "Failed to do flash read\n")); >> + return EFI_DEVICE_ERROR; >> + } >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Writes the specified number of bytes from the input buffer to the block. >> + >> + The Write() function writes the specified number of bytes from >> + the provided buffer to the specified block and offset. If the >> + firmware volume is sticky write, the caller must ensure that >> + all the bits of the specified range to write are in the >> + EFI_FVB_ERASE_POLARITY state before calling the Write() >> + function, or else the result will be unpredictable. This >> + unpredictability arises because, for a sticky-write firmware >> + volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY >> + state but cannot flip it back again. Before calling the >> + Write() function, it is recommended for the caller to first call >> + the EraseBlocks() function to erase the specified block to >> + write. A block erase cycle will transition bits from the >> + (NOT)EFI_FVB_ERASE_POLARITY state back to the >> + EFI_FVB_ERASE_POLARITY state. Implementations should be >> + mindful that the firmware volume might be in the WriteDisabled >> + state. If it is in this state, the Write() function must >> + return the status code EFI_ACCESS_DENIED without modifying the >> + contents of the firmware volume. The Write() function must >> + also prevent spanning block boundaries. If a write is >> + requested that spans a block boundary, the write must store up >> + to the boundary but not beyond. The output parameter NumBytes >> + must be set to correctly indicate the number of bytes actually >> + written. The caller must be aware that a write may be >> + partially completed. All writes, partial or otherwise, must be >> + fully flushed to the hardware before the Write() service >> + returns. >> + >> + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. >> + >> + @param Lba The starting logical block index to write to. >> + >> + @param Offset Offset into the block at which to begin writing. >> + >> + @param NumBytes The pointer to a UINTN. At entry, *NumBytes >> + contains the total size of the buffer. At >> + exit, *NumBytes contains the total number of >> + bytes actually written. >> + >> + @param Buffer The pointer to a caller-allocated buffer that >> + contains the source for the write. >> + >> + @retval EFI_SUCCESS The firmware volume was written successfully. >> + >> + @retval EFI_BAD_BUFFER_SIZE The write was attempted across an >> + LBA boundary. On output, NumBytes >> + contains the total number of bytes >> + actually written. >> + >> + @retval EFI_ACCESS_DENIED The firmware volume is in the >> + WriteDisabled state. >> + >> + @retval EFI_DEVICE_ERROR The block device is malfunctioning >> + and could not be written. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +FlashFvbDxeWrite ( >> + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, >> + IN EFI_LBA Lba, >> + IN UINTN Offset, >> + IN OUT UINTN *NumBytes, >> + IN UINT8 *Buffer >> + ) >> +{ >> + EFI_STATUS Status; >> + >> + ASSERT (NumBytes != NULL); >> + ASSERT (Buffer != NULL); >> + >> + if (Offset + *NumBytes > mFlashBlockSize) { >> + return EFI_BAD_BUFFER_SIZE; >> + } >> + >> + Status = FlashProgramCommand ( >> + (UINT8 *)(mNvFlashBase + Lba * mFlashBlockSize + Offset), >> + Buffer, >> + NumBytes >> + ); >> + >> + if (EFI_ERROR (Status)) { >> + DEBUG ((DEBUG_ERROR, "Failed to do flash program\n")); >> + return EFI_DEVICE_ERROR; >> + } >> + >> + return Status; >> +} >> + >> +/** >> + Erases and initializes a firmware volume block. >> + >> + The EraseBlocks() function erases one or more blocks as denoted >> + by the variable argument list. The entire parameter list of >> + blocks must be verified before erasing any blocks. If a block is >> + requested that does not exist within the associated firmware >> + volume (it has a larger index than the last block of the >> + firmware volume), the EraseBlocks() function must return the >> + status code EFI_INVALID_PARAMETER without modifying the contents >> + of the firmware volume. Implementations should be mindful that >> + the firmware volume might be in the WriteDisabled state. If it >> + is in this state, the EraseBlocks() function must return the >> + status code EFI_ACCESS_DENIED without modifying the contents of >> + the firmware volume. All calls to EraseBlocks() must be fully >> + flushed to the hardware before the EraseBlocks() service >> + returns. >> + >> + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL >> + instance. >> + >> + @param ... The variable argument list is a list of tuples. >> + Each tuple describes a range of LBAs to erase >> + and consists of the following: >> + - An EFI_LBA that indicates the starting LBA >> + - A UINTN that indicates the number of blocks to >> + erase. >> + >> + The list is terminated with an >> + EFI_LBA_LIST_TERMINATOR. For example, the >> + following indicates that two ranges of blocks >> + (5-7 and 10-11) are to be erased: EraseBlocks >> + (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR); >> + >> + @retval EFI_SUCCESS The erase request successfully >> + completed. >> + >> + @retval EFI_ACCESS_DENIED The firmware volume is in the >> + WriteDisabled state. >> + @retval EFI_DEVICE_ERROR The block device is not functioning >> + correctly and could not be written. >> + The firmware device may have been >> + partially erased. >> + @retval EFI_INVALID_PARAMETER One or more of the LBAs listed >> + in the variable argument list do >> + not exist in the firmware volume. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +FlashFvbDxeErase ( >> + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, >> + ... >> + ) >> +{ >> + VA_LIST Args; >> + EFI_LBA Start; >> + UINTN Length; >> + EFI_STATUS Status; >> + >> + Status = EFI_SUCCESS; >> + >> + VA_START (Args, This); >> + >> + for (Start = VA_ARG (Args, EFI_LBA); >> + Start != EFI_LBA_LIST_TERMINATOR; >> + Start = VA_ARG (Args, EFI_LBA)) >> + { >> + Length = VA_ARG (Args, UINTN); >> + Status = FlashEraseCommand ( >> + (UINT8 *)(mNvFlashBase + Start * mFlashBlockSize), >> + Length * mFlashBlockSize >> + ); >> + } >> + >> + VA_END (Args); >> + >> + if (EFI_ERROR (Status)) { >> + DEBUG ((DEBUG_ERROR, "Failed to do flash erase\n")); >> + return EFI_DEVICE_ERROR; >> + } >> + >> + return EFI_SUCCESS; >> +} >> + >> +EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL mFlashFvbProtocol = { >> + FlashFvbDxeGetAttributes, >> + FlashFvbDxeSetAttributes, >> + FlashFvbDxeGetPhysicalAddress, >> + FlashFvbDxeGetBlockSize, >> + FlashFvbDxeRead, >> + FlashFvbDxeWrite, >> + FlashFvbDxeErase >> +}; >> + >> +EFI_STATUS >> +EFIAPI >> +FlashFvbDxeInitialize ( >> + IN EFI_HANDLE ImageHandle, >> + IN EFI_SYSTEM_TABLE *SystemTable >> + ) >> +{ >> + EFI_STATUS Status; >> + EFI_HANDLE FvbHandle = NULL; >> + EFI_EVENT VirtualAddressChangeEvent; >> + >> + // Get NV store FV info >> + mFlashBlockSize = FixedPcdGet32 (PcdFvBlockSize); >> + mNvStorageBase = PcdGet64 (PcdFlashNvStorageVariableBase64); >> + mNvStorageSize = FixedPcdGet32 (PcdFlashNvStorageVariableSize) + >> + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + >> + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize); >> + >> + DEBUG (( >> + DEBUG_INFO, >> + "%a: Using NV store FV in-memory copy at 0x%lx with size 0x%x\n", >> + __FUNCTION__, >> + mNvStorageBase, >> + mNvStorageSize >> + )); >> + >> + // Get NV Flash information >> + Status = FlashGetNvRamInfo ((UINT64 *)&mNvFlashBase, (UINT32 *)&mNvFlashSize); >> + if (EFI_ERROR (Status)) { >> + DEBUG ((DEBUG_ERROR, "%a: Failed to get Flash info\n", __FUNCTION__)); >> + return EFI_DEVICE_ERROR; >> + } >> + >> + if (mNvFlashSize >= (mNvStorageSize * 2)) { >> + DEBUG ((DEBUG_INFO, "%a: NV store on Flash is valid\n", __FUNCTION__)); >> + } else { >> + DEBUG ((DEBUG_ERROR, "%a: NV store on Flash is invalid\n", __FUNCTION__)); >> + return EFI_DEVICE_ERROR; >> + } >> + >> + Status = gBS->CreateEventEx ( >> + EVT_NOTIFY_SIGNAL, >> + TPL_NOTIFY, >> + FlashFvbAddressChangeEvent, >> + NULL, >> + &gEfiEventVirtualAddressChangeGuid, >> + &VirtualAddressChangeEvent >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + Status = gBS->InstallMultipleProtocolInterfaces ( >> + &FvbHandle, >> + &gEfiFirmwareVolumeBlockProtocolGuid, >> + &mFlashFvbProtocol, >> + NULL >> + ); >> + >> + if (EFI_ERROR (Status)) { >> + DEBUG ((DEBUG_ERROR, "Failed to install Firmware Volume Block protocol\n")); >> + return Status; >> + } >> + >> + return EFI_SUCCESS; >> +} >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c >> new file mode 100644 >> index 000000000000..6bfbbbebaa85 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c >> @@ -0,0 +1,283 @@ >> +/** @file >> + >> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +// Convert to string >> +#define _STR(x) #x >> + >> +// Make sure the argument is expanded before converting to string >> +#define STR(x) _STR(x) >> + >> +// Use dynamic UEFI_UUID of each build time >> +#define UEFI_UUID_BUILD STR(UEFI_UUID) >> + >> +EFI_MM_COMM_REQUEST mEfiMmSpiNorReq; >> + >> +STATIC CHAR8 mBuildUuid[sizeof (UEFI_UUID_BUILD)]; >> +STATIC CHAR8 mStoredUuid[sizeof (UEFI_UUID_BUILD)]; >> + >> +STATIC >> +EFI_STATUS >> +UefiMmCreateSpiNorReq ( >> + VOID *Data, >> + UINT64 Size >> + ) >> +{ >> + CopyGuid (&mEfiMmSpiNorReq.EfiMmHdr.HeaderGuid, &gSpiNorMmGuid); >> + mEfiMmSpiNorReq.EfiMmHdr.MsgLength = Size; >> + >> + if (Size != 0) { >> + ASSERT (Data); >> + ASSERT (Size <= EFI_MM_MAX_PAYLOAD_SIZE); >> + >> + CopyMem (mEfiMmSpiNorReq.PayLoad.Data, Data, Size); >> + } >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Entry point function for the PEIM >> + >> + @param FileHandle Handle of the file being invoked. >> + @param PeiServices Describes the list of possible PEI Services. >> + >> + @return EFI_SUCCESS If we installed our PPI >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +FlashPeiEntryPoint ( >> + IN EFI_PEI_FILE_HANDLE FileHandle, >> + IN CONST EFI_PEI_SERVICES **PeiServices >> + ) >> +{ >> + UINT64 FWNvRamStartOffset; >> + EFI_STATUS Status; >> + EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes; >> + EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *MmSpiNorNVInfoRes; >> + UINT64 MmData[5]; >> + UINTN Size; >> + VOID *NvRamAddress; >> + UINTN NvRamSize; >> + >> +#if defined(RAM_BLOCKIO_START_ADDRESS) && defined(RAM_BLOCKIO_SIZE) >> + EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *MmSpiNorNV2InfoRes; >> + UINT64 NV2Base, NV2Size; >> +#endif >> + >> + NvRamAddress = (VOID *)PcdGet64 (PcdFlashNvStorageVariableBase64); >> + NvRamSize = FixedPcdGet32 (PcdFlashNvStorageVariableSize) + >> + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + >> + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize); >> + >> + /* Find out about the start offset of NVRAM to be passed to SMC */ >> + ZeroMem ((VOID *)MmData, sizeof (MmData)); >> + MmData[0] = MM_SPINOR_FUNC_GET_NVRAM_INFO; >> + UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); >> + >> + Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); >> + Status = MmCommunicationCommunicate ( >> + (VOID *)&mEfiMmSpiNorReq, >> + &Size >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + MmSpiNorNVInfoRes = (EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *)&mEfiMmSpiNorReq.PayLoad; >> + if (MmSpiNorNVInfoRes->Status != MM_SPINOR_RES_SUCCESS) { >> + /* Old FW so just exit */ >> + return EFI_SUCCESS; >> + } >> + FWNvRamStartOffset = MmSpiNorNVInfoRes->NVBase; >> + >> + CopyMem ((VOID *)mBuildUuid, (VOID *)UEFI_UUID_BUILD, sizeof (UEFI_UUID_BUILD)); >> + if (MmSpiNorNVInfoRes->NVSize < (NvRamSize * 2 + sizeof (mBuildUuid))) { >> + /* NVRAM size provided by FW is not enough */ >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + /* We stored BIOS UUID build at the offset NVRAM_SIZE * 2 */ >> + ZeroMem ((VOID *)MmData, sizeof (MmData)); >> + MmData[0] = MM_SPINOR_FUNC_READ; >> + MmData[1] = (UINT64)(FWNvRamStartOffset + NvRamSize * 2); >> + MmData[2] = (UINT64)sizeof (mStoredUuid); >> + MmData[3] = (UINT64)mStoredUuid; >> + UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); >> + >> + Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); >> + Status = MmCommunicationCommunicate ( >> + (VOID *)&mEfiMmSpiNorReq, >> + &Size >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad; >> + if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) { >> + return Status; >> + } >> + >> + if (CompareMem ((VOID *)mStoredUuid, (VOID *)mBuildUuid, sizeof (mBuildUuid))) { >> + ZeroMem ((VOID *)MmData, sizeof (MmData)); >> + MmData[0] = MM_SPINOR_FUNC_ERASE; >> + MmData[1] = (UINT64)FWNvRamStartOffset; >> + MmData[2] = (UINT64)(NvRamSize * 2); >> + UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); >> + >> + Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); >> + Status = MmCommunicationCommunicate ( >> + (VOID *)&mEfiMmSpiNorReq, >> + &Size >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad; >> + if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) { >> + return Status; >> + } >> + >> + ZeroMem ((VOID *)MmData, sizeof (MmData)); >> + MmData[0] = MM_SPINOR_FUNC_WRITE; >> + MmData[1] = (UINT64)FWNvRamStartOffset; >> + MmData[2] = (UINT64)(NvRamSize * 2); >> + MmData[3] = (UINT64)NvRamAddress; >> + UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); >> + >> + Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); >> + Status = MmCommunicationCommunicate ( >> + (VOID *)&mEfiMmSpiNorReq, >> + &Size >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad; >> + if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) { >> + return Status; >> + } >> + >> + /* Update UUID */ >> + ZeroMem ((VOID *)MmData, sizeof (MmData)); >> + MmData[0] = MM_SPINOR_FUNC_ERASE; >> + MmData[1] = (UINT64)(FWNvRamStartOffset + NvRamSize * 2); >> + MmData[2] = (UINT64)sizeof (mBuildUuid); >> + UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); >> + >> + Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); >> + Status = MmCommunicationCommunicate ( >> + (VOID *)&mEfiMmSpiNorReq, >> + &Size >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad; >> + if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) { >> + return Status; >> + } >> + >> + ZeroMem ((VOID *)MmData, sizeof (MmData)); >> + MmData[0] = MM_SPINOR_FUNC_WRITE; >> + MmData[1] = (UINT64)(FWNvRamStartOffset + NvRamSize * 2); >> + MmData[2] = (UINT64)sizeof (mBuildUuid); >> + MmData[3] = (UINT64)mBuildUuid; >> + UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); >> + >> + Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); >> + Status = MmCommunicationCommunicate ( >> + (VOID *)&mEfiMmSpiNorReq, >> + &Size >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad; >> + if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) { >> + return Status; >> + } >> + DEBUG ((DEBUG_INFO, "UUID Changed, Update Storage with FV NVRAM\n")); >> + >> + /* Indicate that NVRAM was cleared */ >> + PcdSetBoolS (PcdNvramErased, TRUE); >> + } else { >> + /* Copy the stored NVRAM to RAM */ >> + ZeroMem ((VOID *)MmData, sizeof (MmData)); >> + MmData[0] = MM_SPINOR_FUNC_READ; >> + MmData[1] = (UINT64)FWNvRamStartOffset; >> + MmData[2] = (UINT64)(NvRamSize * 2); >> + MmData[3] = (UINT64)NvRamAddress; >> + UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); >> + >> + Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); >> + Status = MmCommunicationCommunicate ( >> + (VOID *)&mEfiMmSpiNorReq, >> + &Size >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad; >> + if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) { >> + return Status; >> + } >> + DEBUG ((DEBUG_INFO, "Identical UUID, copy stored NVRAM to RAM\n")); >> + } >> + >> +#if defined(RAM_BLOCKIO_START_ADDRESS) && defined(RAM_BLOCKIO_SIZE) >> + /* Find out about the start offset of NVRAM2 to be passed to SMC */ >> + ZeroMem ((VOID *)MmData, sizeof (MmData)); >> + MmData[0] = MM_SPINOR_FUNC_GET_NVRAM2_INFO; >> + UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); >> + >> + Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); >> + Status = MmCommunicationCommunicate ( >> + (VOID *)&mEfiMmSpiNorReq, >> + &Size >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + MmSpiNorNV2InfoRes = (EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *)&mEfiMmSpiNorReq.PayLoad; >> + if (MmSpiNorNV2InfoRes->Status == MM_SPINOR_RES_SUCCESS) { >> + NV2Base = MmSpiNorNV2InfoRes->NVBase; >> + NV2Size = MmSpiNorNV2InfoRes->NVSize; >> + /* Make sure the requested size is smaller than allocated */ >> + if (RAM_BLOCKIO_SIZE <= NV2Size) { >> + /* Copy the ramdisk image to RAM */ >> + ZeroMem ((VOID *)MmData, sizeof (MmData)); >> + MmData[0] = MM_SPINOR_FUNC_READ; >> + MmData[1] = (UINT64)NV2Base; /* Start virtual address */ >> + MmData[2] = (UINT64)RAM_BLOCKIO_SIZE; >> + MmData[3] = (UINT64)RAM_BLOCKIO_START_ADDRESS; >> + UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); >> + >> + Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); >> + Status = MmCommunicationCommunicate ( >> + (VOID *)&mEfiMmSpiNorReq, >> + &Size >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad; >> + ASSERT (MmSpiNorRes->Status == MM_SPINOR_RES_SUCCESS); >> + } >> + >> + BuildMemoryAllocationHob ( >> + (EFI_PHYSICAL_ADDRESS)RAM_BLOCKIO_START_ADDRESS, >> + EFI_SIZE_TO_PAGES (RAM_BLOCKIO_SIZE) * EFI_PAGE_SIZE, >> + EfiLoaderData >> + ); >> + } >> +#endif >> + >> + return EFI_SUCCESS; >> +} >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c >> new file mode 100644 >> index 000000000000..cd77aed3cfe1 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c >> @@ -0,0 +1,358 @@ >> +/** @file >> + >> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +STATIC EFI_MM_COMMUNICATION_PROTOCOL *mMmCommunicationProtocol = NULL; >> +STATIC EFI_MM_COMM_REQUEST *mCommBuffer = NULL; >> + >> +BOOLEAN mIsEfiRuntime; >> +UINT8 *mTmpBufVirt; >> +UINT8 *mTmpBufPhy; >> + >> +/** >> + This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE >> + event. It converts a pointer to a new virtual address. >> + >> + @param Event Event whose notification function is being invoked. >> + @param Context Pointer to the notification function's context >> + >> +**/ >> +VOID >> +EFIAPI >> +FlashLibAddressChangeEvent ( >> + IN EFI_EVENT Event, >> + IN VOID *Context >> + ) >> +{ >> + gRT->ConvertPointer (0x0, (VOID **)&mTmpBufVirt); >> + gRT->ConvertPointer (0x0, (VOID **)&mCommBuffer); >> + gRT->ConvertPointer (0x0, (VOID **)&mMmCommunicationProtocol); >> + >> + mIsEfiRuntime = TRUE; >> +} >> + >> +EFI_STATUS >> +EFIAPI >> +FlashLibConstructor ( >> + IN EFI_HANDLE ImageHandle, >> + IN EFI_SYSTEM_TABLE *SystemTable >> + ) >> +{ >> + EFI_EVENT VirtualAddressChangeEvent = NULL; >> + EFI_STATUS Status = EFI_SUCCESS; >> + >> + mCommBuffer = AllocateRuntimeZeroPool (sizeof (EFI_MM_COMM_REQUEST)); >> + ASSERT (mCommBuffer != NULL); >> + >> + mTmpBufPhy = AllocateRuntimeZeroPool (EFI_MM_MAX_TMP_BUF_SIZE); >> + mTmpBufVirt = mTmpBufPhy; >> + ASSERT (mTmpBufPhy != NULL); >> + >> + Status = gBS->LocateProtocol ( >> + &gEfiMmCommunicationProtocolGuid, >> + NULL, >> + (VOID **)&mMmCommunicationProtocol >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + Status = gBS->CreateEvent ( >> + EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, >> + TPL_CALLBACK, >> + FlashLibAddressChangeEvent, >> + NULL, >> + &VirtualAddressChangeEvent >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + return EFI_SUCCESS; >> +} >> + >> +STATIC >> +EFI_STATUS >> +FlashMmCommunicate ( >> + IN OUT VOID *CommBuffer, >> + IN OUT UINTN *CommSize >> + ) >> +{ >> + if (mMmCommunicationProtocol == NULL) { >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + return mMmCommunicationProtocol->Communicate ( >> + mMmCommunicationProtocol, >> + CommBuffer, >> + CommSize >> + ); >> +} >> + >> +STATIC >> +EFI_STATUS >> +UefiMmCreateSpiNorReq ( >> + IN VOID *Data, >> + IN UINT64 Size >> + ) >> +{ >> + if (mCommBuffer == NULL) { >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + CopyGuid (&mCommBuffer->EfiMmHdr.HeaderGuid, &gSpiNorMmGuid); >> + mCommBuffer->EfiMmHdr.MsgLength = Size; >> + >> + if (Size != 0) { >> + ASSERT (Data); >> + ASSERT (Size <= EFI_MM_MAX_PAYLOAD_SIZE); >> + >> + CopyMem (mCommBuffer->PayLoad.Data, Data, Size); >> + } >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Convert Virtual Address to Physical Address at Runtime Services >> + >> + @param VirtualPtr Virtual Address Pointer >> + @param Size Total bytes of the buffer >> + >> + @retval Ptr Return the pointer of the converted address >> + >> +**/ >> +STATIC >> +UINT8 * >> +ConvertVirtualToPhysical ( >> + IN UINT8 *VirtualPtr, >> + IN UINTN Size >> + ) >> +{ >> + if (mIsEfiRuntime) { >> + ASSERT (VirtualPtr != NULL); >> + CopyMem ((VOID *)mTmpBufVirt, (VOID *)VirtualPtr, Size); >> + return (UINT8 *)mTmpBufPhy; >> + } >> + >> + return (UINT8 *)VirtualPtr; >> +} >> + >> +/** >> + Convert Physical Address to Virtual Address at Runtime Services >> + >> + @param VirtualPtr Physical Address Pointer >> + @param Size Total bytes of the buffer >> + >> +**/ >> +STATIC >> +VOID >> +ConvertPhysicaltoVirtual ( >> + IN UINT8 *PhysicalPtr, >> + IN UINTN Size >> + ) >> +{ >> + if (mIsEfiRuntime) { >> + ASSERT (PhysicalPtr != NULL); >> + CopyMem ((VOID *)PhysicalPtr, (VOID *)mTmpBufVirt, Size); >> + } >> +} >> + >> +EFI_STATUS >> +EFIAPI >> +FlashGetNvRamInfo ( >> + OUT UINT64 *NvRamBase, >> + OUT UINT32 *NvRamSize >> + ) >> +{ >> + EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *MmSpiNorNVInfoRes; >> + EFI_STATUS Status; >> + UINT64 MmData[5]; >> + UINTN Size; >> + >> + MmData[0] = MM_SPINOR_FUNC_GET_NVRAM_INFO; >> + >> + Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); >> + if (EFI_ERROR (Status)) { >> + return Status; >> + } >> + >> + Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); >> + Status = FlashMmCommunicate ( >> + mCommBuffer, >> + &Size >> + ); >> + if (EFI_ERROR (Status)) { >> + return Status; >> + } >> + >> + MmSpiNorNVInfoRes = (EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *)&mCommBuffer->PayLoad; >> + if (MmSpiNorNVInfoRes->Status == MM_SPINOR_RES_SUCCESS) { >> + *NvRamBase = MmSpiNorNVInfoRes->NVBase; >> + *NvRamSize = MmSpiNorNVInfoRes->NVSize; >> + DEBUG ((DEBUG_INFO, "NVInfo Base 0x%llx, Size 0x%lx\n", *NvRamBase, *NvRamSize)); >> + } >> + >> + return EFI_SUCCESS; >> +} >> + >> +EFI_STATUS >> +EFIAPI >> +FlashEraseCommand ( >> + IN UINT8 *pBlockAddress, >> + IN UINT32 Length >> + ) >> +{ >> + EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes; >> + EFI_STATUS Status; >> + UINT64 MmData[5]; >> + UINTN Size; >> + >> + ASSERT (pBlockAddress != NULL); >> + >> + MmData[0] = MM_SPINOR_FUNC_ERASE; >> + MmData[1] = (UINT64)pBlockAddress; >> + MmData[2] = Length; >> + >> + Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); >> + if (EFI_ERROR (Status)) { >> + return Status; >> + } >> + >> + Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); >> + Status = FlashMmCommunicate ( >> + mCommBuffer, >> + &Size >> + ); >> + if (EFI_ERROR (Status)) { >> + return Status; >> + } >> + >> + MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mCommBuffer->PayLoad; >> + if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) { >> + DEBUG ((DEBUG_ERROR, "Flash Erase: Device error %llx\n", MmSpiNorRes->Status)); >> + return EFI_DEVICE_ERROR; >> + } >> + >> + return EFI_SUCCESS; >> +} >> + >> +EFI_STATUS >> +EFIAPI >> +FlashProgramCommand ( >> + IN UINT8 *pByteAddress, >> + IN UINT8 *Byte, >> + IN OUT UINTN *Length >> + ) >> +{ >> + EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes; >> + EFI_STATUS Status; >> + UINT64 MmData[5]; >> + UINTN Remain, Size, NumWrite; >> + UINTN Count = 0; >> + >> + ASSERT (pByteAddress != NULL); >> + ASSERT (Byte != NULL); >> + ASSERT (Length != NULL); >> + >> + Remain = *Length; >> + while (Remain > 0) { >> + NumWrite = (Remain > EFI_MM_MAX_TMP_BUF_SIZE) ? EFI_MM_MAX_TMP_BUF_SIZE : Remain; >> + >> + MmData[0] = MM_SPINOR_FUNC_WRITE; >> + MmData[1] = (UINT64)pByteAddress; >> + MmData[2] = NumWrite; >> + MmData[3] = (UINT64)ConvertVirtualToPhysical (Byte + Count, NumWrite); >> + >> + Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); >> + if (EFI_ERROR (Status)) { >> + return Status; >> + } >> + >> + Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); >> + Status = FlashMmCommunicate ( >> + mCommBuffer, >> + &Size >> + ); >> + if (EFI_ERROR (Status)) { >> + return Status; >> + } >> + >> + MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mCommBuffer->PayLoad; >> + if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) { >> + DEBUG ((DEBUG_ERROR, "Flash program: Device error 0x%llx\n", MmSpiNorRes->Status)); >> + return EFI_DEVICE_ERROR; >> + } >> + >> + Remain -= NumWrite; >> + Count += NumWrite; >> + } >> + >> + return EFI_SUCCESS; >> +} >> + >> +EFI_STATUS >> +EFIAPI >> +FlashReadCommand ( >> + IN UINT8 *pByteAddress, >> + OUT UINT8 *Byte, >> + IN OUT UINTN *Length >> + ) >> +{ >> + EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes; >> + EFI_STATUS Status; >> + UINT64 MmData[5]; >> + UINTN Remain, Size, NumRead; >> + UINTN Count = 0; >> + >> + ASSERT (pByteAddress != NULL); >> + ASSERT (Byte != NULL); >> + ASSERT (Length != NULL); >> + >> + Remain = *Length; >> + while (Remain > 0) { >> + NumRead = (Remain > EFI_MM_MAX_TMP_BUF_SIZE) ? EFI_MM_MAX_TMP_BUF_SIZE : Remain; >> + >> + MmData[0] = MM_SPINOR_FUNC_READ; >> + MmData[1] = (UINT64)pByteAddress; >> + MmData[2] = NumRead; >> + MmData[3] = (UINT64)ConvertVirtualToPhysical (Byte + Count, NumRead); >> + >> + Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); >> + if (EFI_ERROR (Status)) { >> + return Status; >> + } >> + >> + Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); >> + Status = FlashMmCommunicate ( >> + mCommBuffer, >> + &Size >> + ); >> + if (EFI_ERROR (Status)) { >> + return Status; >> + } >> + >> + MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mCommBuffer->PayLoad; >> + if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) { >> + DEBUG ((DEBUG_ERROR, "Flash Read: Device error %llx\n", MmSpiNorRes->Status)); >> + return EFI_DEVICE_ERROR; >> + } >> + >> + ConvertPhysicaltoVirtual (Byte + Count, NumRead); >> + Remain -= NumRead; >> + Count += NumRead; >> + } >> + >> + return EFI_SUCCESS; >> +} >> -- >> 2.17.1 >>