REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
This is copied from
edk2-platforms/Silicon/RISC-V/ProcessorPkg/Universal/CpuDxe
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
UefiCpuPkg/UefiCpuPkg.dsc | 1 +
UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf | 68 ++++
UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h | 199 +++++++++++
UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c | 365 ++++++++++++++++++++
4 files changed, 633 insertions(+)
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 251a8213f022..8f2be6cd1b05 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -198,6 +198,7 @@ [Components.X64]
[Components.RISCV64]
UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
+ UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
[BuildOptions]
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf b/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
new file mode 100644
index 000000000000..5e590d03754f
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
@@ -0,0 +1,68 @@
+## @file
+# RISC-V CPU DXE module.
+#
+# Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = CpuDxeRiscV64
+ MODULE_UNI_FILE = CpuDxe.uni
+ FILE_GUID = BDEA19E2-778F-473C-BF82-5E38D6A27765
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeCpu
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ CpuLib
+ DebugLib
+ DxeServicesTableLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+ CpuExceptionHandlerLib
+ HobLib
+ ReportStatusCodeLib
+ TimerLib
+ PeCoffGetEntryPointLib
+ RiscVSbiLib
+
+[Sources]
+ RiscV64/CpuDxe.c
+ RiscV64/CpuDxe.h
+
+[Protocols]
+ gEfiCpuArchProtocolGuid ## PRODUCES
+ gRiscVEfiBootProtocolGuid ## PRODUCES
+
+[Guids]
+ gIdleLoopEventGuid ## CONSUMES ## Event
+
+[Ppis]
+ gEfiSecPlatformInformation2PpiGuid ## UNDEFINED # HOB
+ gEfiSecPlatformInformationPpiGuid ## UNDEFINED # HOB
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ## CONSUMES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ CpuDxeExtra.uni
diff --git a/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h
new file mode 100644
index 000000000000..49f4e119665a
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h
@@ -0,0 +1,199 @@
+/** @file
+ RISC-V CPU DXE module header file.
+
+ Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CPU_DXE_H_
+#define CPU_DXE_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/RiscVBootProtocol.h>
+#include <Library/BaseRiscVSbiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/CpuExceptionHandlerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+
+/**
+ 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/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c
new file mode 100644
index 000000000000..7551e0653603
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c
@@ -0,0 +1,365 @@
+/** @file
+ RISC-V CPU DXE driver.
+
+ Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+ Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CpuDxe.h"
+
+//
+// Global Variables
+//
+STATIC BOOLEAN mInterruptState = FALSE;
+STATIC EFI_HANDLE mCpuHandle = NULL;
+STATIC UINTN mBootHartId;
+RISCV_EFI_BOOT_PROTOCOL gRiscvBootProtocol;
+
+/**
+ Get the boot hartid
+
+ @param This Protocol instance structure
+ @param BootHartId Pointer to the Boot Hart ID variable
+
+ @retval EFI_SUCCESS If BootHartId is returned
+ @retval EFI_INVALID_PARAMETER Either "BootHartId" is NULL or "This" is not
+ a valid RISCV_EFI_BOOT_PROTOCOL instance.
+
+**/
+EFI_STATUS
+EFIAPI
+RiscvGetBootHartId (
+ IN RISCV_EFI_BOOT_PROTOCOL *This,
+ OUT UINTN *BootHartId
+ )
+{
+ if ((This != &gRiscvBootProtocol) || (BootHartId == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *BootHartId = mBootHartId;
+ return EFI_SUCCESS;
+}
+
+RISCV_EFI_BOOT_PROTOCOL gRiscvBootProtocol = {
+ RISCV_EFI_BOOT_PROTOCOL_LATEST_VERSION,
+ RiscvGetBootHartId
+};
+
+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 ();
+ mInterruptState = 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 ();
+ mInterruptState = 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 = mInterruptState;
+ 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)RiscVReadTimer ();
+ if (TimerPeriod != NULL) {
+ *TimerPeriod = DivU64x32 (
+ 1000000000000000u,
+ PcdGet64 (PcdCpuCoreCrystalClockFrequency)
+ );
+ }
+
+ 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__));
+ return EFI_SUCCESS;
+}
+
+/**
+ 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;
+ EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext;
+
+ GetFirmwareContextPointer (&FirmwareContext);
+ ASSERT (FirmwareContext != NULL);
+ if (FirmwareContext == NULL) {
+ DEBUG ((DEBUG_ERROR, "Failed to get the pointer of EFI_RISCV_FIRMWARE_CONTEXT\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((DEBUG_INFO, " %a: Firmware Context is at 0x%x.\n", __FUNCTION__, FirmwareContext));
+
+ mBootHartId = FirmwareContext->BootHartId;
+ DEBUG ((DEBUG_INFO, " %a: mBootHartId = 0x%x.\n", __FUNCTION__, mBootHartId));
+
+ InitializeCpuExceptionHandlers (NULL);
+
+ //
+ // Make sure interrupts are disabled
+ //
+ DisableInterrupts ();
+
+ //
+ // Install Boot protocol
+ //
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gRiscVEfiBootProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gRiscvBootProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install CPU Architectural Protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mCpuHandle,
+ &gEfiCpuArchProtocolGuid,
+ &gCpu,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
--
2.38.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#99232): https://edk2.groups.io/g/devel/message/99232
Mute This Topic: https://groups.io/mt/96593503/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>
-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Daniel Schaefer <git@danielschaefer.me>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 07/20] UefiCpuPkg/CpuDxe: Add RISC-V instance
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
This is copied from
edk2-platforms/Silicon/RISC-V/ProcessorPkg/Universal/CpuDxe
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
UefiCpuPkg/UefiCpuPkg.dsc | 1 +
UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf | 68 ++++ UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h | 199 +++++++++++ UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c | 365 ++++++++++++++++++++
4 files changed, 633 insertions(+)
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 251a8213f022..8f2be6cd1b05 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -198,6 +198,7 @@ [Components.X64]
[Components.RISCV64]
UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
+ UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
[BuildOptions]
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf b/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
new file mode 100644
index 000000000000..5e590d03754f
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
@@ -0,0 +1,68 @@
+## @file
+# RISC-V CPU DXE module.
+#
+# Copyright (c) 2022, Ventana Micro Systems Inc. All rights
+reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = CpuDxeRiscV64
+ MODULE_UNI_FILE = CpuDxe.uni
+ FILE_GUID = BDEA19E2-778F-473C-BF82-5E38D6A27765
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeCpu
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ CpuLib
+ DebugLib
+ DxeServicesTableLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+ CpuExceptionHandlerLib
+ HobLib
+ ReportStatusCodeLib
+ TimerLib
+ PeCoffGetEntryPointLib
+ RiscVSbiLib
+
+[Sources]
+ RiscV64/CpuDxe.c
+ RiscV64/CpuDxe.h
+
+[Protocols]
+ gEfiCpuArchProtocolGuid ## PRODUCES
+ gRiscVEfiBootProtocolGuid ## PRODUCES
+
+[Guids]
+ gIdleLoopEventGuid ## CONSUMES ## Event
+
+[Ppis]
+ gEfiSecPlatformInformation2PpiGuid ## UNDEFINED # HOB
+ gEfiSecPlatformInformationPpiGuid ## UNDEFINED # HOB
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ## CONSUMES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ CpuDxeExtra.uni
diff --git a/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h
new file mode 100644
index 000000000000..49f4e119665a
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h
@@ -0,0 +1,199 @@
+/** @file
+ RISC-V CPU DXE module header file.
+
+ Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP.
+ All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CPU_DXE_H_
+#define CPU_DXE_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/RiscVBootProtocol.h> #include
+<Library/BaseRiscVSbiLib.h> #include <Library/BaseLib.h> #include
+<Library/CpuExceptionHandlerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+
+/**
+ 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/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c
new file mode 100644
index 000000000000..7551e0653603
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c
@@ -0,0 +1,365 @@
+/** @file
+ RISC-V CPU DXE driver.
+
+ Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP.
+ All rights reserved.<BR> Copyright (c) 2022, Ventana Micro Systems
+ Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CpuDxe.h"
+
+//
+// Global Variables
+//
+STATIC BOOLEAN mInterruptState = FALSE;
+STATIC EFI_HANDLE mCpuHandle = NULL;
+STATIC UINTN mBootHartId;
+RISCV_EFI_BOOT_PROTOCOL gRiscvBootProtocol;
+
+/**
+ Get the boot hartid
+
+ @param This Protocol instance structure
+ @param BootHartId Pointer to the Boot Hart ID variable
+
+ @retval EFI_SUCCESS If BootHartId is returned
+ @retval EFI_INVALID_PARAMETER Either "BootHartId" is NULL or "This" is not
+ a valid RISCV_EFI_BOOT_PROTOCOL instance.
+
+**/
+EFI_STATUS
+EFIAPI
+RiscvGetBootHartId (
+ IN RISCV_EFI_BOOT_PROTOCOL *This,
+ OUT UINTN *BootHartId
+ )
+{
+ if ((This != &gRiscvBootProtocol) || (BootHartId == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *BootHartId = mBootHartId;
+ return EFI_SUCCESS;
+}
+
+RISCV_EFI_BOOT_PROTOCOL gRiscvBootProtocol = {
+ RISCV_EFI_BOOT_PROTOCOL_LATEST_VERSION,
+ RiscvGetBootHartId
+};
+
+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 ();
+ mInterruptState = 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 ();
+ mInterruptState = 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 = mInterruptState;
+ 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)RiscVReadTimer (); if (TimerPeriod != NULL) {
+ *TimerPeriod = DivU64x32 (
+ 1000000000000000u,
+ PcdGet64 (PcdCpuCoreCrystalClockFrequency)
+ );
+ }
+
+ 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__));
+ return EFI_SUCCESS;
+}
+
+/**
+ 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;
+ EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext;
+
+ GetFirmwareContextPointer (&FirmwareContext); ASSERT
+ (FirmwareContext != NULL); if (FirmwareContext == NULL) {
+ DEBUG ((DEBUG_ERROR, "Failed to get the pointer of EFI_RISCV_FIRMWARE_CONTEXT\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((DEBUG_INFO, " %a: Firmware Context is at 0x%x.\n",
+ __FUNCTION__, FirmwareContext));
+
+ mBootHartId = FirmwareContext->BootHartId; DEBUG ((DEBUG_INFO, " %a:
+ mBootHartId = 0x%x.\n", __FUNCTION__, mBootHartId));
+
+ InitializeCpuExceptionHandlers (NULL);
+
+ //
+ // Make sure interrupts are disabled
+ //
+ DisableInterrupts ();
+
+ //
+ // Install Boot protocol
+ //
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gRiscVEfiBootProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gRiscvBootProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install CPU Architectural Protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mCpuHandle,
+ &gEfiCpuArchProtocolGuid,
+ &gCpu,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
--
2.38.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#99673): https://edk2.groups.io/g/devel/message/99673
Mute This Topic: https://groups.io/mt/96593503/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Thanks!, Andrei.
Hi Ray,
These changes are done as per your recommendation in
https://edk2.groups.io/g/devel/message/97106
Could you please help reviewing UefiCpuPkg patches? RISC-V community is
waiting for this support for a long time now. If we get these merged
in early days after the current stable release, I think it allows us to
have sufficient time before next stable release.
Thanks!
Sunil
On Mon, Feb 06, 2023 at 03:58:13PM +0000, Warkentin, Andrei wrote:
> Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>
>
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
> Sent: Saturday, January 28, 2023 1:18 PM
> To: devel@edk2.groups.io
> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Daniel Schaefer <git@danielschaefer.me>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
> Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 07/20] UefiCpuPkg/CpuDxe: Add RISC-V instance
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
>
> This is copied from
> edk2-platforms/Silicon/RISC-V/ProcessorPkg/Universal/CpuDxe
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Daniel Schaefer <git@danielschaefer.me>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Acked-by: Abner Chang <abner.chang@amd.com>
> ---
> UefiCpuPkg/UefiCpuPkg.dsc | 1 +
> UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf | 68 ++++ UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h | 199 +++++++++++ UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c | 365 ++++++++++++++++++++
> 4 files changed, 633 insertions(+)
>
> diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 251a8213f022..8f2be6cd1b05 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dsc
> +++ b/UefiCpuPkg/UefiCpuPkg.dsc
> @@ -198,6 +198,7 @@ [Components.X64]
> [Components.RISCV64]
> UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
> UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
> + UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
>
> [BuildOptions]
> *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf b/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
> new file mode 100644
> index 000000000000..5e590d03754f
> --- /dev/null
> +++ b/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
> @@ -0,0 +1,68 @@
> +## @file
> +# RISC-V CPU DXE module.
> +#
> +# Copyright (c) 2022, Ventana Micro Systems Inc. All rights
> +reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[Defines]
> + INF_VERSION = 0x0001001B
> + BASE_NAME = CpuDxeRiscV64
> + MODULE_UNI_FILE = CpuDxe.uni
> + FILE_GUID = BDEA19E2-778F-473C-BF82-5E38D6A27765
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = InitializeCpu
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + UefiCpuPkg/UefiCpuPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + CpuLib
> + DebugLib
> + DxeServicesTableLib
> + MemoryAllocationLib
> + UefiBootServicesTableLib
> + UefiDriverEntryPoint
> + UefiLib
> + CpuExceptionHandlerLib
> + HobLib
> + ReportStatusCodeLib
> + TimerLib
> + PeCoffGetEntryPointLib
> + RiscVSbiLib
> +
> +[Sources]
> + RiscV64/CpuDxe.c
> + RiscV64/CpuDxe.h
> +
> +[Protocols]
> + gEfiCpuArchProtocolGuid ## PRODUCES
> + gRiscVEfiBootProtocolGuid ## PRODUCES
> +
> +[Guids]
> + gIdleLoopEventGuid ## CONSUMES ## Event
> +
> +[Ppis]
> + gEfiSecPlatformInformation2PpiGuid ## UNDEFINED # HOB
> + gEfiSecPlatformInformationPpiGuid ## UNDEFINED # HOB
> +
> +[Pcd]
> + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
> + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
> + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList ## CONSUMES
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize ## CONSUMES
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ## CONSUMES
> +
> +[Depex]
> + TRUE
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> + CpuDxeExtra.uni
> diff --git a/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h
> new file mode 100644
> index 000000000000..49f4e119665a
> --- /dev/null
> +++ b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h
> @@ -0,0 +1,199 @@
> +/** @file
> + RISC-V CPU DXE module header file.
> +
> + Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP.
> + All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CPU_DXE_H_
> +#define CPU_DXE_H_
> +
> +#include <PiDxe.h>
> +
> +#include <Protocol/Cpu.h>
> +#include <Protocol/RiscVBootProtocol.h> #include
> +<Library/BaseRiscVSbiLib.h> #include <Library/BaseLib.h> #include
> +<Library/CpuExceptionHandlerLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +
> +/**
> + 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/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c
> new file mode 100644
> index 000000000000..7551e0653603
> --- /dev/null
> +++ b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c
> @@ -0,0 +1,365 @@
> +/** @file
> + RISC-V CPU DXE driver.
> +
> + Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP.
> + All rights reserved.<BR> Copyright (c) 2022, Ventana Micro Systems
> + Inc. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "CpuDxe.h"
> +
> +//
> +// Global Variables
> +//
> +STATIC BOOLEAN mInterruptState = FALSE;
> +STATIC EFI_HANDLE mCpuHandle = NULL;
> +STATIC UINTN mBootHartId;
> +RISCV_EFI_BOOT_PROTOCOL gRiscvBootProtocol;
> +
> +/**
> + Get the boot hartid
> +
> + @param This Protocol instance structure
> + @param BootHartId Pointer to the Boot Hart ID variable
> +
> + @retval EFI_SUCCESS If BootHartId is returned
> + @retval EFI_INVALID_PARAMETER Either "BootHartId" is NULL or "This" is not
> + a valid RISCV_EFI_BOOT_PROTOCOL instance.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RiscvGetBootHartId (
> + IN RISCV_EFI_BOOT_PROTOCOL *This,
> + OUT UINTN *BootHartId
> + )
> +{
> + if ((This != &gRiscvBootProtocol) || (BootHartId == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *BootHartId = mBootHartId;
> + return EFI_SUCCESS;
> +}
> +
> +RISCV_EFI_BOOT_PROTOCOL gRiscvBootProtocol = {
> + RISCV_EFI_BOOT_PROTOCOL_LATEST_VERSION,
> + RiscvGetBootHartId
> +};
> +
> +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 ();
> + mInterruptState = 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 ();
> + mInterruptState = 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 = mInterruptState;
> + 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)RiscVReadTimer (); if (TimerPeriod != NULL) {
> + *TimerPeriod = DivU64x32 (
> + 1000000000000000u,
> + PcdGet64 (PcdCpuCoreCrystalClockFrequency)
> + );
> + }
> +
> + 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__));
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + 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;
> + EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext;
> +
> + GetFirmwareContextPointer (&FirmwareContext); ASSERT
> + (FirmwareContext != NULL); if (FirmwareContext == NULL) {
> + DEBUG ((DEBUG_ERROR, "Failed to get the pointer of EFI_RISCV_FIRMWARE_CONTEXT\n"));
> + return EFI_NOT_FOUND;
> + }
> +
> + DEBUG ((DEBUG_INFO, " %a: Firmware Context is at 0x%x.\n",
> + __FUNCTION__, FirmwareContext));
> +
> + mBootHartId = FirmwareContext->BootHartId; DEBUG ((DEBUG_INFO, " %a:
> + mBootHartId = 0x%x.\n", __FUNCTION__, mBootHartId));
> +
> + InitializeCpuExceptionHandlers (NULL);
> +
> + //
> + // Make sure interrupts are disabled
> + //
> + DisableInterrupts ();
> +
> + //
> + // Install Boot protocol
> + //
> + Status = gBS->InstallProtocolInterface (
> + &ImageHandle,
> + &gRiscVEfiBootProtocolGuid,
> + EFI_NATIVE_INTERFACE,
> + &gRiscvBootProtocol
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + //
> + // Install CPU Architectural Protocol
> + //
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &mCpuHandle,
> + &gEfiCpuArchProtocolGuid,
> + &gCpu,
> + NULL
> + );
> + ASSERT_EFI_ERROR (Status);
> + return Status;
> +}
> --
> 2.38.0
>
>
>
>
>
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#99782): https://edk2.groups.io/g/devel/message/99782
Mute This Topic: https://groups.io/mt/96593503/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Since there is nothing shared between RiscV and X86, can you put the driver in a different folder such as RiscVCpuDxe? -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#99864): https://edk2.groups.io/g/devel/message/99864 Mute This Topic: https://groups.io/mt/96593503/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/3901457/1787277/102458076/xyzzy [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
On Wed, Feb 08, 2023 at 09:43:39PM -0800, Ni, Ray wrote: > Since there is nothing shared between RiscV and X86, can you put the driver in a different folder such as RiscVCpuDxe? Thank you very much Ray. Mike had given similar feedback. I am fine with your suggestion. Let me update the series with your suggestion for other patches also. Thanks, Sunil -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#99865): https://edk2.groups.io/g/devel/message/99865 Mute This Topic: https://groups.io/mt/96593503/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2026 Red Hat, Inc.