mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-25 14:44:28 +02:00
UefiCpuPkg: Add CpuMmuLib to UefiCpuPkg
Add a new base library named CpuMmuLib and add a LoongArch64 instance with in the library. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4734 Cc: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Chao Li <lichao@loongson.cn> Co-authored-by: Baoqi Zhang <zhangbaoqi@loongson.cn> Co-authored-by: Dongyan Qian <qiandongyan@loongson.cn> Co-authored-by: Xianglai Li <lixianglai@loongson.cn> Co-authored-by: Bibo Mao <maobibo@loongson.cn> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Ray Ni <ray.ni@intel.com>
This commit is contained in:
parent
c5fb47ddab
commit
032830e968
39
UefiCpuPkg/Library/CpuMmuLib/CpuMmuLib.inf
Normal file
39
UefiCpuPkg/Library/CpuMmuLib/CpuMmuLib.inf
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
## @file
|
||||||
|
# CPU Memory Manager Unit library instance.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
##
|
||||||
|
|
||||||
|
[Defines]
|
||||||
|
INF_VERSION = 1.29
|
||||||
|
BASE_NAME = CpuMmuLib
|
||||||
|
MODULE_UNI_FILE = CpuMmuLib.uni
|
||||||
|
FILE_GUID = DA8F0232-FB14-42F0-922C-63104D2C70BE
|
||||||
|
MODULE_TYPE = BASE
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = CpuMmuLib
|
||||||
|
|
||||||
|
#
|
||||||
|
# VALID_ARCHITECTURES = LOONGARCH64
|
||||||
|
#
|
||||||
|
|
||||||
|
[Sources.LoongArch64]
|
||||||
|
LoongArch64/TlbInvalid.S | GCC
|
||||||
|
LoongArch64/TlbExceptionHandle.S | GCC
|
||||||
|
LoongArch64/CpuMmu.c
|
||||||
|
LoongArch64/Page.h
|
||||||
|
LoongArch64/TlbInvalid.h
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
UefiCpuPkg/UefiCpuPkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
DebugLib
|
||||||
|
MemoryAllocationLib
|
||||||
|
|
||||||
|
[Pcd.LoongArch64]
|
||||||
|
gUefiCpuPkgTokenSpaceGuid.PcdLoongArchExceptionVectorBaseAddress ## CONSUMES
|
14
UefiCpuPkg/Library/CpuMmuLib/CpuMmuLib.uni
Normal file
14
UefiCpuPkg/Library/CpuMmuLib/CpuMmuLib.uni
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// /** @file
|
||||||
|
// CPU Memory Manager Unit library instance.
|
||||||
|
//
|
||||||
|
// CPU Memory Manager Unit library instance.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
//
|
||||||
|
// **/
|
||||||
|
|
||||||
|
#string STR_MODULE_ABSTRACT #language en-US "CPU Memory Manager Unit library instance."
|
||||||
|
|
||||||
|
#string STR_MODULE_DESCRIPTION #language en-US "CPU Memory Manager Unit library instance."
|
784
UefiCpuPkg/Library/CpuMmuLib/LoongArch64/CpuMmu.c
Normal file
784
UefiCpuPkg/Library/CpuMmuLib/LoongArch64/CpuMmu.c
Normal file
@ -0,0 +1,784 @@
|
|||||||
|
/** @file
|
||||||
|
|
||||||
|
CPU Memory Map Unit Handler Library common functions.
|
||||||
|
|
||||||
|
Copyright (c) 2011-2020, ARM Limited. All rights reserved.
|
||||||
|
Copyright (c) 2016, Linaro Limited. All rights reserved.
|
||||||
|
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
Copyright (c) 2023, Ventana Micro Systems Inc. All Rights Reserved.<BR>
|
||||||
|
Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
#include <Uefi.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/CacheMaintenanceLib.h>
|
||||||
|
#include <Library/CpuMmuLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Protocol/DebugSupport.h>
|
||||||
|
#include <Register/LoongArch64/Csr.h>
|
||||||
|
#include "TlbInvalid.h"
|
||||||
|
#include "TlbExceptionHandle.h"
|
||||||
|
#include "Page.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check to see if mmu successfully initializes.
|
||||||
|
|
||||||
|
@param VOID.
|
||||||
|
|
||||||
|
@retval TRUE Initialization has been completed.
|
||||||
|
FALSE Initialization did not complete.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
BOOLEAN
|
||||||
|
MmuIsInit (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (CsrRead (LOONGARCH_CSR_PGDL) != 0) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check to see if mmu is enabled.
|
||||||
|
|
||||||
|
@param VOID.
|
||||||
|
|
||||||
|
@retval TRUE MMU has been enabled.
|
||||||
|
FALSE MMU did not enabled.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
BOOLEAN
|
||||||
|
MmuIsEnabled (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ((CsrRead (LOONGARCH_CSR_CRMD) & BIT4) != 0) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Determine if an entry is valid pte.
|
||||||
|
|
||||||
|
@param Entry The entry value.
|
||||||
|
|
||||||
|
@retval TRUE The entry is a valid pte.
|
||||||
|
@retval FALSE The entry is not a valid pte.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
BOOLEAN
|
||||||
|
IsValidPte (
|
||||||
|
IN UINTN Entry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Entry != INVALID_PAGE) {
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Determine if an entry is huge page.
|
||||||
|
|
||||||
|
@param Entry The entry value.
|
||||||
|
|
||||||
|
@retval TRUE The entry is a huge page.
|
||||||
|
@retval FALSE The entry is not a valid huge page.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
BOOLEAN
|
||||||
|
IsValidHugePage (
|
||||||
|
IN UINTN Entry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ((Entry & (PAGE_HGLOBAL | PAGE_HUGE)) == (PAGE_HGLOBAL | PAGE_HUGE)) {
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set an entry to be a valid pte.
|
||||||
|
|
||||||
|
@param Entry The entry value.
|
||||||
|
|
||||||
|
@return The entry value.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
UINTN
|
||||||
|
SetValidPte (
|
||||||
|
IN UINTN Entry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* Set Valid and Global mapping bits */
|
||||||
|
return Entry | PAGE_GLOBAL | PAGE_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parse max page table level.
|
||||||
|
|
||||||
|
@param[in] PageWalkCfg Page table configure value.
|
||||||
|
|
||||||
|
@return 5 MAX page level is 5
|
||||||
|
4 MAX page level is 4
|
||||||
|
3 MAX page level is 3
|
||||||
|
0 Invalid
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
UINTN
|
||||||
|
ParseMaxPageTableLevel (
|
||||||
|
IN UINT64 PageWalkCfg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 Pwctl0;
|
||||||
|
UINT32 Pwctl1;
|
||||||
|
|
||||||
|
Pwctl0 = PageWalkCfg & MAX_UINT32;
|
||||||
|
Pwctl1 = (PageWalkCfg >> 32) & MAX_UINT32;
|
||||||
|
|
||||||
|
if (((Pwctl1 >> 18) & 0x3F) != 0x0) {
|
||||||
|
return LEVEL5;
|
||||||
|
} else if (((Pwctl1 >> 6) & 0x3F) != 0x0) {
|
||||||
|
return LEVEL4;
|
||||||
|
} else if (((Pwctl0 >> 25) & 0x3F) != 0x0) {
|
||||||
|
return LEVEL3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parse page table bit width.
|
||||||
|
|
||||||
|
Assume that the bit width of the page table that each level is the same to PTwidth.
|
||||||
|
|
||||||
|
@param[in] PageWalkCfg Page table configure value.
|
||||||
|
|
||||||
|
@return page table bit width
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
UINTN
|
||||||
|
ParsePageTableBitWidth (
|
||||||
|
IN UINT64 PageWalkCfg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// PTwidth
|
||||||
|
//
|
||||||
|
return ((PageWalkCfg >> 5) & 0x1F);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Determine if an entry is a HUGE PTE or 4K PTE.
|
||||||
|
|
||||||
|
@param Entry The entry value.
|
||||||
|
@param Level The current page table level.
|
||||||
|
@param PageWalkCfg Page table configure value.
|
||||||
|
|
||||||
|
@retval TRUE The entry is a block pte.
|
||||||
|
@retval FALSE The entry is not a block pte.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
BOOLEAN
|
||||||
|
IsBlockEntry (
|
||||||
|
IN UINTN Entry,
|
||||||
|
IN UINTN Level,
|
||||||
|
IN UINT64 PageWalkCfg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Level == (ParseMaxPageTableLevel (PageWalkCfg) - 1)) {
|
||||||
|
return ((Entry & PAGE_VALID) == PAGE_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsValidHugePage (Entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Determine if an entry is a table pte.
|
||||||
|
|
||||||
|
@param Entry The entry value.
|
||||||
|
@param Level The current page table level.
|
||||||
|
@param PageWalkCfg Page table configure value.
|
||||||
|
|
||||||
|
@retval TRUE The entry is a table pte.
|
||||||
|
@retval FALSE The entry is not a table pte.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
BOOLEAN
|
||||||
|
IsTableEntry (
|
||||||
|
IN UINTN Entry,
|
||||||
|
IN UINTN Level,
|
||||||
|
IN UINT64 PageWalkCfg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Level == (ParseMaxPageTableLevel (PageWalkCfg) - 1)) {
|
||||||
|
//
|
||||||
|
// The last level is PAGE rather than Table.
|
||||||
|
//
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Is DIR4 or DIR3 or DIR2 a Huge Page ?
|
||||||
|
//
|
||||||
|
return (!IsValidHugePage (Entry)) && (IsValidPte (Entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Replace an existing entry with new value.
|
||||||
|
|
||||||
|
@param Entry The entry pointer.
|
||||||
|
@param Value The new entry value.
|
||||||
|
@param RegionStart The start of region that new value affects.
|
||||||
|
@param IsLiveBlockMapping TRUE if this is live update, FALSE otherwise.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
ReplaceTableEntry (
|
||||||
|
IN UINTN *Entry,
|
||||||
|
IN UINTN Value,
|
||||||
|
IN UINTN RegionStart,
|
||||||
|
IN BOOLEAN IsLiveBlockMapping
|
||||||
|
)
|
||||||
|
{
|
||||||
|
*Entry = Value;
|
||||||
|
|
||||||
|
if (IsLiveBlockMapping && MmuIsInit ()) {
|
||||||
|
InvalidTlb (RegionStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get an ppn value from an entry.
|
||||||
|
|
||||||
|
@param Entry The entry value.
|
||||||
|
|
||||||
|
@return The ppn value.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
UINTN
|
||||||
|
GetPpnfromPte (
|
||||||
|
IN UINTN Entry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return ((Entry & PTE_PPN_MASK) >> PTE_PPN_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set an ppn value to a entry.
|
||||||
|
|
||||||
|
@param Entry The entry value.
|
||||||
|
@param Address The address.
|
||||||
|
|
||||||
|
@return The new entry value.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
UINTN
|
||||||
|
SetPpnToPte (
|
||||||
|
UINTN Entry,
|
||||||
|
UINTN Address
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN Ppn;
|
||||||
|
|
||||||
|
Ppn = ((Address >> LOONGARCH_MMU_PAGE_SHIFT) << PTE_PPN_SHIFT);
|
||||||
|
ASSERT (~(Ppn & ~PTE_PPN_MASK));
|
||||||
|
Entry &= ~PTE_PPN_MASK;
|
||||||
|
return Entry | Ppn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free resources of translation table recursively.
|
||||||
|
|
||||||
|
@param TranslationTable The pointer of table.
|
||||||
|
@param PageWalkCfg Page table configure value.
|
||||||
|
@param Level The current level.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
FreePageTablesRecursive (
|
||||||
|
IN UINTN *TranslationTable,
|
||||||
|
IN UINT64 PageWalkCfg,
|
||||||
|
IN UINTN Level
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
UINTN TableEntryNum;
|
||||||
|
|
||||||
|
TableEntryNum = (1 << ParsePageTableBitWidth (PageWalkCfg));
|
||||||
|
|
||||||
|
if (Level < (ParseMaxPageTableLevel (PageWalkCfg) - 1)) {
|
||||||
|
for (Index = 0; Index < TableEntryNum; Index++) {
|
||||||
|
if (IsTableEntry (TranslationTable[Index], Level, PageWalkCfg)) {
|
||||||
|
FreePageTablesRecursive (
|
||||||
|
(UINTN *)(GetPpnfromPte ((TranslationTable[Index])) <<
|
||||||
|
LOONGARCH_MMU_PAGE_SHIFT),
|
||||||
|
PageWalkCfg,
|
||||||
|
Level + 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePages (TranslationTable, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Update region mapping recursively.
|
||||||
|
|
||||||
|
@param RegionStart The start address of the region.
|
||||||
|
@param RegionEnd The end address of the region.
|
||||||
|
@param AttributeSetMask The attribute mask to be set.
|
||||||
|
@param AttributeClearMask The attribute mask to be clear.
|
||||||
|
@param PageTable The pointer of current page table.
|
||||||
|
@param Level The current level.
|
||||||
|
@param PageWalkCfg Page table configure value.
|
||||||
|
@param TableIsLive TRUE if this is live update, FALSE otherwise.
|
||||||
|
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Not enough resource.
|
||||||
|
@retval EFI_SUCCESS The operation succesfully.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
UpdateRegionMappingRecursive (
|
||||||
|
IN UINTN RegionStart,
|
||||||
|
IN UINTN RegionEnd,
|
||||||
|
IN UINTN AttributeSetMask,
|
||||||
|
IN UINTN AttributeClearMask,
|
||||||
|
IN UINTN *PageTable,
|
||||||
|
IN UINTN Level,
|
||||||
|
IN UINT64 PageWalkCfg,
|
||||||
|
IN BOOLEAN TableIsLive
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN BlockShift;
|
||||||
|
UINTN BlockMask;
|
||||||
|
UINTN BlockEnd;
|
||||||
|
UINTN *Entry;
|
||||||
|
UINTN EntryValue;
|
||||||
|
UINTN *TranslationTable;
|
||||||
|
UINTN TableEntryNum;
|
||||||
|
UINTN TableBitWidth;
|
||||||
|
BOOLEAN NextTableIsLive;
|
||||||
|
|
||||||
|
ASSERT (Level < ParseMaxPageTableLevel (PageWalkCfg));
|
||||||
|
ASSERT (((RegionStart | RegionEnd) & EFI_PAGE_MASK) == 0);
|
||||||
|
|
||||||
|
TableBitWidth = ParsePageTableBitWidth (PageWalkCfg);
|
||||||
|
BlockShift = (ParseMaxPageTableLevel (PageWalkCfg) - Level - 1) * TableBitWidth + LOONGARCH_MMU_PAGE_SHIFT;
|
||||||
|
BlockMask = MAX_ADDRESS >> (64 - BlockShift);
|
||||||
|
|
||||||
|
DEBUG (
|
||||||
|
(
|
||||||
|
DEBUG_VERBOSE,
|
||||||
|
"%a(%d): %llx - %llx set %lx clr %lx\n",
|
||||||
|
__func__,
|
||||||
|
Level,
|
||||||
|
RegionStart,
|
||||||
|
RegionEnd,
|
||||||
|
AttributeSetMask,
|
||||||
|
AttributeClearMask
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
TableEntryNum = (1 << TableBitWidth);
|
||||||
|
for ( ; RegionStart < RegionEnd; RegionStart = BlockEnd) {
|
||||||
|
BlockEnd = MIN (RegionEnd, (RegionStart | BlockMask) + 1);
|
||||||
|
Entry = &PageTable[(RegionStart >> BlockShift) & (TableEntryNum - 1)];
|
||||||
|
|
||||||
|
//
|
||||||
|
// If RegionStart or BlockEnd is not aligned to the block size at this
|
||||||
|
// level, we will have to create a table mapping in order to map less
|
||||||
|
// than a block, and recurse to create the block or page entries at
|
||||||
|
// the next level. No block mappings are allowed at all at level 2,
|
||||||
|
// so in that case, we have to recurse unconditionally.
|
||||||
|
//
|
||||||
|
if ((Level < 2) ||
|
||||||
|
(((RegionStart | BlockEnd) & BlockMask) != 0) || IsTableEntry (*Entry, Level, PageWalkCfg))
|
||||||
|
{
|
||||||
|
ASSERT (Level < (ParseMaxPageTableLevel (PageWalkCfg) - 1));
|
||||||
|
if (!IsTableEntry (*Entry, Level, PageWalkCfg)) {
|
||||||
|
//
|
||||||
|
// No table entry exists yet, so we need to allocate a page table
|
||||||
|
// for the next level.
|
||||||
|
//
|
||||||
|
TranslationTable = AllocatePages (1);
|
||||||
|
if (TranslationTable == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeroMem (TranslationTable, EFI_PAGE_SIZE);
|
||||||
|
|
||||||
|
if (IsBlockEntry (*Entry, Level, PageWalkCfg)) {
|
||||||
|
//
|
||||||
|
// We are splitting an existing block entry, so we have to populate
|
||||||
|
// the new table with the attributes of the block entry it replaces.
|
||||||
|
//
|
||||||
|
Status = UpdateRegionMappingRecursive (
|
||||||
|
RegionStart & ~BlockMask,
|
||||||
|
(RegionStart | BlockMask) + 1,
|
||||||
|
*Entry & PTE_ATTRIBUTES_MASK,
|
||||||
|
PTE_ATTRIBUTES_MASK,
|
||||||
|
TranslationTable,
|
||||||
|
Level + 1,
|
||||||
|
PageWalkCfg,
|
||||||
|
FALSE
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// The range we passed to UpdateRegionMappingRecursive () is block
|
||||||
|
// aligned, so it is guaranteed that no further pages were allocated
|
||||||
|
// by it, and so we only have to free the page we allocated here.
|
||||||
|
//
|
||||||
|
FreePages (TranslationTable, 1);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NextTableIsLive = FALSE;
|
||||||
|
} else {
|
||||||
|
TranslationTable = (UINTN *)(GetPpnfromPte (*Entry) << LOONGARCH_MMU_PAGE_SHIFT);
|
||||||
|
NextTableIsLive = TableIsLive;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Recurse to the next level
|
||||||
|
//
|
||||||
|
Status = UpdateRegionMappingRecursive (
|
||||||
|
RegionStart,
|
||||||
|
BlockEnd,
|
||||||
|
AttributeSetMask,
|
||||||
|
AttributeClearMask,
|
||||||
|
TranslationTable,
|
||||||
|
Level + 1,
|
||||||
|
PageWalkCfg,
|
||||||
|
NextTableIsLive
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
if (!IsTableEntry (*Entry, Level, PageWalkCfg)) {
|
||||||
|
//
|
||||||
|
// We are creating a new table entry, so on failure, we can free all
|
||||||
|
// allocations we made recursively, given that the whole subhierarchy
|
||||||
|
// has not been wired into the live page tables yet. (This is not
|
||||||
|
// possible for existing table entries, since we cannot revert the
|
||||||
|
// modifications we made to the subhierarchy it represents.)
|
||||||
|
//
|
||||||
|
FreePageTablesRecursive (TranslationTable, PageWalkCfg, Level + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsTableEntry (*Entry, Level, PageWalkCfg)) {
|
||||||
|
EntryValue = SetPpnToPte (0, (UINTN)TranslationTable);
|
||||||
|
ReplaceTableEntry (
|
||||||
|
Entry,
|
||||||
|
EntryValue,
|
||||||
|
RegionStart,
|
||||||
|
TableIsLive
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
EntryValue = (*Entry & ~AttributeClearMask) | AttributeSetMask;
|
||||||
|
|
||||||
|
EntryValue = SetPpnToPte (EntryValue, RegionStart);
|
||||||
|
EntryValue = SetValidPte (EntryValue);
|
||||||
|
|
||||||
|
if (Level < (ParseMaxPageTableLevel (PageWalkCfg) - 1)) {
|
||||||
|
EntryValue |= (PAGE_HGLOBAL | PAGE_HUGE | PAGE_VALID);
|
||||||
|
} else {
|
||||||
|
EntryValue |= PAGE_GLOBAL | PAGE_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReplaceTableEntry (Entry, EntryValue, RegionStart, TableIsLive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Update region mapping at root table.
|
||||||
|
|
||||||
|
@param RegionStart The start address of the region.
|
||||||
|
@param RegionLength The length of the region.
|
||||||
|
@param PageWalkCfg Page table configure value.
|
||||||
|
@param AttributeSetMask The attribute mask to be set.
|
||||||
|
@param AttributeClearMask The attribute mask to be clear.
|
||||||
|
@param RootTable The pointer of root table.
|
||||||
|
@param TableIsLive TRUE if this is live update, FALSE otherwise.
|
||||||
|
|
||||||
|
@retval EFI_INVALID_PARAMETER The RegionStart or RegionLength was not valid.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Not enough resource.
|
||||||
|
@retval EFI_SUCCESS The operation succesfully.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
UpdateRegionMapping (
|
||||||
|
IN UINTN RegionStart,
|
||||||
|
IN UINTN RegionLength,
|
||||||
|
IN UINT64 PageWalkCfg,
|
||||||
|
IN UINTN AttributeSetMask,
|
||||||
|
IN UINTN AttributeClearMask,
|
||||||
|
IN UINTN *RootTable,
|
||||||
|
IN BOOLEAN TableIsLive
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (((RegionStart | RegionLength) & EFI_PAGE_MASK) != 0) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UpdateRegionMappingRecursive (
|
||||||
|
RegionStart,
|
||||||
|
RegionStart + RegionLength,
|
||||||
|
AttributeSetMask,
|
||||||
|
AttributeClearMask,
|
||||||
|
RootTable,
|
||||||
|
0,
|
||||||
|
PageWalkCfg,
|
||||||
|
TableIsLive
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert EFI Attributes to Loongarch Attributes.
|
||||||
|
|
||||||
|
@param[in] EfiAttributes Efi Attributes.
|
||||||
|
|
||||||
|
@retval Corresponding architecture attributes.
|
||||||
|
**/
|
||||||
|
UINT64
|
||||||
|
EFIAPI
|
||||||
|
EfiAttributeConverse (
|
||||||
|
IN UINT64 EfiAttributes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT64 LoongArchAttributes;
|
||||||
|
|
||||||
|
LoongArchAttributes = PAGE_VALID | PAGE_DIRTY | PLV_KERNEL | PAGE_GLOBAL;
|
||||||
|
|
||||||
|
switch (EfiAttributes & EFI_CACHE_ATTRIBUTE_MASK) {
|
||||||
|
case EFI_MEMORY_UC:
|
||||||
|
LoongArchAttributes |= CACHE_SUC;
|
||||||
|
break;
|
||||||
|
case EFI_MEMORY_WC:
|
||||||
|
LoongArchAttributes |= CACHE_WUC;
|
||||||
|
break;
|
||||||
|
case EFI_MEMORY_WT:
|
||||||
|
case EFI_MEMORY_WB:
|
||||||
|
LoongArchAttributes |= CACHE_CC;
|
||||||
|
break;
|
||||||
|
case EFI_MEMORY_WP:
|
||||||
|
LoongArchAttributes &= ~PAGE_DIRTY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write protection attributes
|
||||||
|
switch (EfiAttributes & EFI_MEMORY_ACCESS_MASK) {
|
||||||
|
case EFI_MEMORY_RP:
|
||||||
|
LoongArchAttributes |= PAGE_NO_READ;
|
||||||
|
break;
|
||||||
|
case EFI_MEMORY_XP:
|
||||||
|
LoongArchAttributes |= PAGE_NO_EXEC;
|
||||||
|
break;
|
||||||
|
case EFI_MEMORY_RO:
|
||||||
|
LoongArchAttributes &= ~PAGE_DIRTY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LoongArchAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
TLB refill handler configure.
|
||||||
|
|
||||||
|
@param VOID.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS TLB refill handler configure successfully.
|
||||||
|
EFI_UNSUPPORTED Size not aligned.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
TlbRefillHandlerConfigure (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN Length;
|
||||||
|
UINTN TlbReEntry;
|
||||||
|
UINTN TlbReEntryOffset;
|
||||||
|
UINTN Remaining;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set TLB exception handler
|
||||||
|
//
|
||||||
|
///
|
||||||
|
/// TLB Re-entry address at the end of exception vector, a vector is up to 512 bytes,
|
||||||
|
/// so the starting address is: total exception vector size + total interrupt vector size + base.
|
||||||
|
/// The total size of TLB handler and exception vector size and interrupt vector size should not
|
||||||
|
/// be lager than 64KB.
|
||||||
|
///
|
||||||
|
Length = (UINTN)HandleTlbRefillEnd - (UINTN)HandleTlbRefillStart;
|
||||||
|
TlbReEntryOffset = (MAX_LOONGARCH_EXCEPTION + MAX_LOONGARCH_INTERRUPT) * 512;
|
||||||
|
Remaining = TlbReEntryOffset % SIZE_4KB;
|
||||||
|
if (Remaining != 0x0) {
|
||||||
|
TlbReEntryOffset += (SIZE_4KB - Remaining);
|
||||||
|
}
|
||||||
|
|
||||||
|
TlbReEntry = PcdGet64 (PcdLoongArchExceptionVectorBaseAddress) + TlbReEntryOffset;
|
||||||
|
if ((TlbReEntryOffset + Length) > SIZE_64KB) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Ensure that TLB refill exception base address alignment is equals to 4KB and is valid.
|
||||||
|
//
|
||||||
|
if (TlbReEntry & (SIZE_4KB - 1)) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem ((VOID *)TlbReEntry, HandleTlbRefillStart, Length);
|
||||||
|
InvalidateInstructionCacheRange ((VOID *)(UINTN)HandleTlbRefillStart, Length);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the address of TLB refill exception handler
|
||||||
|
//
|
||||||
|
SetTlbRebaseAddress ((UINTN)TlbReEntry);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Maps the memory region in the page table to the specified attributes.
|
||||||
|
|
||||||
|
@param[in, out] PageTable The pointer to the page table to update, or pointer to NULL
|
||||||
|
if a new page table is to be created.
|
||||||
|
@param[in] PageWalkCfg The page walk controller configure.
|
||||||
|
@param[in] BaseAddress The base address of the memory region to set the Attributes.
|
||||||
|
@param[in] Length The length of the memory region to set the Attributes.
|
||||||
|
@param[in] Attributes The bitmask of attributes to set, which refer to UEFI SPEC
|
||||||
|
7.2.3(EFI_BOOT_SERVICES.GetMemoryMap()).
|
||||||
|
@param[in] AttributeMask Mask of memory attributes to take into account.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The Attributes was set successfully or Length is 0.
|
||||||
|
@retval EFI_INVALID_PARAMETER PageTable is NULL, PageWalkCfg is invalid.
|
||||||
|
@retval EFI_UNSUPPORTED *PageTable is NULL.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
MemoryRegionMap (
|
||||||
|
IN OUT UINTN *PageTable OPTIONAL,
|
||||||
|
IN UINT64 PageWalkCfg,
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length,
|
||||||
|
IN UINT64 Attributes,
|
||||||
|
IN UINT64 AttributeMask
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT64 LoongArchAttributes;
|
||||||
|
BOOLEAN Initialization;
|
||||||
|
BOOLEAN CreateNew;
|
||||||
|
UINTN PageTableBitWidth;
|
||||||
|
UINTN MaxLevel;
|
||||||
|
UINTN PgdSize;
|
||||||
|
|
||||||
|
if ((PageTable == NULL) || (PageWalkCfg == 0)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageTableBitWidth = ParsePageTableBitWidth (PageWalkCfg);
|
||||||
|
MaxLevel = ParseMaxPageTableLevel (PageWalkCfg);
|
||||||
|
|
||||||
|
if ((!PageTableBitWidth && !MaxLevel) || (PageTableBitWidth > 0x1F) || (MaxLevel > LEVEL5)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Initialization = FALSE;
|
||||||
|
CreateNew = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// *PageTable is NULL, create a new and return.
|
||||||
|
//
|
||||||
|
if (*PageTable == 0) {
|
||||||
|
CreateNew = TRUE;
|
||||||
|
//
|
||||||
|
// If the MMU has not been configured yet, configure it later.
|
||||||
|
//
|
||||||
|
if (!MmuIsInit ()) {
|
||||||
|
Initialization = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Length == 0) {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Initialization == TRUE) {
|
||||||
|
Status = TlbRefillHandlerConfigure ();
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CreateNew == TRUE) {
|
||||||
|
//
|
||||||
|
// Create a new page table.
|
||||||
|
//
|
||||||
|
PgdSize = (1 << PageTableBitWidth) * sizeof (UINTN);
|
||||||
|
*PageTable = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (PgdSize));
|
||||||
|
ZeroMem ((VOID *)*PageTable, PgdSize);
|
||||||
|
|
||||||
|
if ((VOID *)*PageTable == NULL) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LoongArchAttributes = EfiAttributeConverse (Attributes);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update the page table attributes.
|
||||||
|
//
|
||||||
|
// If the MMU has been configured and *PageTable == CSR_PGDL, the page table in use will update.
|
||||||
|
//
|
||||||
|
// If *PageTable != CSR_PGDL, only the page table structure in memory is update, but some TLB
|
||||||
|
// region may be invalidated during the mapping process. So at this time the caller must ensure
|
||||||
|
// that the execution environment must be safe. It is recommended to use the DA mode!
|
||||||
|
//
|
||||||
|
Status = UpdateRegionMapping (
|
||||||
|
BaseAddress,
|
||||||
|
Length,
|
||||||
|
PageWalkCfg,
|
||||||
|
LoongArchAttributes,
|
||||||
|
PTE_ATTRIBUTES_MASK,
|
||||||
|
(UINTN *)(*PageTable),
|
||||||
|
(MmuIsEnabled () && !CreateNew)
|
||||||
|
);
|
||||||
|
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
33
UefiCpuPkg/Library/CpuMmuLib/LoongArch64/Page.h
Normal file
33
UefiCpuPkg/Library/CpuMmuLib/LoongArch64/Page.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/** @file
|
||||||
|
|
||||||
|
Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef PAGE_H_
|
||||||
|
#define PAGE_H_
|
||||||
|
|
||||||
|
#define INVALID_PAGE 0
|
||||||
|
|
||||||
|
#define LEVEL5 5
|
||||||
|
#define LEVEL4 4
|
||||||
|
#define LEVEL3 3
|
||||||
|
#define LEVEL2 2
|
||||||
|
#define LEVEL1 1
|
||||||
|
|
||||||
|
#define PTE_ATTRIBUTES_MASK 0x600000000000007EULL
|
||||||
|
|
||||||
|
#define PTE_PPN_MASK 0xFFFFFFFFF000ULL
|
||||||
|
#define PTE_PPN_SHIFT EFI_PAGE_SHIFT
|
||||||
|
#define LOONGARCH_MMU_PAGE_SHIFT EFI_PAGE_SHIFT
|
||||||
|
|
||||||
|
//
|
||||||
|
// For coding convenience, define the maximum valid
|
||||||
|
// LoongArch exception.
|
||||||
|
// Since UEFI V2.11, it will be present in DebugSupport.h.
|
||||||
|
//
|
||||||
|
#define MAX_LOONGARCH_EXCEPTION 64
|
||||||
|
|
||||||
|
#endif // PAGE_H_
|
@ -0,0 +1,51 @@
|
|||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# TLB refill exception handler
|
||||||
|
#
|
||||||
|
# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <Register/LoongArch64/Csr.h>
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(HandleTlbRefillStart)
|
||||||
|
ASM_GLOBAL ASM_PFX(HandleTlbRefillEnd)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Refill the page table.
|
||||||
|
# @param VOID
|
||||||
|
# @retval VOID
|
||||||
|
#
|
||||||
|
ASM_PFX(HandleTlbRefillStart):
|
||||||
|
csrwr $t0, LOONGARCH_CSR_TLBRSAVE
|
||||||
|
csrrd $t0, LOONGARCH_CSR_PWCTL1
|
||||||
|
srli.d $t0, $t0, 18
|
||||||
|
andi $t0, $t0, 0x3F
|
||||||
|
bnez $t0, Level5
|
||||||
|
csrrd $t0, LOONGARCH_CSR_PWCTL1
|
||||||
|
srli.d $t0, $t0, 6
|
||||||
|
andi $t0, $t0, 0x3F
|
||||||
|
bnez $t0, Level4
|
||||||
|
csrrd $t0, LOONGARCH_CSR_PGD
|
||||||
|
b Level3
|
||||||
|
Level5:
|
||||||
|
csrrd $t0, LOONGARCH_CSR_PGD
|
||||||
|
lddir $t0, $t0, 4 #Put pud BaseAddress into T0
|
||||||
|
lddir $t0, $t0, 3 #Put pud BaseAddress into T0
|
||||||
|
b Level3
|
||||||
|
Level4:
|
||||||
|
csrrd $t0, LOONGARCH_CSR_PGD
|
||||||
|
lddir $t0, $t0, 3 #Put pud BaseAddress into T0
|
||||||
|
Level3:
|
||||||
|
lddir $t0, $t0, 2 #Put pmd BaseAddress into T0
|
||||||
|
lddir $t0, $t0, 1 #Put pte BaseAddress into T0
|
||||||
|
ldpte $t0, 0
|
||||||
|
ldpte $t0, 1
|
||||||
|
tlbfill // refill hi, lo0, lo1
|
||||||
|
csrrd $t0, LOONGARCH_CSR_TLBRSAVE
|
||||||
|
ertn
|
||||||
|
ASM_PFX(HandleTlbRefillEnd):
|
||||||
|
|
||||||
|
.end
|
@ -0,0 +1,36 @@
|
|||||||
|
/** @file
|
||||||
|
|
||||||
|
Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef TLB_EXCEPTION_HANDLE_H_
|
||||||
|
#define TLB_EXCEPTION_HANDLE_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
TLB refill handler start.
|
||||||
|
|
||||||
|
@param none
|
||||||
|
|
||||||
|
@retval none
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
HandleTlbRefillStart (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
TLB refill handler end.
|
||||||
|
|
||||||
|
@param none
|
||||||
|
|
||||||
|
@retval none
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
HandleTlbRefillEnd (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif // TLB_EXCEPTION_HANDLE_H_
|
24
UefiCpuPkg/Library/CpuMmuLib/LoongArch64/TlbInvalid.S
Normal file
24
UefiCpuPkg/Library/CpuMmuLib/LoongArch64/TlbInvalid.S
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Invalid TLB operation function
|
||||||
|
#
|
||||||
|
# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <Register/LoongArch64/Csr.h>
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(InvalidTlb)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Invalid corresponding TLB entries are based on the address given
|
||||||
|
# @param a0 The address corresponding to the invalid page table entry
|
||||||
|
# @retval none
|
||||||
|
#
|
||||||
|
ASM_PFX(InvalidTlb):
|
||||||
|
invtlb INVTLB_ADDR_GTRUE_OR_ASID, $zero, $a0
|
||||||
|
jirl $zero, $ra, 0
|
||||||
|
|
||||||
|
.end
|
24
UefiCpuPkg/Library/CpuMmuLib/LoongArch64/TlbInvalid.h
Normal file
24
UefiCpuPkg/Library/CpuMmuLib/LoongArch64/TlbInvalid.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/** @file
|
||||||
|
|
||||||
|
Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef INVALID_TLB_H_
|
||||||
|
#define INVALID_TLB_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
Invalid corresponding TLB entries are based on the address given
|
||||||
|
|
||||||
|
@param Address The address corresponding to the invalid page table entry
|
||||||
|
|
||||||
|
@retval none
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
InvalidTlb (
|
||||||
|
UINTN Address
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif // INVALID_TLB_H_
|
@ -211,5 +211,8 @@
|
|||||||
UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf
|
UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf
|
||||||
UefiCpuPkg/CpuMmio2Dxe/CpuMmio2Dxe.inf
|
UefiCpuPkg/CpuMmio2Dxe/CpuMmio2Dxe.inf
|
||||||
|
|
||||||
|
[Components.LOONGARCH64]
|
||||||
|
UefiCpuPkg/Library/CpuMmuLib/CpuMmuLib.inf
|
||||||
|
|
||||||
[BuildOptions]
|
[BuildOptions]
|
||||||
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
|
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
|
||||||
|
Loading…
x
Reference in New Issue
Block a user