summaryrefslogtreecommitdiffstats
path: root/MdePkg
diff options
context:
space:
mode:
authorDhaval Sharma <dhaval@rivosinc.com>2023-12-13 20:29:30 +0530
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-12-19 12:48:14 +0000
commit904b002c505cc689a2075745e1de529da5895c41 (patch)
tree21fb01653d3a841b0f1dd9a5a833b4a09d754846 /MdePkg
parent26727c2ae2a8883b7f4be23c26b6209ea763c816 (diff)
downloadedk2-904b002c505cc689a2075745e1de529da5895c41.tar.gz
edk2-904b002c505cc689a2075745e1de529da5895c41.tar.bz2
edk2-904b002c505cc689a2075745e1de529da5895c41.zip
MdePkg: Utilize Cache Management Operations Implementation For RISC-V
Use newly defined cache management operations for RISC-V where possible It builds up on the support added for RISC-V cache management instructions in BaseLib. Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Zhiguang Liu <zhiguang.liu@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Pedro Falcato <pedro.falcato@gmail.com> Signed-off-by: Dhaval Sharma <dhaval@rivosinc.com> Acked-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Pedro Falcato <pedro.falcato@gmail.com> Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
Diffstat (limited to 'MdePkg')
-rw-r--r--MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf5
-rw-r--r--MdePkg/Library/BaseCacheMaintenanceLib/RiscVCache.c176
-rw-r--r--MdePkg/MdePkg.dec8
-rw-r--r--MdePkg/MdePkg.uni4
4 files changed, 165 insertions, 28 deletions
diff --git a/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf b/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
index 6fd9cbe5f6..601a38d6c1 100644
--- a/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+++ b/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
@@ -56,3 +56,8 @@
BaseLib
DebugLib
+[LibraryClasses.RISCV64]
+ PcdLib
+
+[Pcd.RISCV64]
+ gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride ## CONSUMES
diff --git a/MdePkg/Library/BaseCacheMaintenanceLib/RiscVCache.c b/MdePkg/Library/BaseCacheMaintenanceLib/RiscVCache.c
index ac2a3c23a2..73a5a6b6b5 100644
--- a/MdePkg/Library/BaseCacheMaintenanceLib/RiscVCache.c
+++ b/MdePkg/Library/BaseCacheMaintenanceLib/RiscVCache.c
@@ -2,6 +2,7 @@
RISC-V specific functionality for cache.
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+ Copyright (c) 2023, Rivos Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -9,10 +10,116 @@
#include <Base.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+//
+// TODO: Grab cache block size and make Cache Management Operation
+// enabling decision based on RISC-V CPU HOB in
+// future when it is available and convert PcdRiscVFeatureOverride
+// PCD to a pointer that contains pointer to bitmap structure
+// which can be operated more elegantly.
+//
+#define RISCV_CACHE_BLOCK_SIZE 64
+#define RISCV_CPU_FEATURE_CMO_BITMASK 0x1
+
+typedef enum {
+ CacheOpClean,
+ CacheOpFlush,
+ CacheOpInvld,
+} CACHE_OP;
+
+/**
+Verify CBOs are supported by this HW
+TODO: Use RISC-V CPU HOB once available.
+
+**/
+STATIC
+BOOLEAN
+RiscVIsCMOEnabled (
+ VOID
+ )
+{
+ // If CMO is disabled in HW, skip Override check
+ // Otherwise this PCD can override settings
+ return ((PcdGet64 (PcdRiscVFeatureOverride) & RISCV_CPU_FEATURE_CMO_BITMASK) != 0);
+}
+
+/**
+ Performs required opeartion on cache lines in the cache coherency domain
+ of the calling CPU. If Address is not aligned on a cache line boundary,
+ then entire cache line containing Address is operated. If Address + Length
+ is not aligned on a cache line boundary, then the entire cache line
+ containing Address + Length -1 is operated.
+ If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().
+ @param Address The base address of the cache lines to
+ invalidate.
+ @param Length The number of bytes to invalidate from the instruction
+ cache.
+ @param Op Type of CMO operation to be performed
+ @return Address.
+
+**/
+STATIC
+VOID
+CacheOpCacheRange (
+ IN VOID *Address,
+ IN UINTN Length,
+ IN CACHE_OP Op
+ )
+{
+ UINTN CacheLineSize;
+ UINTN Start;
+ UINTN End;
+
+ if (Length == 0) {
+ return;
+ }
+
+ if ((Op != CacheOpInvld) && (Op != CacheOpFlush) && (Op != CacheOpClean)) {
+ return;
+ }
+
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Address));
+
+ CacheLineSize = RISCV_CACHE_BLOCK_SIZE;
+
+ Start = (UINTN)Address;
+ //
+ // Calculate the cache line alignment
+ //
+ End = (Start + Length + (CacheLineSize - 1)) & ~(CacheLineSize - 1);
+ Start &= ~((UINTN)CacheLineSize - 1);
+
+ DEBUG (
+ (DEBUG_VERBOSE,
+ "CacheOpCacheRange: Performing Cache Management Operation %d \n", Op)
+ );
+
+ do {
+ switch (Op) {
+ case CacheOpInvld:
+ RiscVCpuCacheInvalCmoAsm (Start);
+ break;
+ case CacheOpFlush:
+ RiscVCpuCacheFlushCmoAsm (Start);
+ break;
+ case CacheOpClean:
+ RiscVCpuCacheCleanCmoAsm (Start);
+ break;
+ default:
+ break;
+ }
+
+ Start = Start + CacheLineSize;
+ } while (Start != End);
+}
/**
Invalidates the entire instruction cache in cache coherency domain of the
- calling CPU.
+ calling CPU. Risc-V does not have currently an CBO implementation which can
+ invalidate the entire I-cache. Hence using Fence instruction for now. P.S.
+ Fence instruction may or may not implement full I-cache invd functionality
+ on all implementations.
**/
VOID
@@ -28,17 +135,11 @@ InvalidateInstructionCache (
Invalidates a range of instruction cache lines in the cache coherency domain
of the calling CPU.
- Invalidates the instruction cache lines specified by Address and Length. If
- Address is not aligned on a cache line boundary, then entire instruction
- cache line containing Address is invalidated. If Address + Length is not
- aligned on a cache line boundary, then the entire instruction cache line
- containing Address + Length -1 is invalidated. This function may choose to
- invalidate the entire instruction cache if that is more efficient than
- invalidating the specified range. If Length is 0, then no instruction cache
- lines are invalidated. Address is returned.
-
- If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().
-
+ An operation from a CMO instruction is defined to operate only on the copies
+ of a cache block that are cached in the caches accessible by the explicit
+ memory accesses performed by the set of coherent agents.In other words CMO
+ operations are not applicable to instruction cache. Use fence.i instruction
+ instead to achieve the same purpose.
@param Address The base address of the instruction cache lines to
invalidate. If the CPU is in a physical addressing mode, then
Address is a physical address. If the CPU is in a virtual
@@ -57,9 +158,10 @@ InvalidateInstructionCacheRange (
)
{
DEBUG (
- (DEBUG_WARN,
- "%a:RISC-V unsupported function.\n"
- "Invalidating the whole instruction cache instead.\n", __func__)
+ (DEBUG_VERBOSE,
+ "InvalidateInstructionCacheRange: RISC-V unsupported function.\n"
+ "Invalidating the whole instruction cache instead.\n"
+ )
);
InvalidateInstructionCache ();
return Address;
@@ -81,7 +183,11 @@ WriteBackInvalidateDataCache (
VOID
)
{
- DEBUG ((DEBUG_ERROR, "%a:RISC-V unsupported function.\n", __func__));
+ ASSERT (FALSE);
+ DEBUG ((
+ DEBUG_ERROR,
+ "WriteBackInvalidateDataCache: RISC-V unsupported function.\n"
+ ));
}
/**
@@ -117,7 +223,12 @@ WriteBackInvalidateDataCacheRange (
IN UINTN Length
)
{
- DEBUG ((DEBUG_ERROR, "%a:RISC-V unsupported function.\n", __func__));
+ if (RiscVIsCMOEnabled ()) {
+ CacheOpCacheRange (Address, Length, CacheOpFlush);
+ } else {
+ ASSERT (FALSE);
+ }
+
return Address;
}
@@ -137,7 +248,7 @@ WriteBackDataCache (
VOID
)
{
- DEBUG ((DEBUG_ERROR, "%a:RISC-V unsupported function.\n", __func__));
+ ASSERT (FALSE);
}
/**
@@ -156,10 +267,7 @@ WriteBackDataCache (
If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().
- @param Address The base address of the data cache lines to write back. If
- the CPU is in a physical addressing mode, then Address is a
- physical address. If the CPU is in a virtual addressing
- mode, then Address is a virtual address.
+ @param Address The base address of the data cache lines to write back.
@param Length The number of bytes to write back from the data cache.
@return Address of cache written in main memory.
@@ -172,7 +280,12 @@ WriteBackDataCacheRange (
IN UINTN Length
)
{
- DEBUG ((DEBUG_ERROR, "%a:RISC-V unsupported function.\n", __func__));
+ if (RiscVIsCMOEnabled ()) {
+ CacheOpCacheRange (Address, Length, CacheOpClean);
+ } else {
+ ASSERT (FALSE);
+ }
+
return Address;
}
@@ -214,10 +327,7 @@ InvalidateDataCache (
If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().
- @param Address The base address of the data cache lines to invalidate. If
- the CPU is in a physical addressing mode, then Address is a
- physical address. If the CPU is in a virtual addressing mode,
- then Address is a virtual address.
+ @param Address The base address of the data cache lines to invalidate.
@param Length The number of bytes to invalidate from the data cache.
@return Address.
@@ -230,6 +340,16 @@ InvalidateDataCacheRange (
IN UINTN Length
)
{
- DEBUG ((DEBUG_ERROR, "%a:RISC-V unsupported function.\n", __func__));
+ if (RiscVIsCMOEnabled ()) {
+ CacheOpCacheRange (Address, Length, CacheOpInvld);
+ } else {
+ DEBUG (
+ (DEBUG_VERBOSE,
+ "InvalidateDataCacheRange: Zicbom not supported.\n"
+ "Invalidating the whole Data cache instead.\n")
+ );
+ InvalidateDataCache ();
+ }
+
return Address;
}
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index bec63f5416..2ee112cc08 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -2400,6 +2400,14 @@
# @Prompt CPU Rng algorithm's GUID.
gEfiMdePkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm|{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}|VOID*|0x00000037
+[PcdsFixedAtBuild.RISCV64, PcdsPatchableInModule.RISCV64]
+ #
+ # Configurability to override RISC-V CPU Features
+ # BIT 0 = Cache Management Operations. This bit is relevant only if
+ # previous stage has feature enabled and user wants to disable it.
+ #
+ gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride|0xFFFFFFFFFFFFFFFF|UINT64|0x69
+
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
## This value is used to set the base address of PCI express hierarchy.
# @Prompt PCI Express Base Address.
diff --git a/MdePkg/MdePkg.uni b/MdePkg/MdePkg.uni
index 75dbc6ffe3..67b79f0270 100644
--- a/MdePkg/MdePkg.uni
+++ b/MdePkg/MdePkg.uni
@@ -289,6 +289,10 @@
#string STR_gEfiMdePkgTokenSpaceGuid_PcdGuidedExtractHandlerTableAddress_HELP #language en-US "This value is used to set the available memory address to store Guided Extract Handlers. The required memory space is decided by the value of PcdMaximumGuidedExtractHandler."
+#string STR_gEfiMdePkgTokenSpaceGuid_PcdRiscVFeatureOverride_PROMPT #language en-US "RISC-V Feature Override"
+
+#string STR_gEfiMdePkgTokenSpaceGuid_PcdRiscVFeatureOverride_HELP #language en-US "This value is used to override any RISC-V specific features supported by this PCD"
+
#string STR_gEfiMdePkgTokenSpaceGuid_PcdPciExpressBaseAddress_PROMPT #language en-US "PCI Express Base Address"
#string STR_gEfiMdePkgTokenSpaceGuid_PcdPciExpressBaseAddress_HELP #language en-US "This value is used to set the base address of PCI express hierarchy."