From: "Tinh Nguyen" <tinhnguyen@os.amperecomputing.com>
To: devel@edk2.groups.io
Cc: patches@amperecomputing.com, quic_llindhol@quicinc.com,
ardb+tianocore@kernel.org, nhi@os.amperecomputing.com,
thang@os.amperecomputing.com, minhnguyen1@os.amperecomputing.com,
khanh.pham@os.amperecomputing.com,
Tinh Nguyen <tinhnguyen@os.amperecomputing.com>
Subject: [edk2-platforms][PATCH 1/1] AmpereAltraPkg: Add PlatformInitDxe module
Date: Tue, 16 May 2023 13:28:38 +0700 [thread overview]
Message-ID: <20230516062838.830272-1-tinhnguyen@os.amperecomputing.com> (raw)
From: Minh Nguyen <minhnguyen1@os.amperecomputing.com>
In FailSafe context, there's one field to indicate which setting is using
to boot (BOOT_LAST_KNOWN_SETTINGS, BOOT_DEFAULT_SETTINGS, BOOT_NORMAL).
At SCP and ATF side, they will check their NVPARAM for Failsafe
(NV_SI_PMPRO_FAILURE_FAILSAFE - NV_SI_ATF_FAILURE_FAILSAFE) to decide
which setting they will use. If Failsafe occurs at SCP or ATF, a mission
of UEFI at DXE phase is to clear Failsafe context for normal behavior.
Signed-off-by: Tinh Nguyen <tinhnguyen@os.amperecomputing.com>
---
Platform/Ampere/JadePkg/Jade.fdf | 5 +
Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc | 5 +
Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.c | 133 ++++++++++++++++++++
Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.h | 38 ++++++
Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.inf | 33 +++++
5 files changed, 214 insertions(+)
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index a578d05330..9d26847b36 100644
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -228,6 +228,11 @@ APRIORI DXE {
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
INF ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
+ #
+ # Initialize works at Dxe phase
+ #
+ INF Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.inf
+
#
# Environment Variables Protocol
#
diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
index 9275e0053a..8191da5820 100644
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -609,6 +609,11 @@
NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
}
+ #
+ # Initialize works at Dxe phase
+ #
+ Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.inf
+
#
# Timer
#
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.c
new file mode 100644
index 0000000000..6e92a59f4b
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.c
@@ -0,0 +1,133 @@
+/** @file
+
+ Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/FlashLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include "PlatformInitDxe.h"
+
+UINT16
+CheckCrc16 (
+ IN UINT8 *Pointer,
+ IN INTN Count
+ )
+{
+ INTN Crc = 0;
+ INTN Index;
+
+ while (--Count >= 0) {
+ Crc = Crc ^ (INTN)*Pointer++ << 8;
+ for (Index = 0; Index < 8; ++Index) {
+ if ((Crc & 0x8000) != 0) {
+ Crc = Crc << 1 ^ 0x1021;
+ } else {
+ Crc = Crc << 1;
+ }
+ }
+ }
+
+ return Crc & 0xFFFF;
+}
+
+BOOLEAN
+FailSafeValidCRC (
+ IN FAIL_SAFE_CONTEXT *FailSafeBuf
+ )
+{
+ BOOLEAN Valid;
+ UINT16 Crc;
+ UINT32 Len;
+
+ Len = sizeof (FAIL_SAFE_CONTEXT);
+ Crc = FailSafeBuf->CRC16;
+ FailSafeBuf->CRC16 = 0;
+
+ Valid = (Crc == CheckCrc16 ((UINT8 *)FailSafeBuf, Len));
+ FailSafeBuf->CRC16 = Crc;
+
+ return Valid;
+}
+
+BOOLEAN
+FailSafeFailureStatus (
+ IN UINT8 Status
+ )
+{
+ if ((Status == FAILSAFE_BOOT_LAST_KNOWN_SETTINGS) ||
+ (Status == FAILSAFE_BOOT_DEFAULT_SETTINGS) ||
+ (Status == FAILSAFE_BOOT_DDR_DOWNGRADE))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+EFI_STATUS
+FailSafeClearContext (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ FAIL_SAFE_CONTEXT FailSafeBuf;
+ UINT32 FailSafeSize;
+ UINT64 FailSafeStartOffset;
+
+ Status = FlashGetFailSafeInfo (&FailSafeStartOffset, &FailSafeSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to get context region information\n", __func__));
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = FlashReadCommand (FailSafeStartOffset, (UINT8 *)&FailSafeBuf, sizeof (FAIL_SAFE_CONTEXT));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // 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;
+ }
+
+ return FlashEraseCommand (FailSafeStartOffset, FailSafeSize);
+}
+
+EFI_STATUS
+EFIAPI
+PlatformInitDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // In FailSafe context, there's one field to indicate which setting is using
+ // to boot (BOOT_LAST_KNOWN_SETTINGS, BOOT_DEFAULT_SETTINGS, BOOT_NORMAL).
+ //
+ // At SCP and ATF side, they will check their NVPARAM for Failsafe
+ // (NV_SI_PMPRO_FAILURE_FAILSAFE - NV_SI_ATF_FAILURE_FAILSAFE) to decide
+ // which setting they will use. If Failsafe occurs at SCP or ATF, a mission
+ // of UEFI at DXE phase is to clear Failsafe context for normal behavior.
+ //
+
+ Status = FailSafeClearContext ();
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.h
new file mode 100644
index 0000000000..3e6da742d0
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.h
@@ -0,0 +1,38 @@
+/** @file
+
+ Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PLATFORM_INIT_DXE_H_
+#define PLATFORM_INIT_DXE_H_
+
+#define FAILSAFE_BOOT_NORMAL 0x00
+#define FAILSAFE_BOOT_LAST_KNOWN_SETTINGS 0x01
+#define FAILSAFE_BOOT_DEFAULT_SETTINGS 0x02
+#define FAILSAFE_BOOT_DDR_DOWNGRADE 0x03
+#define FAILSAFE_BOOT_SUCCESSFUL 0x04
+
+#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()
+
+#endif /* PLATFORM_INIT_DXE_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.inf
new file mode 100644
index 0000000000..9074e56ded
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInitDxe/PlatformInitDxe.inf
@@ -0,0 +1,33 @@
+## @file
+#
+# Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = PlatformInitDxe
+ FILE_GUID = 59E2571E-9A57-4247-A586-BF151F900876
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PlatformInitDxeEntryPoint
+
+[Sources]
+ PlatformInitDxe.h
+ PlatformInitDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ FlashLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Depex]
+ TRUE
--
2.40.0
reply other threads:[~2023-05-16 6:29 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20230516062838.830272-1-tinhnguyen@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