mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-26 15:14:02 +02:00
OvmfPkg/LoongArchVirt: Add CpuMmuInit library
Added a new library for LoongArch, it use for initialization the CPU MMU, it consumed the CpuMmuLib. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jiewen Yao <jiewen.yao@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>
This commit is contained in:
parent
e3e27f22d2
commit
ace279c036
26
OvmfPkg/Include/Library/CpuMmuInitLib.h
Normal file
26
OvmfPkg/Include/Library/CpuMmuInitLib.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/** @file
|
||||||
|
CPU Memory Map Unit Initialization library header.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Uefi/UefiSpec.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create a page table and initialize the memory management unit(MMU).
|
||||||
|
|
||||||
|
@param[in] MemoryTable A pointer to a memory ragion table.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Configure MMU successfully.
|
||||||
|
EFI_INVALID_PARAMETER MemoryTable is NULL.
|
||||||
|
EFI_UNSUPPORTED MemoryRegionMap failed or out of memory space or size not aligned
|
||||||
|
or MaxLivel out of bound.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
ConfigureMemoryManagementUnit (
|
||||||
|
IN EFI_MEMORY_DESCRIPTOR *MemoryTable
|
||||||
|
);
|
200
OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c
Normal file
200
OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
/** @file
|
||||||
|
CPU Memory Map Unit Initialization library instance.
|
||||||
|
|
||||||
|
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/CacheMaintenanceLib.h>
|
||||||
|
#include <Library/CpuMmuLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Register/LoongArch64/Csr.h>
|
||||||
|
#include <Register/LoongArch64/Cpucfg.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Because the page size in edk2 is 4KB, the lowest level
|
||||||
|
// page table is align to 12 bits, and the page table width
|
||||||
|
// of other levels is set to 9 bits by default, which will
|
||||||
|
// be 3 or 4 or 5 level page tables, and continuous.
|
||||||
|
//
|
||||||
|
// Correspondence between max virtual memory address width
|
||||||
|
// and page table level:
|
||||||
|
// 39 bit >= VA > 31 bit, 3 level page tables
|
||||||
|
// 48 bit >= VA > 40 bit, 4 level page tables
|
||||||
|
// 57 bit >= VA > 49 bit, 5 level page tables
|
||||||
|
//
|
||||||
|
#define DEFAULT_BIT_WIDTH_PER_LEVEL (EFI_PAGE_SHIFT - 3)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Decided page walker width, level.
|
||||||
|
|
||||||
|
@param[in, out] PageWalkCfg Page walker value instance.
|
||||||
|
@param[in] BitWidt The bit width what you want, 0 is means use the default bit width.
|
||||||
|
|
||||||
|
@retval PageTableLevelNum The max page table level.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
UINT8
|
||||||
|
DecidePageWalkConfiguration (
|
||||||
|
IN OUT UINT64 *PageWalkCfg OPTIONAL,
|
||||||
|
IN UINT8 BitWidth
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CPUCFG_REG1_INFO_DATA CpucfgReg1Data;
|
||||||
|
UINT8 CpuVirtMemAddressWidth;
|
||||||
|
UINT8 PageTableLevelNum;
|
||||||
|
UINT8 CurrentPageTableLevel;
|
||||||
|
UINT32 Pwcl0Value;
|
||||||
|
UINT32 Pwcl1Value;
|
||||||
|
|
||||||
|
//
|
||||||
|
// If BitWidth is 0, use the default bit width.
|
||||||
|
//
|
||||||
|
if (BitWidth == 0) {
|
||||||
|
BitWidth = DEFAULT_BIT_WIDTH_PER_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the the CPU virtual memory address width.
|
||||||
|
//
|
||||||
|
AsmCpucfg (CPUCFG_REG1_INFO, &CpucfgReg1Data.Uint32);
|
||||||
|
|
||||||
|
CpuVirtMemAddressWidth = (UINT8)(CpucfgReg1Data.Bits.VALEN + 1);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Statisitics the maximum page table level
|
||||||
|
//
|
||||||
|
PageTableLevelNum = 0x0;
|
||||||
|
if (((CpuVirtMemAddressWidth - EFI_PAGE_SHIFT) % BitWidth) > 0) {
|
||||||
|
PageTableLevelNum++;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageTableLevelNum += (CpuVirtMemAddressWidth - EFI_PAGE_SHIFT) / BitWidth;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set page table level
|
||||||
|
//
|
||||||
|
Pwcl0Value = 0x0;
|
||||||
|
Pwcl1Value = 0x0;
|
||||||
|
for (CurrentPageTableLevel = 0x0; CurrentPageTableLevel < PageTableLevelNum; CurrentPageTableLevel++) {
|
||||||
|
if (CurrentPageTableLevel < 0x3) {
|
||||||
|
// Less then or equal to level 3
|
||||||
|
Pwcl0Value |= ((BitWidth * CurrentPageTableLevel + EFI_PAGE_SHIFT) << 10 * CurrentPageTableLevel) |
|
||||||
|
BitWidth << (10 * CurrentPageTableLevel + 5);
|
||||||
|
} else {
|
||||||
|
// Lager then level 3
|
||||||
|
Pwcl1Value |= ((BitWidth * CurrentPageTableLevel + EFI_PAGE_SHIFT) << 12 * (CurrentPageTableLevel - 3)) |
|
||||||
|
BitWidth << (12 * (CurrentPageTableLevel - 3) + 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_INFO,
|
||||||
|
"%a %d Level %d DIR shift %d.\n",
|
||||||
|
__func__,
|
||||||
|
__LINE__,
|
||||||
|
(CurrentPageTableLevel + 1),
|
||||||
|
(BitWidth * CurrentPageTableLevel + EFI_PAGE_SHIFT)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
*PageWalkCfg = ((UINT64)Pwcl1Value << 32) | Pwcl0Value;
|
||||||
|
|
||||||
|
return PageTableLevelNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create a page table and initialize the memory management unit(MMU).
|
||||||
|
|
||||||
|
@param[in] MemoryTable A pointer to a memory ragion table.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Configure MMU successfully.
|
||||||
|
EFI_INVALID_PARAMETER MemoryTable is NULL.
|
||||||
|
EFI_UNSUPPORTED MemoryRegionMap failed or out of memory space or size not aligned
|
||||||
|
or MaxLivel out of bound.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
ConfigureMemoryManagementUnit (
|
||||||
|
IN EFI_MEMORY_DESCRIPTOR *MemoryTable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN PageTable;
|
||||||
|
UINT64 PageWalkCfg;
|
||||||
|
UINT8 MaxLevel;
|
||||||
|
|
||||||
|
if (MemoryTable == NULL) {
|
||||||
|
ASSERT (MemoryTable != NULL);
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Automatically obtain the current appropriate page walker configuration.
|
||||||
|
//
|
||||||
|
MaxLevel = DecidePageWalkConfiguration (&PageWalkCfg, 0);
|
||||||
|
|
||||||
|
if ((MaxLevel < 0) || (MaxLevel > 5)) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageTable = 0;
|
||||||
|
while (MemoryTable->NumberOfPages != 0) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_INFO,
|
||||||
|
"%a %d VirtualBase %p VirtualEnd %p Attributes %p .\n",
|
||||||
|
__func__,
|
||||||
|
__LINE__,
|
||||||
|
MemoryTable->VirtualStart,
|
||||||
|
(EFI_PAGES_TO_SIZE (MemoryTable->NumberOfPages) + MemoryTable->VirtualStart),
|
||||||
|
MemoryTable->Attribute
|
||||||
|
));
|
||||||
|
|
||||||
|
Status = MemoryRegionMap (
|
||||||
|
&PageTable,
|
||||||
|
PageWalkCfg,
|
||||||
|
MemoryTable->VirtualStart,
|
||||||
|
EFI_PAGES_TO_SIZE (MemoryTable->NumberOfPages),
|
||||||
|
MemoryTable->Attribute,
|
||||||
|
0x0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryTable++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure page walker.
|
||||||
|
//
|
||||||
|
CsrWrite (LOONGARCH_CSR_PWCTL0, (UINT32)PageWalkCfg);
|
||||||
|
if ((PageWalkCfg >> 32) != 0x0) {
|
||||||
|
CsrWrite (LOONGARCH_CSR_PWCTL1, (UINT32)(PageWalkCfg >> 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set page size
|
||||||
|
//
|
||||||
|
CsrXChg (LOONGARCH_CSR_TLBIDX, (DEFAULT_PAGE_SIZE << CSR_TLBIDX_SIZE), CSR_TLBIDX_SIZE_MASK);
|
||||||
|
CsrWrite (LOONGARCH_CSR_STLBPGSIZE, DEFAULT_PAGE_SIZE);
|
||||||
|
CsrXChg (LOONGARCH_CSR_TLBREHI, (DEFAULT_PAGE_SIZE << CSR_TLBREHI_PS_SHIFT), CSR_TLBREHI_PS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enable MMU
|
||||||
|
//
|
||||||
|
CsrWrite (LOONGARCH_CSR_PGDL, PageTable);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enable Paging
|
||||||
|
//
|
||||||
|
CsrXChg (LOONGARCH_CSR_CRMD, BIT4, BIT4|BIT3);
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_INFO, "%a %d Enable MMU Start PageBassAddress %p.\n", __func__, __LINE__, PageTable));
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
## @file
|
||||||
|
# CPU Memory Map Unit Initialization 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 = CpuMmuInitLib
|
||||||
|
MODULE_UNI_FILE = CpuMmuInitLib.uni
|
||||||
|
FILE_GUID = F67EB983-AC2A-7550-AB69-3BC51A1C895B
|
||||||
|
MODULE_TYPE = BASE
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = CpuMmuInitLib
|
||||||
|
|
||||||
|
#
|
||||||
|
# VALID_ARCHITECTURES = LOONGARCH64
|
||||||
|
#
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
CpuMmuInit.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
|
UefiCpuPkg/UefiCpuPkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
BaseLib
|
||||||
|
CacheMaintenanceLib
|
||||||
|
CpuMmuLib
|
||||||
|
DebugLib
|
@ -0,0 +1,14 @@
|
|||||||
|
// /** @file
|
||||||
|
// CPU Memory Map Unit Initialization library instance.
|
||||||
|
//
|
||||||
|
// CPU Memory Map Unit Initialization 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 for PEI modules."
|
||||||
|
|
||||||
|
#string STR_MODULE_DESCRIPTION #language en-US "CPU Memory Manager Unit library instance for PEI modules."
|
@ -148,6 +148,10 @@
|
|||||||
#
|
#
|
||||||
HardwareInfoLib|Include/Library/HardwareInfoLib.h
|
HardwareInfoLib|Include/Library/HardwareInfoLib.h
|
||||||
|
|
||||||
|
## @libraryclass CPU MMU Initialization library.
|
||||||
|
#
|
||||||
|
CpuMmuInitLib|Include/Library/CpuMmuInitLib.h
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gUefiOvmfPkgTokenSpaceGuid = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}}
|
gUefiOvmfPkgTokenSpaceGuid = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}}
|
||||||
gEfiXenInfoGuid = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}}
|
gEfiXenInfoGuid = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user