public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel] [PATCH v5 0/3] ArmPkg: GenericWatchdogDxe fixes and improvements
@ 2024-01-29 18:25 Rebecca Cran via groups.io
  2024-01-29 18:25 ` [edk2-devel] [PATCH v5 1/3] ArmPkg: Update GenericWatchdogDxe to allow setting full 48-bit offset Rebecca Cran via groups.io
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Rebecca Cran via groups.io @ 2024-01-29 18:25 UTC (permalink / raw)
  To: Leif Lindholm, Ard Biesheuvel, Sami Mujawar, devel; +Cc: Rebecca Cran

Fixes and improvements to GenericWatchdogDxe.

PR: https://github.com/tianocore/edk2/pull/5176

Changes between v4 and v5:

- Updated documentation header for WatchdogSetTimerPeriod.
- Added GetMaxWatchdogOffsetRegisterValue to do arch revision check.
- Renamed GENERIC_WDOG_ macros.

Rebecca Cran (3):
  ArmPkg: Update GenericWatchdogDxe to allow setting full 48-bit offset
  ArmPkg: Introduce global mTimerPeriod and remove calculation
  ArmPkg: Disable watchdog interaction after exiting boot services

 ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h    | 11 ++-
 ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c | 94 ++++++++++++++------
 2 files changed, 79 insertions(+), 26 deletions(-)

-- 
2.34.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114726): https://edk2.groups.io/g/devel/message/114726
Mute This Topic: https://groups.io/mt/104037316/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [edk2-devel] [PATCH v5 1/3] ArmPkg: Update GenericWatchdogDxe to allow setting full 48-bit offset
  2024-01-29 18:25 [edk2-devel] [PATCH v5 0/3] ArmPkg: GenericWatchdogDxe fixes and improvements Rebecca Cran via groups.io
@ 2024-01-29 18:25 ` Rebecca Cran via groups.io
  2024-01-30 14:01   ` Sami Mujawar
  2024-01-29 18:25 ` [edk2-devel] [PATCH v5 2/3] ArmPkg: Introduce global mTimerPeriod and remove calculation Rebecca Cran via groups.io
  2024-01-29 18:25 ` [edk2-devel] [PATCH v5 3/3] ArmPkg: Disable watchdog interaction after exiting boot services Rebecca Cran via groups.io
  2 siblings, 1 reply; 8+ messages in thread
From: Rebecca Cran via groups.io @ 2024-01-29 18:25 UTC (permalink / raw)
  To: Leif Lindholm, Ard Biesheuvel, Sami Mujawar, devel; +Cc: Rebecca Cran

The generic watchdog offset register is 48 bits wide, and can be set by
performing two 32-bit writes.

Add support for writing the high 16 bits of the offset register and
update the signature of the WatchdogWriteOffsetRegister function to take
a UINT64 value.

Signed-off-by: Rebecca Cran <rebecca@os.amperecomputing.com>
---
 ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h    | 11 ++++-
 ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c | 48 ++++++++++++++++++--
 2 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h
index 9bc3bf47047c..b7d6f7e7847e 100644
--- a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h
+++ b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h
@@ -1,9 +1,13 @@
 /** @file
 *
+*  Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
 *  Copyright (c) 2013-2017, ARM Limited. All rights reserved.
 *
 *  SPDX-License-Identifier: BSD-2-Clause-Patent
 *
+*  @par Reference(s):
+*  - Generic Watchdog specification in Arm Base System Architecture 1.0C:
+*    https://developer.arm.com/documentation/den0094/c/
 **/
 
 #ifndef GENERIC_WATCHDOG_H_
@@ -14,12 +18,17 @@
 
 // Control Frame:
 #define GENERIC_WDOG_CONTROL_STATUS_REG      ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x000)
-#define GENERIC_WDOG_OFFSET_REG              ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x008)
+#define GENERIC_WDOG_OFFSET_REG_LOW          ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x008)
+#define GENERIC_WDOG_OFFSET_REG_HIGH         ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x00C)
 #define GENERIC_WDOG_COMPARE_VALUE_REG_LOW   ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x010)
 #define GENERIC_WDOG_COMPARE_VALUE_REG_HIGH  ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x014)
+#define GENERIC_WDOG_IID_REG                 ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0xFCC)
 
 // Values of bit 0 of the Control/Status Register
 #define GENERIC_WDOG_ENABLED   1
 #define GENERIC_WDOG_DISABLED  0
 
+#define GENERIC_WDOG_IID_ARCH_REV_SHIFT  16
+#define GENERIC_WDOG_IID_ARCH_REV_MASK   0xF
+
 #endif // GENERIC_WATCHDOG_H_
diff --git a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
index 66c6c37c08b0..6ff947d4b746 100644
--- a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
+++ b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
@@ -1,5 +1,6 @@
 /** @file
 *
+*  Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
 *  Copyright (c) 2013-2018, ARM Limited. All rights reserved.
 *
 *  SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -35,16 +36,53 @@ STATIC UINTN  mTimerFrequencyHz = 0;
    It is therefore stored here. 0 means the timer is not running. */
 STATIC UINT64  mNumTimerTicks = 0;
 
+/* disables watchdog interaction after Exit Boot Services */
+STATIC BOOLEAN  mExitedBootServices = FALSE;
+
+#define MAX_UINT48  0xFFFFFFFFFFFFULL
+
 STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL  *mInterruptProtocol;
 STATIC EFI_WATCHDOG_TIMER_NOTIFY         mWatchdogNotify;
 
+/**
+  This function returns the maximum watchdog offset register value.
+
+  @retval MAX_UINT32 The watchdog offset register holds a 32-bit value.
+  @retval MAX_UINT48 The watchdog offset register holds a 48-bit value.
+**/
+STATIC
+UINT64
+GetMaxWatchdogOffsetRegisterValue (
+  VOID
+  )
+{
+  UINT64 MaxWatchdogOffsetValue;
+  UINT32 WatchdogIId;
+  UINT8  WatchdogArchRevision;
+
+  WatchdogIId          = MmioRead32 (GENERIC_WDOG_IID_REG);
+  WatchdogArchRevision = (WatchdogIId >> GENERIC_WDOG_IID_ARCH_REV_SHIFT) & GENERIC_WDOG_IID_ARCH_REV_MASK;
+
+  if (WatchdogArchRevision == 0) {
+    MaxWatchdogOffsetValue = MAX_UINT32;
+  } else {
+    MaxWatchdogOffsetValue = MAX_UINT48;
+  }
+
+  return MaxWatchdogOffsetValue;
+
+}
+
 STATIC
 VOID
 WatchdogWriteOffsetRegister (
-  UINT32  Value
+  UINT64  Value
   )
 {
-  MmioWrite32 (GENERIC_WDOG_OFFSET_REG, Value);
+  MmioWrite32 (GENERIC_WDOG_OFFSET_REG_LOW, Value & MAX_UINT32);
+  if (GetMaxWatchdogOffsetRegisterValue () == MAX_UINT48) {
+    MmioWrite32 (GENERIC_WDOG_OFFSET_REG_HIGH, (Value >> 32) & MAX_UINT16);
+  }
 }
 
 STATIC
@@ -211,17 +249,17 @@ WatchdogSetTimerPeriod (
   /* If the number of required ticks is greater than the max the watchdog's
      offset register (WOR) can hold, we need to manually compute and set
      the compare register (WCV) */
-  if (mNumTimerTicks > MAX_UINT32) {
+  if (mNumTimerTicks > MAX_UINT48) {
     /* We need to enable the watchdog *before* writing to the compare register,
        because enabling the watchdog causes an "explicit refresh", which
        clobbers the compare register (WCV). In order to make sure this doesn't
        trigger an interrupt, set the offset to max. */
-    WatchdogWriteOffsetRegister (MAX_UINT32);
+    WatchdogWriteOffsetRegister (MAX_UINT48);
     WatchdogEnable ();
     SystemCount = ArmGenericTimerGetSystemCount ();
     WatchdogWriteCompareRegister (SystemCount + mNumTimerTicks);
   } else {
-    WatchdogWriteOffsetRegister ((UINT32)mNumTimerTicks);
+    WatchdogWriteOffsetRegister (mNumTimerTicks);
     WatchdogEnable ();
   }
 
-- 
2.34.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114729): https://edk2.groups.io/g/devel/message/114729
Mute This Topic: https://groups.io/mt/104037319/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [edk2-devel] [PATCH v5 2/3] ArmPkg: Introduce global mTimerPeriod and remove calculation
  2024-01-29 18:25 [edk2-devel] [PATCH v5 0/3] ArmPkg: GenericWatchdogDxe fixes and improvements Rebecca Cran via groups.io
  2024-01-29 18:25 ` [edk2-devel] [PATCH v5 1/3] ArmPkg: Update GenericWatchdogDxe to allow setting full 48-bit offset Rebecca Cran via groups.io
@ 2024-01-29 18:25 ` Rebecca Cran via groups.io
  2024-01-29 18:25 ` [edk2-devel] [PATCH v5 3/3] ArmPkg: Disable watchdog interaction after exiting boot services Rebecca Cran via groups.io
  2 siblings, 0 replies; 8+ messages in thread
From: Rebecca Cran via groups.io @ 2024-01-29 18:25 UTC (permalink / raw)
  To: Leif Lindholm, Ard Biesheuvel, Sami Mujawar, devel; +Cc: Rebecca Cran

The calculation of the timer period was broken. Introduce a global
mTimerPeriod so the calculation can be removed. Since mTimerFrequencyHz
is only used in one place, remove the global and make it a local
variable. Do the same with mNumTimerTicks.

Signed-off-by: Rebecca Cran <rebecca@os.amperecomputing.com>
Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
---
 ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c | 34 +++++++++-----------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
index 6ff947d4b746..d4f9fe6f4ece 100644
--- a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
+++ b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
@@ -28,13 +28,10 @@
    in a second */
 #define TIME_UNITS_PER_SECOND  10000000
 
-// Tick frequency of the generic timer basis of the generic watchdog.
-STATIC UINTN  mTimerFrequencyHz = 0;
-
 /* In cases where the compare register was set manually, information about
    how long the watchdog was asked to wait cannot be retrieved from hardware.
    It is therefore stored here. 0 means the timer is not running. */
-STATIC UINT64  mNumTimerTicks = 0;
+STATIC UINT64  mTimerPeriod = 0;
 
 /* disables watchdog interaction after Exit Boot Services */
 STATIC BOOLEAN  mExitedBootServices = FALSE;
@@ -125,7 +122,7 @@ WatchdogExitBootServicesEvent (
   )
 {
   WatchdogDisable ();
-  mNumTimerTicks = 0;
+  mTimerPeriod = 0;
 }
 
 /* This function is called when the watchdog's first signal (WS0) goes high.
@@ -140,7 +137,6 @@ WatchdogInterruptHandler (
   )
 {
   STATIC CONST CHAR16  ResetString[] = L"The generic watchdog timer ran out.";
-  UINT64               TimerPeriod;
 
   WatchdogDisable ();
 
@@ -153,8 +149,7 @@ WatchdogInterruptHandler (
   // the timer period plus 1.
   //
   if (mWatchdogNotify != NULL) {
-    TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);
-    mWatchdogNotify (TimerPeriod + 1);
+    mWatchdogNotify (mTimerPeriod + 1);
   }
 
   gRT->ResetSystem (
@@ -234,22 +229,27 @@ WatchdogSetTimerPeriod (
   IN UINT64                            TimerPeriod          // In 100ns units
   )
 {
-  UINTN  SystemCount;
+  UINTN   SystemCount;
+  UINT64  TimerFrequencyHz;
+  UINT64  NumTimerTicks;
 
   // if TimerPeriod is 0, this is a request to stop the watchdog.
   if (TimerPeriod == 0) {
-    mNumTimerTicks = 0;
+    mTimerPeriod = 0;
     WatchdogDisable ();
     return EFI_SUCCESS;
   }
 
   // Work out how many timer ticks will equate to TimerPeriod
-  mNumTimerTicks = (mTimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
+  TimerFrequencyHz = ArmGenericTimerGetTimerFreq ();
+  ASSERT (TimerFrequencyHz != 0);
+  mTimerPeriod  = TimerPeriod;
+  NumTimerTicks = (TimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
 
   /* If the number of required ticks is greater than the max the watchdog's
      offset register (WOR) can hold, we need to manually compute and set
      the compare register (WCV) */
-  if (mNumTimerTicks > MAX_UINT48) {
+  if (NumTimerTicks > MAX_UINT48) {
     /* We need to enable the watchdog *before* writing to the compare register,
        because enabling the watchdog causes an "explicit refresh", which
        clobbers the compare register (WCV). In order to make sure this doesn't
@@ -257,9 +257,9 @@ WatchdogSetTimerPeriod (
     WatchdogWriteOffsetRegister (MAX_UINT48);
     WatchdogEnable ();
     SystemCount = ArmGenericTimerGetSystemCount ();
-    WatchdogWriteCompareRegister (SystemCount + mNumTimerTicks);
+    WatchdogWriteCompareRegister (SystemCount + NumTimerTicks);
   } else {
-    WatchdogWriteOffsetRegister (mNumTimerTicks);
+    WatchdogWriteOffsetRegister (NumTimerTicks);
     WatchdogEnable ();
   }
 
@@ -294,7 +294,7 @@ WatchdogGetTimerPeriod (
     return EFI_INVALID_PARAMETER;
   }
 
-  *TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);
+  *TimerPeriod = mTimerPeriod;
 
   return EFI_SUCCESS;
 }
@@ -361,9 +361,6 @@ GenericWatchdogEntry (
      This will avoid conflicts with the universal watchdog */
   ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
 
-  mTimerFrequencyHz = ArmGenericTimerGetTimerFreq ();
-  ASSERT (mTimerFrequencyHz != 0);
-
   // Install interrupt handler
   Status = mInterruptProtocol->RegisterInterruptSource (
                                  mInterruptProtocol,
@@ -405,7 +402,6 @@ GenericWatchdogEntry (
                   );
   ASSERT_EFI_ERROR (Status);
 
-  mNumTimerTicks = 0;
   WatchdogDisable ();
 
   return EFI_SUCCESS;
-- 
2.34.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114728): https://edk2.groups.io/g/devel/message/114728
Mute This Topic: https://groups.io/mt/104037318/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [edk2-devel] [PATCH v5 3/3] ArmPkg: Disable watchdog interaction after exiting boot services
  2024-01-29 18:25 [edk2-devel] [PATCH v5 0/3] ArmPkg: GenericWatchdogDxe fixes and improvements Rebecca Cran via groups.io
  2024-01-29 18:25 ` [edk2-devel] [PATCH v5 1/3] ArmPkg: Update GenericWatchdogDxe to allow setting full 48-bit offset Rebecca Cran via groups.io
  2024-01-29 18:25 ` [edk2-devel] [PATCH v5 2/3] ArmPkg: Introduce global mTimerPeriod and remove calculation Rebecca Cran via groups.io
@ 2024-01-29 18:25 ` Rebecca Cran via groups.io
  2 siblings, 0 replies; 8+ messages in thread
From: Rebecca Cran via groups.io @ 2024-01-29 18:25 UTC (permalink / raw)
  To: Leif Lindholm, Ard Biesheuvel, Sami Mujawar, devel; +Cc: Rebecca Cran

Update GenericWatchdogDxe to disable watchdog interaction after exiting
boot services. Also, move the mEfiExitBootServicesEvent event to the top
of the file with the other static variables.

Signed-off-by: Rebecca Cran <rebecca@os.amperecomputing.com>
Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
---
 ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
index d4f9fe6f4ece..51ff9bdf8cd3 100644
--- a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
+++ b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
@@ -40,6 +40,7 @@ STATIC BOOLEAN  mExitedBootServices = FALSE;
 
 STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL  *mInterruptProtocol;
 STATIC EFI_WATCHDOG_TIMER_NOTIFY         mWatchdogNotify;
+STATIC EFI_EVENT                         mEfiExitBootServicesEvent;
 
 /**
   This function returns the maximum watchdog offset register value.
@@ -122,7 +123,8 @@ WatchdogExitBootServicesEvent (
   )
 {
   WatchdogDisable ();
-  mTimerPeriod = 0;
+  mTimerPeriod        = 0;
+  mExitedBootServices = TRUE;
 }
 
 /* This function is called when the watchdog's first signal (WS0) goes high.
@@ -219,6 +221,8 @@ WatchdogRegisterHandler (
 
   @retval EFI_SUCCESS           The watchdog timer has been programmed to fire
                                 in TimerPeriod 100ns units.
+  @retval EFI_DEVICE_ERROR      Boot Services has been exited but TimerPeriod
+                                is not zero.
 
 **/
 STATIC
@@ -233,7 +237,15 @@ WatchdogSetTimerPeriod (
   UINT64  TimerFrequencyHz;
   UINT64  NumTimerTicks;
 
-  // if TimerPeriod is 0, this is a request to stop the watchdog.
+  // If we've exited Boot Services but TimerPeriod isn't zero, this
+  // indicates that the caller is doing something wrong.
+  if (mExitedBootServices && (TimerPeriod != 0)) {
+    mTimerPeriod = 0;
+    WatchdogDisable ();
+    return EFI_DEVICE_ERROR;
+  }
+
+  // If TimerPeriod is 0 this is a request to stop the watchdog.
   if (TimerPeriod == 0) {
     mTimerPeriod = 0;
     WatchdogDisable ();
@@ -337,8 +349,6 @@ STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  mWatchdogTimer = {
   WatchdogGetTimerPeriod
 };
 
-STATIC EFI_EVENT  mEfiExitBootServicesEvent;
-
 EFI_STATUS
 EFIAPI
 GenericWatchdogEntry (
-- 
2.34.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114727): https://edk2.groups.io/g/devel/message/114727
Mute This Topic: https://groups.io/mt/104037317/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [edk2-devel] [PATCH v5 1/3] ArmPkg: Update GenericWatchdogDxe to allow setting full 48-bit offset
  2024-01-29 18:25 ` [edk2-devel] [PATCH v5 1/3] ArmPkg: Update GenericWatchdogDxe to allow setting full 48-bit offset Rebecca Cran via groups.io
@ 2024-01-30 14:01   ` Sami Mujawar
  2024-01-30 14:49     ` Ard Biesheuvel
  2024-01-30 14:56     ` Rebecca Cran via groups.io
  0 siblings, 2 replies; 8+ messages in thread
From: Sami Mujawar @ 2024-01-30 14:01 UTC (permalink / raw)
  To: Rebecca Cran, Leif Lindholm, Ard Biesheuvel, devel@edk2.groups.io; +Cc: nd

Hi Rebecca,

Please find my feedback inline marked [SAMI].

I have fixed those changes in the pull request at https://github.com/tianocore/edk2/pull/5322
Please let me know if you agree with the changes.

Hi Ard, Leif,

Can you please let me know if it is ok to merge the above pull request, please?

Regards,

Sami Mujawar

On 29/01/2024, 18:25, "Rebecca Cran" <rebecca@os.amperecomputing.com <mailto:rebecca@os.amperecomputing.com>> wrote:


The generic watchdog offset register is 48 bits wide, and can be set by
performing two 32-bit writes.


Add support for writing the high 16 bits of the offset register and
update the signature of the WatchdogWriteOffsetRegister function to take
a UINT64 value.


Signed-off-by: Rebecca Cran <rebecca@os.amperecomputing.com <mailto:rebecca@os.amperecomputing.com>>
---
ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h | 11 ++++-
ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c | 48 ++++++++++++++++++--
2 files changed, 53 insertions(+), 6 deletions(-)


diff --git a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h
index 9bc3bf47047c..b7d6f7e7847e 100644
--- a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h
+++ b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h
@@ -1,9 +1,13 @@
/** @file
*
+* Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
* Copyright (c) 2013-2017, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
+* @par Reference(s):
+* - Generic Watchdog specification in Arm Base System Architecture 1.0C:
+* https://developer.arm.com/documentation/den0094/c/ <https://developer.arm.com/documentation/den0094/c/>
**/


#ifndef GENERIC_WATCHDOG_H_
@@ -14,12 +18,17 @@


// Control Frame:
#define GENERIC_WDOG_CONTROL_STATUS_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x000)
-#define GENERIC_WDOG_OFFSET_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x008)
+#define GENERIC_WDOG_OFFSET_REG_LOW ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x008)
+#define GENERIC_WDOG_OFFSET_REG_HIGH ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x00C)
#define GENERIC_WDOG_COMPARE_VALUE_REG_LOW ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x010)
#define GENERIC_WDOG_COMPARE_VALUE_REG_HIGH ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x014)
+#define GENERIC_WDOG_IID_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0xFCC)


// Values of bit 0 of the Control/Status Register
#define GENERIC_WDOG_ENABLED 1
#define GENERIC_WDOG_DISABLED 0


+#define GENERIC_WDOG_IID_ARCH_REV_SHIFT 16
+#define GENERIC_WDOG_IID_ARCH_REV_MASK 0xF
+
#endif // GENERIC_WATCHDOG_H_
diff --git a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
index 66c6c37c08b0..6ff947d4b746 100644
--- a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
+++ b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
@@ -1,5 +1,6 @@
/** @file
*
+* Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
* Copyright (c) 2013-2018, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -35,16 +36,53 @@ STATIC UINTN mTimerFrequencyHz = 0;
It is therefore stored here. 0 means the timer is not running. */
STATIC UINT64 mNumTimerTicks = 0;


+/* disables watchdog interaction after Exit Boot Services */
+STATIC BOOLEAN mExitedBootServices = FALSE;
[SAMI] I think the above line should have been in patch 3/3.
+
+#define MAX_UINT48 0xFFFFFFFFFFFFULL
+
STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;
STATIC EFI_WATCHDOG_TIMER_NOTIFY mWatchdogNotify;


+/**
+ This function returns the maximum watchdog offset register value.
+
+ @retval MAX_UINT32 The watchdog offset register holds a 32-bit value.
+ @retval MAX_UINT48 The watchdog offset register holds a 48-bit value.
+**/
+STATIC
+UINT64
+GetMaxWatchdogOffsetRegisterValue (
+ VOID
+ )
+{
+ UINT64 MaxWatchdogOffsetValue;
+ UINT32 WatchdogIId;
+ UINT8 WatchdogArchRevision;
+
+ WatchdogIId = MmioRead32 (GENERIC_WDOG_IID_REG);
+ WatchdogArchRevision = (WatchdogIId >> GENERIC_WDOG_IID_ARCH_REV_SHIFT) & GENERIC_WDOG_IID_ARCH_REV_MASK;
+
+ if (WatchdogArchRevision == 0) {
+ MaxWatchdogOffsetValue = MAX_UINT32;
+ } else {
+ MaxWatchdogOffsetValue = MAX_UINT48;
+ }
+
+ return MaxWatchdogOffsetValue;
+
+}
+
STATIC
VOID
WatchdogWriteOffsetRegister (
- UINT32 Value
+ UINT64 Value
)
{
- MmioWrite32 (GENERIC_WDOG_OFFSET_REG, Value);
+ MmioWrite32 (GENERIC_WDOG_OFFSET_REG_LOW, Value & MAX_UINT32);
+ if (GetMaxWatchdogOffsetRegisterValue () == MAX_UINT48) {
+ MmioWrite32 (GENERIC_WDOG_OFFSET_REG_HIGH, (Value >> 32) & MAX_UINT16);
+ }
}


STATIC
@@ -211,17 +249,17 @@ WatchdogSetTimerPeriod (
/* If the number of required ticks is greater than the max the watchdog's
offset register (WOR) can hold, we need to manually compute and set
the compare register (WCV) */
<SNIP>
- if (mNumTimerTicks > MAX_UINT32) {
+ if (mNumTimerTicks > MAX_UINT48) {
/* We need to enable the watchdog *before* writing to the compare register,
because enabling the watchdog causes an "explicit refresh", which
clobbers the compare register (WCV). In order to make sure this doesn't
trigger an interrupt, set the offset to max. */
- WatchdogWriteOffsetRegister (MAX_UINT32);
+ WatchdogWriteOffsetRegister (MAX_UINT48);
WatchdogEnable ();
</SNIP>
[SAMI] I think the above code should look like below. The reason being that the NumTimerTicks rollover is different for Revision 0 and Revision 1. 
	
@@ -211,17 +249,17 @@ WatchdogSetTimerPeriod ()
...
+  UINT64 MaxWatchdogOffsetValue;
...
  /* If the number of required ticks is greater than the max the watchdog's
     offset register (WOR) can hold, we need to manually compute and set
     the compare register (WCV) */
 + MaxWatchdogOffsetValue = GetMaxWatchdogOffsetRegisterValue ();
 - if (NumTimerTicks > MAX_UINT48) {
+ if (NumTimerTicks > MaxWatchdogOffsetValue) {
    /* We need to enable the watchdog *before* writing to the compare register,
       because enabling the watchdog causes an "explicit refresh", which
       clobbers the compare register (WCV). In order to make sure this doesn't
       trigger an interrupt, set the offset to max. */
-    WatchdogWriteOffsetRegister (MAX_UINT48);
+    WatchdogWriteOffsetRegister (MaxWatchdogOffsetValue);
    WatchdogEnable ();
...
[/SAMI]

SystemCount = ArmGenericTimerGetSystemCount ();
WatchdogWriteCompareRegister (SystemCount + mNumTimerTicks);
} else {
- WatchdogWriteOffsetRegister ((UINT32)mNumTimerTicks);
+ WatchdogWriteOffsetRegister (mNumTimerTicks);
WatchdogEnable ();
}


-- 
2.34.1







-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114785): https://edk2.groups.io/g/devel/message/114785
Mute This Topic: https://groups.io/mt/104037319/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [edk2-devel] [PATCH v5 1/3] ArmPkg: Update GenericWatchdogDxe to allow setting full 48-bit offset
  2024-01-30 14:01   ` Sami Mujawar
@ 2024-01-30 14:49     ` Ard Biesheuvel
  2024-01-30 14:56     ` Rebecca Cran via groups.io
  1 sibling, 0 replies; 8+ messages in thread
From: Ard Biesheuvel @ 2024-01-30 14:49 UTC (permalink / raw)
  To: Sami Mujawar
  Cc: Rebecca Cran, Leif Lindholm, Ard Biesheuvel, devel@edk2.groups.io,
	nd

On Tue, 30 Jan 2024 at 15:01, Sami Mujawar <Sami.Mujawar@arm.com> wrote:
>
> Hi Rebecca,
>
> Please find my feedback inline marked [SAMI].
>
> I have fixed those changes in the pull request at https://github.com/tianocore/edk2/pull/5322
> Please let me know if you agree with the changes.
>
> Hi Ard, Leif,
>
> Can you please let me know if it is ok to merge the above pull request, please?
>

Yes, please go ahead and merge this if you are happy with the changes.


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114789): https://edk2.groups.io/g/devel/message/114789
Mute This Topic: https://groups.io/mt/104037319/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [edk2-devel] [PATCH v5 1/3] ArmPkg: Update GenericWatchdogDxe to allow setting full 48-bit offset
  2024-01-30 14:01   ` Sami Mujawar
  2024-01-30 14:49     ` Ard Biesheuvel
@ 2024-01-30 14:56     ` Rebecca Cran via groups.io
  2024-01-30 15:03       ` Sami Mujawar
  1 sibling, 1 reply; 8+ messages in thread
From: Rebecca Cran via groups.io @ 2024-01-30 14:56 UTC (permalink / raw)
  To: Sami Mujawar, Leif Lindholm, Ard Biesheuvel, devel@edk2.groups.io; +Cc: nd

On 1/30/2024 7:01 AM, Sami Mujawar wrote:
> Hi Rebecca,
> 
> Please find my feedback inline marked [SAMI].
> 
> I have fixed those changes in the pull request at https://github.com/tianocore/edk2/pull/5322
> Please let me know if you agree with the changes.

Thanks. Please go ahead and merge the changes.

-- 
Rebecca Cran



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114791): https://edk2.groups.io/g/devel/message/114791
Mute This Topic: https://groups.io/mt/104037319/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [edk2-devel] [PATCH v5 1/3] ArmPkg: Update GenericWatchdogDxe to allow setting full 48-bit offset
  2024-01-30 14:56     ` Rebecca Cran via groups.io
@ 2024-01-30 15:03       ` Sami Mujawar
  0 siblings, 0 replies; 8+ messages in thread
From: Sami Mujawar @ 2024-01-30 15:03 UTC (permalink / raw)
  To: Rebecca Cran, Leif Lindholm, Ard Biesheuvel, devel@edk2.groups.io; +Cc: nd

Merged as 98c7cb3be73d..909a9a5ae4b8

Thanks.

Regards,

Sami Mujawar

On 30/01/2024, 14:57, "Rebecca Cran" <rebecca@os.amperecomputing.com <mailto:rebecca@os.amperecomputing.com>> wrote:


On 1/30/2024 7:01 AM, Sami Mujawar wrote:
> Hi Rebecca,
> 
> Please find my feedback inline marked [SAMI].
> 
> I have fixed those changes in the pull request at https://github.com/tianocore/edk2/pull/5322 <https://github.com/tianocore/edk2/pull/5322>
> Please let me know if you agree with the changes.


Thanks. Please go ahead and merge the changes.


-- 
Rebecca Cran







-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114792): https://edk2.groups.io/g/devel/message/114792
Mute This Topic: https://groups.io/mt/104037319/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-01-30 15:03 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-29 18:25 [edk2-devel] [PATCH v5 0/3] ArmPkg: GenericWatchdogDxe fixes and improvements Rebecca Cran via groups.io
2024-01-29 18:25 ` [edk2-devel] [PATCH v5 1/3] ArmPkg: Update GenericWatchdogDxe to allow setting full 48-bit offset Rebecca Cran via groups.io
2024-01-30 14:01   ` Sami Mujawar
2024-01-30 14:49     ` Ard Biesheuvel
2024-01-30 14:56     ` Rebecca Cran via groups.io
2024-01-30 15:03       ` Sami Mujawar
2024-01-29 18:25 ` [edk2-devel] [PATCH v5 2/3] ArmPkg: Introduce global mTimerPeriod and remove calculation Rebecca Cran via groups.io
2024-01-29 18:25 ` [edk2-devel] [PATCH v5 3/3] ArmPkg: Disable watchdog interaction after exiting boot services Rebecca Cran via groups.io

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox