On Thu, Sep 19, 2019 at 11:51:29AM +0800, Gilbert Chen wrote: > Timer DXE driver for U500 platform based U500 platform implementation > specifc timer registers. > > Signed-off-by: Gilbert Chen <gilbert.c...@hpe.com> > --- > .../SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c | 311 > +++++++++++++++++++++ > .../SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h | 174 ++++++++++++ > .../U500Pkg/Universal/Dxe/TimerDxe/Timer.uni | 14 + > .../U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf | 48 ++++ > .../U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni | 12 + > 5 files changed, 559 insertions(+) > create mode 100644 > Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c > create mode 100644 > Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h > create mode 100644 > Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.uni > create mode 100644 > Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf > create mode 100644 > Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni > > diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c > b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c > new file mode 100644 > index 00000000..5cb42943 > --- /dev/null > +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c > @@ -0,0 +1,311 @@ > +/** @file > + RISC-V Timer Architectural Protocol for U500 platform. > + > + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights > reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "Timer.h" > +#include <sbi/riscv_asm.h> > +#include <sbi/riscv_encoding.h> > +#include <sbi/sbi.h> > +#include <sbi/riscv_io.h> > +#include <sbi/riscv_atomic.h> > + > +#define CLINT_REG_MTIME 0x0200BFF8 > +#define CLINT_REG_MTIMECMP0 0x02004000 > +#define CLINT_REG_MTIMECMP1 0x02004008 > +#define CLINT_REG_MTIMECMP2 0x02004010 > +#define CLINT_REG_MTIMECMP3 0x02004018 > +#define CLINT_REG_MTIMECMP4 0x02004020 > + > +static volatile void * const p_mtime = (void *)CLINT_REG_MTIME; > +#define MTIME (*p_mtime) > +#define MTIMECMP(i) (p_mtimecmp[i]) > + > +// > +// The handle onto which the Timer Architectural Protocol will be installed > +// > +EFI_HANDLE mTimerHandle = NULL;
This one is exported? Or can it be STATIC? > + > +// > +// 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; But this is only for internal use surely? STATIC? > + > +// > +// The notification function to call on every timer interrupt. > +// A bug in the compiler prevents us from initializing this here. > +// > +EFI_TIMER_NOTIFY mTimerNotifyFunction; STATIC? > + > +// > +// The current period of the timer interrupt > +// > +volatile UINT64 mTimerPeriod = 0; This would be VOLATILE, but I dont think it has the effect you think it does. > + > + > +/** > + 8254 Timer #0 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; > + > + csr_clear(CSR_SIE, MIP_STIP); // enable timer int > + OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); > + if (mTimerPeriod == 0) { > + gBS->RestoreTPL (OriginalTPL); > + mCpu->DisableInterrupt(mCpu); > + return; > + } > + if (mTimerNotifyFunction != NULL) { > + mTimerNotifyFunction (mTimerPeriod); > + } > + gBS->RestoreTPL (OriginalTPL); > + > + > + RiscvTimer = readq_relaxed(p_mtime); > + sbi_set_timer(RiscvTimer += mTimerPeriod); > + csr_set(CSR_SIE, MIP_STIP); // enable 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; > + mCpu->DisableInterrupt(mCpu); > + csr_clear(CSR_SIE, MIP_STIP); // disable timer int > + return EFI_SUCCESS; > + } > + > + mTimerPeriod = TimerPeriod / 10; // convert unit from 100ns to 1us > + > + mCpu->EnableInterrupt(mCpu); > + csr_set(CSR_SIE, MIP_STIP); // enable timer int > + > + RiscvTimer = readq_relaxed(p_mtime); > + sbi_set_timer(RiscvTimer + mTimerPeriod); > + 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/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h > b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h > new file mode 100644 > index 00000000..3bfc415d > --- /dev/null > +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h > @@ -0,0 +1,174 @@ > +/** @file > + RISC-V Timer Architectural Protocol definitions for U500 platform, > + > + 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_ Please drop leading _. But also, TIMER_H_ is a bit too generic for an include guard. U500_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> > +#include <Library/RiscVCpuLib.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/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.uni > b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.uni > new file mode 100644 > index 00000000..38302244 > --- /dev/null > +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.uni > @@ -0,0 +1,14 @@ > +// /** @file > +// > +// RISC-V 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 "RISC-V timer driver > that provides Timer Arch protocol" > + > +#string STR_MODULE_DESCRIPTION #language en-US "RISC-V timer driver > that provides Timer Arch protocol." > diff --git > a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf > b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf > new file mode 100644 > index 00000000..f8af6889 > --- /dev/null > +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf > @@ -0,0 +1,48 @@ > +## @file > +# RISC-V Timer Arch protocol module for U500 platform > +# > +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights > reserved.<BR> > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x00010005 Please bump specification version. > + BASE_NAME = Timer > + MODULE_UNI_FILE = Timer.uni > + FILE_GUID = 3F75D495-23FF-46B6-9D19-0DECC8A4EA91 > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + > + ENTRY_POINT = TimerDriverInitialize > + > +[Packages] > + MdePkg/MdePkg.dec > + RiscVPkg/RiscVPkg.dec > + > +[LibraryClasses] > + UefiBootServicesTableLib > + BaseLib > + DebugLib > + UefiDriverEntryPoint > + IoLib > + RiscVCpuLib > + RiscVOpensbiLib Please sort alphabetically. / Leif > + > +[Sources] > + Timer.h > + Timer.c > + > +[Protocols] > + gEfiCpuArchProtocolGuid ## CONSUMES > + gEfiTimerArchProtocolGuid ## PRODUCES > + > +[Pcd] > + gUefiRiscVPkgTokenSpaceGuid.PcdRiscVMachineTimerFrequencyInHerz > + > +[Depex] > + gEfiCpuArchProtocolGuid > + > +[UserExtensions.TianoCore."ExtraFiles"] > + TimerExtra.uni > diff --git > a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni > b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni > new file mode 100644 > index 00000000..cf25ff14 > --- /dev/null > +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.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 > +"RISC-V Timer DXE Driver" > -- > 2.12.0.windows.1 > > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#48440): https://edk2.groups.io/g/devel/message/48440 Mute This Topic: https://groups.io/mt/34196361/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-