On Mon, Sep 23, 2019 at 08:31:49AM +0800, Abner Chang wrote: > The driver produces RISC-V EFI_CPU_ARCH_PROTOCOL and use RISC-V > platform level timer library. > > Due to RISC-V timer CSR is platform implementation specific,
Please expand CSR. > RISC-V CPU DXE driver invokes platform level timer library > to access to timer CSRs. > > Signed-off-by: Abner Chang <abner.ch...@hpe.com> > --- > RiscVPkg/Universal/CpuDxe/CpuDxe.c | 318 > ++++++++++++++++++++++++++++++ > RiscVPkg/Universal/CpuDxe/CpuDxe.h | 206 +++++++++++++++++++ > RiscVPkg/Universal/CpuDxe/CpuDxe.inf | 56 ++++++ > RiscVPkg/Universal/CpuDxe/CpuDxe.uni | 13 ++ > RiscVPkg/Universal/CpuDxe/CpuDxeExtra.uni | 14 ++ > 5 files changed, 607 insertions(+) > create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxe.c > create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxe.h > create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxe.inf > create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxe.uni > create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxeExtra.uni > > diff --git a/RiscVPkg/Universal/CpuDxe/CpuDxe.c > b/RiscVPkg/Universal/CpuDxe/CpuDxe.c > new file mode 100644 > index 0000000..30d1115 > --- /dev/null > +++ b/RiscVPkg/Universal/CpuDxe/CpuDxe.c > @@ -0,0 +1,318 @@ > +/** @file > + RISC-V CPU DXE driver. > + > + Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. All > rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "CpuDxe.h" > + > +// > +// Global Variables > +// > +BOOLEAN InterruptState = FALSE; Global variables need m or g prefix. > +EFI_HANDLE mCpuHandle = NULL; > +BOOLEAN mIsFlushingGCD; Please use STATIC on variables global only in current file. > + > +EFI_CPU_ARCH_PROTOCOL gCpu = { > + CpuFlushCpuDataCache, > + CpuEnableInterrupt, > + CpuDisableInterrupt, > + CpuGetInterruptState, > + CpuInit, > + CpuRegisterInterruptHandler, > + CpuGetTimerValue, > + CpuSetMemoryAttributes, > + 1, // NumberOfTimers > + 4 // DmaBufferAlignment > +}; > + > +// > +// CPU Arch Protocol Functions > +// > + > +/** > + Flush CPU data cache. If the instruction cache is fully coherent > + with all DMA operations then function can just return EFI_SUCCESS. > + > + @param This Protocol instance structure > + @param Start Physical address to start flushing from. > + @param Length Number of bytes to flush. Round up to chipset > + granularity. > + @param FlushType Specifies the type of flush operation to perform. > + > + @retval EFI_SUCCESS If cache was flushed > + @retval EFI_UNSUPPORTED If flush type is not supported. > + @retval EFI_DEVICE_ERROR If requested range could not be flushed. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuFlushCpuDataCache ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS Start, > + IN UINT64 Length, > + IN EFI_CPU_FLUSH_TYPE FlushType > + ) > +{ > + return EFI_SUCCESS; > +} > + > + > +/** > + Enables CPU interrupts. > + > + @param This Protocol instance structure > + > + @retval EFI_SUCCESS If interrupts were enabled in the CPU > + @retval EFI_DEVICE_ERROR If interrupts could not be enabled on the CPU. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuEnableInterrupt ( > + IN EFI_CPU_ARCH_PROTOCOL *This > + ) > +{ > + EnableInterrupts (); > + InterruptState = TRUE; > + return EFI_SUCCESS; > +} > + > + > +/** > + Disables CPU interrupts. > + > + @param This Protocol instance structure > + > + @retval EFI_SUCCESS If interrupts were disabled in the CPU. > + @retval EFI_DEVICE_ERROR If interrupts could not be disabled on the CPU. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuDisableInterrupt ( > + IN EFI_CPU_ARCH_PROTOCOL *This > + ) > +{ > + DisableInterrupts (); > + InterruptState = FALSE; > + return EFI_SUCCESS; > +} > + > + > +/** > + Return the state of interrupts. > + > + @param This Protocol instance structure > + @param State Pointer to the CPU's current interrupt state > + > + @retval EFI_SUCCESS If interrupts were disabled in the CPU. > + @retval EFI_INVALID_PARAMETER State is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuGetInterruptState ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + OUT BOOLEAN *State > + ) > +{ > + if (State == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + *State = InterruptState; > + return EFI_SUCCESS; > +} > + > + > +/** > + Generates an INIT to the CPU. > + > + @param This Protocol instance structure > + @param InitType Type of CPU INIT to perform > + > + @retval EFI_SUCCESS If CPU INIT occurred. This value should never be > + seen. > + @retval EFI_DEVICE_ERROR If CPU INIT failed. > + @retval EFI_UNSUPPORTED Requested type of CPU INIT not supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuInit ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_CPU_INIT_TYPE InitType > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > + > +/** > + Registers a function to be called from the CPU interrupt handler. > + > + @param This Protocol instance structure > + @param InterruptType Defines which interrupt to hook. IA-32 > + valid range is 0x00 through 0xFF > + @param InterruptHandler A pointer to a function of type > + EFI_CPU_INTERRUPT_HANDLER that is called > + when a processor interrupt occurs. A null > + pointer is an error condition. > + > + @retval EFI_SUCCESS If handler installed or uninstalled. > + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler > + for InterruptType was previously installed. > + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for > + InterruptType was not previously installed. > + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType > + is not supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuRegisterInterruptHandler ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_EXCEPTION_TYPE InterruptType, > + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler > + ) > +{ > + return RegisterCpuInterruptHandler (InterruptType, InterruptHandler); > +} > + > + > +/** > + Returns a timer value from one of the CPU's internal timers. There is no > + inherent time interval between ticks but is a function of the CPU > frequency. > + > + @param This - Protocol instance structure. > + @param TimerIndex - Specifies which CPU timer is requested. > + @param TimerValue - Pointer to the returned timer value. > + @param TimerPeriod - A pointer to the amount of time that passes > + in femtoseconds (10-15) for each increment > + of TimerValue. If TimerValue does not > + increment at a predictable rate, then 0 is > + returned. The amount of time that has > + passed between two calls to GetTimerValue() > + can be calculated with the formula > + (TimerValue2 - TimerValue1) * TimerPeriod. > + This parameter is optional and may be NULL. > + > + @retval EFI_SUCCESS - If the CPU timer count was returned. > + @retval EFI_UNSUPPORTED - If the CPU does not have any readable > timers. > + @retval EFI_DEVICE_ERROR - If an error occurred while reading the > timer. > + @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is > NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuGetTimerValue ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN UINT32 TimerIndex, > + OUT UINT64 *TimerValue, > + OUT UINT64 *TimerPeriod OPTIONAL > + ) > +{ > + if (TimerValue == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (TimerIndex != 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + *TimerValue = (UINT64)RiscVReadMachineTimer (); > + if (TimerPeriod != NULL) { > + *TimerPeriod = DivU64x32 ( > + 1000000000000000u, > + PcdGet64 (PcdRiscVMachineTimerFrequencyInHerz) > + ); > + } > + return EFI_SUCCESS; > +} > + > + > +/** > + Implementation of SetMemoryAttributes() service of CPU Architecture > Protocol. > + > + This function modifies the attributes for the memory region specified by > BaseAddress and > + Length from their current attributes to the attributes specified by > Attributes. > + > + @param This The EFI_CPU_ARCH_PROTOCOL instance. > + @param BaseAddress The physical address that is the start address of > a memory region. > + @param Length The size in bytes of the memory region. > + @param Attributes The bit mask of attributes to set for the memory > region. > + > + @retval EFI_SUCCESS The attributes were set for the memory > region. > + @retval EFI_ACCESS_DENIED The attributes for the memory resource range > specified by > + BaseAddress and Length cannot be modified. > + @retval EFI_INVALID_PARAMETER Length is zero. > + Attributes specified an illegal combination > of attributes that > + cannot be set together. > + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to > modify the attributes of > + the memory resource range. > + @retval EFI_UNSUPPORTED The processor does not support one or more > bytes of the memory > + resource range specified by BaseAddress and > Length. > + The bit mask of attributes is not support > for the memory resource > + range specified by BaseAddress and Length. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuSetMemoryAttributes ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > + IN UINT64 Length, > + IN UINT64 Attributes > + ) > +{ > + DEBUG ((DEBUG_INFO, "%a:Set memory attributes not supported yet\n", > __FUNCTION__)); Suggest space after :. > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > +} > + > +/** > + Initialize the state information for the CPU Architectural Protocol. > + > + @param ImageHandle Image handle this driver. > + @param SystemTable Pointer to the System Table. > + > + @retval EFI_SUCCESS Thread can be successfully created > + @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure > + @retval EFI_DEVICE_ERROR Cannot create the thread > + > +**/ > +EFI_STATUS > +EFIAPI > +InitializeCpu ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + > + // > + // Machine mode handler is initiated in CpuExceptionHandlerLibConstructor > in > + // CpuExecptionHandlerLib. > + // > + > + // > + // Make sure interrupts are disabled > + // > + DisableInterrupts (); > + > + // > + // Install CPU Architectural Protocol > + // > + Status = gBS->InstallMultipleProtocolInterfaces ( > + &mCpuHandle, > + &gEfiCpuArchProtocolGuid, &gCpu, > + NULL > + ); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > + > diff --git a/RiscVPkg/Universal/CpuDxe/CpuDxe.h > b/RiscVPkg/Universal/CpuDxe/CpuDxe.h > new file mode 100644 > index 0000000..e423fae > --- /dev/null > +++ b/RiscVPkg/Universal/CpuDxe/CpuDxe.h > @@ -0,0 +1,206 @@ > +/** @file > + RISC-V CPU DXE module header file. > + > + Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. All > rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef _CPU_DXE_H_ > +#define _CPU_DXE_H_ Please drop leading _. > + > +#include <PiDxe.h> > + > +#include <Protocol/Cpu.h> > + > +#include <Library/UefiDriverEntryPoint.h> > +#include <Library/UefiBootServicesTableLib.h> > +#include <Library/DxeServicesTableLib.h> > +#include <Library/BaseLib.h> > +#include <Library/CpuLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/MemoryAllocationLib.h> > +#include <Library/DebugLib.h> > +#include <Library/UefiLib.h> > +#include <Library/CpuExceptionHandlerLib.h> > +#include <Library/TimerLib.h> > +#include <Library/RiscVCpuLib.h> Please keep only the include statements required for this file. (And please sort the remaining ones alphabetically.) > + > +/** > + Flush CPU data cache. If the instruction cache is fully coherent > + with all DMA operations then function can just return EFI_SUCCESS. > + > + @param This Protocol instance structure > + @param Start Physical address to start flushing from. > + @param Length Number of bytes to flush. Round up to chipset > + granularity. > + @param FlushType Specifies the type of flush operation to perform. > + > + @retval EFI_SUCCESS If cache was flushed > + @retval EFI_UNSUPPORTED If flush type is not supported. > + @retval EFI_DEVICE_ERROR If requested range could not be flushed. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuFlushCpuDataCache ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS Start, > + IN UINT64 Length, > + IN EFI_CPU_FLUSH_TYPE FlushType > + ); > + > +/** > + Enables CPU interrupts. > + > + @param This Protocol instance structure > + > + @retval EFI_SUCCESS If interrupts were enabled in the CPU > + @retval EFI_DEVICE_ERROR If interrupts could not be enabled on the CPU. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuEnableInterrupt ( > + IN EFI_CPU_ARCH_PROTOCOL *This > + ); > + > +/** > + Disables CPU interrupts. > + > + @param This Protocol instance structure > + > + @retval EFI_SUCCESS If interrupts were disabled in the CPU. > + @retval EFI_DEVICE_ERROR If interrupts could not be disabled on the CPU. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuDisableInterrupt ( > + IN EFI_CPU_ARCH_PROTOCOL *This > + ); > + > +/** > + Return the state of interrupts. > + > + @param This Protocol instance structure > + @param State Pointer to the CPU's current interrupt state > + > + @retval EFI_SUCCESS If interrupts were disabled in the CPU. > + @retval EFI_INVALID_PARAMETER State is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuGetInterruptState ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + OUT BOOLEAN *State > + ); > + > +/** > + Generates an INIT to the CPU. > + > + @param This Protocol instance structure > + @param InitType Type of CPU INIT to perform > + > + @retval EFI_SUCCESS If CPU INIT occurred. This value should never be > + seen. > + @retval EFI_DEVICE_ERROR If CPU INIT failed. > + @retval EFI_UNSUPPORTED Requested type of CPU INIT not supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuInit ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_CPU_INIT_TYPE InitType > + ); > + > +/** > + Registers a function to be called from the CPU interrupt handler. > + > + @param This Protocol instance structure > + @param InterruptType Defines which interrupt to hook. IA-32 > + valid range is 0x00 through 0xFF > + @param InterruptHandler A pointer to a function of type > + EFI_CPU_INTERRUPT_HANDLER that is called > + when a processor interrupt occurs. A null > + pointer is an error condition. > + > + @retval EFI_SUCCESS If handler installed or uninstalled. > + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler > + for InterruptType was previously installed. > + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for > + InterruptType was not previously installed. > + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType > + is not supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuRegisterInterruptHandler ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_EXCEPTION_TYPE InterruptType, > + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler > + ); > + > +/** > + Returns a timer value from one of the CPU's internal timers. There is no > + inherent time interval between ticks but is a function of the CPU > frequency. > + > + @param This - Protocol instance structure. > + @param TimerIndex - Specifies which CPU timer is requested. > + @param TimerValue - Pointer to the returned timer value. > + @param TimerPeriod - A pointer to the amount of time that passes > + in femtoseconds (10-15) for each increment > + of TimerValue. If TimerValue does not > + increment at a predictable rate, then 0 is > + returned. The amount of time that has > + passed between two calls to GetTimerValue() > + can be calculated with the formula > + (TimerValue2 - TimerValue1) * TimerPeriod. > + This parameter is optional and may be NULL. > + > + @retval EFI_SUCCESS - If the CPU timer count was returned. > + @retval EFI_UNSUPPORTED - If the CPU does not have any readable > timers. > + @retval EFI_DEVICE_ERROR - If an error occurred while reading the > timer. > + @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is > NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuGetTimerValue ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN UINT32 TimerIndex, > + OUT UINT64 *TimerValue, > + OUT UINT64 *TimerPeriod OPTIONAL > + ); > + > +/** > + Set memory cacheability attributes for given range of memeory. > + > + @param This Protocol instance structure > + @param BaseAddress Specifies the start address of the > + memory range > + @param Length Specifies the length of the memory range > + @param Attributes The memory cacheability for the memory range > + > + @retval EFI_SUCCESS If the cacheability of that memory range is > + set successfully > + @retval EFI_UNSUPPORTED If the desired operation cannot be done > + @retval EFI_INVALID_PARAMETER The input parameter is not correct, > + such as Length = 0 > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuSetMemoryAttributes ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > + IN UINT64 Length, > + IN UINT64 Attributes > + ); > + > +#endif > + > diff --git a/RiscVPkg/Universal/CpuDxe/CpuDxe.inf > b/RiscVPkg/Universal/CpuDxe/CpuDxe.inf > new file mode 100644 > index 0000000..1931f45 > --- /dev/null > +++ b/RiscVPkg/Universal/CpuDxe/CpuDxe.inf > @@ -0,0 +1,56 @@ > +## @file > +# RISC-V CPU DXE module. > +# > +# Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. All > rights reserved.<BR> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x0001001b > + BASE_NAME = CpuDxe > + MODULE_UNI_FILE = CpuDxe.uni > + FILE_GUID = 1A1E4886-9517-440e-9FDE-3BE44CEE2136 > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + > + ENTRY_POINT = InitializeCpu > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec Please sort alphabetically. > + RiscVPkg/RiscVPkg.dec > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > + CpuLib > + DebugLib > + DxeServicesTableLib > + MemoryAllocationLib > + UefiBootServicesTableLib > + UefiDriverEntryPoint > + UefiLib > + CpuExceptionHandlerLib > + TimerLib > + SynchronizationLib > + HobLib > + ReportStatusCodeLib > + RiscVCpuLib > + RiscVPlatformTimerLib Please sort the above alphabetically. Also please check whether *all* of these are really used by this driver. / Leif > + > +[Sources] > + CpuDxe.c > + CpuDxe.h > + > +[Protocols] > + gEfiCpuArchProtocolGuid ## PRODUCES > + > +[Pcd] > + gUefiRiscVPkgTokenSpaceGuid.PcdRiscVMachineTimerFrequencyInHerz > + > +[Depex] > + TRUE > + > +[UserExtensions.TianoCore."ExtraFiles"] > + CpuDxeExtra.uni > diff --git a/RiscVPkg/Universal/CpuDxe/CpuDxe.uni > b/RiscVPkg/Universal/CpuDxe/CpuDxe.uni > new file mode 100644 > index 0000000..460141a > --- /dev/null > +++ b/RiscVPkg/Universal/CpuDxe/CpuDxe.uni > @@ -0,0 +1,13 @@ > +// /** @file > +// > +// Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. All > rights reserved.<BR> > +// > +// SPDX-License-Identifier: BSD-2-Clause-Patent > +// > +// **/ > + > + > +#string STR_MODULE_ABSTRACT #language en-US "Installs RISC-V CPU > Architecture Protocol" > + > +#string STR_MODULE_DESCRIPTION #language en-US "RISC-V CPU driver > installs CPU Architecture Protocol." > + > diff --git a/RiscVPkg/Universal/CpuDxe/CpuDxeExtra.uni > b/RiscVPkg/Universal/CpuDxe/CpuDxeExtra.uni > new file mode 100644 > index 0000000..6f819f0 > --- /dev/null > +++ b/RiscVPkg/Universal/CpuDxe/CpuDxeExtra.uni > @@ -0,0 +1,14 @@ > +// /** @file > +// CpuDxe Localized Strings and Content > +// > +// Copyright (c) 2016 - 2019, 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 Architectural DXE Driver" > + > + > -- > 2.7.4 > > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#48310): https://edk2.groups.io/g/devel/message/48310 Mute This Topic: https://groups.io/mt/34258221/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-