public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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