forked from tianocore/edk2
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <[email protected]> Cc: Jiewen Yao <[email protected]> Cc: Gerd Hoffmann <[email protected]> Signed-off-by: Chao Li <[email protected]> Co-authored-by: Baoqi Zhang <[email protected]> Co-authored-by: Dongyan Qian <[email protected]> Co-authored-by: Xianglai Li <[email protected]> Co-authored-by: Bibo Mao <[email protected]>
- Loading branch information
1 parent
e3e27f2
commit ace279c
Showing
5 changed files
with
279 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 changes: 200 additions & 0 deletions
200
OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
35 changes: 35 additions & 0 deletions
35
OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInitLib.inf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
14 changes: 14 additions & 0 deletions
14
OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInitLib.uni
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters