[AMD Official Use Only - General] Acked-by: Abner Chang <abner.ch...@amd.com>
Need maintainer's agreement. Abner > -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L > via groups.io > Sent: Saturday, October 15, 2022 12:48 AM > To: devel@edk2.groups.io > Cc: Eric Dong <eric.d...@intel.com>; Ray Ni <ray...@intel.com>; Rahul > Kumar <rahul1.ku...@intel.com>; Daniel Schaefer > <g...@danielschaefer.me> > Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V4 20/34] > UefiCpuPkg: Add CpuTimerDxe module > > Caution: This message originated from an External Source. Use proper > caution when opening attachments, clicking links, or responding. > > > REF: > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugz > illa.tianocore.org%2Fshow_bug.cgi%3Fid%3D4076&data=05%7C01%7Ca > bner.chang%40amd.com%7Cb8b27a5b30864359da3408daae045448%7C3dd89 > 61fe4884e608e11a82d994e183d%7C0%7C0%7C638013630881288660%7CUnkn > own%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik > 1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=Tuh%2BRGCWd > YvjFXMWH%2FfEYRBoND5OhLWWk2VHINqUhb4%3D&reserved=0 > > This DXE module initializes the timer interrupt handler and installs the Arch > Timer protocol. > > Cc: Eric Dong <eric.d...@intel.com> > Cc: Ray Ni <ray...@intel.com> > Cc: Rahul Kumar <rahul1.ku...@intel.com> > Cc: Daniel Schaefer <g...@danielschaefer.me> > Signed-off-by: Sunil V L <suni...@ventanamicro.com> > --- > UefiCpuPkg/UefiCpuPkg.dsc | 3 + > UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf | 51 ++++ > UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h | 177 ++++++++++++ > UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c | 294 ++++++++++++++++++++ > UefiCpuPkg/CpuTimerDxe/CpuTimer.uni | 14 + > UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni | 12 + > 6 files changed, 551 insertions(+) > > diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index > 6ea90507e36f..54ef5edd6eae 100644 > --- a/UefiCpuPkg/UefiCpuPkg.dsc > +++ b/UefiCpuPkg/UefiCpuPkg.dsc > @@ -178,5 +178,8 @@ [Components.IA32, Components.X64] > UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRendezvousLib.inf > UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf > > +[Components.RISCV64] > + UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf > + > [BuildOptions] > *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES diff --git > a/UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf > b/UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf > new file mode 100644 > index 000000000000..d7706328b591 > --- /dev/null > +++ b/UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf > @@ -0,0 +1,51 @@ > +## @file > +# Timer Arch protocol module > +# > +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All > +rights reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent # > +## > + > +[Defines] > + INF_VERSION = 0x0001001b > + BASE_NAME = CpuTimerDxe > + MODULE_UNI_FILE = CpuTimer.uni > + FILE_GUID = 055DDAC6-9142-4013-BF20-FC2E5BC325C9 > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + ENTRY_POINT = TimerDriverInitialize > +# > +# The following information is for reference only and not required by > +the build # tools. > +# > +# VALID_ARCHITECTURES = RISCV64 > +# > +[Packages] > + MdePkg/MdePkg.dec > + UefiCpuPkg/UefiCpuPkg.dec > + > +[LibraryClasses] > + BaseLib > + DebugLib > + IoLib > + CpuLib > + UefiBootServicesTableLib > + UefiDriverEntryPoint > + > +[LibraryClasses.RISCV64] > + RiscVSbiLib > + > +[Sources.RISCV64] > + RiscV64/Timer.h > + RiscV64/Timer.c > + > +[Protocols] > + gEfiCpuArchProtocolGuid ## CONSUMES > + gEfiTimerArchProtocolGuid ## PRODUCES > + > +[Depex] > + gEfiCpuArchProtocolGuid > + > +[UserExtensions.TianoCore."ExtraFiles"] > + CpuTimerExtra.uni > diff --git a/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h > b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h > new file mode 100644 > index 000000000000..586eb0cfadb4 > --- /dev/null > +++ b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h > @@ -0,0 +1,177 @@ > +/** @file > + RISC-V Timer Architectural Protocol definitions > + > + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All > + rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef TIMER_H_ > +#define TIMER_H_ > + > +#include <PiDxe.h> > + > +#include <Protocol/Cpu.h> > +#include <Protocol/Timer.h> > + > +#include <Library/UefiBootServicesTableLib.h> > +#include <Library/BaseLib.h> > +#include <Library/DebugLib.h> > +#include <Library/IoLib.h> > + > +// > +// RISC-V use 100us timer. > +// The default timer tick duration is set to 10 ms = 10 * 1000 * 10 100 > +ns units // #define DEFAULT_TIMER_TICK_DURATION 100000 > + > +extern VOID > +RiscvSetTimerPeriod ( > + UINT32 TimerPeriod > + ); > + > +// > +// Function Prototypes > +// > + > +/** > + Initialize the Timer Architectural Protocol driver > + > + @param ImageHandle ImageHandle of the loaded driver > + @param SystemTable Pointer to the System Table > + > + @retval EFI_SUCCESS Timer Architectural Protocol created > + @retval EFI_OUT_OF_RESOURCES Not enough resources available to > initialize driver. > + @retval EFI_DEVICE_ERROR A device error occured attempting to > initialize the driver. > + > +**/ > +EFI_STATUS > +EFIAPI > +TimerDriverInitialize ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +; > + > +/** > + > + This function adjusts the period of timer interrupts to the value > + specified by TimerPeriod. If the timer period is updated, then the > + selected timer period is stored in EFI_TIMER.TimerPeriod, and > + EFI_SUCCESS is returned. If the timer hardware is not programmable, then > EFI_UNSUPPORTED is returned. > + If an error occurs while attempting to update the timer period, then > + the timer hardware will be put back in its state prior to this call, > + and EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the > + timer interrupt is disabled. This is not the same as disabling the CPU's > interrupts. > + Instead, it must either turn off the timer hardware, or it must > + adjust the interrupt controller so that a CPU interrupt is not > + generated when the timer interrupt fires. > + > + > + @param This The EFI_TIMER_ARCH_PROTOCOL instance. > + @param NotifyFunction The rate to program the timer interrupt in 100 nS > units. If > + the timer hardware is not programmable, then > EFI_UNSUPPORTED is > + returned. If the timer is programmable, then the > timer period > + will be rounded up to the nearest timer period that > is > supported > + by the timer hardware. If TimerPeriod is set to 0, > then the > + timer interrupts will be disabled. > + > + @retval EFI_SUCCESS The timer period was changed. > + @retval EFI_UNSUPPORTED The platform cannot change the period of > the timer interrupt. > + @retval EFI_DEVICE_ERROR The timer period could not be changed > due to a device error. > + > +**/ > +EFI_STATUS > +EFIAPI > +TimerDriverRegisterHandler ( > + IN EFI_TIMER_ARCH_PROTOCOL *This, > + IN EFI_TIMER_NOTIFY NotifyFunction > + ) > +; > + > +/** > + > + This function adjusts the period of timer interrupts to the value > + specified by TimerPeriod. If the timer period is updated, then the > + selected timer period is stored in EFI_TIMER.TimerPeriod, and > + EFI_SUCCESS is returned. If the timer hardware is not programmable, then > EFI_UNSUPPORTED is returned. > + If an error occurs while attempting to update the timer period, then > + the timer hardware will be put back in its state prior to this call, > + and EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the > + timer interrupt is disabled. This is not the same as disabling the CPU's > interrupts. > + Instead, it must either turn off the timer hardware, or it must > + adjust the interrupt controller so that a CPU interrupt is not > + generated when the timer interrupt fires. > + > + > + @param This The EFI_TIMER_ARCH_PROTOCOL instance. > + @param TimerPeriod The rate to program the timer interrupt in 100 nS > units. If > + the timer hardware is not programmable, then > EFI_UNSUPPORTED is > + returned. If the timer is programmable, then the > timer period > + will be rounded up to the nearest timer period that > is > supported > + by the timer hardware. If TimerPeriod is set to 0, > then the > + timer interrupts will be disabled. > + > + @retval EFI_SUCCESS The timer period was changed. > + @retval EFI_UNSUPPORTED The platform cannot change the period of > the timer interrupt. > + @retval EFI_DEVICE_ERROR The timer period could not be changed > due to a device error. > + > +**/ > +EFI_STATUS > +EFIAPI > +TimerDriverSetTimerPeriod ( > + IN EFI_TIMER_ARCH_PROTOCOL *This, > + IN UINT64 TimerPeriod > + ) > +; > + > +/** > + > + This function retrieves the period of timer interrupts in 100 ns > + units, returns that value in TimerPeriod, and returns EFI_SUCCESS. > + If TimerPeriod is NULL, then EFI_INVALID_PARAMETER is returned. If a > + TimerPeriod of 0 is returned, then the timer is currently disabled. > + > + > + @param This The EFI_TIMER_ARCH_PROTOCOL instance. > + @param TimerPeriod A pointer to the timer period to retrieve in 100 ns > units. If > + 0 is returned, then the timer is currently disabled. > + > + @retval EFI_SUCCESS The timer period was returned in > TimerPeriod. > + @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +TimerDriverGetTimerPeriod ( > + IN EFI_TIMER_ARCH_PROTOCOL *This, > + OUT UINT64 *TimerPeriod > + ) > +; > + > +/** > + > + This function generates a soft timer interrupt. If the platform does > + not support soft timer interrupts, then EFI_UNSUPPORTED is returned. > Otherwise, EFI_SUCCESS is returned. > + If a handler has been registered through the > + EFI_TIMER_ARCH_PROTOCOL.RegisterHandler() > + service, then a soft timer interrupt will be generated. If the timer > + interrupt is enabled when this service is called, then the registered > + handler will be invoked. The registered handler should not be able to > + distinguish a hardware-generated timer interrupt from a software- > generated timer interrupt. > + > + > + @param This The EFI_TIMER_ARCH_PROTOCOL instance. > + > + @retval EFI_SUCCESS The soft timer interrupt was generated. > + @retval EFI_UNSUPPORTEDT The platform does not support the > generation of soft timer interrupts. > + > +**/ > +EFI_STATUS > +EFIAPI > +TimerDriverGenerateSoftInterrupt ( > + IN EFI_TIMER_ARCH_PROTOCOL *This > + ) > +; > + > +#endif > diff --git a/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c > b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c > new file mode 100644 > index 000000000000..db153f715e60 > --- /dev/null > +++ b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c > @@ -0,0 +1,294 @@ > +/** @file > + RISC-V Timer Architectural Protocol > + > + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All > + rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include <Library/BaseLib.h> > +#include <Library/BaseRiscVSbiLib.h> > +#include "Timer.h" > + > +// > +// The handle onto which the Timer Architectural Protocol will be > +installed // STATIC EFI_HANDLE mTimerHandle = NULL; > + > +// > +// The Timer Architectural Protocol that this driver produces // > +EFI_TIMER_ARCH_PROTOCOL mTimer = { > + TimerDriverRegisterHandler, > + TimerDriverSetTimerPeriod, > + TimerDriverGetTimerPeriod, > + TimerDriverGenerateSoftInterrupt > +}; > + > +// > +// Pointer to the CPU Architectural Protocol instance // > +EFI_CPU_ARCH_PROTOCOL *mCpu; > + > +// > +// The notification function to call on every timer interrupt. > +// A bug in the compiler prevents us from initializing this here. > +// > +STATIC EFI_TIMER_NOTIFY mTimerNotifyFunction; > + > +// > +// The current period of the timer interrupt // STATIC UINT64 > +mTimerPeriod = 0; > + > +/** > + Timer Interrupt Handler. > + > + @param InterruptType The type of interrupt that occured > + @param SystemContext A pointer to the system context when the > interrupt occured > +**/ > +VOID > +EFIAPI > +TimerInterruptHandler ( > + IN EFI_EXCEPTION_TYPE InterruptType, > + IN EFI_SYSTEM_CONTEXT SystemContext > + ) > +{ > + EFI_TPL OriginalTPL; > + UINT64 RiscvTimer; > + > + OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); if > + (mTimerNotifyFunction != NULL) { > + mTimerNotifyFunction (mTimerPeriod); } > + > + RiscVDisableTimerInterrupt (); // Disable SMode timer int > + RiscVClearPendingTimerInterrupt (); if (mTimerPeriod == 0) { > + gBS->RestoreTPL (OriginalTPL); > + RiscVDisableTimerInterrupt (); // Disable SMode timer int > + return; > + } > + > + RiscvTimer = RiscVReadTimer (); > + SbiSetTimer (RiscvTimer += mTimerPeriod); > + gBS->RestoreTPL (OriginalTPL); > + RiscVEnableTimerInterrupt (); // enable SMode timer int } > + > +/** > + > + This function registers the handler NotifyFunction so it is called > + every time the timer interrupt fires. It also passes the amount of > + time since the last handler call to the NotifyFunction. If > + NotifyFunction is NULL, then the handler is unregistered. If the > + handler is registered, then EFI_SUCCESS is returned. If the CPU does > + not support registering a timer interrupt handler, then > + EFI_UNSUPPORTED is returned. If an attempt is made to register a handler > when a handler is already registered, then EFI_ALREADY_STARTED is > returned. > + If an attempt is made to unregister a handler when a handler is not > + registered, then EFI_INVALID_PARAMETER is returned. If an error > + occurs attempting to register the NotifyFunction with the timer > + interrupt, then EFI_DEVICE_ERROR is returned. > + > + @param This The EFI_TIMER_ARCH_PROTOCOL instance. > + @param NotifyFunction The function to call when a timer interrupt fires. > This > + function executes at TPL_HIGH_LEVEL. The DXE Core > will > + register a handler for the timer interrupt, so it > can know > + how much time has passed. This information is > used to > + signal timer based events. NULL will unregister > the handler. > + > + @retval EFI_SUCCESS The timer handler was registered. > + @retval EFI_UNSUPPORTED The platform does not support timer > interrupts. > + @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a > handler is already > + registered. > + @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a > handler was not > + previously registered. > + @retval EFI_DEVICE_ERROR The timer handler could not be > registered. > + > +**/ > +EFI_STATUS > +EFIAPI > +TimerDriverRegisterHandler ( > + IN EFI_TIMER_ARCH_PROTOCOL *This, > + IN EFI_TIMER_NOTIFY NotifyFunction > + ) > +{ > + DEBUG ((DEBUG_INFO, "TimerDriverRegisterHandler(0x%lx) called\n", > +NotifyFunction)); > + mTimerNotifyFunction = NotifyFunction; > + return EFI_SUCCESS; > +} > + > +/** > + > + This function adjusts the period of timer interrupts to the value > + specified by TimerPeriod. If the timer period is updated, then the > + selected timer period is stored in EFI_TIMER.TimerPeriod, and > + EFI_SUCCESS is returned. If the timer hardware is not programmable, then > EFI_UNSUPPORTED is returned. > + If an error occurs while attempting to update the timer period, then > + the timer hardware will be put back in its state prior to this call, > + and EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the > + timer interrupt is disabled. This is not the same as disabling the CPU's > interrupts. > + Instead, it must either turn off the timer hardware, or it must > + adjust the interrupt controller so that a CPU interrupt is not > + generated when the timer interrupt fires. > + > + > + @param This The EFI_TIMER_ARCH_PROTOCOL instance. > + @param TimerPeriod The rate to program the timer interrupt in 100 nS > units. If > + the timer hardware is not programmable, then > EFI_UNSUPPORTED is > + returned. If the timer is programmable, then the > timer period > + will be rounded up to the nearest timer period that > is > supported > + by the timer hardware. If TimerPeriod is set to 0, > then the > + timer interrupts will be disabled. > + > + @retval EFI_SUCCESS The timer period was changed. > + @retval EFI_UNSUPPORTED The platform cannot change the period of > the timer interrupt. > + @retval EFI_DEVICE_ERROR The timer period could not be changed > due to a device error. > + > +**/ > +EFI_STATUS > +EFIAPI > +TimerDriverSetTimerPeriod ( > + IN EFI_TIMER_ARCH_PROTOCOL *This, > + IN UINT64 TimerPeriod > + ) > +{ > + UINT64 RiscvTimer; > + > + DEBUG ((DEBUG_INFO, "TimerDriverSetTimerPeriod(0x%lx)\n", > + TimerPeriod)); > + > + if (TimerPeriod == 0) { > + mTimerPeriod = 0; > + RiscVDisableTimerInterrupt (); // Disable SMode timer int > + return EFI_SUCCESS; > + } > + > + mTimerPeriod = TimerPeriod / 10; // convert unit from 100ns to 1us > + RiscvTimer = RiscVReadTimer (); > + SbiSetTimer (RiscvTimer + mTimerPeriod); > + > + mCpu->EnableInterrupt (mCpu); > + RiscVEnableTimerInterrupt (); // enable SMode timer int > + return EFI_SUCCESS; > +} > + > +/** > + > + This function retrieves the period of timer interrupts in 100 ns > + units, returns that value in TimerPeriod, and returns EFI_SUCCESS. > + If TimerPeriod is NULL, then EFI_INVALID_PARAMETER is returned. If a > + TimerPeriod of 0 is returned, then the timer is currently disabled. > + > + > + @param This The EFI_TIMER_ARCH_PROTOCOL instance. > + @param TimerPeriod A pointer to the timer period to retrieve in 100 ns > units. If > + 0 is returned, then the timer is currently disabled. > + > + @retval EFI_SUCCESS The timer period was returned in > TimerPeriod. > + @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +TimerDriverGetTimerPeriod ( > + IN EFI_TIMER_ARCH_PROTOCOL *This, > + OUT UINT64 *TimerPeriod > + ) > +{ > + *TimerPeriod = mTimerPeriod; > + return EFI_SUCCESS; > +} > + > +/** > + > + This function generates a soft timer interrupt. If the platform does > + not support soft timer interrupts, then EFI_UNSUPPORTED is returned. > Otherwise, EFI_SUCCESS is returned. > + If a handler has been registered through the > + EFI_TIMER_ARCH_PROTOCOL.RegisterHandler() > + service, then a soft timer interrupt will be generated. If the timer > + interrupt is enabled when this service is called, then the registered > + handler will be invoked. The registered handler should not be able to > + distinguish a hardware-generated timer interrupt from a software- > generated timer interrupt. > + > + > + @param This The EFI_TIMER_ARCH_PROTOCOL instance. > + > + @retval EFI_SUCCESS The soft timer interrupt was generated. > + @retval EFI_UNSUPPORTEDT The platform does not support the > generation of soft timer interrupts. > + > +**/ > +EFI_STATUS > +EFIAPI > +TimerDriverGenerateSoftInterrupt ( > + IN EFI_TIMER_ARCH_PROTOCOL *This > + ) > +{ > + return EFI_SUCCESS; > +} > + > +/** > + Initialize the Timer Architectural Protocol driver > + > + @param ImageHandle ImageHandle of the loaded driver > + @param SystemTable Pointer to the System Table > + > + @retval EFI_SUCCESS Timer Architectural Protocol created > + @retval EFI_OUT_OF_RESOURCES Not enough resources available to > initialize driver. > + @retval EFI_DEVICE_ERROR A device error occured attempting to > initialize the driver. > + > +**/ > +EFI_STATUS > +EFIAPI > +TimerDriverInitialize ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + > + // > + // Initialize the pointer to our notify function. > + // > + mTimerNotifyFunction = NULL; > + > + // > + // Make sure the Timer Architectural Protocol is not already > + installed in the system // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, > + &gEfiTimerArchProtocolGuid); > + > + // > + // Find the CPU architectural protocol. > + // > + Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID > + **)&mCpu); ASSERT_EFI_ERROR (Status); > + > + // > + // Force the timer to be disabled > + // > + Status = TimerDriverSetTimerPeriod (&mTimer, 0); ASSERT_EFI_ERROR > + (Status); > + > + // > + // Install interrupt handler for RISC-V Timer. > + // > + Status = mCpu->RegisterInterruptHandler (mCpu, > + EXCEPT_RISCV_TIMER_INT, TimerInterruptHandler); ASSERT_EFI_ERROR > + (Status); > + > + // > + // Force the timer to be enabled at its default period // Status = > + TimerDriverSetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Install the Timer Architectural Protocol onto a new handle > + // > + Status = gBS->InstallMultipleProtocolInterfaces ( > + &mTimerHandle, > + &gEfiTimerArchProtocolGuid, > + &mTimer, > + NULL > + ); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git a/UefiCpuPkg/CpuTimerDxe/CpuTimer.uni > b/UefiCpuPkg/CpuTimerDxe/CpuTimer.uni > new file mode 100644 > index 000000000000..76de1f3f352a > --- /dev/null > +++ b/UefiCpuPkg/CpuTimerDxe/CpuTimer.uni > @@ -0,0 +1,14 @@ > +// /** @file > +// > +// Timer Arch protocol strings. > +// > +// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All > +rights reserved.<BR> // // SPDX-License-Identifier: BSD-2-Clause-Patent > +// // **/ > + > + > +#string STR_MODULE_ABSTRACT #language en-US "Timer driver that > provides Timer Arch protocol" > + > +#string STR_MODULE_DESCRIPTION #language en-US "Timer driver > that provides Timer Arch protocol." > diff --git a/UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni > b/UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni > new file mode 100644 > index 000000000000..ceb93a7ce82f > --- /dev/null > +++ b/UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni > @@ -0,0 +1,12 @@ > +// /** @file > +// Timer Localized Strings and Content > +// > +// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All > +rights reserved.<BR> // // SPDX-License-Identifier: BSD-2-Clause-Patent > +// // **/ > + > +#string STR_PROPERTIES_MODULE_NAME > +#language en-US > +"Timer DXE Driver" > -- > 2.38.0 > > > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#95272): https://edk2.groups.io/g/devel/message/95272 Mute This Topic: https://groups.io/mt/94330849/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-