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>
This commit is contained in:
committed by
mergify[bot]
parent
26727c2ae2
commit
904b002c50
@@ -56,3 +56,8 @@
|
|||||||
BaseLib
|
BaseLib
|
||||||
DebugLib
|
DebugLib
|
||||||
|
|
||||||
|
[LibraryClasses.RISCV64]
|
||||||
|
PcdLib
|
||||||
|
|
||||||
|
[Pcd.RISCV64]
|
||||||
|
gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride ## CONSUMES
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
RISC-V specific functionality for cache.
|
RISC-V specific functionality for cache.
|
||||||
|
|
||||||
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
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
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
**/
|
**/
|
||||||
@@ -9,10 +10,116 @@
|
|||||||
#include <Base.h>
|
#include <Base.h>
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/DebugLib.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
|
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
|
VOID
|
||||||
@@ -28,17 +135,11 @@ InvalidateInstructionCache (
|
|||||||
Invalidates a range of instruction cache lines in the cache coherency domain
|
Invalidates a range of instruction cache lines in the cache coherency domain
|
||||||
of the calling CPU.
|
of the calling CPU.
|
||||||
|
|
||||||
Invalidates the instruction cache lines specified by Address and Length. If
|
An operation from a CMO instruction is defined to operate only on the copies
|
||||||
Address is not aligned on a cache line boundary, then entire instruction
|
of a cache block that are cached in the caches accessible by the explicit
|
||||||
cache line containing Address is invalidated. If Address + Length is not
|
memory accesses performed by the set of coherent agents.In other words CMO
|
||||||
aligned on a cache line boundary, then the entire instruction cache line
|
operations are not applicable to instruction cache. Use fence.i instruction
|
||||||
containing Address + Length -1 is invalidated. This function may choose to
|
instead to achieve the same purpose.
|
||||||
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().
|
|
||||||
|
|
||||||
@param Address The base address of the instruction cache lines to
|
@param Address The base address of the instruction cache lines to
|
||||||
invalidate. If the CPU is in a physical addressing mode, then
|
invalidate. If the CPU is in a physical addressing mode, then
|
||||||
Address is a physical address. If the CPU is in a virtual
|
Address is a physical address. If the CPU is in a virtual
|
||||||
@@ -57,9 +158,10 @@ InvalidateInstructionCacheRange (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
DEBUG (
|
DEBUG (
|
||||||
(DEBUG_WARN,
|
(DEBUG_VERBOSE,
|
||||||
"%a:RISC-V unsupported function.\n"
|
"InvalidateInstructionCacheRange: RISC-V unsupported function.\n"
|
||||||
"Invalidating the whole instruction cache instead.\n", __func__)
|
"Invalidating the whole instruction cache instead.\n"
|
||||||
|
)
|
||||||
);
|
);
|
||||||
InvalidateInstructionCache ();
|
InvalidateInstructionCache ();
|
||||||
return Address;
|
return Address;
|
||||||
@@ -81,7 +183,11 @@ WriteBackInvalidateDataCache (
|
|||||||
VOID
|
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
|
IN UINTN Length
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
DEBUG ((DEBUG_ERROR, "%a:RISC-V unsupported function.\n", __func__));
|
if (RiscVIsCMOEnabled ()) {
|
||||||
|
CacheOpCacheRange (Address, Length, CacheOpFlush);
|
||||||
|
} else {
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
return Address;
|
return Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +248,7 @@ WriteBackDataCache (
|
|||||||
VOID
|
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().
|
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
|
@param Address The base address of the data cache lines to write back.
|
||||||
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 Length The number of bytes to write back from the data cache.
|
@param Length The number of bytes to write back from the data cache.
|
||||||
|
|
||||||
@return Address of cache written in main memory.
|
@return Address of cache written in main memory.
|
||||||
@@ -172,7 +280,12 @@ WriteBackDataCacheRange (
|
|||||||
IN UINTN Length
|
IN UINTN Length
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
DEBUG ((DEBUG_ERROR, "%a:RISC-V unsupported function.\n", __func__));
|
if (RiscVIsCMOEnabled ()) {
|
||||||
|
CacheOpCacheRange (Address, Length, CacheOpClean);
|
||||||
|
} else {
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
return Address;
|
return Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,10 +327,7 @@ InvalidateDataCache (
|
|||||||
|
|
||||||
If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().
|
If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().
|
||||||
|
|
||||||
@param Address The base address of the data cache lines to invalidate. If
|
@param Address The base address of the data cache lines to invalidate.
|
||||||
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 Length The number of bytes to invalidate from the data cache.
|
@param Length The number of bytes to invalidate from the data cache.
|
||||||
|
|
||||||
@return Address.
|
@return Address.
|
||||||
@@ -230,6 +340,16 @@ InvalidateDataCacheRange (
|
|||||||
IN UINTN Length
|
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;
|
return Address;
|
||||||
}
|
}
|
||||||
|
@@ -2400,6 +2400,14 @@
|
|||||||
# @Prompt CPU Rng algorithm's GUID.
|
# @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
|
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]
|
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
|
||||||
## This value is used to set the base address of PCI express hierarchy.
|
## This value is used to set the base address of PCI express hierarchy.
|
||||||
# @Prompt PCI Express Base Address.
|
# @Prompt PCI Express Base Address.
|
||||||
|
@@ -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_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_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."
|
#string STR_gEfiMdePkgTokenSpaceGuid_PcdPciExpressBaseAddress_HELP #language en-US "This value is used to set the base address of PCI express hierarchy."
|
||||||
|
Reference in New Issue
Block a user