mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-23 21:54:27 +02:00
ArmPkg: Update GenericWatchdogDxe to allow setting full 48-bit offset
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> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
This commit is contained in:
parent
98c7cb3be7
commit
beefa753f3
@ -1,9 +1,13 @@
|
|||||||
/** @file
|
/** @file
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
|
||||||
* Copyright (c) 2013-2017, ARM Limited. All rights reserved.
|
* Copyright (c) 2013-2017, ARM Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
* 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_
|
#ifndef GENERIC_WATCHDOG_H_
|
||||||
@ -14,12 +18,17 @@
|
|||||||
|
|
||||||
// Control Frame:
|
// Control Frame:
|
||||||
#define GENERIC_WDOG_CONTROL_STATUS_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x000)
|
#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_LOW ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x010)
|
||||||
#define GENERIC_WDOG_COMPARE_VALUE_REG_HIGH ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x014)
|
#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
|
// Values of bit 0 of the Control/Status Register
|
||||||
#define GENERIC_WDOG_ENABLED 1
|
#define GENERIC_WDOG_ENABLED 1
|
||||||
#define GENERIC_WDOG_DISABLED 0
|
#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_
|
#endif // GENERIC_WATCHDOG_H_
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/** @file
|
/** @file
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
|
||||||
* Copyright (c) 2013-2018, ARM Limited. All rights reserved.
|
* Copyright (c) 2013-2018, ARM Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
@ -35,16 +36,49 @@ STATIC UINTN mTimerFrequencyHz = 0;
|
|||||||
It is therefore stored here. 0 means the timer is not running. */
|
It is therefore stored here. 0 means the timer is not running. */
|
||||||
STATIC UINT64 mNumTimerTicks = 0;
|
STATIC UINT64 mNumTimerTicks = 0;
|
||||||
|
|
||||||
|
#define MAX_UINT48 0xFFFFFFFFFFFFULL
|
||||||
|
|
||||||
STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;
|
STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;
|
||||||
STATIC EFI_WATCHDOG_TIMER_NOTIFY mWatchdogNotify;
|
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
|
STATIC
|
||||||
VOID
|
VOID
|
||||||
WatchdogWriteOffsetRegister (
|
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
|
STATIC
|
||||||
@ -196,7 +230,8 @@ WatchdogSetTimerPeriod (
|
|||||||
IN UINT64 TimerPeriod // In 100ns units
|
IN UINT64 TimerPeriod // In 100ns units
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN SystemCount;
|
UINTN SystemCount;
|
||||||
|
UINT64 MaxWatchdogOffsetValue;
|
||||||
|
|
||||||
// if TimerPeriod is 0, this is a request to stop the watchdog.
|
// if TimerPeriod is 0, this is a request to stop the watchdog.
|
||||||
if (TimerPeriod == 0) {
|
if (TimerPeriod == 0) {
|
||||||
@ -211,17 +246,18 @@ WatchdogSetTimerPeriod (
|
|||||||
/* If the number of required ticks is greater than the max the watchdog's
|
/* 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
|
offset register (WOR) can hold, we need to manually compute and set
|
||||||
the compare register (WCV) */
|
the compare register (WCV) */
|
||||||
if (mNumTimerTicks > MAX_UINT32) {
|
MaxWatchdogOffsetValue = GetMaxWatchdogOffsetRegisterValue ();
|
||||||
|
if (mNumTimerTicks > MaxWatchdogOffsetValue) {
|
||||||
/* We need to enable the watchdog *before* writing to the compare register,
|
/* We need to enable the watchdog *before* writing to the compare register,
|
||||||
because enabling the watchdog causes an "explicit refresh", which
|
because enabling the watchdog causes an "explicit refresh", which
|
||||||
clobbers the compare register (WCV). In order to make sure this doesn't
|
clobbers the compare register (WCV). In order to make sure this doesn't
|
||||||
trigger an interrupt, set the offset to max. */
|
trigger an interrupt, set the offset to max. */
|
||||||
WatchdogWriteOffsetRegister (MAX_UINT32);
|
WatchdogWriteOffsetRegister (MaxWatchdogOffsetValue);
|
||||||
WatchdogEnable ();
|
WatchdogEnable ();
|
||||||
SystemCount = ArmGenericTimerGetSystemCount ();
|
SystemCount = ArmGenericTimerGetSystemCount ();
|
||||||
WatchdogWriteCompareRegister (SystemCount + mNumTimerTicks);
|
WatchdogWriteCompareRegister (SystemCount + mNumTimerTicks);
|
||||||
} else {
|
} else {
|
||||||
WatchdogWriteOffsetRegister ((UINT32)mNumTimerTicks);
|
WatchdogWriteOffsetRegister (mNumTimerTicks);
|
||||||
WatchdogEnable ();
|
WatchdogEnable ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user