From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 0136C94148A for ; Wed, 20 Mar 2024 08:43:55 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=Ng3/In5gywF8sIMIF/0DfaeTSLG0iiP2xeMx1Kvl/RE=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20240206; t=1710924234; v=1; b=Jg5i4PjWbLfDGwETMNx2Eyv+N54YKopTrkSBZ1USFDCenLhLOy43YwZ7iDcG5UMf+Md5MNNo z3jTwqOwgDXA+WjN9DAz4UrTHk0iaf5yR4ZxTOboFkvF/3u89IhEilAcC+/DHtdvkQgr6jhk1yn GrLPaFB2bKMWkxouyn0nbBOCb+KZk1fLImJxRCBCaH4yjPzHeIGAiE65hIp0EZHrpYkp4bE3fiG /PbmsJ8iC2dcEGNmGFkkYdNwOfg5PCC7fiD3NLMGF07rtYMPC1JiV6tx5Xeei9KkkczMFHNTuJy t0Wdt2s4oRlTKMdYB/hfSAO4H4M5dVC4FnTHzjd1i9oOw== X-Received: by 127.0.0.2 with SMTP id vXqjYY7687511xxs26ScG083; Wed, 20 Mar 2024 01:43:54 -0700 X-Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.38933.1710924232110855511 for ; Wed, 20 Mar 2024 01:43:53 -0700 X-Received: from loongson.cn (unknown [10.2.9.245]) by gateway (Coremail) with SMTP id _____8DxfevEofplSC0bAA--.64747S3; Wed, 20 Mar 2024 16:43:48 +0800 (CST) X-Received: from code-server.gen (unknown [10.2.9.245]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxnhPBofplNEBeAA--.62527S2; Wed, 20 Mar 2024 16:43:45 +0800 (CST) From: "Chao Li" To: devel@edk2.groups.io Cc: Ray Ni , Rahul Kumar , Gerd Hoffmann , Baoqi Zhang , Dongyan Qian , Xianglai Li , Bibo Mao Subject: [edk2-devel] [PATCH v2 11/13] UefiCpuPkg: Add CpuMmuInitLib to UefiCpuPkg Date: Wed, 20 Mar 2024 16:43:45 +0800 Message-Id: <20240320084345.282542-1-lichao@loongson.cn> In-Reply-To: <20240320084152.268323-1-lichao@loongson.cn> References: <20240320084152.268323-1-lichao@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf8BxnhPBofplNEBeAA--.62527S2 X-CM-SenderInfo: xolfxt3r6o00pqjv00gofq/1tbiAQACCGX5TOgKgAAYsh X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Resent-Date: Wed, 20 Mar 2024 01:43:53 -0700 Reply-To: devel@edk2.groups.io,lichao@loongson.cn List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: xXFA73HsjWpLGJLsEJIJTsYox7686176AA= Content-Transfer-Encoding: 8bit X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=Jg5i4PjW; dmarc=none; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io Add a new base library named CpuMmuInitLib and add a LoongArch64 instance with in the library. It is the consumer of the CpuMmuLib. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4734 Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Signed-off-by: Chao Li Co-authored-by: Baoqi Zhang Co-authored-by: Dongyan Qian Co-authored-by: Xianglai Li Co-authored-by: Bibo Mao --- .../Library/CpuMmuInitLib/CpuMmuInitLib.inf | 41 ++++ .../Library/CpuMmuInitLib/CpuMmuInitLib.uni | 14 ++ .../CpuMmuInitLib/LoongArch64/CpuMmuInit.c | 232 ++++++++++++++++++ .../LoongArch64/TlbExceptionHandle.S | 51 ++++ .../LoongArch64/TlbExceptionHandle.h | 36 +++ UefiCpuPkg/UefiCpuPkg.dsc | 1 + 6 files changed, 375 insertions(+) create mode 100644 UefiCpuPkg/Library/CpuMmuInitLib/CpuMmuInitLib.inf create mode 100644 UefiCpuPkg/Library/CpuMmuInitLib/CpuMmuInitLib.uni create mode 100644 UefiCpuPkg/Library/CpuMmuInitLib/LoongArch64/CpuMmuInit.c create mode 100644 UefiCpuPkg/Library/CpuMmuInitLib/LoongArch64/TlbExceptionHandle.S create mode 100644 UefiCpuPkg/Library/CpuMmuInitLib/LoongArch64/TlbExceptionHandle.h diff --git a/UefiCpuPkg/Library/CpuMmuInitLib/CpuMmuInitLib.inf b/UefiCpuPkg/Library/CpuMmuInitLib/CpuMmuInitLib.inf new file mode 100644 index 0000000000..673d2a8eab --- /dev/null +++ b/UefiCpuPkg/Library/CpuMmuInitLib/CpuMmuInitLib.inf @@ -0,0 +1,41 @@ +## @file +# CPU Memory Map Unit Initialization library instance. +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# 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.LoongArch64] + LoongArch64/TlbExceptionHandle.S | GCC + LoongArch64/CpuMmuInit.c + LoongArch64/TlbExceptionHandle.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuExceptionVectorBaseAddress + +[LibraryClasses] + CacheMaintenanceLib + CpuMmuLib + DebugLib + MemoryAllocationLib + PcdLib diff --git a/UefiCpuPkg/Library/CpuMmuInitLib/CpuMmuInitLib.uni b/UefiCpuPkg/Library/CpuMmuInitLib/CpuMmuInitLib.uni new file mode 100644 index 0000000000..907f024302 --- /dev/null +++ b/UefiCpuPkg/Library/CpuMmuInitLib/CpuMmuInitLib.uni @@ -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.
+// +// 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." diff --git a/UefiCpuPkg/Library/CpuMmuInitLib/LoongArch64/CpuMmuInit.c b/UefiCpuPkg/Library/CpuMmuInitLib/LoongArch64/CpuMmuInit.c new file mode 100644 index 0000000000..5c74bdc264 --- /dev/null +++ b/UefiCpuPkg/Library/CpuMmuInitLib/LoongArch64/CpuMmuInit.c @@ -0,0 +1,232 @@ +/** @file + CPU Memory Map Unit Initialization library instance. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "TlbExceptionHandle.h" + +// +// 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 + +// +// 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 BIT_WIDTH_PER_LEVEL 9 +#define MAX_SIZE_OF_PGD ((1 << BIT_WIDTH_PER_LEVEL) * 8) // 512 items, 8 Byte each. + +/** + Create a page table and initialize the memory management unit(MMU). + + @param[in] MemoryTable A pointer to a memory ragion table. + @param[out] TranslationTableBase A pointer to a translation table base address. + @param[out] TranslationTableSize A pointer to a translation table base size. + + @retval EFI_SUCCESS Configure MMU successfully. + EFI_INVALID_PARAMETER MemoryTable is NULL. + EFI_UNSUPPORTED Out of memory space or size not aligned. +**/ +EFI_STATUS +EFIAPI +ConfigureMemoryManagementUnit ( + IN EFI_MEMORY_DESCRIPTOR *MemoryTable, + OUT VOID **TranslationTableBase OPTIONAL, + OUT UINTN *TranslationTableSize OPTIONAL + ) +{ + VOID *TranslationTable; + UINTN Length; + UINTN TlbReEntry; + UINTN TlbReEntryOffset; + UINTN Remaining; + EFI_STATUS Status; + CPUCFG_REG1_INFO_DATA CpucfgReg1Data; + UINT8 CpuVirtMemAddressWidth; + UINT8 PageTableLevelNum; + UINT8 CurrentPageTableLevel; + UINT32 Pwcl0Value; + UINT32 Pwcl1Value; + + if (MemoryTable == NULL) { + ASSERT (MemoryTable != NULL); + return EFI_INVALID_PARAMETER; + } + + // + // 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) % BIT_WIDTH_PER_LEVEL) > 0) { + PageTableLevelNum++; + } + + PageTableLevelNum += (CpuVirtMemAddressWidth - EFI_PAGE_SHIFT) / BIT_WIDTH_PER_LEVEL; + + // + // 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 |= ((BIT_WIDTH_PER_LEVEL * CurrentPageTableLevel + EFI_PAGE_SHIFT) << 10 * CurrentPageTableLevel) | + BIT_WIDTH_PER_LEVEL << (10 * CurrentPageTableLevel + 5); + } else { + // Lager then level 3 + Pwcl1Value |= ((BIT_WIDTH_PER_LEVEL * CurrentPageTableLevel + EFI_PAGE_SHIFT) << 12 * (CurrentPageTableLevel - 3)) | + BIT_WIDTH_PER_LEVEL << (12 * (CurrentPageTableLevel - 3) + 6); + } + + DEBUG (( + DEBUG_INFO, + "%a %d Level %d DIR shift %d.\n", + __func__, + __LINE__, + (CurrentPageTableLevel + 1), + (BIT_WIDTH_PER_LEVEL * CurrentPageTableLevel + EFI_PAGE_SHIFT) + )); + } + + CsrWrite (LOONGARCH_CSR_PWCTL0, Pwcl0Value); + if (Pwcl1Value != 0x0) { + CsrWrite (LOONGARCH_CSR_PWCTL1, Pwcl1Value); + } + + // + // 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); + + // + // Create PGD and set the PGD address to PGDL + // + TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (MAX_SIZE_OF_PGD)); + ZeroMem (TranslationTable, MAX_SIZE_OF_PGD); + + if (TranslationTable == NULL) { + goto FreeTranslationTable; + } + + CsrWrite (LOONGARCH_CSR_PGDL, (UINTN)TranslationTable); + + // + // Fill page tables + // + 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 = SetMemoryRegionAttributes ( + MemoryTable->VirtualStart, + EFI_PAGES_TO_SIZE (MemoryTable->NumberOfPages), + MemoryTable->Attribute, + 0x0 + ); + + if (EFI_ERROR (Status)) { + goto FreeTranslationTable; + } + + MemoryTable++; + } + + // + // 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 (PcdCpuExceptionVectorBaseAddress) + TlbReEntryOffset; + if ((TlbReEntryOffset + Length) > SIZE_64KB) { + goto FreeTranslationTable; + } + + // + // Ensure that TLB refill exception base address alignment is equals to 4KB and is valid. + // + if (TlbReEntry & (SIZE_4KB - 1)) { + goto FreeTranslationTable; + } + + CopyMem ((VOID *)TlbReEntry, HandleTlbRefillStart, Length); + InvalidateInstructionCacheRange ((VOID *)(UINTN)HandleTlbRefillStart, Length); + + // + // Set the address of TLB refill exception handler + // + SetTlbRebaseAddress ((UINTN)TlbReEntry); + + // + // Enable MMU + // + CsrXChg (LOONGARCH_CSR_CRMD, BIT4, BIT4|BIT3); + + DEBUG ((DEBUG_INFO, "%a %d Enable MMU Start PageBassAddress %p.\n", __func__, __LINE__, TranslationTable)); + + // + // Set MMU enable flag. + // + return EFI_SUCCESS; + +FreeTranslationTable: + if (TranslationTable != NULL) { + FreePages (TranslationTable, EFI_SIZE_TO_PAGES (MAX_SIZE_OF_PGD)); + } + + return EFI_UNSUPPORTED; +} diff --git a/UefiCpuPkg/Library/CpuMmuInitLib/LoongArch64/TlbExceptionHandle.S b/UefiCpuPkg/Library/CpuMmuInitLib/LoongArch64/TlbExceptionHandle.S new file mode 100644 index 0000000000..4395b574f5 --- /dev/null +++ b/UefiCpuPkg/Library/CpuMmuInitLib/LoongArch64/TlbExceptionHandle.S @@ -0,0 +1,51 @@ +#------------------------------------------------------------------------------ +# +# TLB refill exception handler +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#----------------------------------------------------------------------------- + +#include + +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 diff --git a/UefiCpuPkg/Library/CpuMmuInitLib/LoongArch64/TlbExceptionHandle.h b/UefiCpuPkg/Library/CpuMmuInitLib/LoongArch64/TlbExceptionHandle.h new file mode 100644 index 0000000000..c164db567d --- /dev/null +++ b/UefiCpuPkg/Library/CpuMmuInitLib/LoongArch64/TlbExceptionHandle.h @@ -0,0 +1,36 @@ +/** @file + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + 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_ diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index e92ceb6466..a9787f9d70 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -213,6 +213,7 @@ [Components.RISCV64] [Components.LOONGARCH64] UefiCpuPkg/Library/CpuMmuLib/CpuMmuLib.inf + UefiCpuPkg/Library/CpuMmuInitLib/CpuMmuInitLib.inf [BuildOptions] *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -- 2.27.0 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#116927): https://edk2.groups.io/g/devel/message/116927 Mute This Topic: https://groups.io/mt/105041101/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-