From: "Nhi Pham" <nhi@os.amperecomputing.com>
To: devel@edk2.groups.io
Cc: Nhi Pham <nhi@os.amperecomputing.com>
Subject: [edk2-platforms][PATCH 02/34] Platform/Ampere: Implement FailSafe library
Date: Wed, 9 Dec 2020 16:24:59 +0700 [thread overview]
Message-ID: <20201209092531.30867-3-nhi@os.amperecomputing.com> (raw)
In-Reply-To: <20201209092531.30867-1-nhi@os.amperecomputing.com>
The FailSafeLib support 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 is consumed by FailSafe DXE driver.
Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
Platform/Ampere/AmperePkg.dec | 3 +
Platform/Ampere/Library/FailSafeLib/FailSafeLib.inf | 41 +++
Platform/Ampere/Include/Library/FailSafeLib.h | 64 +++++
Platform/Ampere/Library/FailSafeLib/FailSafeLib.c | 267 ++++++++++++++++++++
4 files changed, 375 insertions(+)
diff --git a/Platform/Ampere/AmperePkg.dec b/Platform/Ampere/AmperePkg.dec
index e6a73b25286c..472b44550fee 100755
--- a/Platform/Ampere/AmperePkg.dec
+++ b/Platform/Ampere/AmperePkg.dec
@@ -22,7 +22,10 @@ [Defines]
#
################################################################################
[Includes]
+ Include # Root include for the package
[LibraryClasses]
+ ## @libraryclass Provides functions to support FailSafe operations.
+ FailSafeLib|Platform/Ampere/Include/Library/FailSafeLib.h
[Guids]
diff --git a/Platform/Ampere/Library/FailSafeLib/FailSafeLib.inf b/Platform/Ampere/Library/FailSafeLib/FailSafeLib.inf
new file mode 100755
index 000000000000..3ce0c2209cf1
--- /dev/null
+++ b/Platform/Ampere/Library/FailSafeLib/FailSafeLib.inf
@@ -0,0 +1,41 @@
+## @file
+#
+# Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = FailSafeLib
+ FILE_GUID = 3403D080-6D76-11E7-907B-A6006AD3DBA0
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FailSafeLib
+
+[Sources]
+ FailSafeLib.c
+
+[Protocols]
+ gEfiMmCommunicationProtocolGuid ## CONSUMES
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ MdePkg/MdePkg.dec
+ Silicon/Ampere/AmperePkg.dec
+ Silicon/Ampere/AmpereAltraPkg/Ac01Pkg.dec
+ Platform/Ampere/AmperePkg.dec
+
+[LibraryClasses]
+ IoLib
+ DebugLib
+ BaseLib
+ BaseMemoryLib
+ ArmSmcLib
+ HobLib
+ NVParamLib
+
+[Guids]
+ gSpiNorMmGuid
diff --git a/Platform/Ampere/Include/Library/FailSafeLib.h b/Platform/Ampere/Include/Library/FailSafeLib.h
new file mode 100755
index 000000000000..6319284e5ecd
--- /dev/null
+++ b/Platform/Ampere/Include/Library/FailSafeLib.h
@@ -0,0 +1,64 @@
+/** @file
+
+ Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+
+ 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 = 0,
+ FAILSAFE_BOOT_LAST_KNOWN_SETTINGS,
+ FAILSAFE_BOOT_DEFAULT_SETTINGS,
+ FAILSAFE_BOOT_SUCCESSFUL
+};
+
+/**
+ Get the FailSafe region information.
+**/
+EFI_STATUS
+EFIAPI
+FailSafeGetRegionInfo (
+ UINT64 *Offset,
+ UINT64 *Size
+ );
+
+/**
+ Get the current FailSafe status.
+**/
+UINT64
+EFIAPI
+FailSafeGetStatus (VOID);
+
+/**
+ 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/Library/FailSafeLib/FailSafeLib.c b/Platform/Ampere/Library/FailSafeLib/FailSafeLib.c
new file mode 100755
index 000000000000..244c0b49d085
--- /dev/null
+++ b/Platform/Ampere/Library/FailSafeLib/FailSafeLib.c
@@ -0,0 +1,267 @@
+/** @file
+
+ Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/UefiRuntimeLib.h>
+#include <PiPei.h>
+#include <Library/ArmSmcLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Library/FailSafeLib.h>
+#include <Library/NVParamLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/MmCommunication.h>
+#include <Platform/Ac01.h>
+
+#define EFI_MM_MAX_PAYLOAD_U64_E 10
+#define EFI_MM_MAX_PAYLOAD_SIZE (EFI_MM_MAX_PAYLOAD_U64_E * sizeof (UINT64))
+
+EFI_MM_COMMUNICATION_PROTOCOL *mFlashLibMmCommProtocol = 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;
+
+typedef struct {
+ 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;
+} __attribute__((packed, aligned(4))) FailsafeCtx_t;
+
+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;
+}
+
+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 == NULL) {
+ Status = gBS->LocateProtocol (
+ &gEfiMmCommunicationProtocolGuid,
+ NULL,
+ (VOID **) &mFlashLibMmCommProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Can't locate gEfiMmCommunicationProtocolGuid\n", __FUNCTION__));
+ return Status;
+ }
+ }
+
+ MmData[0] = MM_SPINOR_FUNC_GET_FAILSAFE_INFO;
+ UefiMmCreateSpiNorReq ((VOID *) &MmData, sizeof (MmData));
+
+ DataSize = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+ Status = mFlashLibMmCommProtocol->Communicate (
+ mFlashLibMmCommProtocol,
+ (VOID *) &mEfiMmSpiNorReq,
+ &DataSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ MmSpiNorFailSafeInfoRes = (EFI_MM_COMMUNICATE_SPINOR_FAILSAFE_INFO_RES *) &mEfiMmSpiNorReq.PayLoad;
+ if (MmSpiNorFailSafeInfoRes->Status != MM_SPINOR_RES_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "%a: Get flash information failed: %d\n",
+ __FUNCTION__,
+ MmSpiNorFailSafeInfoRes->Status));
+ return EFI_DEVICE_ERROR;
+ }
+
+ *Offset = MmSpiNorFailSafeInfoRes->FailSafeBase;
+ *Size = 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;
+
+ Status = FailSafeGetRegionInfo (&FailSafeStartOffset, &FailSafeSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to get context region information\n", __FUNCTION__));
+ return EFI_DEVICE_ERROR;
+ }
+
+ ASSERT (mFlashLibMmCommProtocol != NULL);
+
+ MmData[0] = MM_SPINOR_FUNC_ERASE;
+ MmData[1] = FailSafeStartOffset;
+ MmData[2] = FailSafeSize;
+ UefiMmCreateSpiNorReq ((VOID *) &MmData, sizeof (MmData));
+
+ Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+ Status = mFlashLibMmCommProtocol->Communicate (
+ mFlashLibMmCommProtocol,
+ (VOID *) &mEfiMmSpiNorReq,
+ &Size
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *) &mEfiMmSpiNorReq.PayLoad;
+ if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "%a: erase context failed: %d\n",
+ __FUNCTION__,
+ MmSpiNorRes->Status));
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+UINT8
+FailSafeValidStatus (
+ IN UINT8 Status
+ )
+{
+ if ((Status == FAILSAFE_BOOT_NORMAL) ||
+ (Status == FAILSAFE_BOOT_LAST_KNOWN_SETTINGS) ||
+ (Status == FAILSAFE_BOOT_DEFAULT_SETTINGS) ||
+ (Status == FAILSAFE_BOOT_SUCCESSFUL)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+UINT64
+EFIAPI
+FailSafeGetStatus (VOID)
+{
+ EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes;
+ UINT64 MmData[5];
+ UINTN Size;
+ EFI_STATUS Status;
+ UINT64 FailSafeStartOffset;
+ UINT64 FailSafeSize;
+ FailsafeCtx_t FailsafeBuf;
+
+ Status = FailSafeGetRegionInfo (&FailSafeStartOffset, &FailSafeSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to get region information\n", __FUNCTION__));
+ return EFI_DEVICE_ERROR;
+ }
+
+ ASSERT (mFlashLibMmCommProtocol != NULL);
+
+ MmData[0] = MM_SPINOR_FUNC_READ;
+ MmData[1] = FailSafeStartOffset;
+ MmData[2] = (UINT64) sizeof (FailsafeCtx_t);
+ MmData[3] = (UINT64) &FailsafeBuf;
+ UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof(MmData));
+
+ Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+ Status = mFlashLibMmCommProtocol->Communicate (
+ mFlashLibMmCommProtocol,
+ (VOID *) &mEfiMmSpiNorReq,
+ &Size
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *) &mEfiMmSpiNorReq.PayLoad;
+ if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "%a: read context failed: %d\n",
+ __FUNCTION__,
+ MmSpiNorRes->Status));
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (FailSafeValidStatus (FailsafeBuf.Status) == 0) {
+ FailsafeBuf.Status = FAILSAFE_BOOT_NORMAL;
+ }
+
+ return FailsafeBuf.Status;
+}
+
+EFI_STATUS
+EFIAPI
+FailSafeTestBootFailure (VOID)
+{
+ EFI_STATUS Status;
+ UINT32 Value = 0;
+
+ /*
+ * Simulate UEFI boot failure due to config wrong NVPARAM for
+ * testing failsafe feature
+ */
+ Status = NVParamGet (NV_UEFI_FAILURE_FAILSAFE_OFFSET, NV_PERM_ALL, &Value);
+ if (!EFI_ERROR (Status) && (Value == 1)) {
+ while (1);
+ }
+
+ return EFI_SUCCESS;
+}
--
2.17.1
next prev parent reply other threads:[~2020-12-09 9:24 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-09 9:24 [edk2-platforms][PATCH 00/34] Add new Ampere Mt. Jade platform Nhi Pham
2020-12-09 9:24 ` [edk2-platforms][PATCH 01/34] Initial support for Ampere Altra and " Nhi Pham
2021-01-07 23:57 ` [edk2-devel] " Leif Lindholm
2021-01-15 4:59 ` Vu Nguyen
2020-12-09 9:24 ` Nhi Pham [this message]
2020-12-09 9:25 ` [edk2-platforms][PATCH 03/34] Platform/Ampere: Add FailSafe and WDT support Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 04/34] AmpereAltraPkg: Implement GpioLib and I2cLib modules Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 05/34] JadePkg: Implement RealTimeClockLib for PCF85063 Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 06/34] Platform/Ampere: Add AcpiPccLib to support ACPI PCCT Table Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 07/34] Platform/Ampere: Add AcpiHelperLib to update ACPI DSDT table Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 08/34] JadePkg: Initial support for static ACPI tables Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 09/34] JadePkg: Install some ACPI tables at runtime Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 10/34] Silicon/Ampere: Support Non Volatile storage for Variable service Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 11/34] Silicon/Ampere: Support PlatformManagerUiLib Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 12/34] AmpereAltraPkg: Add PcieCore Library Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 13/34] AmpereAltraPkg: Add PciHostBridge driver Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 14/34] JadePkg: Add implementation for PcieBoardLib Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 15/34] JadePkg: Enable PCIe support Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 16/34] JadePkg: Add ASpeed GOP driver Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 17/34] Silicon/Ampere: Add Random Number Generator Support Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 18/34] Silicon/Ampere: Fixup runtime memory attribute Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 19/34] JadePkg: Add SMBIOS tables support Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 20/34] AmpereAltraPkg: Add DebugInfoPei module Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 21/34] Silicon/Ampere: Add platform info screen Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 22/34] Silicon/Ampere: Add Memory " Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 23/34] AmpereAltraPkg: Add CPU Configuration for SubNUMA Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 24/34] AmpereAltraPkg: Add ACPI configuration screen Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 25/34] AmpereAltraPkg: Implement PlatformFlashAccessLib instance Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 26/34] JadePkg: Add implementation for UEFI Capsule Update Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 27/34] JadePkg: Add Capsule Update support Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 28/34] Silicon/Ampere: Implement PlatformBootManagerLib for LinuxBoot Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 29/34] Platform/Ampere: Add LinuxBoot image Nhi Pham
2020-12-10 12:40 ` [edk2-devel] " Leif Lindholm
2020-12-11 2:38 ` Nhi Pham
2020-12-11 11:15 ` Leif Lindholm
2020-12-09 9:25 ` [edk2-platforms][PATCH 30/34] JadePkg: Support LinuxBoot DSC/FDF build for Jade platform Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 31/34] AmpereAltraPkg: Add BootProgress support Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 32/34] JadePkg: Add ACPI/APEI tables Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 33/34] Platform/Ampere: Add AcpiApeiLib Nhi Pham
2020-12-09 9:25 ` [edk2-platforms][PATCH 34/34] AmpereAltraPkg, JadePkg: Add RAS setting screen Nhi Pham
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201209092531.30867-3-nhi@os.amperecomputing.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox