From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM04-MW2-obe.outbound.protection.outlook.com (NAM04-MW2-obe.outbound.protection.outlook.com [40.107.101.91]) by mx.groups.io with SMTP id smtpd.web08.10068.1631721563892015702 for ; Wed, 15 Sep 2021 08:59:24 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@os.amperecomputing.com header.s=selector2 header.b=die93wVL; spf=pass (domain: os.amperecomputing.com, ip: 40.107.101.91, mailfrom: nhi@os.amperecomputing.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=XEHTvfc9pD0zTvvl6JwENW3mfBk6O6SRMfH08+U4PiNcyOG15WRspEC+ZH7BKPtpBFJXeFBhnVOTm8eIgfRqVNsUG5lP6WN6ICmjxqpdaHL8X0WP26qLpOkwWXKNUTF9yik5IoPB5BGLlMjatJtD62Rjdots/EGqLoTsq6xMpLYYc27B5u+Wqg40CDEsQruSsBQKGjfl50FrKoFL57QVw0UN3/k3mPcOoJ2LQxW6YJ1nUnYURCXI0eRJLlWIYvPZVuXNWo5qomWSVAmyCiwlTf+62S4nv8KjVQD+2TJ8CD7g1fl47PXu3aDN9zuuy/EgET6WnrNI+hnJZ45g+4ig7A== 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; bh=rN+QvZpMlzV6IdcBjFhEVtzfx8bVZ3Be7hZJe6Ew5jo=; b=hvMD5SFBbY93ifRkSv4RqoJbNOAWNEcPVg/3tMgeXtmj4orJ2nVPy57XcGMRSvQpS9+F20lV86PK3Lq+uaWSXSNMOJn+wxE847S3mZlxVv9F8n6rqeP3Ijv+diKYPSP7KIhyNNOdPWcfZAy6dx7EVaiPNPnzmwe/fv4mXYvAfT/BT0yuHmYqUYk4DJGhzTFslYEFLUg0CMs0s/0jyDY4/Zf5/0nqPixfR1G2EbWfcZJGhe7HvoButFDzwDORdaXNItgwtGe3CNSZT+gKqLIQUZsPGB3HiB4p+zv+LmB6DIEz92UsGUyfSJqj2B+eIT6ob258aIgtPucERMH0E7v+YQ== 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=rN+QvZpMlzV6IdcBjFhEVtzfx8bVZ3Be7hZJe6Ew5jo=; b=die93wVLqyqYFwnJ8XhAYDSyoe1Zq27sJZhdnaHFXUh+bIfO5PfHifL9LM2I5McNoP2jj1o2UV0rwG2n/dQEVXVGdkcdByLzTJYBNGSXkw/6oVAnnFLC2fzcYT6d1CEKkWQgCRXOLfomEEIjBrA5p5VcjzGEEsOEvz+/rziClTs= Authentication-Results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=os.amperecomputing.com; Received: from DM6PR01MB5849.prod.exchangelabs.com (2603:10b6:5:205::20) by DM6PR01MB5513.prod.exchangelabs.com (2603:10b6:5:151::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4500.17; Wed, 15 Sep 2021 15:59:22 +0000 Received: from DM6PR01MB5849.prod.exchangelabs.com ([fe80::8eb:704f:2ba7:9bc3]) by DM6PR01MB5849.prod.exchangelabs.com ([fe80::8eb:704f:2ba7:9bc3%4]) with mapi id 15.20.4523.014; Wed, 15 Sep 2021 15:59:22 +0000 From: "Nhi Pham" To: devel@edk2.groups.io CC: patches@amperecomputing.com, nhi@os.amperecomputing.com, vunguyen@os.amperecomputing.com, Thang Nguyen , Chuong Tran , Phong Vo , Leif Lindholm , Michael D Kinney , Ard Biesheuvel , Nate DeSimone Subject: [PATCH v3 03/28] AmperePlatformPkg: Implement FailSafe library Date: Wed, 15 Sep 2021 22:55:02 +0700 Message-ID: <20210915155527.8176-4-nhi@os.amperecomputing.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210915155527.8176-1-nhi@os.amperecomputing.com> References: <20210915155527.8176-1-nhi@os.amperecomputing.com> X-ClientProxiedBy: HK2PR0302CA0012.apcprd03.prod.outlook.com (2603:1096:202::22) To DM6PR01MB5849.prod.exchangelabs.com (2603:10b6:5:205::20) Return-Path: nhi@os.amperecomputing.com MIME-Version: 1.0 Received: from sw004.amperecomputing.com (118.69.219.201) by HK2PR0302CA0012.apcprd03.prod.outlook.com (2603:1096:202::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.5 via Frontend Transport; Wed, 15 Sep 2021 15:59:18 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b0791852-cc6c-4891-4a6e-08d97861c84c X-MS-TrafficTypeDiagnostic: DM6PR01MB5513: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:5516; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 4kB5as/S2e3Xvc1RBmnq7ha4bB3iUR7wl4zAY39yVAO2JNJF7iawU9weiXd/VXd3BoA+JzZMvrJJ5RQXvNcnjuEdp/tnsAO9x2YR0hY0tPFpy6fjv3E6z7G5l2CC+sGKZ/f9klMjCIP+UaooS8etqMQYU9Y0LYUKhnhpbIe5b849beB/w91DIBMyEIk2nXWJgyLBgb5GYTe7hdnC8gNBidtEd3bixRNl59PIv2Fr3AGeAoasxyKbkDX2TpR1yTmdnLBPY/U5oZnzdmjM+ez5Zq0eYCtEm/LdgE8uOsL6aJstNX+U8BL3Wv/rUr+VYryeSzMRypMQyjnbM3r2NWZ3PT8030gUWBasvRG6wThPa7WxC/In4oIYakdijYH1YBAe8+DzpVARAfjohWsMxOmfFFzX0d3+jDVN7/4rtWs7w3NK7hEtZBFf/tLEpYdqQaL1cA9FhEGiadSxm3+r9WbGtrdwrdyEXPN2picL3+1za0SLOQmGWNXKHwwP97pXGXO2sUbRth6hGLXkvJwbZhs6Dv2VYDaY5dRevA8D2oj8Mp6UEwnE+Hqrx1m6CJXkpXvBxJllVvfafRiZraRVR0k3vQ5CA+wrwkVTGmFrsYv4im9hpO+7PN5hEpT5QkJdIgstfAFvFdDSI+OudgRLypjXF6+psN7/c4AETavnq3VO/gG13+DdJEYUXtQNmZOQnV9RBSajddwZvAk1vdAPQRt2OQ== 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)(376002)(136003)(366004)(396003)(39850400004)(346002)(316002)(30864003)(1076003)(5660300002)(83380400001)(54906003)(6506007)(6666004)(4326008)(8676002)(186003)(956004)(6512007)(86362001)(38100700002)(6486002)(38350700002)(478600001)(66946007)(66476007)(66556008)(2616005)(26005)(6916009)(8936002)(52116002)(2906002);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?faUrpfgfrOrepyfKIWtf7u0OY3eu2y9PmwSI/fP+V/F1qvKIYsw49eko5Dqg?= =?us-ascii?Q?WhKEShCvWUkPjYnEoacG9PsKgKW5M7Z0z24kprB8t+MNlumVtGvZcpS7kure?= =?us-ascii?Q?oFzshiYPYLMYPcHEfKdr3/QESxsgX0fB27HsHcMzXPcxmo7O8tF7bW1h56Lu?= =?us-ascii?Q?aOWDIojawFcQMadRYjJ5Gvjaq3Dqz9lWA7mEwvRGLASSW+MEN4/c3I/Fvmj1?= =?us-ascii?Q?DaUlI8nVH80G5RR3yuOVtUSt/vORYJ50KsZIK6aVmmn6kkjOL8MS65ldTKNk?= =?us-ascii?Q?tlc+iMoijIKkGKCA1zN9sdRv3mb05aYjBN2Wq5Mh3YIAV/lta8/XFxs2cpJb?= =?us-ascii?Q?bzSY4/Z+86m5q24Rn/oPqL7l6bEUXFZk0Yv3gjy8MDM5zJ+BWqyhp8Av661B?= =?us-ascii?Q?dRTnzrJEpCvIIRRAh7FLcRxq7cODypD5nkcu4GGfTLfQ8hTyWiMMLADRZlCV?= =?us-ascii?Q?rYkBViE/3UVd0lHBEAYnWrmZJfbZkwayyNRrLOx/eEo+sORAhqLSqLvq0eRq?= =?us-ascii?Q?O2jAFjO7bYE7t7Hf9/ayWfcp0PQjLV62Cqq1HMgVCzspNzBwTnz7gJqBxGqQ?= =?us-ascii?Q?9DVY8DLr4XThlrNNa4ymztZyelL4wqlJkRd7Ha3eT72sKuMF+XwpfYN8OWUs?= =?us-ascii?Q?oQBn2dI6lebz39hmSGW8dS8rTxie2umNyHhkbP5WPha3fuZcuug7BiC16W+c?= =?us-ascii?Q?+58tmDVVuvPBr+HkZ3j9Hl53OdM341A+RImrfVux/m2S5zaDl+KYJcgB51hl?= =?us-ascii?Q?sXzos5se0wFUDYpGX7g7kDNpKAdi2dyzvPN9dnT4ADuKbL/51GnwIIK4mBt4?= =?us-ascii?Q?aUuU2n0uG/yozBdNJJfYLmA9PdJquad3FSxiZIQmOVv5Xoa9rRrZhi03IZZ0?= =?us-ascii?Q?g90XmAHiiiRgsCc+JcGF8lI6xs8ieULuutcMiXq4k7UkUNjK7eVhq0vElCHk?= =?us-ascii?Q?1w6q39msuytkk5lccjliZpWe1SwPJ2kuieNbQBEG6mZQiVflU3cDTUO+jKET?= =?us-ascii?Q?0O8NsQ0kwaRLpBCclMsLYhYfKroJerBTv2UmR7cHky5YmK0DV7lQpBzWMn4a?= =?us-ascii?Q?fpWA8iUKk9viM/M0aPeqiqCxLpYjAvicNlulH/D3sIy8kUFFRBRQe6+tfVCD?= =?us-ascii?Q?AIjs2MSh0GnTq2vPf7im+GKupHMy2xCMd3G9R0hvyAaW67G2WrUdxW0yk443?= =?us-ascii?Q?9x/HOgXCDvUntFleCq92+5WYv8FmgZw1ZM/n1GzuNx4Bj7uROGmgbkw+R9sL?= =?us-ascii?Q?zN25PAwcNFbMQJ/ZwKCyohjr1/2I51MYpS3mrGU4UWJc/oWIM5UceOvJ45Ps?= =?us-ascii?Q?Xt2ARmGsoFUu79CMREEVWT66?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: b0791852-cc6c-4891-4a6e-08d97861c84c X-MS-Exchange-CrossTenant-AuthSource: DM6PR01MB5849.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Sep 2021 15:59:22.2376 (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: 6lZs+VUtZ4zDNkpLdiPPg+Cxep413beGeFXQiCC06fNU2rpV6XVlLIMuFbj8PnEfAqL6917jrLKgdRQbYXgzYHbe5y+hvWlv/6Xx8PmcuGY= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR01MB5513 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain The Ampere Altra System Firmware provides a fail-safe feature to help recover the system if there are setting changes such as Core voltage, DRAM parameters that cause the UEFI failed to boot. The FailSafeLib supports API calls to Secure World to: * Get the FailSafe region information. * Get the current FailSafe status. * Inform to FailSafe monitor that the system boots successfully. * Simulate UEFI boot failure due to config wrong NVPARAM for testing failsafe feature. This library will be consumed by FailSafe DXE driver. 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: Nhi Pham Reviewed-by: Leif Lindholm --- Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec | = 3 + Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf | 4= 1 +++ Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h | 6= 2 ++++ Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c | 31= 3 ++++++++++++++++++++ 4 files changed, 419 insertions(+) diff --git a/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec b/Plat= form/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec index 7c1d1f84f780..6e33d96c7ea5 100644 --- a/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec +++ b/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec @@ -22,7 +22,10 @@ [Defines] # ##########################################################################= ###### [Includes] + Include # Root include for the package =20 [LibraryClasses] + ## @libraryclass Provides functions to support FailSafe operations. + FailSafeLib|Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLi= b.h =20 [Guids] diff --git a/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafe= Lib.inf b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib= .inf new file mode 100644 index 000000000000..456b9d5fc85b --- /dev/null +++ b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf @@ -0,0 +1,41 @@ +## @file +# +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x0001001B + BASE_NAME =3D FailSafeLib + FILE_GUID =3D 3403D080-6D76-11E7-907B-A6006AD3DBA0 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D FailSafeLib + +[Sources] + FailSafeLib.c + +[Protocols] + gEfiMmCommunicationProtocolGuid ## CONSUMES + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec + Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec + +[LibraryClasses] + ArmSmcLib + BaseLib + BaseMemoryLib + DebugLib + HobLib + IoLib + NVParamLib + +[Guids] + gSpiNorMmGuid diff --git a/Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.= h b/Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h new file mode 100644 index 000000000000..7ebd1c8a74a2 --- /dev/null +++ b/Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h @@ -0,0 +1,62 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef FAILSAFE_LIB_H_ +#define FAILSAFE_LIB_H_ + +enum { + MM_SPINOR_FUNC_GET_INFO, + MM_SPINOR_FUNC_READ, + MM_SPINOR_FUNC_WRITE, + MM_SPINOR_FUNC_ERASE, + MM_SPINOR_FUNC_GET_NVRAM_INFO, + MM_SPINOR_FUNC_GET_NVRAM2_INFO, + MM_SPINOR_FUNC_GET_FAILSAFE_INFO +}; + +#define MM_SPINOR_RES_SUCCESS 0xAABBCC00 +#define MM_SPINOR_RES_FAIL 0xAABBCCFF + +enum { + FAILSAFE_BOOT_NORMAL =3D 0, + FAILSAFE_BOOT_LAST_KNOWN_SETTINGS, + FAILSAFE_BOOT_DEFAULT_SETTINGS, + FAILSAFE_BOOT_DDR_DOWNGRADE, + FAILSAFE_BOOT_SUCCESSFUL +}; + +/** + Get the FailSafe region information. +**/ +EFI_STATUS +EFIAPI +FailSafeGetRegionInfo ( + UINT64 *Offset, + UINT64 *Size + ); + +/** + Inform to FailSafe monitor that the system boots successfully. +**/ +EFI_STATUS +EFIAPI +FailSafeBootSuccessfully ( + VOID + ); + +/** + Simulate UEFI boot failure due to config wrong NVPARAM for + testing failsafe feature +**/ +EFI_STATUS +EFIAPI +FailSafeTestBootFailure ( + VOID + ); + +#endif /* FAILSAFE_LIB_H_ */ diff --git a/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafe= Lib.c b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c new file mode 100644 index 000000000000..d74962d73396 --- /dev/null +++ b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c @@ -0,0 +1,313 @@ +/** @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 +#include +#include +#include +#include + +#define EFI_MM_MAX_PAYLOAD_U64_E 10 +#define EFI_MM_MAX_PAYLOAD_SIZE (EFI_MM_MAX_PAYLOAD_U64_E * sizeof (UINT= 64)) + +EFI_MM_COMMUNICATION_PROTOCOL *mFlashLibMmCommProtocol =3D NULL; + +typedef struct { + /* Allows for disambiguation of the message format */ + EFI_GUID HeaderGuid; + /* + * Describes the size of Data (in bytes) and does not include the size + * of the header + */ + UINTN MsgLength; +} EFI_MM_COMM_HEADER_NOPAYLOAD; + +typedef struct { + UINT64 Data[EFI_MM_MAX_PAYLOAD_U64_E]; +} EFI_MM_COMM_SPINOR_PAYLOAD; + +typedef struct { + EFI_MM_COMM_HEADER_NOPAYLOAD EfiMmHdr; + EFI_MM_COMM_SPINOR_PAYLOAD PayLoad; +} EFI_MM_COMM_REQUEST; + +typedef struct { + UINT64 Status; +} EFI_MM_COMMUNICATE_SPINOR_RES; + +typedef struct { + UINT64 Status; + UINT64 FailSafeBase; + UINT64 FailSafeSize; +} EFI_MM_COMMUNICATE_SPINOR_FAILSAFE_INFO_RES; + +EFI_MM_COMM_REQUEST mEfiMmSpiNorReq; + +#pragma pack(1) +typedef struct { + UINT8 ImgMajorVer; + UINT8 ImgMinorVer; + UINT32 NumRetry1; + UINT32 NumRetry2; + UINT32 MaxRetry; + UINT8 Status; + /* + * Byte[3]: Reserved + * Byte[2]: Slave MCU Failure Mask + * Byte[1]: Reserved + * Byte[0]: Master MCU Failure Mask + */ + UINT32 MCUFailsMask; + UINT16 CRC16; + UINT8 Reserved[3]; +} FAIL_SAFE_CONTEXT; + +#pragma pack() + +STATIC +EFI_STATUS +UefiMmCreateSpiNorReq ( + VOID *Data, + UINT64 Size + ) +{ + CopyGuid (&mEfiMmSpiNorReq.EfiMmHdr.HeaderGuid, &gSpiNorMmGuid); + mEfiMmSpiNorReq.EfiMmHdr.MsgLength =3D Size; + + if (Size !=3D 0) { + ASSERT (Data); + ASSERT (Size <=3D EFI_MM_MAX_PAYLOAD_SIZE); + + CopyMem (mEfiMmSpiNorReq.PayLoad.Data, Data, Size); + } + + return EFI_SUCCESS; +} + +STATIC +INTN +CheckCrc16 ( + UINT8 *Pointer, + INTN Count + ) +{ + INTN Crc =3D 0; + INTN Index; + + while (--Count >=3D 0) { + Crc =3D Crc ^ (INTN)*Pointer++ << 8; + for (Index =3D 0; Index < 8; ++Index) { + if ((Crc & 0x8000) !=3D 0) { + Crc =3D Crc << 1 ^ 0x1021; + } else { + Crc =3D Crc << 1; + } + } + } + + return Crc & 0xFFFF; +} + +BOOLEAN +FailSafeValidCRC ( + FAIL_SAFE_CONTEXT *FailSafeBuf + ) +{ + UINT8 Valid; + UINT16 Crc; + UINT32 Len; + + Len =3D sizeof (FAIL_SAFE_CONTEXT); + Crc =3D FailSafeBuf->CRC16; + FailSafeBuf->CRC16 =3D 0; + + Valid =3D (Crc =3D=3D CheckCrc16 ((UINT8 *)FailSafeBuf, Len)); + FailSafeBuf->CRC16 =3D Crc; + + return Valid; +} + +BOOLEAN +FailSafeFailureStatus ( + UINT8 Status + ) +{ + if ((Status =3D=3D FAILSAFE_BOOT_LAST_KNOWN_SETTINGS) || + (Status =3D=3D FAILSAFE_BOOT_DEFAULT_SETTINGS) || + (Status =3D=3D FAILSAFE_BOOT_DDR_DOWNGRADE)) + { + return TRUE; + } + + return FALSE; +} + +EFI_STATUS +EFIAPI +FailSafeGetRegionInfo ( + UINT64 *Offset, + UINT64 *Size + ) +{ + EFI_MM_COMMUNICATE_SPINOR_FAILSAFE_INFO_RES *MmSpiNorFailSafeInfoRes; + UINT64 MmData[5]; + UINTN DataSize; + EFI_STATUS Status; + + if (mFlashLibMmCommProtocol =3D=3D NULL) { + Status =3D gBS->LocateProtocol ( + &gEfiMmCommunicationProtocolGuid, + NULL, + (VOID **)&mFlashLibMmCommProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Can't locate gEfiMmCommunicationProtocolGu= id\n", __FUNCTION__)); + return Status; + } + } + + MmData[0] =3D MM_SPINOR_FUNC_GET_FAILSAFE_INFO; + UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); + + DataSize =3D sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); + Status =3D mFlashLibMmCommProtocol->Communicate ( + mFlashLibMmCommProtocol, + (VOID *)&mEfiMmSpiNorReq, + &DataSize + ); + ASSERT_EFI_ERROR (Status); + + MmSpiNorFailSafeInfoRes =3D (EFI_MM_COMMUNICATE_SPINOR_FAILSAFE_INFO_RES= *)&mEfiMmSpiNorReq.PayLoad; + if (MmSpiNorFailSafeInfoRes->Status !=3D MM_SPINOR_RES_SUCCESS) { + DEBUG (( + DEBUG_ERROR, + "%a: Get flash information failed: 0x%llx\n", + __FUNCTION__, + MmSpiNorFailSafeInfoRes->Status + )); + return EFI_DEVICE_ERROR; + } + + *Offset =3D MmSpiNorFailSafeInfoRes->FailSafeBase; + *Size =3D MmSpiNorFailSafeInfoRes->FailSafeSize; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +FailSafeBootSuccessfully ( + VOID + ) +{ + EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes; + UINT64 MmData[5]; + UINTN Size; + EFI_STATUS Status; + UINT64 FailSafeStartOffset; + UINT64 FailSafeSize; + FAIL_SAFE_CONTEXT FailSafeBuf; + + Status =3D FailSafeGetRegionInfo (&FailSafeStartOffset, &FailSafeSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to get context region information\n",= __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + + MmData[0] =3D MM_SPINOR_FUNC_READ; + MmData[1] =3D FailSafeStartOffset; + MmData[2] =3D (UINT64)sizeof (FAIL_SAFE_CONTEXT); + MmData[3] =3D (UINT64)&FailSafeBuf; + UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); + + Size =3D sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); + Status =3D mFlashLibMmCommProtocol->Communicate ( + mFlashLibMmCommProtocol, + (VOID *)&mEfiMmSpiNorReq, + &Size + ); + ASSERT_EFI_ERROR (Status); + + MmSpiNorRes =3D (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoa= d; + if (MmSpiNorRes->Status !=3D MM_SPINOR_RES_SUCCESS) { + DEBUG (( + DEBUG_ERROR, + "%a: Read context failed: 0x%llx\n", + __FUNCTION__, + MmSpiNorRes->Status + )); + return EFI_DEVICE_ERROR; + } + + /* + * If failsafe context is valid, and: + * - The status indicate non-failure, then don't clear it + * - The status indicate a failure, then go and clear it + */ + if (FailSafeValidCRC (&FailSafeBuf) + && !FailSafeFailureStatus (FailSafeBuf.Status)) { + return EFI_SUCCESS; + } + + MmData[0] =3D MM_SPINOR_FUNC_ERASE; + MmData[1] =3D FailSafeStartOffset; + MmData[2] =3D FailSafeSize; + UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData)); + + Size =3D sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData); + Status =3D mFlashLibMmCommProtocol->Communicate ( + mFlashLibMmCommProtocol, + (VOID *)&mEfiMmSpiNorReq, + &Size + ); + ASSERT_EFI_ERROR (Status); + + MmSpiNorRes =3D (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoa= d; + if (MmSpiNorRes->Status !=3D MM_SPINOR_RES_SUCCESS) { + DEBUG (( + DEBUG_ERROR, + "%a: Erase context failed: 0x%llx\n", + __FUNCTION__, + MmSpiNorRes->Status + )); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +FailSafeTestBootFailure ( + VOID + ) +{ + EFI_STATUS Status; + UINT32 Value =3D 0; + + /* + * Simulate UEFI boot failure due to config wrong NVPARAM for + * testing failsafe feature + */ + Status =3D NVParamGet (NV_UEFI_FAILURE_FAILSAFE_OFFSET, NV_PERM_ALL, &Va= lue); + if (!EFI_ERROR (Status) && (Value =3D=3D 1)) { + while (1) { + } + } + + return EFI_SUCCESS; +} --=20 2.17.1