mirror of https://github.com/acidanthera/audk.git
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:
parent
26727c2ae2
commit
904b002c50
|
@ -56,3 +56,8 @@
|
|||
BaseLib
|
||||
DebugLib
|
||||
|
||||
[LibraryClasses.RISCV64]
|
||||
PcdLib
|
||||
|
||||
[Pcd.RISCV64]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride ## CONSUMES
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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."
|
||||
|
|
Loading…
Reference in New Issue