From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.3707.1668159761397335425 for ; Fri, 11 Nov 2022 01:42:46 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: loongson.cn, ip: 114.242.206.163, mailfrom: lichao@loongson.cn) Received: from loongson.cn (unknown [10.40.24.149]) by gateway (Coremail) with SMTP id _____8AxStgOGW5jARYGAA--.17292S3; Fri, 11 Nov 2022 17:42:38 +0800 (CST) Received: from lichao-PC (unknown [10.40.24.149]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Dx_1cNGW5jqdIQAA--.46330S2; Fri, 11 Nov 2022 17:42:37 +0800 (CST) Date: Fri, 11 Nov 2022 17:42:37 +0800 From: "Chao Li" To: xianglai li Cc: "=?utf-8?Q?devel=40edk2.groups.io?=" , Bibo Mao , Leif Lindholm , Liming Gao , Michael D Kinney Message-ID: In-Reply-To: <40c87e6da8780f77f841e5b531c866596ff26048.1668157715.git.lixianglai@loongson.cn> References: <40c87e6da8780f77f841e5b531c866596ff26048.1668157715.git.lixianglai@loongson.cn> Subject: Re: [edk2-platforms][PATCH V5 05/15] Platform/Loongson: Add MmuLib. X-Mailer: Mailspring MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Dx_1cNGW5jqdIQAA--.46330S2 X-CM-SenderInfo: xolfxt3r6o00pqjv00gofq/1tbiAQAHCGNs6eQZ0AAXsS X-Coremail-Antispam: 1Uk129KBjvAXoWDWF1kWw1kZF1fJw15Jr17Awb_yoW7CFy7Co WY9F4ruw4UJw4rZr4rCwn2gayxtFsYq39xXr1FvF4jqFsYvrs0kFWUtay5J34fZ34Svrnr GrykXaykJFWS9r1rn29KB7ZKAUJUUUUD529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ec02F40Eb7x2x7xS6r1j6r4UMc02F40EFcxC0VAKzVAqx4xG6I80ewAqx4xG64kEw2xG 04xIwI0_Xr0_WrUv73VFW2AGmfu7bjvjm3AaLaJ3UjIYCTnIWjp_UUUOf7kC6x804xWl14 x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0rVWrJVCq3wAFIxvE14AKwVWU XVWUAwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84ACjcxK6xIIjxv20xvE14 v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4j6F4UM28EF7xvwVC2z280aVAF wI0_Cr1j6rxdM28EF7xvwVC2z280aVCY1x0267AKxVWxJr0_GcWln4kS14v26r126r1DM2 AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx1l5I8CrVAYj202 j2C_Jr0_Gr1l5I8CrVACY4xI64kE6c02F40Ex7xfMc02F40Ew4AK048IF2xKxVW5JVWrJw Av7VC0I7IYx2IY67AKxVWUtVWrXwAv7VC2z280aVAFwI0_Gr0_Cr1lOx8S6xCaFVCjc4AY 6r1j6r4UM4x0Y48IcxkI7VAKI48JMx8GjcxK6IxK0xIIj40E5I8CrwCY1x0262kKe7AKxV WUAVWUtwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E 14v26r106r1rMI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIx kGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVW8JVW5JwCI42IY6xIIjxv20xvEc7CjxVAF wI0_Gr0_Cr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r4j6F 4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x07j7eOLU UUUU= Content-Type: multipart/alternative; boundary="636e190d_24bd76bf_1e57b" --636e190d_24bd76bf_1e57b Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Reviewed-by: Chao Li Thanks, Chao -------- On 11=E6=9C=88 11 2022, at 5:12 =E4=B8=8B=E5=8D=88, xianglai li wrote: > Read the memory map information through the Qemu=46wCfg interface, > > then build the page table through the memory map information, > and finally enable Mmu. > > > RE=46: https://bugzilla.tianocore.org/show=5Fbug.cgi=3Fid=3D4054 > > > Cc: Bibo Mao > Cc: Chao Li > Cc: Leif Lindholm > Cc: Liming Gao > Cc: Michael D Kinney > Signed-off-by: xianglai li > --- > .../LoongArchQemuPkg/Include/Library/MmuLib.h =7C 85 ++ > .../LoongArchQemuPkg/Library/MmuLib/Mmu.S =7C 155 ++++ > .../Library/MmuLib/MmuBaseLib.inf =7C 40 + > .../Library/MmuLib/MmuBaseLibPei.inf =7C 47 + > .../Library/MmuLib/MmuLibCore.c =7C 831 ++++++++++++++++++ > .../Library/MmuLib/MmuLibCore.h =7C 40 + > .../Library/MmuLib/MmuLibCorePei.c =7C 231 +++++ > .../LoongArchQemuPkg/Library/MmuLib/mmu.h =7C 190 ++++ > .../LoongArchQemuPkg/Library/MmuLib/page.h =7C 280 ++++++ > .../LoongArchQemuPkg/Library/MmuLib/pte.h =7C 57 ++ > 10 files changed, 1956 insertions(+) > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Include/Library/M= muLib.h > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mm= u.S > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mm= uBaseLib.inf > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mm= uBaseLibPei.inf > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mm= uLibCore.c > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mm= uLibCore.h > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mm= uLibCorePei.c > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/mm= u.h > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/pa= ge.h > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/pt= e.h > > > diff --git a/Platform/Loongson/LoongArchQemuPkg/Include/Library/MmuLib.= h b/Platform/Loongson/LoongArchQemuPkg/Include/Library/MmuLib.h > new file mode 100644 > index 0000000000..9880fc385c > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Include/Library/MmuLib.h > =40=40 -0,0 +1,85 =40=40 > +/** =40file > + > + Copyright (c) 2022 Loongson Technology Corporation Limited. All right= s reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + =40par Glossary: > + - EXC - execute > +**/ > +=23ifndef MMU=5FLIB=5FH=5F > +=23define MMU=5FLIB=5FH=5F > +/** > + write operation is performed Count times from the first element of Bu= ffer. > + Convert E=46I Attributes to Loongarch Attributes. > + =40param=5Bin=5D EfiAttributes Efi Attributes. > + > + =40retval LoongArch Attributes. > +**/ > +UINTN > +EfiAttributeToLoongArchAttribute ( > + IN UINTN EfiAttributes > + ); > + > +/** > + =46inds the length and memory properties of the memory region corresp= onding to the specified base address. > + > + =40param=5Bin=5D BaseAddress To find the base address of the memory r= egion. > + =40param=5Bin=5D EndAddress To find the end address of the memory reg= ion. > + =40param=5Bout=5D RegionLength The length of the memory region found.= > + =40param=5Bout=5D RegionAttributes Properties of the memory region fo= und. > + > + =40retval E=46I=5FSUCCESS The corresponding memory area was successfu= lly found > + E=46I=5FNOT=5F=46OUND No memory area found > +**/ > +E=46I=5FSTATUS > +GetLoongArchMemoryRegion ( > + IN UINTN BaseAddress, > + IN UINTN EndAddress, > + OUT UINTN *RegionLength, > + OUT UINTN *RegionAttributes > + ); > + > +/** > + Sets the Attributes of the specified memory region > + > + =40param=5Bin=5D BaseAddress The base address of the memory region to= set the Attributes. > + =40param=5Bin=5D Length The length of the memory region to set the At= tributes. > + =40param=5Bin=5D Attributes The Attributes to be set. > + > + =40retval E=46I=5FSUCCESS The Attributes was set successfully > +**/ > +E=46I=5FSTATUS > +LoongArchSetMemoryAttributes ( > + IN E=46I=5FPHYSICAL=5FADDRESS BaseAddress, > + IN UINTN Length, > + IN UINTN Attributes > + ); > + > +/** > + Sets the non-executable Attributes for the specified memory region > + > + =40param=5Bin=5D BaseAddress The base address of the memory region to= set the Attributes. > + =40param=5Bin=5D Length The length of the memory region to set the At= tributes. > + > + =40retval E=46I=5FSUCCESS The Attributes was set successfully > +**/ > +E=46I=5FSTATUS > +LoongArchSetMemoryRegionNoExec ( > + IN E=46I=5FPHYSICAL=5FADDRESS BaseAddress, > + IN UINTN Length > + ); > + > +/** > + Create a page table and initialize the MMU. > + > + =40param=5B=5D VOID > + > + =40retval VOID > +**/ > +VOID > +E=46IAPI > +ConfigureMmu ( > + VOID > + ); > +=23endif // MMU=5FLIB=5FH=5F > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mmu.S b/= Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mmu.S > new file mode 100644 > index 0000000000..d5863de072 > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mmu.S > =40=40 -0,0 +1,155 =40=40 > +=23-------------------------------------------------------------------= ----------- > +=23 > +=23 LoongArch for LoongArch > +=23 > +=23 Copyright (c) 2022 Loongson Technology Corporation Limited. All ri= ghts reserved.
> +=23 > +=23 SPDX-License-Identifier: BSD-2-Clause-Patent > +=23 > +=23-------------------------------------------------------------------= ---------- > + > +=23ifndef =5F=5FASSEMBLY=5F=5F > +=23define =5F=5FASSEMBLY=5F=5F > +=23endif > + > +=23include =22Library/Cpu.h=22 > +=23include =22mmu.h=22 > + > +ASM=5FGLOBAL ASM=5FP=46X(HandleTlbRefill) > +ASM=5FGLOBAL HandleTlbRefillEnd > +ASM=5FGLOBAL ASM=5FP=46X(LoongarchInvalidTlb) > +ASM=5FGLOBAL ASM=5FP=46X(SetTlbRefill=46uncBase) > +ASM=5FGLOBAL ASM=5FP=46X(WriteCsrPageSize) > +ASM=5FGLOBAL ASM=5FP=46X(WriteCsrTlbRefillPageSize) > +ASM=5FGLOBAL ASM=5FP=46X(WriteCsrStlbPageSize) > +ASM=5FGLOBAL ASM=5FP=46X(LoongArchWriteqCsrPwctl0) > +ASM=5FGLOBAL ASM=5FP=46X(LoongArchWriteqCsrPwctl1) > +ASM=5FGLOBAL ASM=5FP=46X(LoongArchWriteqCsrPgdl) > +ASM=5FGLOBAL ASM=5FP=46X(LoongArchWriteqCsrPgdh) > +ASM=5FGLOBAL ASM=5FP=46X(LoongArchXchgCsrCrmd) > + > +=23 > +=23 Refill the page table. > +=23 =40param VOID > +=23 =40retval VOID > +=23 > + > +ASM=5FP=46X(HandleTlbRefill): > + csrwr T0, LOONGARCH=5FCSR=5FTLBRSAVE > + csrrd T0, LOONGARCH=5FCSR=5FPGD > + lddir T0, T0, 3 =23Put pud BaseAddress into T0 > + lddir T0, T0, 2 =23Put pmd BaseAddress into T0 > + lddir T0, T0, 1 =23Put pte BaseAddress into T0 > + ldpte T0, 0 > + ldpte T0, 1 > + tlbfill > + csrrd T0, LOONGARCH=5FCSR=5FTLBRSAVE > + ertn > +HandleTlbRefillEnd: > + > +=23 > +=23 Invalid corresponding TLB entries are based on the address given > +=23 =40param A0 The address corresponding to the invalid page table en= try > +=23 =40retval none > +=23 > + > +ASM=5FP=46X(LoongarchInvalidTlb): > + invtlb INVTLB=5FADDR=5FGTRUE=5FOR=5FASID, ZERO, A0 > + jirl ZERO, RA, 0 > + > +=23 > +=23 Set Tlb Refill function to hardware > +=23 =40param A0 The address of tlb refill function > +=23 =40retval none > +=23 > + > +ASM=5FP=46X(SetTlbRefill=46uncBase): > + csrwr A0, LOONGARCH=5FCSR=5FTLBREBASE > + jirl ZERO, RA,0 > + > +=23 > +=23 Set Cpu Status Register Page Size. > +=23 =40param A0 Page Size. > +=23 =40retval none > +=23 > + > +ASM=5FP=46X(WriteCsrPageSize): > + li.d T0, CSR=5FTLBIDX=5FSIZE > + sll.d A0, A0, T0 > + li.d T0, CSR=5FTLBIDX=5FSIZE=5FMASK > + csrxchg A0, T0, LOONGARCH=5FCSR=5FTLBIDX > + jirl ZERO, RA,0 > + > +=23 > +=23 Set Cpu Status Register TLBRE=46ILL Page Size. > +=23 =40param A0 Page Size. > +=23 =40retval none > +=23 > + > +ASM=5FP=46X(WriteCsrTlbRefillPageSize): > + li.d T0, CSR=5FTLBREHI=5FPS=5FSHI=46T > + sll.d A0, A0, T0 > + li.d T0, CSR=5FTLBREHI=5FPS > + csrxchg A0, T0, LOONGARCH=5FCSR=5FTLBREHI > + jirl ZERO, RA,0 > + > +=23 > +=23 Set Cpu Status Register STLB Page Size. > +=23 =40param val Page Size. > +=23 =40retval VOID > +=23 > + > +ASM=5FP=46X(WriteCsrStlbPageSize): > + csrwr A0, LOONGARCH=5FCSR=5FSTLBPGSIZE > + jirl ZERO, RA,0 > + > +=23 > +=23 Write Csr PWCTL0 register. > +=23 =40param A0 The value used to write to the PWCTL0 register > +=23 =40retval none > +=23 > + > +ASM=5FP=46X(LoongArchWriteqCsrPwctl0): > + csrwr A0, LOONGARCH=5FCSR=5FPWCTL0 > + jirl ZERO, RA,0 > + > +=23 > +=23 Write Csr PWCTL1 register. > +=23 =40param A0 The value used to write to the PWCTL1 register > +=23 =40retval none > +=23 > + > +ASM=5FP=46X(LoongArchWriteqCsrPwctl1): > + csrwr A0, LOONGARCH=5FCSR=5FPWCTL1 > + jirl ZERO, RA,0 > + > +=23 > +=23 Write Csr PGDL register. > +=23 =40param A0 The value used to write to the PGDL register > +=23 =40retval none > +=23 > + > +ASM=5FP=46X(LoongArchWriteqCsrPgdl): > + csrwr A0, LOONGARCH=5FCSR=5FPGDL > + jirl ZERO, RA,0 > + > +=23 > +=23 Write Csr PGDH register. > +=23 =40param A0 The value used to write to the PGDH register > +=23 =40retval none > +=23 > + > +ASM=5FP=46X(LoongArchWriteqCsrPgdh): > + csrwr A0, LOONGARCH=5FCSR=5FPGDH > + jirl ZERO, RA,0 > + > +=23 > +=23 Exchange specified bit data with the Csr CRMD register. > +=23 =40param=5BIN=5D A0 The value Exchanged with the CSR CRMD register= . > +=23 =40param=5BIN=5D A1 Specifies the mask for swapping bits > +=23 =40retval VOID > +=23 > + > +ASM=5FP=46X(LoongArchXchgCsrCrmd): > + csrxchg A0, A1, LOONGARCH=5FCSR=5FCRMD > + jirl ZERO, RA,0 > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseL= ib.inf b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseLib.inf= > new file mode 100644 > index 0000000000..abd864a324 > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseLib.inf > =40=40 -0,0 +1,40 =40=40 > +=23=23 =40file > +=23 > +=23 Copyright (c) 2022 Loongson Technology Corporation Limited. All ri= ghts reserved.
> +=23 > +=23 SPDX-License-Identifier: BSD-2-Clause-Patent > +=23 > +=23=23 > + > +=5BDefines=5D > + IN=46=5FVERSION =3D 0x00010005 > + BASE=5FNAME =3D MmuBaseLib > + =46ILE=5FGUID =3D da8f0232-fb14-42f0-922c-63104d2c70be > + MODULE=5FTYPE =3D BASE > + VERSION=5FSTRING =3D 1.0 > + LIBRARY=5FCLASS =3D MmuLib > + CONSTRUCTOR =3D MmuInitialize > + > +=23 > +=23 VALID=5FARCHITECTURES =3D LOONGARCH64 > +=23 > + > +=5BSources=5D > + MmuLibCore.c > + Mmu.S > + > +=5BPackages=5D > + MdePkg/MdePkg.dec > + Platform/Loongson/LoongArchQemuPkg/Loongson.dec > + > +=5BPCD=5D > + gLoongArchQemuPkgTokenSpaceGuid.PcdSwapPageDir > + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPgd > + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPud > + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPmd > + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPte > + > +=5BLibraryClasses=5D > + MemoryAllocationLib > + PcdLib > + DebugLib > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseL= ibPei.inf b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseLibP= ei.inf > new file mode 100644 > index 0000000000..12848eecfe > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseLibPei.i= nf > =40=40 -0,0 +1,47 =40=40 > +=23=23 =40file > +=23 > +=23 Copyright (c) 2022 Loongson Technology Corporation Limited. All ri= ghts reserved.
> +=23 > +=23 SPDX-License-Identifier: BSD-2-Clause-Patent > +=23 > +=23=23 > + > +=5BDefines=5D > + IN=46=5FVERSION =3D 0x00010005 > + BASE=5FNAME =3D MmuPeiLib > + =46ILE=5FGUID =3D da8f0232-fb14-42f0-922c-63104d2c70bd > + MODULE=5FTYPE =3D BASE > + VERSION=5FSTRING =3D 1.0 > + LIBRARY=5FCLASS =3D MmuLib =7C SEC PEIM > + > +=23 > +=23 VALID=5FARCHITECTURES =3D LOONGARCH64 > +=23 > + > +=5BSources=5D > + MmuLibCorePei.c > + Mmu.S > + MmuLibCore.h > + MmuLibCore.c > + > +=5BPackages=5D > + MdePkg/MdePkg.dec > + Platform/Loongson/LoongArchQemuPkg/Loongson.dec > + OvmfPkg/OvmfPkg.dec > + > +=5BPCD=5D > + gLoongArchQemuPkgTokenSpaceGuid.PcdSwapPageDir > + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPgd > + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPud > + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPmd > + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPte > + gLoongArchQemuPkgTokenSpaceGuid.Pcd=46lashSec=46vSize > + gLoongArchQemuPkgTokenSpaceGuid.Pcd=46lashSec=46vBase > + gLoongArchQemuPkgTokenSpaceGuid.PcdRamSize > + > +=5BLibraryClasses=5D > + MemoryAllocationLib > + CacheMaintenanceLib > + PcdLib > + DebugLib > + Qemu=46wCfgLib > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCo= re.c b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.c > new file mode 100644 > index 0000000000..b932e3d568 > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.c > =40=40 -0,0 +1,831 =40=40 > +/** =40file > + > + Copyright (c) 2022 Loongson Technology Corporation Limited. All right= s reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + =40par Glossary: > + - Pgd or Pgd or PGD - Page Global Directory > + - Pud or Pud or PUD - Page Upper Directory > + - Pmd or Pmd or PMD - Page Middle Directory > + - Pte or pte or PTE - Page Table Entry > + - Val or VAL or val - Value > + - Dir - Directory > +**/ > +=23include > +=23include > +=23include > +=23include > +=23include > +=23include =22Library/Cpu.h=22 > +=23include =22pte.h=22 > +=23include =22page.h=22 > +=23include =22mmu.h=22 > + > +BOOLEAN mMmuInited =3D =46ALSE; > +/** > + Check to see if mmu successfully initializes. > + > + =40param VOID. > + > + =40retval TRUE Initialization has been completed. > + =46ALSE Initialization did not complete. > +**/ > +BOOLEAN > +MmuIsInit (VOID) =7B > + if ((mMmuInited =3D=3D TRUE) =7C=7C > + (PcdGet64 (PcdSwapPageDir) =21=3D 0)) =7B > + return TRUE; > + =7D > + return =46ALSE; > +=7D > + > +/** > + Iterates through the page directory to initialize it. > + > + =40param Dst A pointer to the directory of the page to initialize. > + =40param Num The number of page directories to initialize. > + =40param Src A pointer to the data used to initialize the page direct= ory. > + > + =40retval VOID. > +**/ > +VOID > +PageDirInit ( > + IN VOID *Dst, > + IN UINTN Num, > + IN VOID *Src > + ) > +=7B > + UINTN *Ptr; > + UINTN *End; > + UINTN Entry; > + > + Entry =3D (UINTN)Src; > + Ptr =3D (UINTN *)Dst; > + End =3D Ptr + Num; > + > + for ( ;Ptr < End; Ptr++) =7B > + *Ptr =3D Entry; > + =7D > + > + return ; > +=7D > + > +/** > + Gets the virtual address corresponding to the page global directory t= able entry. > + > + =40param Address the virtual address for the table entry. > + > + =40retval PGD A pointer to get the table item. > +**/ > +PGD * > +PgdOffset ( > + IN UINTN Address > + ) > +=7B > + return ((PGD *)PcdGet64 (PcdSwapPageDir)) + PGD=5FINDEX (Address); > +=7D > + > +/** > + Gets the virtual address corresponding to the page upper directory ta= ble entry. > + > + =40param Pgd A pointer to a page global directory table entry. > + =40param Address the virtual address for the table entry. > + > + =40retval PUD A pointer to get the table item. > +**/ > +PUD * > +PudOffset ( > + IN PGD *Pgd, > + IN UINTN Address > + ) > +=7B > + UINTN PgdVal =3D (UINTN)PGD=5FVAL (*Pgd); > + return (PUD *)PgdVal + PUD=5FINDEX (Address); > +=7D > + > +/** > + Gets the virtual address corresponding to the page middle directory t= able entry. > + > + =40param Pud A pointer to a page upper directory table entry. > + =40param Address the virtual address for the table entry. > + > + =40retval PMD A pointer to get the table item. > +**/ > +PMD * > +PmdOffset ( > + IN PUD *Pud, > + IN UINTN Address > + ) > +=7B > + UINTN PudVal =3D PUD=5FVAL (*Pud); > + return (PMD *)PudVal + PMD=5FINDEX (Address); > +=7D > + > +/** > + Gets the virtual address corresponding to the page table entry. > + > + =40param Pmd A pointer to a page middle directory table entry. > + =40param Address the virtual address for the table entry. > + > + =40retval PTE A pointer to get the table item. > +**/ > +PTE * > +PteOffset ( > + IN PMD *Pmd, > + IN UINTN Address > + ) > +=7B > + UINTN PmdVal =3D (UINTN)PMD=5FVAL (*Pmd); > + return (PTE *)PmdVal + PTE=5FINDEX (Address); > +=7D > + > +/** > + Sets the value of the page table entry. > + > + =40param Pte A pointer to a page table entry. > + =40param PteVal The value of the page table entry to set. > + > + =40retval VOID > +**/ > +VOID > +SetPte ( > + IN PTE *Pte, > + IN PTE PteVal > + ) > +=7B > + *Pte =3D PteVal; > +=7D > + > +/** > + Sets the value of the page global directory. > + > + =40param Pgd A pointer to a page global directory. > + =40param Pud The value of the page global directory to set. > + > + =40retval VOID > +**/ > +VOID > +SetPgd ( > + IN PGD *Pgd, > + IN PUD *Pud > + ) > +=7B > + *Pgd =3D (PGD) =7B((UINTN)Pud)=7D; > +=7D > + > +/** > + Sets the value of the page upper directory. > + > + =40param Pud A pointer to a page upper directory. > + =40param Pmd The value of the page upper directory to set. > + > + =40retval VOID > +**/ > +VOID > +SetPud ( > + IN PUD *Pud, > + IN PMD *Pmd > + ) > +=7B > + *Pud =3D (PUD) =7B((UINTN)Pmd)=7D; > +=7D > + > +/** > + Sets the value of the page middle directory. > + > + =40param Pmd A pointer to a page middle directory. > + =40param Pte The value of the page middle directory to set. > + > + =40retval VOID > +**/ > +VOID > +SetPmd ( > + IN PMD *Pmd, > + IN PTE *Pte > + ) > +=7B > + *Pmd =3D (PMD) =7B((UINTN)Pte)=7D; > +=7D > + > +/** > + =46ree up memory space occupied by page tables. > + > + =40param Pte A pointer to the page table. > + > + =40retval VOID > +**/ > +VOID > +Pte=46ree ( > + IN PTE *Pte > + ) > +=7B > + =46reePages ((VOID *)Pte, 1); > +=7D > + > +/** > + =46ree up memory space occupied by page middle directory. > + > + =40param Pmd A pointer to the page middle directory. > + > + =40retval VOID > +**/ > +VOID > +Pmd=46ree ( > + IN PMD *Pmd > + ) > +=7B > + =46reePages ((VOID *)Pmd, 1); > +=7D > + > +/** > + =46ree up memory space occupied by page upper directory. > + > + =40param Pud A pointer to the page upper directory. > + > + =40retval VOID > +**/ > +VOID > +Pud=46ree ( > + IN PUD *Pud > + ) > +=7B > + =46reePages ((VOID *)Pud, 1); > +=7D > + > +/** > + Requests the memory space required for the page upper directory, > + initializes it, and places it in the specified page global directory > + > + =40param Pgd A pointer to the page global directory. > + > + =40retval E=46I=5FSUCCESS Memory request successful. > + =40retval E=46I=5FOUT=5FO=46=5FRESOURCES Resource exhaustion cannot b= e requested to memory. > +**/ > +INTN > +PudAlloc ( > + IN PGD *Pgd > + ) > +=7B > + PUD *Pud =3D (PUD *) AllocatePages (1); > + if (=21Pud) =7B > + return E=46I=5FOUT=5FO=46=5FRESOURCES; > + =7D > + > + PageDirInit ((VOID *)Pud, ENTRYS=5FPER=5FPUD, (VOID *)PcdGet64 (PcdIn= validPmd)); > + > + if (pgd=5Fnone (*Pgd)) =7B > + SetPgd (Pgd, Pud); > + =7D else =7B /* Another has populated it */ > + Pud=46ree (Pud); > + =7D > + > + return E=46I=5FSUCCESS; > +=7D > + > +/** > + Requests the memory space required for the page middle directory, > + initializes it, and places it in the specified page upper directory > + > + =40param Pud A pointer to the page upper directory. > + > + =40retval E=46I=5FSUCCESS Memory request successful. > + =40retval E=46I=5FOUT=5FO=46=5FRESOURCES Resource exhaustion cannot b= e requested to memory. > +**/ > +E=46I=5FSTATUS > +PmdAlloc ( > + IN PUD *Pud > + ) > +=7B > + PMD *Pmd; > + > + Pmd =3D (PMD *) AllocatePages (1); > + if (=21Pmd) =7B > + return E=46I=5FOUT=5FO=46=5FRESOURCES; > + =7D > + > + PageDirInit ((VOID *)Pmd, ENTRYS=5FPER=5FPMD, (VOID *)PcdGet64 (PcdIn= validPte)); > + > + if (pud=5Fnone (*Pud)) =7B > + SetPud (Pud, Pmd); > + =7D else =7B/* Another has populated it */ > + Pmd=46ree (Pmd); > + =7D > + > + return E=46I=5FSUCCESS; > +=7D > + > +/** > + Requests the memory space required for the page table, > + initializes it, and places it in the specified page middle directory > + > + =40param Pmd A pointer to the page middle directory. > + > + =40retval E=46I=5FSUCCESS Memory request successful. > + =40retval E=46I=5FOUT=5FO=46=5FRESOURCES Resource exhaustion cannot b= e requested to memory. > +**/ > +INTN > +PteAlloc ( > + IN PMD *Pmd > + ) > +=7B > + PTE *Pte; > + > + Pte =3D (PTE *) AllocatePages (1); > + if (=21Pte) =7B > + return E=46I=5FOUT=5FO=46=5FRESOURCES; > + =7D > + > + Pte =3D ZeroMem (Pte, E=46I=5FPAGE=5FSIZE); > + > + if (pmd=5Fnone (*Pmd)) =7B > + SetPmd (Pmd, Pte); > + =7D else =7B /* Another has populated it */ > + Pte=46ree (Pte); > + =7D > + > + return E=46I=5FSUCCESS; > +=7D > + > +/** > + Requests the memory space required for the page upper directory, > + initializes it, and places it in the specified page global directory,= > + and get the page upper directory entry corresponding to the virtual a= ddress > + > + =40param Pgd A pointer to the page global directory. > + > + =40retval Gets the page upper directory entry > +**/ > +PUD * > +PudAllocGet ( > + IN PGD *Pgd, > + IN UINTN Address > + ) > +=7B > + return ((pgd=5Fnone (*(Pgd)) && PudAlloc (Pgd)) =3F > + NULL : PudOffset (Pgd, Address)); > +=7D > + > +/** > + Requests the memory space required for the page middle directory, > + initializes it, and places it in the specified page upper directory, > + and get the page middle directory entry corresponding to the virtual = address > + > + =40param Pud A pointer to the page upper directory. > + > + =40retval Gets the page middle directory entry > +**/ > +PMD * > +PmdAllocGet ( > + IN PUD *Pud, > + IN UINTN Address > + ) > +=7B > + PMD * ret =3D (pud=5Fnone (*Pud) && PmdAlloc (Pud))=3F > + NULL: PmdOffset (Pud, Address); > + DEBUG ((DEBUG=5FVERBOSE, =22%a %d PudVal %p PmdOffset %p PMD=5FINDEX = %p .=5Cn=22, =5F=5Ffunc=5F=5F, =5F=5FLINE=5F=5F, > + Pud->PudVal, PmdOffset (Pud, Address), PMD=5FINDEX (Address) )); > + > + return ret; > +=7D > + > +/** > + Requests the memory space required for the page table, > + initializes it, and places it in the specified page middle directory,= > + and get the page table entry corresponding to the virtual address > + > + =40param Pmd A pointer to the page upper directory. > + > + =40retval Gets the page table entry > +**/ > +PTE * > +PteAllocGet ( > + IN PMD *Pmd, > + IN UINTN Address > + ) > +=7B > + return (pmd=5Fnone (*Pmd) && PteAlloc (Pmd))=3F > + NULL: PteOffset (Pmd, Address); > +=7D > + > +/** > + Gets the physical address of the page table entry corresponding to th= e specified virtual address. > + > + =40param Address the corresponding virtual address of the page table = entry. > + > + =40retval A pointer to the page table entry. > + =40retval NULL > +**/ > +PTE * > +GetPteAddress ( > + IN UINTN Address > + ) > +=7B > + PGD *Pgd; > + PUD *Pud; > + PMD *Pmd; > + > + Pgd =3D PgdOffset (Address); > + > + if (pgd=5Fnone (*Pgd)) =7B > + return NULL; > + =7D > + > + Pud =3D PudOffset (Pgd, Address); > + > + if (pud=5Fnone (*Pud)) =7B > + return NULL; > + =7D > + > + Pmd =3D PmdOffset (Pud, Address); > + if (pmd=5Fnone (*Pmd)) =7B > + return NULL; > + =7D > + > + if (IS=5FHUGE=5FPAGE (Pmd->PmdVal)) =7B > + return ((PTE *)Pmd); > + =7D > + > + return PteOffset (Pmd, Address); > +=7D > + > +/** > + Establishes a page table entry based on the specified memory region. > + > + =40param Pmd A pointer to the page middle directory. > + =40param Address The memory space start address. > + =40param End The end address of the memory space. > + =40param Attributes Memory space Attributes. > + > + =40retval E=46I=5FSUCCESS The page table entry was created successful= ly. > + =40retval E=46I=5FOUT=5FO=46=5FRESOURCES Page table entry establishme= nt failed due to resource exhaustion. > +**/ > +E=46I=5FSTATUS > +MemoryMapPteRange ( > + IN PMD *Pmd, > + IN UINTN Address, > + IN UINTN End, > + IN UINTN Attributes > + ) > +=7B > + PTE *Pte; > + PTE PteVal; > + BOOLEAN UpDate; > + > + Pte =3D PteAllocGet (Pmd, Address); > + if (=21Pte) =7B > + return E=46I=5FOUT=5FO=46=5FRESOURCES; > + =7D > + > + do =7B > + UpDate =3D =46ALSE; > + PteVal =3D MAKE=5FPTE (Address, Attributes); > + DEBUG ((DEBUG=5FVERBOSE, > + =22%a %d Address %p PGD=5FINDEX %p PUD=5FINDEX %p PMD=5FINDEX %p PTE=5F= INDEX %p MAKE=5FPTE %p=5Cn=22, > + =5F=5Ffunc=5F=5F, =5F=5FLINE=5F=5F, Address, PGD=5FINDEX (Address), P= UD=5FINDEX (Address), PMD=5FINDEX (Address), > + PTE=5FINDEX (Address), PteVal)); > + > + if ((=21pte=5Fnone (*Pte)) && > + (PTE=5FVAL(*Pte) =21=3D PTE=5FVAL(PteVal))) > + =7B > + UpDate =3D TRUE; > + =7D > + > + SetPte (Pte, PteVal); > + if (UpDate) =7B > + LoongarchInvalidTlb(Address); > + =7D > + =7D while (Pte++, Address +=3D E=46I=5FPAGE=5FSIZE, Address =21=3D En= d); > + > + return E=46I=5FSUCCESS; > +=7D > + > +/** > + Establishes a page middle directory based on the specified memory reg= ion. > + > + =40param Pud A pointer to the page upper directory. > + =40param Address The memory space start address. > + =40param End The end address of the memory space. > + =40param Attributes Memory space Attributes. > + > + =40retval E=46I=5FSUCCESS The page middle directory was created succe= ssfully. > + =40retval E=46I=5FOUT=5FO=46=5FRESOURCES Page middle directory establ= ishment failed due to resource exhaustion. > +**/ > +E=46I=5FSTATUS > +MemoryMapPmdRange ( > + IN PUD *Pud, > + IN UINTN Address, > + IN UINTN End, > + IN UINTN Attributes > + ) > +=7B > + PMD *Pmd; > + PTE *Pte; > + UINTN Next; > + UINTN AddressStart=5FHugePage; > + UINTN AddressEnd=5FHugePage; > + > + Pmd =3D PmdAllocGet (Pud, Address); > + if (=21Pmd) =7B > + return E=46I=5FOUT=5FO=46=5FRESOURCES; > + =7D > + > + do =7B > + Next =3D PMD=5FADDRESS=5FEND (Address, End); > + if (((Address & (=7EPMD=5FMASK)) =3D=3D 0) && > + ((Next & (=7EPMD=5FMASK)) =3D=3D 0) && > + (pmd=5Fnone (*Pmd))) > + =7B > + DEBUG ((DEBUG=5FVERBOSE, > + =22%a %d Address %p PGD=5FINDEX %p PUD=5FINDEX %p PMD=5FINDEX %p MAKE= =5FHUGE=5FPTE %p=5Cn=22, > + =5F=5Ffunc=5F=5F, =5F=5FLINE=5F=5F, Address, PGD=5FINDEX (Address), P= UD=5FINDEX (Address), PMD=5FINDEX (Address), > + MAKE=5FHUGE=5FPTE (Address, Attributes))); > + > + SetPmd (Pmd, (PTE *)MAKE=5FHUGE=5FPTE (Address, Attributes)); > + =7D else =7B > + if ((pmd=5Fnone (*Pmd)) =7C=7C > + ((=21pmd=5Fnone (*Pmd)) && > + (=21IS=5FHUGE=5FPAGE (Pmd->PmdVal)))) > + =7B > + if (MemoryMapPteRange (Pmd, Address, Next, Attributes)) =7B > + return E=46I=5FOUT=5FO=46=5FRESOURCES; > + =7D > + =7D else =7B > + SetPmd (Pmd, (PTE *)PcdGet64 (PcdInvalidPte)); > + AddressStart=5FHugePage =3D Address & PMD=5FMASK; > + AddressEnd=5FHugePage =3D AddressStart=5FHugePage + HUGE=5FPAGE=5FSIZ= E; > + if (MemoryMapPteRange (Pmd, AddressStart=5FHugePage, AddressEnd=5FHug= ePage, Attributes)) =7B > + return E=46I=5FOUT=5FO=46=5FRESOURCES; > + =7D > + Pte =3D GetPteAddress (AddressStart=5FHugePage); > + if (Pte =3D=3D NULL) =7B > + continue ; > + =7D > + if (AddressEnd=5FHugePage > End) =7B > + Next =3D End; > + =7D > + =7D > + =7D > + =7D while (Pmd++, Address =3D Next, Address =21=3D End); > + > + return 0; > +=7D > + > +/** > + Establishes a page upper directory based on the specified memory regi= on. > + > + =40param Pgd A pointer to the page global directory. > + =40param Address The memory space start address. > + =40param End The end address of the memory space. > + =40param Attributes Memory space Attributes. > + > + =40retval E=46I=5FSUCCESS The page upper directory was created succes= sfully. > + =40retval E=46I=5FOUT=5FO=46=5FRESOURCES Page upper directory establi= shment failed due to resource exhaustion. > +**/ > +E=46I=5FSTATUS > +MemoryMapPudRange ( > + IN PGD *Pgd, > + IN UINTN Address, > + IN UINTN End, > + IN UINTN Attributes > + ) > +=7B > + PUD *Pud; > + UINTN Next; > + > + Pud =3D PudAllocGet (Pgd, Address); > + if (=21Pud) =7B > + return E=46I=5FOUT=5FO=46=5FRESOURCES; > + =7D > + > + do =7B > + Next =3D PUD=5FADDRESS=5FEND (Address, End); > + if (MemoryMapPmdRange (Pud, Address, Next, Attributes)) =7B > + return E=46I=5FOUT=5FO=46=5FRESOURCES; > + =7D > + =7D while (Pud++, Address =3D Next, Address =21=3D End); > + return E=46I=5FSUCCESS; > +=7D > + > +/** > + Establishes a page global directory based on the specified memory reg= ion. > + > + =40param Start The memory space start address. > + =40param End The end address of the memory space. > + =40param Attributes Memory space Attributes. > + > + =40retval E=46I=5FSUCCESS The page global directory was created succe= ssfully. > + =40retval E=46I=5FOUT=5FO=46=5FRESOURCES Page global directory establ= ishment failed due to resource exhaustion. > +**/ > +E=46I=5FSTATUS > +MemoryMapPageRange ( > + IN UINTN Start, > + IN UINTN End, > + IN UINTN Attributes > + ) > +=7B > + PGD *Pgd; > + UINTN Next; > + UINTN Address =3D Start; > + E=46I=5FSTATUS Err; > + > + Pgd =3D PgdOffset (Address); > + do =7B > + Next =3D PGD=5FADDRESS=5FEND (Address, End); > + Err =3D MemoryMapPudRange (Pgd, Address, Next, Attributes); > + if (Err) =7B > + return Err; > + =7D > + =7D while (Pgd++, Address =3D Next, Address =21=3D End); > + > + return E=46I=5FSUCCESS; > +=7D > + > +/** > + Page tables are established from memory-mapped tables. > + > + =40param MemoryRegion A pointer to a memory-mapped table entry. > + > + =40retval E=46I=5FSUCCESS The page table was created successfully. > + =40retval E=46I=5FOUT=5FO=46=5FRESOURCES Page table establishment fai= led due to resource exhaustion. > +**/ > +E=46I=5FSTATUS > +=46illTranslationTable ( > + IN MEMORY=5FREGION=5FDESCRIPTOR *MemoryRegion > + ) > +=7B > + return MemoryMapPageRange (MemoryRegion->VirtualBase, > + (MemoryRegion->Length + MemoryRegion->VirtualBase), > + MemoryRegion->Attributes); > +=7D > + > +/** > + write operation is performed Count times from the first element of Bu= ffer. > + Convert E=46I Attributes to Loongarch Attributes. > + =40param=5Bin=5D EfiAttributes Efi Attributes. > + > + =40retval LoongArch Attributes. > +**/ > +UINTN > +EfiAttributeToLoongArchAttribute ( > + IN UINTN EfiAttributes > + ) > +=7B > + UINTN LoongArchAttributes =3D PAGE=5FVALID =7C PAGE=5FDIRTY =7C CACHE= =5FCC =7C PAGE=5FUSER =7C PAGE=5FGLOBAL; > + switch (EfiAttributes & E=46I=5FMEMORY=5FCACHETYPE=5FMASK) =7B > + case E=46I=5FMEMORY=5FUC: > + LoongArchAttributes =7C=3D CACHE=5FSUC; > + break; > + case E=46I=5FMEMORY=5FWC: > + case E=46I=5FMEMORY=5FWT: > + case E=46I=5FMEMORY=5FWB: > + LoongArchAttributes =7C=3D CACHE=5FCC; > + break; > + default : > + LoongArchAttributes =7C=3D CACHE=5FCC; > + break; > + =7D > + > + // Write protection attributes > + if ((EfiAttributes & E=46I=5FMEMORY=5FRO) =21=3D 0) =7B > + LoongArchAttributes &=3D =7EPAGE=5FDIRTY; > + =7D > + > + //eXecute protection attribute > + if ((EfiAttributes & E=46I=5FMEMORY=5FXP) =21=3D 0) =7B > + LoongArchAttributes =7C=3D PAGE=5FNO=5FEXEC; > + =7D > + > + return LoongArchAttributes; > +=7D > + > +/** > + =46inds the length and memory properties of the memory region corresp= onding to the specified base address. > + > + =40param=5Bin=5D BaseAddress To find the base address of the memory r= egion. > + =40param=5Bin=5D EndAddress To find the end address of the memory reg= ion. > + =40param=5Bout=5D RegionLength The length of the memory region found.= > + =40param=5Bout=5D RegionAttributes Properties of the memory region fo= und. > + > + =40retval E=46I=5FSUCCESS The corresponding memory area was successfu= lly found > + E=46I=5FNOT=5F=46OUND No memory area found > +**/ > +E=46I=5FSTATUS > +GetLoongArchMemoryRegion ( > + IN UINTN BaseAddress, > + IN UINTN EndAddress, > + OUT UINTN *RegionLength, > + OUT UINTN *RegionAttributes > + ) > +=7B > + PTE *Pte; > + UINTN Attributes; > + UINTN AttributesTmp; > + UINTN MaxAddress; > + MaxAddress =3D LShiftU64 (1ULL, MAX=5FVA=5FBITS) - 1; > + Pte =3D GetPteAddress (BaseAddress); > + > + if (=21MmuIsInit ()) =7B > + return E=46I=5FSUCCESS; > + =7D > + if (Pte =3D=3D NULL) =7B > + return E=46I=5FNOT=5F=46OUND; > + =7D > + Attributes =3D GET=5FPAGE=5FATTRIBUTES (*Pte); > + if (IS=5FHUGE=5FPAGE (Pte->PteVal)) =7B > + *RegionAttributes =3D Attributes & (=7E(PAGE=5FHUGE)); > + *RegionLength +=3D HUGE=5FPAGE=5FSIZE; > + =7D else =7B > + *RegionLength +=3D E=46I=5FPAGE=5FSIZE; > + *RegionAttributes =3D Attributes; > + =7D > + > + while (BaseAddress <=3D MaxAddress) =7B > + Pte =3D GetPteAddress (BaseAddress); > + if (Pte =3D=3D NULL) =7B > + return E=46I=5FSUCCESS; > + =7D > + AttributesTmp =3D GET=5FPAGE=5FATTRIBUTES (*Pte); > + if (IS=5FHUGE=5FPAGE (Pte->PteVal)) =7B > + if (AttributesTmp =3D=3D Attributes) =7B > + *RegionLength +=3D HUGE=5FPAGE=5FSIZE; > + =7D > + BaseAddress +=3D HUGE=5FPAGE=5FSIZE; > + =7D else =7B > + if (AttributesTmp =3D=3D Attributes) =7B > + *RegionLength +=3D E=46I=5FPAGE=5FSIZE; > + =7D > + BaseAddress +=3D E=46I=5FPAGE=5FSIZE; > + =7D > + > + if (BaseAddress > EndAddress) =7B > + break; > + =7D > + =7D > + return E=46I=5FSUCCESS; > +=7D > + > +/** > + Sets the Attributes of the specified memory region > + > + =40param=5Bin=5D BaseAddress The base address of the memory region to= set the Attributes. > + =40param=5Bin=5D Length The length of the memory region to set the At= tributes. > + =40param=5Bin=5D Attributes The Attributes to be set. > + > + =40retval E=46I=5FSUCCESS The Attributes was set successfully > +**/ > +E=46I=5FSTATUS > +LoongArchSetMemoryAttributes ( > + IN E=46I=5FPHYSICAL=5FADDRESS BaseAddress, > + IN UINTN Length, > + IN UINTN Attributes > + ) > +=7B > + > + if (=21MmuIsInit ()) =7B > + return E=46I=5FSUCCESS; > + =7D > + Attributes =3D EfiAttributeToLoongArchAttribute (Attributes); > + DEBUG ((DEBUG=5FVERBOSE, =22%a %d %p %p %p.=5Cn=22, =5F=5Ffunc=5F=5F,= =5F=5FLINE=5F=5F, BaseAddress , Length, Attributes)); > + MemoryMapPageRange (BaseAddress, BaseAddress + Length, Attributes); > + > + return E=46I=5FSUCCESS; > +=7D > + > +/** > + Sets the non-executable Attributes for the specified memory region > + > + =40param=5Bin=5D BaseAddress The base address of the memory region to= set the Attributes. > + =40param=5Bin=5D Length The length of the memory region to set the At= tributes. > + > + =40retval E=46I=5FSUCCESS The Attributes was set successfully > +**/ > +E=46I=5FSTATUS > +LoongArchSetMemoryRegionNoExec ( > + IN E=46I=5FPHYSICAL=5FADDRESS BaseAddress, > + IN UINTN Length > + ) > +=7B > + if (MmuIsInit ()) =7B > + Length =3D E=46I=5FPAGES=5FTO=5FSIZE (E=46I=5FSIZE=5FTO=5FPAGES (Leng= th)); > + LoongArchSetMemoryAttributes (BaseAddress, Length, E=46I=5FMEMORY=5FX= P); > + =7D > + return E=46I=5FSUCCESS; > +=7D > + > +/** > + Check to see if mmu successfully initializes and saves the result. > + > + =40param VOID. > + > + =40retval E=46I=5FSUCCESS Initialization succeeded. > +**/ > +E=46I=5FSTATUS > +MmuInitialize (VOID) > +=7B > + if (PcdGet64 (PcdSwapPageDir) =21=3D 0) =7B > + mMmuInited =3D TRUE; > + =7D > + > + return E=46I=5FSUCCESS; > +=7D > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCo= re.h b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.h > new file mode 100644 > index 0000000000..7a5e8ea0dd > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.h > =40=40 -0,0 +1,40 =40=40 > +/** =40file > + > + Copyright (c) 2022 Loongson Technology Corporation Limited. All right= s reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + =40par Glossary: > + - Dir - Directory > +**/ > +=23ifndef MMU=5FLIB=5FCORE=5FH=5F > +=23define MMU=5FLIB=5FCORE=5FH=5F > +/** > + Iterates through the page directory to initialize it. > + > + =40param Dst A pointer to the directory of the page to initialize. > + =40param Num The number of page directories to initialize. > + =40param Src A pointer to the data used to initialize the page direct= ory. > + > + =40retval VOID. > +**/ > +VOID > +PageDirInit ( > + IN VOID *dest, > + IN UINTN Count, > + IN VOID *src > + ); > + > +/** > + Page tables are established from memory-mapped tables. > + > + =40param MemoryRegion A pointer to a memory-mapped table entry. > + > + =40retval E=46I=5FSUCCESS The page table was created successfully. > + =40retval E=46I=5FOUT=5FO=46=5FRESOURCES Page table establishment fai= led due to resource exhaustion. > +**/ > +E=46I=5FSTATUS > +=46illTranslationTable ( > + IN MEMORY=5FREGION=5FDESCRIPTOR *MemoryRegion > + ); > +=23endif // MMU=5FLIB=5FCORE=5FH=5F > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCo= rePei.c b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCorePei= .c > new file mode 100644 > index 0000000000..32a7fc0beb > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCorePei.c= > =40=40 -0,0 +1,231 =40=40 > +/** =40file > + Platform PEI driver > + > + Copyright (c) 2022 Loongson Technology Corporation Limited. All right= s reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + =40par Glossary: > + - =46wCfg - =46irmeware Config > + - Tlb - Translation Lookaside Buffer > +**/ > +=23include > +=23include > +=23include > +=23include > +=23include > +=23include =22Library/Cpu.h=22 > +=23include =22pte.h=22 > +=23include =22page.h=22 > +=23include =22mmu.h=22 > +=23include > +=23include =22MmuLibCore.h=22 > +=23include > + > +/** > + Return the Virtual Memory Map of your platform > + > + This Virtual Memory Map is used by MemoryInitPei Module to initialize= the MMU > + on your platform. > + > + =40param=5Bout=5D VirtualMemoryMap Array of MEMORY=5FREGION=5FDESCRIP= TOR > + describing a Physical-to-Virtual Memory > + mapping. This array must be ended by a > + zero-filled entry. The allocated memory > + will not be freed. > +**/ > +VOID > +GetMemoryMap=46rom=46wCfg ( > + OUT MEMORY=5FREGION=5FDESCRIPTOR **VirtualMemoryMap > + ) > +=7B > + > + E=46I=5FSTATUS Status; > + =46IRMWARE=5FCON=46IG=5FITEM =46wCfgItem; > + UINTN =46wCfgSize; > + LOONGARCH=5FMEMMAP=5FENTRY MemoryMapEntry; > + LOONGARCH=5FMEMMAP=5FENTRY *StartEntry; > + LOONGARCH=5FMEMMAP=5FENTRY *pEntry; > + UINTN Processed; > + MEMORY=5FREGION=5FDESCRIPTOR *VirtualMemoryTable; > + UINTN Index =3D 0; > + ASSERT (VirtualMemoryMap =21=3D NULL); > + > + VirtualMemoryTable =3D AllocatePool ( > + sizeof (MEMORY=5FREGION=5FDESCRIPTOR) * > + MAX=5FVIRTUAL=5FMEMORY=5FMAP=5FDESCRIPTORS > + ); > + VirtualMemoryTable=5BIndex=5D.PhysicalBase =3D 0x10000000; > + VirtualMemoryTable=5BIndex=5D.VirtualBase =3D VirtualMemoryTable=5BIn= dex=5D.PhysicalBase; > + VirtualMemoryTable=5BIndex=5D.Length =3D 0x10000000; > + VirtualMemoryTable=5BIndex=5D.Attributes =3D PAGE=5FVALID =7C PLV=5FK= ERNEL =7C CACHE=5FSUC =7C PAGE=5FDIRTY =7C PAGE=5FGLOBAL; > + ++Index; > + > + Status =3D Qemu=46wCfg=46ind=46ile (=22etc/memmap=22, &=46wCfgItem, &= =46wCfgSize); > + if (E=46I=5FERROR (Status)) =7B > + DEBUG ((DEBUG=5FERROR, =22%a %d read etc/memmap error Status %d =5Cn=22= , =5F=5Ffunc=5F=5F, =5F=5FLINE=5F=5F, Status)); > + ZeroMem (&VirtualMemoryTable=5BIndex=5D, sizeof (MEMORY=5FREGION=5FDE= SCRIPTOR)); > + *VirtualMemoryMap =3D VirtualMemoryTable; > + return ; > + =7D > + if (=46wCfgSize % sizeof MemoryMapEntry =21=3D 0) =7B > + DEBUG ((DEBUG=5FERROR, =22no MemoryMapEntry =46wCfgSize:%d=5Cn=22, =46= wCfgSize)); > + =7D > + > + Qemu=46wCfgSelectItem (=46wCfgItem); > + StartEntry =3D AllocatePages (E=46I=5FSIZE=5FTO=5FPAGES (=46wCfgSize)= ); > + Qemu=46wCfgReadBytes (=46wCfgSize, StartEntry); > + for (Processed =3D 0; Processed < (=46wCfgSize / sizeof MemoryMapEntr= y); Processed++) =7B > + pEntry =3D StartEntry + Processed; > + if (pEntry->Length =3D=3D 0) =7B > + continue; > + =7D > + > + DEBUG ((DEBUG=5FIN=46O, =22MemmapEntry Base %p length %p type %d=5Cn=22= , pEntry->BaseAddr, pEntry->Length, pEntry->Type)); > + VirtualMemoryTable=5BIndex=5D.PhysicalBase =3D pEntry->BaseAddr; > + VirtualMemoryTable=5BIndex=5D.VirtualBase =3D VirtualMemoryTable=5BIn= dex=5D.PhysicalBase; > + VirtualMemoryTable=5BIndex=5D.Length =3D pEntry->Length; > + VirtualMemoryTable=5BIndex=5D.Attributes =3D PAGE=5FVALID =7C PLV=5FK= ERNEL =7C CACHE=5FCC =7C PAGE=5FDIRTY =7C PAGE=5FGLOBAL; > + ++Index; > + =7D > + > + =46reePages (StartEntry, E=46I=5FSIZE=5FTO=5FPAGES (=46wCfgSize)); > + // End of Table > + ZeroMem (&VirtualMemoryTable=5BIndex=5D, sizeof (MEMORY=5FREGION=5FDE= SCRIPTOR)); > + *VirtualMemoryMap =3D VirtualMemoryTable; > + return ; > +=7D > + > +/** > + Create a page table and initialize the MMU. > + > + =40param=5B=5D VOID > + > + =40retval VOID > +**/ > +E=46IAPI > +VOID > +ConfigureMmu (VOID) > +=7B > + PGD *SwapperPageDir =3D NULL; > + PGD *InvalidPgd =3D NULL; > + PUD *InvalidPudTable =3D NULL; > + PMD *InvalidPmdTable =3D NULL; > + PTE *InvalidPteTable =3D NULL; > + MEMORY=5FREGION=5FDESCRIPTOR *MemoryTable =3D NULL; > + RETURN=5FSTATUS PcdStatus; > + UINTN PgdShift =3D PGD=5FSHI=46T; > + UINTN PgdWide =3D PGD=5FWIDE; > + UINTN PudShift =3D PUD=5FSHI=46T; > + UINTN PudWide =3D PUD=5FWIDE; > + UINTN PmdShift =3D PMD=5FSHI=46T; > + UINTN PmdWide =3D PMD=5FWIDE; > + UINTN PteShift =3D PTE=5FSHI=46T; > + UINTN PteWide =3D PTE=5FWIDE; > + UINTN PageEnable =3D 1 << 4; > + VOID *TlbReEntry; > + > + SwapperPageDir =3D AllocatePages (E=46I=5FSIZE=5FTO=5FPAGES (PGD=5FTA= BLE=5FSIZE)); > + InvalidPgd =3D AllocatePages (E=46I=5FSIZE=5FTO=5FPAGES (PGD=5FTABLE=5F= SIZE)); > + InvalidPudTable =3D AllocatePages (E=46I=5FSIZE=5FTO=5FPAGES (PUD=5FT= ABLE=5FSIZE)); > + InvalidPmdTable =3D AllocatePages (E=46I=5FSIZE=5FTO=5FPAGES (PMD=5FT= ABLE=5FSIZE)); > + InvalidPteTable =3D AllocatePages (E=46I=5FSIZE=5FTO=5FPAGES (PTE=5FT= ABLE=5FSIZE)); > + ZeroMem (InvalidPteTable, PTE=5FTABLE=5FSIZE); > + > + if ((=21InvalidPgd) =7C=7C > + (=21InvalidPudTable) =7C=7C > + (=21InvalidPmdTable) =7C=7C > + (=21InvalidPteTable)) > + =7B > + goto =46reeTranslationTable; > + =7D > + > + /*pgd init*/ > + PageDirInit (SwapperPageDir , ENTRYS=5FPER=5FPGD, InvalidPudTable); > + /*pgd init*/ > + PageDirInit (InvalidPgd, ENTRYS=5FPER=5FPGD, InvalidPudTable); > + /*pud init*/ > + PageDirInit (InvalidPudTable, ENTRYS=5FPER=5FPUD, InvalidPmdTable); > + /*pmd init*/ > + PageDirInit (InvalidPmdTable, ENTRYS=5FPER=5FPMD, InvalidPteTable); > + GetMemoryMap=46rom=46wCfg (&MemoryTable); > + > + PcdStatus =7C=3D PcdSet64S (PcdSwapPageDir, (UINTN)SwapperPageDir); > + PcdStatus =7C=3D PcdSet64S (PcdInvalidPgd, (UINTN)InvalidPgd); > + PcdStatus =7C=3D PcdSet64S (PcdInvalidPud, (UINTN)InvalidPudTable); > + PcdStatus =7C=3D PcdSet64S (PcdInvalidPmd, (UINTN)InvalidPmdTable); > + PcdStatus =7C=3D PcdSet64S (PcdInvalidPte, (UINTN)InvalidPteTable); > + ASSERT=5FRETURN=5FERROR (PcdStatus); > + > + while (MemoryTable->Length =21=3D 0) =7B > + DEBUG ((DEBUG=5FVERBOSE, =22%a %d VirtualBase %p VirtualEnd %p Attrib= utes %p .=5Cn=22, =5F=5Ffunc=5F=5F, =5F=5FLINE=5F=5F, > + MemoryTable->VirtualBase, > + (MemoryTable->Length + MemoryTable->VirtualBase), > + MemoryTable->Attributes)); > + > + PcdStatus =3D =46illTranslationTable (MemoryTable); > + if (E=46I=5FERROR (PcdStatus)) =7B > + goto =46reeTranslationTable; > + =7D > + MemoryTable++; > + =7D > + > + TlbReEntry =3D AllocatePages (1); > + if (TlbReEntry =3D=3D NULL) =7B > + goto =46reeTranslationTable; > + =7D > + CopyMem ((char *)TlbReEntry, HandleTlbRefill, (HandleTlbRefillEnd - H= andleTlbRefill)); > + InvalidateInstructionCacheRange ((VOID *)(UINTN)HandleTlbRefill, (UIN= TN)(HandleTlbRefillEnd - HandleTlbRefill)); > + > + DEBUG ((DEBUG=5FVERBOSE, > + =22%a %d PteShift %d PteWide %d PmdShift %d PmdWide %d PudShift %d Pu= dWide %d PgdShift %d PgdWide %d.=5Cn=22, > + =5F=5Ffunc=5F=5F, =5F=5FLINE=5F=5F, > + PteShift, PteWide, PmdShift, PmdWide,PudShift, PudWide, PgdShift, Pgd= Wide)); > + > + SetTlbRefill=46uncBase ((UINTN)TlbReEntry); > + /*set page size*/ > + WriteCsrPageSize (DE=46AULT=5FPAGE=5FSIZE); > + WriteCsrStlbPageSize (DE=46AULT=5FPAGE=5FSIZE); > + WriteCsrTlbRefillPageSize (DE=46AULT=5FPAGE=5FSIZE); > + > + LoongArchWriteqCsrPwctl0 ((PteShift =7C PteWide << 5 =7C PmdShift << = 10 =7C PmdWide << 15 =7C PudShift << 20 =7C PudWide << 25 > + )); > + LoongArchWriteqCsrPwctl1 (PgdShift =7C PgdWide << 6); > + LoongArchWriteqCsrPgdl ((UINTN)SwapperPageDir); > + LoongArchWriteqCsrPgdh ((UINTN)InvalidPgd); > + > + DEBUG ((DEBUG=5FIN=46O, =22%a %d Enable Mmu Start PageBassAddress %p.= =5Cn=22, =5F=5Ffunc=5F=5F, =5F=5FLINE=5F=5F, SwapperPageDir)); > + LoongArchXchgCsrCrmd ( PageEnable, 1 << 4); > + DEBUG ((DEBUG=5FIN=46O, =22%a %d Enable Mmu End.=5Cn=22, =5F=5Ffunc=5F= =5F, =5F=5FLINE=5F=5F)); > + > + return ; > + > +=46reeTranslationTable: > + if (SwapperPageDir) =7B > + =46reePages (SwapperPageDir, E=46I=5FSIZE=5FTO=5FPAGES (PGD=5FTABLE=5F= SIZE)); > + =7D > + > + if (InvalidPgd) =7B > + =46reePages (InvalidPgd, E=46I=5FSIZE=5FTO=5FPAGES (PGD=5FTABLE=5FSIZ= E)); > + =7D > + > + if (InvalidPudTable) =7B > + =46reePages (InvalidPudTable, E=46I=5FSIZE=5FTO=5FPAGES (PUD=5FTABLE=5F= SIZE)); > + =7D > + > + if (InvalidPmdTable) =7B > + =46reePages (InvalidPmdTable, E=46I=5FSIZE=5FTO=5FPAGES (PMD=5FTABLE=5F= SIZE)); > + =7D > + > + if (InvalidPteTable) =7B > + =46reePages (InvalidPteTable, E=46I=5FSIZE=5FTO=5FPAGES (PTE=5FTABLE=5F= SIZE)); > + =7D > + > + PcdSet64S (PcdSwapPageDir, (UINTN)0); > + PcdSet64S (PcdInvalidPgd, (UINTN)0); > + PcdSet64S (PcdInvalidPud, (UINTN)0); > + PcdSet64S (PcdInvalidPmd, (UINTN)0); > + PcdSet64S (PcdInvalidPte, (UINTN)0); > + > + return ; > +=7D > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/mmu.h b/= Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/mmu.h > new file mode 100644 > index 0000000000..8e284a2ecd > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/mmu.h > =40=40 -0,0 +1,190 =40=40 > +/** =40file > + > + Copyright (c) 2022 Loongson Technology Corporation Limited. All right= s reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + =40par Glossary: > + - Tlb or TLB - Translation Lookaside Buffer > + - CSR - Cpu State Register > + - PGDL - Page Global Directory Low > + - PGDH - Page Global Directory High > + - TLBIDX - TLB Index > + - TLBREHI - TLB Refill Entry High > + - PWCTL - Page Walk Control > + - STLB - Singular Page Size TLB > + - PS - Page Size > +**/ > +=23ifndef MMU=5FH=5F > +=23define MMU=5FH=5F > +/*page size 4k*/ > +=23define DE=46AULT=5FPAGE=5FSIZE 0x0c > +=23define LOONGARCH=5FCSR=5FPGDL 0x19 /* Page table base address when = VA=5B47=5D =3D 0 */ > +=23define LOONGARCH=5FCSR=5FPGDH 0x1a /* Page table base address when = VA=5B47=5D =3D 1 */ > +=23define LOONGARCH=5FCSR=5FTLBIDX 0x10 /* TLB Index, EHINV, PageSize,= NP */ > +=23define LOONGARCH=5FCSR=5FTLBEHI 0x11 /* TLB EntryHi */ > +=23define LOONGARCH=5FCSR=5FTLBELO0 0x12 /* TLB EntryLo0 */ > +=23define LOONGARCH=5FCSR=5FTLBELO1 0x13 /* TLB EntryLo1 */ > +=23define LOONGARCH=5FCSR=5FTLBREHI 0x8e /* TLB refill entryhi */ > +=23define LOONGARCH=5FCSR=5FPWCTL0 0x1c /* PWCtl0 */ > +=23define LOONGARCH=5FCSR=5FPWCTL1 0x1d /* PWCtl1 */ > +=23define LOONGARCH=5FCSR=5FSTLBPGSIZE 0x1e > +=23define CSR=5FTLBIDX=5FSIZE=5FMASK 0x3f000000 > +=23define CSR=5FTLBIDX=5FPS=5FSHI=46T 24 > +=23define CSR=5FTLBIDX=5FSIZE CSR=5FTLBIDX=5FPS=5FSHI=46T > + > +=23define CSR=5FTLBREHI=5FPS=5FSHI=46T 0 > +=23define CSR=5FTLBREHI=5FPS 0x3f > + > +=23define E=46I=5FMEMORY=5FCACHETYPE=5FMASK (E=46I=5FMEMORY=5FUC =7C =5C= > + E=46I=5FMEMORY=5FWC =7C =5C > + E=46I=5FMEMORY=5FWT =7C =5C > + E=46I=5FMEMORY=5FWB =7C =5C > + E=46I=5FMEMORY=5FUCE =5C > + ) > + > +typedef struct =7B > + E=46I=5FPHYSICAL=5FADDRESS PhysicalBase; > + E=46I=5FVIRTUAL=5FADDRESS VirtualBase; > + UINTN Length; > + UINTN Attributes; > +=7D MEMORY=5FREGION=5FDESCRIPTOR; > + > +// The total number of descriptors, including the final =22end-of-tabl= e=22 descriptor. > +=23define MAX=5FVIRTUAL=5FMEMORY=5FMAP=5FDESCRIPTORS (128) > + > +extern CHAR8 HandleTlbRefill=5B=5D, HandleTlbRefillEnd=5B=5D; > + > +/* > + Invalid corresponding TLB entries are based on the address given > + > + =40param Address The address corresponding to the invalid page table = entry > + > + =40retval none > +*/ > +extern > +VOID > +LoongarchInvalidTlb ( > + UINTN Address > + ); > + > +/* > + Set Tlb Refill function to hardware > + > + =40param A0 The address of tlb refill function > + > + =40retval none > +*/ > +extern > +VOID > +SetTlbRefill=46uncBase ( > + UINTN Address > + ); > + > +/* > + Set Cpu Status Register Page Size. > + > + =40param PageSize Page Size. > + > + =40retval none > +*/ > +extern > +VOID > +WriteCsrPageSize ( > + UINTN PageSize > + ); > + > +/* > + Set Cpu Status Register TLBRE=46ILL Page Size. > + > + =40param PageSize Page Size. > + > + =40retval none > +*/ > +extern > +VOID > +WriteCsrTlbRefillPageSize ( > + UINTN PageSize > + ); > + > +/* > + Set Cpu Status Register STLB Page Size. > + > + =40param PageSize Page Size. > + > + =40retval VOID > +*/ > +extern > +VOID > +WriteCsrStlbPageSize ( > + UINTN PageSize > +); > + > +/* > + Write Csr PWCTL0 register. > + > + =40param Val The value used to write to the PWCTL0 register > + > + =40retval none > +*/ > +extern > +VOID > +LoongArchWriteqCsrPwctl0 ( > + UINTN Val > + ); > + > +/* > + Write Csr PWCTL1 register. > + > + =40param Val The value used to write to the PWCTL1 register > + > + =40retval none > +*/ > +extern > +VOID > +LoongArchWriteqCsrPwctl1 ( > + UINTN Val > + ); > + > +/* > + Write Csr PGDL register. > + > + =40param Val The value used to write to the PGDL register > + > + =40retval none > +*/ > +extern > +VOID > +LoongArchWriteqCsrPgdl ( > + UINTN Val > + ); > + > +/* > + Write Csr PGDH register. > + > + =40param Val The value used to write to the PGDH register > + > + =40retval none > +*/ > +extern > +VOID > +LoongArchWriteqCsrPgdh ( > + UINTN Val > + ); > + > +/* > + Exchange specified bit data with the Csr CRMD register. > + > + =40param=5BIN=5D Val The value Exchanged with the CSR CRMD register. > + =40param=5BIN=5D Mask Specifies the mask for swapping bits > + > + =40retval VOID > +*/ > +extern > +VOID > +LoongArchXchgCsrCrmd ( > + UINTN Val, > + UINTN Mask > + ); > + > +=23endif // MMU=5FH=5F > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/page.h b= /Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/page.h > new file mode 100644 > index 0000000000..6ab07e7900 > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/page.h > =40=40 -0,0 +1,280 =40=40 > +/** =40file > + > + Copyright (c) 2022 Loongson Technology Corporation Limited. All right= s reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + =40par Glossary: > + - Pgd or Pgd or PGD - Page Global Directory > + - Pud or Pud or PUD - Page Upper Directory > + - Pmd or Pmd or PMD - Page Middle Directory > + - Pte or pte or PTE - Page Table Entry > + - Val or VAL or val - Value > + - Dir - Directory > +**/ > +=23ifndef PAGE=5FH=5F > +=23define PAGE=5FH=5F > + > +=23define MAX=5FVA=5FBITS 47 > +=23define PGD=5FWIDE (8) > +=23define PUD=5FWIDE (9) > +=23define PMD=5FWIDE (9) > +=23define PTE=5FWIDE (9) > + > +=23define ENTRYS=5FPER=5FPGD (1 << PGD=5FWIDE) > +=23define ENTRYS=5FPER=5FPUD (1 << PUD=5FWIDE) > +=23define ENTRYS=5FPER=5FPMD (1 << PMD=5FWIDE) > +=23define ENTRYS=5FPER=5FPTE (1 << PTE=5FWIDE) > + > +=23define PGD=5FSHI=46T (PUD=5FSHI=46T + PUD=5FWIDE) > +=23define PUD=5FSHI=46T (PMD=5FSHI=46T + PMD=5FWIDE) > +=23define PMD=5FSHI=46T (E=46I=5FPAGE=5FSHI=46T + PTE=5FWIDE) > +=23define PTE=5FSHI=46T (E=46I=5FPAGE=5FSHI=46T) > + > +=23define PGD=5FSIZE (1UL << PGD=5FSHI=46T) > +=23define PUD=5FSIZE (1UL << PUD=5FSHI=46T) > +=23define PMD=5FSIZE (1UL << PMD=5FSHI=46T) > + > +=23define PGD=5FMASK (=7E(PGD=5FSIZE-1)) > +=23define PUD=5FMASK (=7E(PUD=5FSIZE-1)) > +=23define PMD=5FMASK (=7E(PMD=5FSIZE-1)) > +=23define PAGE=5FMASK (=7E(E=46I=5FPAGE=5FSIZE - 1)) > +=23define P=46N=5FMASK (=7E(((UINTN)(1) << (E=46I=5FPAGE=5FSHI=46T)) -= 1) & =5C > + (((UINTN)(1) << (PAGE=5FP=46N=5FEND=5FSHI=46T)) - 1)) > + > +typedef struct =7B UINTN PgdVal; =7D PGD; > +typedef struct =7B UINTN PudVal; =7D PUD; > +typedef struct =7B UINTN PmdVal; =7D PMD; > +typedef struct =7B UINTN PteVal; =7D PTE; > +/** > + Gets the value of the page global directory table entry. > + > + =40param x Page global directory struct variables. > + > + =40retval the value of the page global directory table entry. > + **/ > +=23define PGD=5FVAL(x) ((x).PgdVal) > +/** > + Gets the value of the page upper directory table entry. > + > + =40param x Page upper directory struct variables. > + > + =40retval the value of the page upper directory table entry. > + **/ > +=23define PUD=5FVAL(x) ((x).PudVal) > +/** > + Gets the value of the page middle directory table entry. > + > + =40param x Page middle directory struct variables. > + > + =40retval the value of the page middle directory table entry. > + **/ > +=23define PMD=5FVAL(x) ((x).PmdVal) > +/** > + Gets the value of the page table entry. > + > + =40param x Page table entry struct variables. > + > + =40retval the value of the page table entry. > + **/ > +=23define PTE=5FVAL(x) ((x).PteVal) > + > +=23define PGD=5FTABLE=5FSIZE (ENTRYS=5FPER=5FPGD * sizeof(PGD)) > +=23define PUD=5FTABLE=5FSIZE (ENTRYS=5FPER=5FPUD * sizeof(PUD)) > +=23define PMD=5FTABLE=5FSIZE (ENTRYS=5FPER=5FPMD * sizeof(PMD)) > +=23define PTE=5FTABLE=5FSIZE (ENTRYS=5FPER=5FPTE * sizeof(PTE)) > +/** > + Gets the physical address of the record in the page table entry. > + > + =40param x Page table entry struct variables. > + > + =40retval the value of the physical address. > + **/ > +=23define GET=5FPAGE=5FATTRIBUTES(x) (UINTN) =7B(PTE=5FVAL(x) & =7EP=46= N=5FMASK)=7D > +/** > + Gets the virtual address of the next block of the specified virtual a= ddress > + that is aligned with the size of the global page directory mapping. > + > + =40param Address Specifies the virtual address. > + =40param End The end address of the memory region. > + > + =40retval the specified virtual address of the next block. > + **/ > +=23define PGD=5FADDRESS=5FEND(Address, End) =5C > +(=7B =5C > + UINTN Boundary =3D ((Address) + PGD=5FSIZE) & PGD=5FMASK; =5C > + (Boundary - 1 < (End) - 1)=3F Boundary: (End); =5C > +=7D) > +/** > + Gets the virtual address of the next block of the specified virtual a= ddress > + that is aligned with the size of the page upper directory mapping. > + > + =40param Address Specifies the virtual address. > + =40param End The end address of the memory region. > + > + =40retval the specified virtual address of the next block. > + **/ > +=23define PUD=5FADDRESS=5FEND(Address, End) =5C > +(=7B =5C > + UINTN Boundary =3D ((Address) + PUD=5FSIZE) & PUD=5FMASK; =5C > + (Boundary - 1 < (End) - 1)=3F Boundary: (End); =5C > +=7D) > +/** > + Gets the virtual address of the next block of the specified virtual a= ddress > + that is aligned with the size of the page middle directory mapping. > + > + =40param Address Specifies the virtual address. > + =40param End The end address of the memory region. > + > + =40retval the specified virtual address of the next block. > + **/ > +=23define PMD=5FADDRESS=5FEND(Address, End) =5C > +(=7B =5C > + UINTN Boundary =3D ((Address) + PMD=5FSIZE) & PMD=5FMASK; =5C > + (Boundary - 1 < (End) - 1)=3F Boundary: (End); =5C > +=7D) > +/** > + Get Specifies the virtual address corresponding to the index of the p= age global directory table entry. > + > + =40param Address Specifies the virtual address. > + > + =40retval the index of the page global directory table entry. > + **/ > +=23define PGD=5FINDEX(Address) (((Address) >> PGD=5FSHI=46T) & (ENTRYS= =5FPER=5FPGD-1)) > +/** > + Get Specifies the virtual address corresponding to the index of the p= age upper directory table entry. > + > + =40param Address Specifies the virtual address. > + =40param End The end address of the memory region. > + > + =40retval the index of the page upper directory table entry. > + **/ > +=23define PUD=5FINDEX(Address) (((Address) >> PUD=5FSHI=46T) & (ENTRYS= =5FPER=5FPUD - 1)) > +/** > + Get Specifies the virtual address corresponding to the index of the p= age middle directory table entry. > + > + =40param Address Specifies the virtual address. > + > + =40retval the index of the page middle directory table entry. > + **/ > +=23define PMD=5FINDEX(Address) (((Address) >> PMD=5FSHI=46T) & (ENTRYS= =5FPER=5FPMD - 1)) > +/** > + Get Specifies the virtual address corresponding to the index of the p= age table entry. > + > + =40param Address Specifies the virtual address. > + > + =40retval the index of the page table entry. > + **/ > +=23define PTE=5FINDEX(Address) (((Address) >> E=46I=5FPAGE=5FSHI=46T) = & (ENTRYS=5FPER=5FPTE - 1)) > + > +/** > + Calculates the value of the page table entry based on the specified v= irtual address and properties. > + > + =40param Address Specifies the virtual address. > + =40param Attributes Specifies the Attributes. > + > + =40retval the value of the page table entry. > + **/ > +=23define MAKE=5FPTE(Address, Attributes) (PTE)=7B((((Address) >> E=46= I=5FPAGE=5FSHI=46T) << 12) =7C (Attributes))=7D > +/** > + Get Global bit from Attributes > + > + =40param Attributes Specifies the Attributes. > + * */ > +=23define GET=5FGLOBALBIT(Attributes) ((Attributes & PAGE=5FGLOBAL) >>= PAGE=5FGLOBAL=5FSHI=46T) > +/** > + Calculates the value of the Huge page table entry based on the specif= ied virtual address and properties. > + > + =40param Address Specifies the virtual address. > + =40param Attributes Specifies the Attributes. > + > + =40retval the value of the HUGE page table entry. > + **/ > +=23define MAKE=5FHUGE=5FPTE(Address, Attributes) (((((Address) >> PMD=5F= SHI=46T) << PMD=5FSHI=46T) =7C =5C > + ((Attributes) =7C (GET=5FGLOBALBIT(Attributes) << PAGE=5FHGLOBAL=5FSH= I=46T) =7C =5C > + PAGE=5FHUGE))) > + > + /** > + Check whether the large page table entry is. > + > + =40param Val The value of the page table entry. > + > + =40retval 1 Is huge page table entry. > + =40retval 0 Isn't huge page table entry. > + **/ > +=23define IS=5FHUGE=5FPAGE(Val) ((((Val) & PAGE=5FHUGE) =3D=3D PAGE=5F= HUGE) && =5C > + (((Val) & PAGE=5FHGLOBAL) =3D=3D PAGE=5FHGLOBAL)) > + > +=23define HUGE=5FPAGE=5FSIZE (PMD=5FSIZE) > + > + /** > + Check that the global page directory table entry is empty. > + > + =40param pgd the global page directory struct variables. > + > + =40retval 1 Is huge page table entry. > + =40retval 0 Isn't huge page table entry. > + **/ > +STATIC > +inline > +UINTN > +pgd=5Fnone ( > + IN PGD pgd > + ) > +=7B > + return (PGD=5FVAL(pgd) =3D=3D (UINTN)PcdGet64(PcdInvalidPud)); > +=7D > + > + /** > + Check that the page upper directory table entry is empty. > + > + =40param pud Page upper directory struct variables. > + > + =40retval 1 Is huge page table entry. > + =40retval 0 Isn't huge page table entry. > + **/ > +STATIC > +inline > +UINTN > +pud=5Fnone ( > + IN PUD pud > + ) > +=7B > + return (PUD=5FVAL(pud) =3D=3D (UINTN)PcdGet64 (PcdInvalidPmd)); > +=7D > + > + /** > + Check that the page middle directory table entry is empty. > + > + =40param pmd Page middle directory struct variables. > + > + =40retval 1 Is huge page table entry. > + =40retval 0 Isn't huge page table entry. > + **/ > +STATIC > +inline > +UINTN > +pmd=5Fnone ( > + IN PMD pmd > + ) > +=7B > + return (PMD=5FVAL(pmd) =3D=3D (UINTN)PcdGet64(PcdInvalidPte)); > +=7D > + /** > + Check that the page table entry is empty. > + > + =40param pmd Page table entry struct variables. > + > + =40retval 1 Is huge page table entry. > + =40retval 0 Isn't huge page table entry. > + **/ > +STATIC > +inline > +UINTN > +pte=5Fnone ( > + IN PTE pte > + ) > +=7B > + return (=21(PTE=5FVAL(pte) & (=7EPAGE=5FGLOBAL))); > +=7D > +=23endif // PAGE=5FH=5F > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/pte.h b/= Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/pte.h > new file mode 100644 > index 0000000000..aacbf81744 > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/pte.h > =40=40 -0,0 +1,57 =40=40 > +/** =40file > + > + Copyright (c) 2022 Loongson Technology Corporation Limited. All right= s reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + =40par Glossary: > + - Tlb or TLB - Translation Lookaside Buffer > + - HGLOBAL - Huge Global > + - P=46N - Page =46rame number > + - EXEC - Execute > + - PLV - Privilege Level > + - RPLV - Restricted Privilege Level > + - SUC - Strong-ordered UnCached > + - CC - Coherent Cached > + - WUC - Weak-ordered UnCached > +**/ > +=23ifndef PTE=5FH=5F > +=23define PTE=5FH=5F > +/*Page table property definitions */ > +=23define PAGE=5FVALID=5FSHI=46T 0 > +=23define PAGE=5FDIRTY=5FSHI=46T 1 > +=23define PAGE=5FPLV=5FSHI=46T 2 /* 2=7E3, two bits */ > +=23define CACHE=5FSHI=46T 4 /* 4=7E5, two bits */ > +=23define PAGE=5FGLOBAL=5FSHI=46T 6 > +=23define PAGE=5FHUGE=5FSHI=46T 6 /* HUGE is a PMD bit */ > + > +=23define PAGE=5FHGLOBAL=5FSHI=46T 12 /* HGlobal is a PMD bit */ > +=23define PAGE=5FP=46N=5FSHI=46T 12 > +=23define PAGE=5FP=46N=5FEND=5FSHI=46T 48 > +=23define PAGE=5FNO=5FREAD=5FSHI=46T 61 > +=23define PAGE=5FNO=5FEXEC=5FSHI=46T 62 > +=23define PAGE=5FRPLV=5FSHI=46T 63 > + > +/* Used by TLB hardware (placed in EntryLo*) */ > +=23define PAGE=5FVALID ((UINTN)(1) << PAGE=5FVALID=5FSHI=46T) > +=23define PAGE=5FDIRTY ((UINTN)(1) << PAGE=5FDIRTY=5FSHI=46T) > +=23define PAGE=5FPLV ((UINTN)(3) << PAGE=5FPLV=5FSHI=46T) > +=23define PAGE=5FGLOBAL ((UINTN)(1) << PAGE=5FGLOBAL=5FSHI=46T) > +=23define PAGE=5FHUGE ((UINTN)(1) << PAGE=5FHUGE=5FSHI=46T) > +=23define PAGE=5FHGLOBAL ((UINTN)(1) << PAGE=5FHGLOBAL=5FSHI=46T) > +=23define PAGE=5FNO=5FREAD ((UINTN)(1) << PAGE=5FNO=5FREAD=5FSHI=46T) > +=23define PAGE=5FNO=5FEXEC ((UINTN)(1) << PAGE=5FNO=5FEXEC=5FSHI=46T) > +=23define PAGE=5FRPLV ((UINTN)(1) << PAGE=5FRPLV=5FSHI=46T) > +=23define CACHE=5FMASK ((UINTN)(3) << CACHE=5FSHI=46T) > +=23define P=46N=5FSHI=46T (E=46I=5FPAGE=5FSHI=46T - 12 + PAGE=5FP=46N=5F= SHI=46T) > + > +=23define PLV=5FKERNEL 0 > +=23define PLV=5FUSER 3 > + > +=23define PAGE=5FUSER (PLV=5FUSER << PAGE=5FPLV=5FSHI=46T) > +=23define PAGE=5FKERNEL (PLV=5FKERN << PAGE=5FPLV=5FSHI=46T) > + > +=23define CACHE=5FSUC (0 << CACHE=5FSHI=46T) /* Strong-ordered UnCache= d */ > +=23define CACHE=5FCC (1 << CACHE=5FSHI=46T) /* Coherent Cached */ > +=23define CACHE=5FWUC (2 << CACHE=5FSHI=46T) /* Weak-ordered UnCached = */ > +=23endif // PTE=5FH=5F > -- > 2.31.1 --636e190d_24bd76bf_1e57b Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline
Reviewed-by: Chao Li  <lichao=40loongson.cn>


Thanks,
Chao
--------

On 11=E6=9C=88 11 2= 022, at 5:12 =E4=B8=8B=E5=8D=88, xianglai li <lixianglai=40loongson.cn= > wrote:
Read the memory map information th= rough the Qemu=46wCfg interface,

then build the page table = through the memory map information,

and finally enable Mmu.=



RE=46: https://bugzilla.tianocore.org/show=5Fbug.c= gi=3Fid=3D4054



Cc: Bibo Mao <maobibo=40loongson.= cn>

Cc: Chao Li <lichao=40loongson.cn>

Cc: Leif Lindholm <quic=5Fllindhol=40quicinc.com>

= Cc: Liming Gao <gaoliming=40byosoft.com.cn>

Cc: Micha= el D Kinney <michael.d.kinney=40intel.com>

Signed-off= -by: xianglai li <lixianglai=40loongson.cn>

---
=
.../LoongArchQemuPkg/Include/Library/MmuLib.h =7C 85 ++
.../LoongArchQemuPkg/Library/MmuLib/Mmu.S =7C 155 ++++

.../Library/MmuLib/MmuBaseLib.inf =7C 40 +
.../Library/Mm= uLib/MmuBaseLibPei.inf =7C 47 +

.../Library/MmuLib/MmuLibCo= re.c =7C 831 ++++++++++++++++++

.../Library/MmuLib/MmuLibCo= re.h =7C 40 +

.../Library/MmuLib/MmuLibCorePei.c =7C 231 ++= +++

.../LoongArchQemuPkg/Library/MmuLib/mmu.h =7C 190 ++++<= /div>
.../LoongArchQemuPkg/Library/MmuLib/page.h =7C 280 ++++++
.../LoongArchQemuPkg/Library/MmuLib/pte.h =7C 57 ++
10 files changed, 1956 insertions(+)

create mode 1006= 44 Platform/Loongson/LoongArchQemuPkg/Include/Library/MmuLib.h

<= div>create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/= Mmu.S

create mode 100644 Platform/Loongson/LoongArchQemuPkg= /Library/MmuLib/MmuBaseLib.inf

create mode 100644 Platform/= Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseLibPei.inf

= create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuL= ibCore.c

create mode 100644 Platform/Loongson/LoongArchQemu= Pkg/Library/MmuLib/MmuLibCore.h

create mode 100644 Platform= /Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCorePei.c

c= reate mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/mmu.h=

create mode 100644 Platform/Loongson/LoongArchQemuPkg/Libr= ary/MmuLib/page.h

create mode 100644 Platform/Loongson/Loon= gArchQemuPkg/Library/MmuLib/pte.h



diff --git a/Plat= form/Loongson/LoongArchQemuPkg/Include/Library/MmuLib.h b/Platform/Loongs= on/LoongArchQemuPkg/Include/Library/MmuLib.h

new file mode = 100644

index 0000000000..9880fc385c

--- /dev/= null

+++ b/Platform/Loongson/LoongArchQemuPkg/Include/Libra= ry/MmuLib.h

=40=40 -0,0 +1,85 =40=40

+/** =40= file

+

+ Copyright (c) 2022 Loongson Technolo= gy Corporation Limited. All rights reserved.<BR>

+
+ SPDX-License-Identifier: BSD-2-Clause-Patent

= +

+ =40par Glossary:

+ - EXC - execute
<= br>
+**/

+=23ifndef MMU=5FLIB=5FH=5F

+=23= define MMU=5FLIB=5FH=5F

+/**

+ write operatio= n is performed Count times from the first element of Buffer.

+ Convert E=46I Attributes to Loongarch Attributes.

+ =40= param=5Bin=5D EfiAttributes Efi Attributes.

+

+ =40retval LoongArch Attributes.

+**/

+UINT= N

+EfiAttributeToLoongArchAttribute (

+ IN UI= NTN EfiAttributes

+ );

+

+/**
+ =46inds the length and memory properties of the memory reg= ion corresponding to the specified base address.

+
+ =40param=5Bin=5D BaseAddress To find the base address of the memo= ry region.

+ =40param=5Bin=5D EndAddress To find the end ad= dress of the memory region.

+ =40param=5Bout=5D RegionLengt= h The length of the memory region found.

+ =40param=5Bout=5D= RegionAttributes Properties of the memory region found.

+<= /div>
+ =40retval E=46I=5FSUCCESS The corresponding memory area w= as successfully found

+ E=46I=5FNOT=5F=46OUND No memory are= a found

+**/

+E=46I=5FSTATUS

+G= etLoongArchMemoryRegion (

+ IN UINTN BaseAddress,

=
+ IN UINTN EndAddress,

+ OUT UINTN *RegionLength,
+ OUT UINTN *RegionAttributes

+ );

= +

+/**

+ Sets the Attributes of the specified= memory region

+

+ =40param=5Bin=5D BaseAddre= ss The base address of the memory region to set the Attributes.

=
+ =40param=5Bin=5D Length The length of the memory region to set the= Attributes.

+ =40param=5Bin=5D Attributes The Attributes t= o be set.

+

+ =40retval E=46I=5FSUCCESS The A= ttributes was set successfully

+**/

+E=46I=5F= STATUS

+LoongArchSetMemoryAttributes (

+ IN E= =46I=5FPHYSICAL=5FADDRESS BaseAddress,

+ IN UINTN Length,
+ IN UINTN Attributes

+ );

+
+/**

+ Sets the non-executable Attributes for th= e specified memory region

+

+ =40param=5Bin=5D= BaseAddress The base address of the memory region to set the Attributes.=

+ =40param=5Bin=5D Length The length of the memory region = to set the Attributes.

+

+ =40retval E=46I=5F= SUCCESS The Attributes was set successfully

+**/

<= div>+E=46I=5FSTATUS

+LoongArchSetMemoryRegionNoExec (
=
+ IN E=46I=5FPHYSICAL=5FADDRESS BaseAddress,

+ IN = UINTN Length

+ );

+

+/**
<= br>
+ Create a page table and initialize the MMU.

+
+ =40param=5B=5D VOID

+

+ =40retva= l VOID

+**/

+VOID

+E=46IAPI
+ConfigureMmu (

+ VOID

+ );
<= br>
+=23endif // MMU=5FLIB=5FH=5F

diff --git a/Platform= /Loongson/LoongArchQemuPkg/Library/MmuLib/Mmu.S b/Platform/Loongson/Loong= ArchQemuPkg/Library/MmuLib/Mmu.S

new file mode 100644
=
index 0000000000..d5863de072

--- /dev/null
+++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mmu.S
=40=40 -0,0 +1,155 =40=40

+=23-------------------= -----------------------------------------------------------

+=23

+=23 LoongArch for LoongArch

+=23
=
+=23 Copyright (c) 2022 Loongson Technology Corporation Limited.= All rights reserved.<BR>

+=23

+=23 SPD= X-License-Identifier: BSD-2-Clause-Patent

+=23

+=23-------------------------------------------------------------------= ----------

+

+=23ifndef =5F=5FASSEMBLY=5F=5F<= /div>
+=23define =5F=5FASSEMBLY=5F=5F

+=23endif
+

+=23include =22Library/Cpu.h=22

= +=23include =22mmu.h=22

+

+ASM=5FGLOBAL ASM=5F= P=46X(HandleTlbRefill)

+ASM=5FGLOBAL HandleTlbRefillEnd
+ASM=5FGLOBAL ASM=5FP=46X(LoongarchInvalidTlb)

+= ASM=5FGLOBAL ASM=5FP=46X(SetTlbRefill=46uncBase)

+ASM=5FGLO= BAL ASM=5FP=46X(WriteCsrPageSize)

+ASM=5FGLOBAL ASM=5FP=46X= (WriteCsrTlbRefillPageSize)

+ASM=5FGLOBAL ASM=5FP=46X(Write= CsrStlbPageSize)

+ASM=5FGLOBAL ASM=5FP=46X(LoongArchWriteqC= srPwctl0)

+ASM=5FGLOBAL ASM=5FP=46X(LoongArchWriteqCsrPwctl= 1)

+ASM=5FGLOBAL ASM=5FP=46X(LoongArchWriteqCsrPgdl)
<= br>
+ASM=5FGLOBAL ASM=5FP=46X(LoongArchWriteqCsrPgdh)

+= ASM=5FGLOBAL ASM=5FP=46X(LoongArchXchgCsrCrmd)

+

<= div>+=23

+=23 Refill the page table.

+=23 =40= param VOID

+=23 =40retval VOID

+=23

=
+

+ASM=5FP=46X(HandleTlbRefill):

+ csrwr= T0, LOONGARCH=5FCSR=5FTLBRSAVE

+ csrrd T0, LOONGARCH=5FCSR= =5FPGD

+ lddir T0, T0, 3 =23Put pud BaseAddress into T0
+ lddir T0, T0, 2 =23Put pmd BaseAddress into T0

+ lddir T0, T0, 1 =23Put pte BaseAddress into T0

+ ldpte T= 0, 0

+ ldpte T0, 1

+ tlbfill

+ = csrrd T0, LOONGARCH=5FCSR=5FTLBRSAVE

+ ertn

+= HandleTlbRefillEnd:

+

+=23

+=23= Invalid corresponding TLB entries are based on the address given
+=23 =40param A0 The address corresponding to the invalid page tab= le entry

+=23 =40retval none

+=23

+

+ASM=5FP=46X(LoongarchInvalidTlb):

+ inv= tlb INVTLB=5FADDR=5FGTRUE=5FOR=5FASID, ZERO, A0

+ jirl ZERO= , RA, 0

+

+=23

+=23 Set Tlb Ref= ill function to hardware

+=23 =40param A0 The address of tl= b refill function

+=23 =40retval none

+=23
+

+ASM=5FP=46X(SetTlbRefill=46uncBase):
+ csrwr A0, LOONGARCH=5FCSR=5FTLBREBASE

+ jirl ZERO,= RA,0

+

+=23

+=23 Set Cpu Statu= s Register Page Size.

+=23 =40param A0 Page Size.

=
+=23 =40retval none

+=23

+

+ASM=5FP=46X(WriteCsrPageSize):

+ li.d T0, CSR=5FTLBIDX=5F= SIZE

+ sll.d A0, A0, T0

+ li.d T0, CSR=5FTLBI= DX=5FSIZE=5FMASK

+ csrxchg A0, T0, LOONGARCH=5FCSR=5FTLBIDX=

+ jirl ZERO, RA,0

+

+=23
=
+=23 Set Cpu Status Register TLBRE=46ILL Page Size.

+=23 =40param A0 Page Size.

+=23 =40retval none

=
+=23

+

+ASM=5FP=46X(WriteCsrTlbRefillPag= eSize):

+ li.d T0, CSR=5FTLBREHI=5FPS=5FSHI=46T

+ sll.d A0, A0, T0

+ li.d T0, CSR=5FTLBREHI=5FPS
+ csrxchg A0, T0, LOONGARCH=5FCSR=5FTLBREHI

+ jirl Z= ERO, RA,0

+

+=23

+=23 Set Cpu S= tatus Register STLB Page Size.

+=23 =40param val Page Size.=

+=23 =40retval VOID

+=23

+
+ASM=5FP=46X(WriteCsrStlbPageSize):

+ csrwr A0, = LOONGARCH=5FCSR=5FSTLBPGSIZE

+ jirl ZERO, RA,0

+

+=23

+=23 Write Csr PWCTL0 register.
+=23 =40param A0 The value used to write to the PWCTL0 register=

+=23 =40retval none

+=23

+
+ASM=5FP=46X(LoongArchWriteqCsrPwctl0):

+ csrwr = A0, LOONGARCH=5FCSR=5FPWCTL0

+ jirl ZERO, RA,0

+

+=23

+=23 Write Csr PWCTL1 register.
+=23 =40param A0 The value used to write to the PWCTL1 register=

+=23 =40retval none

+=23

+
+ASM=5FP=46X(LoongArchWriteqCsrPwctl1):

+ csrwr = A0, LOONGARCH=5FCSR=5FPWCTL1

+ jirl ZERO, RA,0

+

+=23

+=23 Write Csr PGDL register.
<= br>
+=23 =40param A0 The value used to write to the PGDL register
+=23 =40retval none

+=23

+
+ASM=5FP=46X(LoongArchWriteqCsrPgdl):

+ csrwr A0, LO= ONGARCH=5FCSR=5FPGDL

+ jirl ZERO, RA,0

+
+=23

+=23 Write Csr PGDH register.

= +=23 =40param A0 The value used to write to the PGDH register

+=23 =40retval none

+=23

+

+= ASM=5FP=46X(LoongArchWriteqCsrPgdh):

+ csrwr A0, LOONGARCH=5F= CSR=5FPGDH

+ jirl ZERO, RA,0

+

= +=23

+=23 Exchange specified bit data with the Csr CRMD reg= ister.

+=23 =40param=5BIN=5D A0 The value Exchanged with th= e CSR CRMD register.

+=23 =40param=5BIN=5D A1 Specifies the= mask for swapping bits

+=23 =40retval VOID

+= =23

+

+ASM=5FP=46X(LoongArchXchgCsrCrmd):
+ csrxchg A0, A1, LOONGARCH=5FCSR=5FCRMD

+ jirl = ZERO, RA,0

diff --git a/Platform/Loongson/LoongArchQemuPkg/= Library/MmuLib/MmuBaseLib.inf b/Platform/Loongson/LoongArchQemuPkg/Librar= y/MmuLib/MmuBaseLib.inf

new file mode 100644

= index 0000000000..abd864a324

--- /dev/null

++= + b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseLib.inf
=40=40 -0,0 +1,40 =40=40

+=23=23 =40file
+=23

+=23 Copyright (c) 2022 Loongson Technology Corp= oration Limited. All rights reserved.<BR>

+=23
<= br>
+=23 SPDX-License-Identifier: BSD-2-Clause-Patent

+= =23

+=23=23

+

+=5BDefines=5D
+ IN=46=5FVERSION =3D 0x00010005

+ BASE=5FNAME = =3D MmuBaseLib

+ =46ILE=5FGUID =3D da8f0232-fb14-42f0-922c-= 63104d2c70be

+ MODULE=5FTYPE =3D BASE

+ VERSI= ON=5FSTRING =3D 1.0

+ LIBRARY=5FCLASS =3D MmuLib

<= div>+ CONSTRUCTOR =3D MmuInitialize

+

+=23
+=23 VALID=5FARCHITECTURES =3D LOONGARCH64

+=23=

+

+=5BSources=5D

+ MmuLibCore.= c

+ Mmu.S

+

+=5BPackages=5D
+ MdePkg/MdePkg.dec

+ Platform/Loongson/LoongArc= hQemuPkg/Loongson.dec

+

+=5BPCD=5D

<= div>+ gLoongArchQemuPkgTokenSpaceGuid.PcdSwapPageDir

+ gLoo= ngArchQemuPkgTokenSpaceGuid.PcdInvalidPgd

+ gLoongArchQemuP= kgTokenSpaceGuid.PcdInvalidPud

+ gLoongArchQemuPkgTokenSpac= eGuid.PcdInvalidPmd

+ gLoongArchQemuPkgTokenSpaceGuid.PcdIn= validPte

+

+=5BLibraryClasses=5D

+ MemoryAllocationLib

+ PcdLib

+ DebugLib
diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuL= ib/MmuBaseLibPei.inf b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/= MmuBaseLibPei.inf

new file mode 100644

index = 0000000000..12848eecfe

--- /dev/null

+++ b/Pl= atform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseLibPei.inf
=40=40 -0,0 +1,47 =40=40

+=23=23 =40file

+=23

+=23 Copyright (c) 2022 Loongson Technology Corpora= tion Limited. All rights reserved.<BR>

+=23

=
+=23 SPDX-License-Identifier: BSD-2-Clause-Patent

+=23=

+=23=23

+

+=5BDefines=5D
=
+ IN=46=5FVERSION =3D 0x00010005

+ BASE=5FNAME =3D= MmuPeiLib

+ =46ILE=5FGUID =3D da8f0232-fb14-42f0-922c-6310= 4d2c70bd

+ MODULE=5FTYPE =3D BASE

+ VERSION=5F= STRING =3D 1.0

+ LIBRARY=5FCLASS =3D MmuLib =7C SEC PEIM
+

+=23

+=23 VALID=5FARCHITECTURES= =3D LOONGARCH64

+=23

+

+=5BSou= rces=5D

+ MmuLibCorePei.c

+ Mmu.S

+ MmuLibCore.h

+ MmuLibCore.c

+

<= div>+=5BPackages=5D

+ MdePkg/MdePkg.dec

+ Pla= tform/Loongson/LoongArchQemuPkg/Loongson.dec

+ OvmfPkg/Ovmf= Pkg.dec

+

+=5BPCD=5D

+ gLoongAr= chQemuPkgTokenSpaceGuid.PcdSwapPageDir

+ gLoongArchQemuPkgT= okenSpaceGuid.PcdInvalidPgd

+ gLoongArchQemuPkgTokenSpaceGu= id.PcdInvalidPud

+ gLoongArchQemuPkgTokenSpaceGuid.PcdInval= idPmd

+ gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPte
=
+ gLoongArchQemuPkgTokenSpaceGuid.Pcd=46lashSec=46vSize
+ gLoongArchQemuPkgTokenSpaceGuid.Pcd=46lashSec=46vBase

+ gLoongArchQemuPkgTokenSpaceGuid.PcdRamSize

+

=
+=5BLibraryClasses=5D

+ MemoryAllocationLib

<= div>+ CacheMaintenanceLib

+ PcdLib

+ DebugLib=

+ Qemu=46wCfgLib

diff --git a/Platform/Loong= son/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.c b/Platform/Loongson/Loon= gArchQemuPkg/Library/MmuLib/MmuLibCore.c

new file mode 1006= 44

index 0000000000..b932e3d568

--- /dev/null=

+++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mm= uLibCore.c

=40=40 -0,0 +1,831 =40=40

+/** =40= file

+

+ Copyright (c) 2022 Loongson Technolo= gy Corporation Limited. All rights reserved.<BR>

+
+ SPDX-License-Identifier: BSD-2-Clause-Patent

= +

+ =40par Glossary:

+ - Pgd or Pgd or PGD - = Page Global Directory

+ - Pud or Pud or PUD - Page Upper Di= rectory

+ - Pmd or Pmd or PMD - Page Middle Directory
=
+ - Pte or pte or PTE - Page Table Entry

+ - Val o= r VAL or val - Value

+ - Dir - Directory

+**/=

+=23include <Uefi.h>

+=23include <L= ibrary/BaseMemoryLib.h>

+=23include <Library/MemoryAl= locationLib.h>

+=23include <Library/BaseLib.h>
+=23include <Library/DebugLib.h>

+=23inclu= de =22Library/Cpu.h=22

+=23include =22pte.h=22

+=23include =22page.h=22

+=23include =22mmu.h=22
+

+BOOLEAN mMmuInited =3D =46ALSE;

+/**=

+ Check to see if mmu successfully initializes.

<= div>+

+ =40param VOID.

+

+ =40r= etval TRUE Initialization has been completed.

+ =46ALSE Ini= tialization did not complete.

+**/

+BOOLEAN
+MmuIsInit (VOID) =7B

+ if ((mMmuInited =3D=3D= TRUE) =7C=7C

+ (PcdGet64 (PcdSwapPageDir) =21=3D 0)) =7B
+ return TRUE;

+ =7D

+ return =46= ALSE;

+=7D

+

+/**

+ Iterates through the page directory to initialize it.

+<= /div>
+ =40param Dst A pointer to the directory of the page to in= itialize.

+ =40param Num The number of page directories to = initialize.

+ =40param Src A pointer to the data used to in= itialize the page directory.

+

+ =40retval VO= ID.

+**/

+VOID

+PageDirInit (
+ IN VOID *Dst,

+ IN UINTN Num,

= + IN VOID *Src

+ )

+=7B

+ UINTN= *Ptr;

+ UINTN *End;

+ UINTN Entry;

=
+

+ Entry =3D (UINTN)Src;

+ Ptr =3D (UIN= TN *)Dst;

+ End =3D Ptr + Num;

+

+ for ( ;Ptr < End; Ptr++) =7B

+ *Ptr =3D Entry;
=
+ =7D

+

+ return ;

+=7D=

+

+/**

+ Gets the virtual addr= ess corresponding to the page global directory table entry.

+

+ =40param Address the virtual address for the table ent= ry.

+

+ =40retval PGD A pointer to get the ta= ble item.

+**/

+PGD *

+PgdOffse= t (

+ IN UINTN Address

+ )

+=7B=

+ return ((PGD *)PcdGet64 (PcdSwapPageDir)) + PGD=5FINDEX = (Address);

+=7D

+

+/**
+ Gets the virtual address corresponding to the page upper director= y table entry.

+

+ =40param Pgd A pointer to = a page global directory table entry.

+ =40param Address the= virtual address for the table entry.

+

+ =40= retval PUD A pointer to get the table item.

+**/

<= div>+PUD *

+PudOffset (

+ IN PGD *Pgd,
<= br>
+ IN UINTN Address

+ )

+=7B

=
+ UINTN PgdVal =3D (UINTN)PGD=5FVAL (*Pgd);

+ return (= PUD *)PgdVal + PUD=5FINDEX (Address);

+=7D

+<= /div>
+/**

+ Gets the virtual address corresponding= to the page middle directory table entry.

+

= + =40param Pud A pointer to a page upper directory table entry.

=
+ =40param Address the virtual address for the table entry.
+

+ =40retval PMD A pointer to get the table item.
+**/

+PMD *

+PmdOffset (
+ IN PUD *Pud,

+ IN UINTN Address

+ )
+=7B

+ UINTN PudVal =3D PUD=5FVAL (*Pud);
+ return (PMD *)PudVal + PMD=5FINDEX (Address);

+= =7D

+

+/**

+ Gets the virtual a= ddress corresponding to the page table entry.

+

+ =40param Pmd A pointer to a page middle directory table entry.
=
+ =40param Address the virtual address for the table entry.
+

+ =40retval PTE A pointer to get the table item= .

+**/

+PTE *

+PteOffset (
+ IN PMD *Pmd,

+ IN UINTN Address

+= )

+=7B

+ UINTN PmdVal =3D (UINTN)PMD=5FVAL (= *Pmd);

+ return (PTE *)PmdVal + PTE=5FINDEX (Address);
+=7D

+

+/**

+ Sets th= e value of the page table entry.

+

+ =40param= Pte A pointer to a page table entry.

+ =40param PteVal The= value of the page table entry to set.

+

+ =40= retval VOID

+**/

+VOID

+SetPte = (

+ IN PTE *Pte,

+ IN PTE PteVal

+ )

+=7B

+ *Pte =3D PteVal;

+= =7D

+

+/**

+ Sets the value of = the page global directory.

+

+ =40param Pgd A= pointer to a page global directory.

+ =40param Pud The val= ue of the page global directory to set.

+

+ =40= retval VOID

+**/

+VOID

+SetPgd = (

+ IN PGD *Pgd,

+ IN PUD *Pud

= + )

+=7B

+ *Pgd =3D (PGD) =7B((UINTN)Pud)=7D;=

+=7D

+

+/**

+ Se= ts the value of the page upper directory.

+

+= =40param Pud A pointer to a page upper directory.

+ =40par= am Pmd The value of the page upper directory to set.

+
+ =40retval VOID

+**/

+VOID
+SetPud (

+ IN PUD *Pud,

+ IN PMD *Pmd=

+ )

+=7B

+ *Pud =3D (PUD) =7B(= (UINTN)Pmd)=7D;

+=7D

+

+/**
+ Sets the value of the page middle directory.

+=

+ =40param Pmd A pointer to a page middle directory.
=
+ =40param Pte The value of the page middle directory to set.
+

+ =40retval VOID

+**/

=
+VOID

+SetPmd (

+ IN PMD *Pmd,

=
+ IN PTE *Pte

+ )

+=7B

+ *= Pmd =3D (PMD) =7B((UINTN)Pte)=7D;

+=7D

+
+/**

+ =46ree up memory space occupied by page ta= bles.

+

+ =40param Pte A pointer to the page = table.

+

+ =40retval VOID

+**/<= /div>
+VOID

+Pte=46ree (

+ IN PTE *Pt= e

+ )

+=7B

+ =46reePages ((VOID= *)Pte, 1);

+=7D

+

+/**
+ =46ree up memory space occupied by page middle directory.
<= br>
+

+ =40param Pmd A pointer to the page middle direc= tory.

+

+ =40retval VOID

+**/
+VOID

+Pmd=46ree (

+ IN PMD *Pmd=

+ )

+=7B

+ =46reePages ((VOID = *)Pmd, 1);

+=7D

+

+/**
+ =46ree up memory space occupied by page upper directory.
+

+ =40param Pud A pointer to the page upper director= y.

+

+ =40retval VOID

+**/
+VOID

+Pud=46ree (

+ IN PUD *Pud
+ )

+=7B

+ =46reePages ((VOID *)P= ud, 1);

+=7D

+

+/**

+ Requests the memory space required for the page upper directory,
+ initializes it, and places it in the specified page global d= irectory

+

+ =40param Pgd A pointer to the pa= ge global directory.

+

+ =40retval E=46I=5FSU= CCESS Memory request successful.

+ =40retval E=46I=5FOUT=5F= O=46=5FRESOURCES Resource exhaustion cannot be requested to memory.
=
+**/

+INTN

+PudAlloc (

+ IN PGD *Pgd

+ )

+=7B

+ PUD *= Pud =3D (PUD *) AllocatePages (1);

+ if (=21Pud) =7B
<= br>
+ return E=46I=5FOUT=5FO=46=5FRESOURCES;

+ =7D
+

+ PageDirInit ((VOID *)Pud, ENTRYS=5FPER=5FPUD,= (VOID *)PcdGet64 (PcdInvalidPmd));

+

+ if (p= gd=5Fnone (*Pgd)) =7B

+ SetPgd (Pgd, Pud);

+ = =7D else =7B /* Another has populated it */

+ Pud=46ree (Pu= d);

+ =7D

+

+ return E=46I=5FSU= CCESS;

+=7D

+

+/**

+ Requests the memory space required for the page middle directory,
+ initializes it, and places it in the specified page upper di= rectory

+

+ =40param Pud A pointer to the pag= e upper directory.

+

+ =40retval E=46I=5FSUCC= ESS Memory request successful.

+ =40retval E=46I=5FOUT=5FO=46= =5FRESOURCES Resource exhaustion cannot be requested to memory.

=
+**/

+E=46I=5FSTATUS

+PmdAlloc (
+ IN PUD *Pud

+ )

+=7B

+= PMD *Pmd;

+

+ Pmd =3D (PMD *) AllocatePages = (1);

+ if (=21Pmd) =7B

+ return E=46I=5FOUT=5F= O=46=5FRESOURCES;

+ =7D

+

+ Pag= eDirInit ((VOID *)Pmd, ENTRYS=5FPER=5FPMD, (VOID *)PcdGet64 (PcdInvalidPt= e));

+

+ if (pud=5Fnone (*Pud)) =7B

=
+ SetPud (Pud, Pmd);

+ =7D else =7B/* Another has popu= lated it */

+ Pmd=46ree (Pmd);

+ =7D
+

+ return E=46I=5FSUCCESS;

+=7D
<= br>
+

+/**

+ Requests the memory space re= quired for the page table,

+ initializes it, and places it = in the specified page middle directory

+

+ =40= param Pmd A pointer to the page middle directory.

+
+ =40retval E=46I=5FSUCCESS Memory request successful.

+ =40retval E=46I=5FOUT=5FO=46=5FRESOURCES Resource exhaustion cannot = be requested to memory.

+**/

+INTN

<= div>+PteAlloc (

+ IN PMD *Pmd

+ )

+=7B

+ PTE *Pte;

+

+ Pte =3D= (PTE *) AllocatePages (1);

+ if (=21Pte) =7B

+ return E=46I=5FOUT=5FO=46=5FRESOURCES;

+ =7D

+

+ Pte =3D ZeroMem (Pte, E=46I=5FPAGE=5FSIZE);
+

+ if (pmd=5Fnone (*Pmd)) =7B

+ SetPmd= (Pmd, Pte);

+ =7D else =7B /* Another has populated it */<= /div>
+ Pte=46ree (Pte);

+ =7D

+
+ return E=46I=5FSUCCESS;

+=7D

+
+/**

+ Requests the memory space required for t= he page upper directory,

+ initializes it, and places it in= the specified page global directory,

+ and get the page up= per directory entry corresponding to the virtual address

+<= /div>
+ =40param Pgd A pointer to the page global directory.
+

+ =40retval Gets the page upper directory entry=

+**/

+PUD *

+PudAllocGet (
+ IN PGD *Pgd,

+ IN UINTN Address

= + )

+=7B

+ return ((pgd=5Fnone (*(Pgd)) &= & PudAlloc (Pgd)) =3F

+ NULL : PudOffset (Pgd, Address)= );

+=7D

+

+/**

+ = Requests the memory space required for the page middle directory,
+ initializes it, and places it in the specified page upper direct= ory,

+ and get the page middle directory entry correspondin= g to the virtual address

+

+ =40param Pud A p= ointer to the page upper directory.

+

+ =40re= tval Gets the page middle directory entry

+**/

+PMD *

+PmdAllocGet (

+ IN PUD *Pud,
<= br>
+ IN UINTN Address

+ )

+=7B

=
+ PMD * ret =3D (pud=5Fnone (*Pud) && PmdAlloc (Pud))=3F
+ NULL: PmdOffset (Pud, Address);

+ DEBUG ((DEBU= G=5FVERBOSE, =22%a %d PudVal %p PmdOffset %p PMD=5FINDEX %p .=5Cn=22, =5F= =5Ffunc=5F=5F, =5F=5FLINE=5F=5F,

+ Pud->PudVal, PmdOffse= t (Pud, Address), PMD=5FINDEX (Address) ));

+

+ return ret;

+=7D

+

+/**
+ Requests the memory space required for the page table,
<= br>
+ initializes it, and places it in the specified page middle dire= ctory,

+ and get the page table entry corresponding to the = virtual address

+

+ =40param Pmd A pointer to= the page upper directory.

+

+ =40retval Gets= the page table entry

+**/

+PTE *

+PteAllocGet (

+ IN PMD *Pmd,

+ IN UINTN A= ddress

+ )

+=7B

+ return (pmd=5F= none (*Pmd) && PteAlloc (Pmd))=3F

+ NULL: PteOffset= (Pmd, Address);

+=7D

+

+/**
+ Gets the physical address of the page table entry correspon= ding to the specified virtual address.

+

+ =40= param Address the corresponding virtual address of the page table entry.<= /div>
+

+ =40retval A pointer to the page table ent= ry.

+ =40retval NULL

+**/

+PTE = *

+GetPteAddress (

+ IN UINTN Address
+ )

+=7B

+ PGD *Pgd;

+ P= UD *Pud;

+ PMD *Pmd;

+

+ Pgd =3D= PgdOffset (Address);

+

+ if (pgd=5Fnone (*Pg= d)) =7B

+ return NULL;

+ =7D

+<= /div>
+ Pud =3D PudOffset (Pgd, Address);

+
+ if (pud=5Fnone (*Pud)) =7B

+ return NULL;
+ =7D

+

+ Pmd =3D PmdOffset (Pud, Addre= ss);

+ if (pmd=5Fnone (*Pmd)) =7B

+ return NU= LL;

+ =7D

+

+ if (IS=5FHUGE=5FP= AGE (Pmd->PmdVal)) =7B

+ return ((PTE *)Pmd);

<= div>+ =7D

+

+ return PteOffset (Pmd, Address)= ;

+=7D

+

+/**

+ E= stablishes a page table entry based on the specified memory region.
=
+

+ =40param Pmd A pointer to the page middle dire= ctory.

+ =40param Address The memory space start address.
+ =40param End The end address of the memory space.
+ =40param Attributes Memory space Attributes.

+
+ =40retval E=46I=5FSUCCESS The page table entry was created su= ccessfully.

+ =40retval E=46I=5FOUT=5FO=46=5FRESOURCES Page= table entry establishment failed due to resource exhaustion.

+**/

+E=46I=5FSTATUS

+MemoryMapPteRange (<= /div>
+ IN PMD *Pmd,

+ IN UINTN Address,

<= div>+ IN UINTN End,

+ IN UINTN Attributes

+ )=

+=7B

+ PTE *Pte;

+ PTE PteVal;=

+ BOOLEAN UpDate;

+

+ Pte =3D = PteAllocGet (Pmd, Address);

+ if (=21Pte) =7B

+ return E=46I=5FOUT=5FO=46=5FRESOURCES;

+ =7D

+

+ do =7B

+ UpDate =3D =46ALSE;

=
+ PteVal =3D MAKE=5FPTE (Address, Attributes);

+ DEBUG= ((DEBUG=5FVERBOSE,

+ =22%a %d Address %p PGD=5FINDEX %p PU= D=5FINDEX %p PMD=5FINDEX %p PTE=5FINDEX %p MAKE=5FPTE %p=5Cn=22,
+ =5F=5Ffunc=5F=5F, =5F=5FLINE=5F=5F, Address, PGD=5FINDEX (Address= ), PUD=5FINDEX (Address), PMD=5FINDEX (Address),

+ PTE=5FIN= DEX (Address), PteVal));

+

+ if ((=21pte=5Fno= ne (*Pte)) &&

+ (PTE=5FVAL(*Pte) =21=3D PTE=5FVAL(P= teVal)))

+ =7B

+ UpDate =3D TRUE;

+ =7D

+

+ SetPte (Pte, PteVal);

<= div>+ if (UpDate) =7B

+ LoongarchInvalidTlb(Address);
=
+ =7D

+ =7D while (Pte++, Address +=3D E=46I=5FPAG= E=5FSIZE, Address =21=3D End);

+

+ return E=46= I=5FSUCCESS;

+=7D

+

+/**
<= br>
+ Establishes a page middle directory based on the specified memo= ry region.

+

+ =40param Pud A pointer to the = page upper directory.

+ =40param Address The memory space s= tart address.

+ =40param End The end address of the memory = space.

+ =40param Attributes Memory space Attributes.
=
+

+ =40retval E=46I=5FSUCCESS The page middle dire= ctory was created successfully.

+ =40retval E=46I=5FOUT=5FO= =46=5FRESOURCES Page middle directory establishment failed due to resourc= e exhaustion.

+**/

+E=46I=5FSTATUS

<= div>+MemoryMapPmdRange (

+ IN PUD *Pud,

+ IN = UINTN Address,

+ IN UINTN End,

+ IN UINTN Att= ributes

+ )

+=7B

+ PMD *Pmd;
+ PTE *Pte;

+ UINTN Next;

+ UINTN= AddressStart=5FHugePage;

+ UINTN AddressEnd=5FHugePage;
+

+ Pmd =3D PmdAllocGet (Pud, Address);
+ if (=21Pmd) =7B

+ return E=46I=5FOUT=5FO=46=5FRESO= URCES;

+ =7D

+

+ do =7B
+ Next =3D PMD=5FADDRESS=5FEND (Address, End);

+ if = (((Address & (=7EPMD=5FMASK)) =3D=3D 0) &&

+ ((= Next & (=7EPMD=5FMASK)) =3D=3D 0) &&

+ (pmd=5Fn= one (*Pmd)))

+ =7B

+ DEBUG ((DEBUG=5FVERBOSE,=

+ =22%a %d Address %p PGD=5FINDEX %p PUD=5FINDEX %p PMD=5F= INDEX %p MAKE=5FHUGE=5FPTE %p=5Cn=22,

+ =5F=5Ffunc=5F=5F, =5F= =5FLINE=5F=5F, Address, PGD=5FINDEX (Address), PUD=5FINDEX (Address), PMD= =5FINDEX (Address),

+ MAKE=5FHUGE=5FPTE (Address, Attribute= s)));

+

+ SetPmd (Pmd, (PTE *)MAKE=5FHUGE=5FP= TE (Address, Attributes));

+ =7D else =7B

+ i= f ((pmd=5Fnone (*Pmd)) =7C=7C

+ ((=21pmd=5Fnone (*Pmd)) &am= p;&

+ (=21IS=5FHUGE=5FPAGE (Pmd->PmdVal))))
+ =7B

+ if (MemoryMapPteRange (Pmd, Address, Next, At= tributes)) =7B

+ return E=46I=5FOUT=5FO=46=5FRESOURCES;
+ =7D

+ =7D else =7B

+ SetPmd (Pmd= , (PTE *)PcdGet64 (PcdInvalidPte));

+ AddressStart=5FHugePa= ge =3D Address & PMD=5FMASK;

+ AddressEnd=5FHugePage =3D= AddressStart=5FHugePage + HUGE=5FPAGE=5FSIZE;

+ if (Memory= MapPteRange (Pmd, AddressStart=5FHugePage, AddressEnd=5FHugePage, Attribu= tes)) =7B

+ return E=46I=5FOUT=5FO=46=5FRESOURCES;
+ =7D

+ Pte =3D GetPteAddress (AddressStart=5FHugePag= e);

+ if (Pte =3D=3D NULL) =7B

+ continue ;
+ =7D

+ if (AddressEnd=5FHugePage > End) =7B=

+ Next =3D End;

+ =7D

+ =7D
+ =7D

+ =7D while (Pmd++, Address =3D Next, Add= ress =21=3D End);

+

+ return 0;

+=7D

+

+/**

+ Establishes a pa= ge upper directory based on the specified memory region.

+<= /div>
+ =40param Pgd A pointer to the page global directory.
+ =40param Address The memory space start address.

+ =40param End The end address of the memory space.

+ =40= param Attributes Memory space Attributes.

+

+= =40retval E=46I=5FSUCCESS The page upper directory was created successfu= lly.

+ =40retval E=46I=5FOUT=5FO=46=5FRESOURCES Page upper = directory establishment failed due to resource exhaustion.

= +**/

+E=46I=5FSTATUS

+MemoryMapPudRange (
+ IN PGD *Pgd,

+ IN UINTN Address,

+ IN UINTN End,

+ IN UINTN Attributes

+ )
+=7B

+ PUD *Pud;

+ UINTN Next;
+

+ Pud =3D PudAllocGet (Pgd, Address);
+ if (=21Pud) =7B

+ return E=46I=5FOUT=5FO=46=5FRESO= URCES;

+ =7D

+

+ do =7B
+ Next =3D PUD=5FADDRESS=5FEND (Address, End);

+ if = (MemoryMapPmdRange (Pud, Address, Next, Attributes)) =7B

+ = return E=46I=5FOUT=5FO=46=5FRESOURCES;

+ =7D

= + =7D while (Pud++, Address =3D Next, Address =21=3D End);

= + return E=46I=5FSUCCESS;

+=7D

+

+/**

+ Establishes a page global directory based on the s= pecified memory region.

+

+ =40param Start Th= e memory space start address.

+ =40param End The end addres= s of the memory space.

+ =40param Attributes Memory space A= ttributes.

+

+ =40retval E=46I=5FSUCCESS The = page global directory was created successfully.

+ =40retval= E=46I=5FOUT=5FO=46=5FRESOURCES Page global directory establishment faile= d due to resource exhaustion.

+**/

+E=46I=5FS= TATUS

+MemoryMapPageRange (

+ IN UINTN Start,=

+ IN UINTN End,

+ IN UINTN Attributes
<= br>
+ )

+=7B

+ PGD *Pgd;

+ = UINTN Next;

+ UINTN Address =3D Start;

+ E=46= I=5FSTATUS Err;

+

+ Pgd =3D PgdOffset (Addres= s);

+ do =7B

+ Next =3D PGD=5FADDRESS=5FEND (= Address, End);

+ Err =3D MemoryMapPudRange (Pgd, Address, N= ext, Attributes);

+ if (Err) =7B

+ return Err= ;

+ =7D

+ =7D while (Pgd++, Address =3D Next,= Address =21=3D End);

+

+ return E=46I=5FSUCC= ESS;

+=7D

+

+/**

= + Page tables are established from memory-mapped tables.

+<= /div>
+ =40param MemoryRegion A pointer to a memory-mapped table = entry.

+

+ =40retval E=46I=5FSUCCESS The page= table was created successfully.

+ =40retval E=46I=5FOUT=5F= O=46=5FRESOURCES Page table establishment failed due to resource exhausti= on.

+**/

+E=46I=5FSTATUS

+=46il= lTranslationTable (

+ IN MEMORY=5FREGION=5FDESCRIPTOR *Memo= ryRegion

+ )

+=7B

+ return Memo= ryMapPageRange (MemoryRegion->VirtualBase,

+ (MemoryRegi= on->Length + MemoryRegion->VirtualBase),

+ MemoryRegi= on->Attributes);

+=7D

+

+/**=

+ write operation is performed Count times from the first = element of Buffer.

+ Convert E=46I Attributes to Loongarch = Attributes.

+ =40param=5Bin=5D EfiAttributes Efi Attributes= .

+

+ =40retval LoongArch Attributes.
+**/

+UINTN

+EfiAttributeToLoongArchAt= tribute (

+ IN UINTN EfiAttributes

+ )
<= br>
+=7B

+ UINTN LoongArchAttributes =3D PAGE=5FVALID =7C= PAGE=5FDIRTY =7C CACHE=5FCC =7C PAGE=5FUSER =7C PAGE=5FGLOBAL;

=
+ switch (EfiAttributes & E=46I=5FMEMORY=5FCACHETYPE=5FMASK) =7B=

+ case E=46I=5FMEMORY=5FUC:

+ LoongArchAttri= butes =7C=3D CACHE=5FSUC;

+ break;

+ case E=46= I=5FMEMORY=5FWC:

+ case E=46I=5FMEMORY=5FWT:

= + case E=46I=5FMEMORY=5FWB:

+ LoongArchAttributes =7C=3D CA= CHE=5FCC;

+ break;

+ default :

= + LoongArchAttributes =7C=3D CACHE=5FCC;

+ break;

=
+ =7D

+

+ // Write protection attributes=

+ if ((EfiAttributes & E=46I=5FMEMORY=5FRO) =21=3D 0) = =7B

+ LoongArchAttributes &=3D =7EPAGE=5FDIRTY;
+ =7D

+

+ //eXecute protection attribu= te

+ if ((EfiAttributes & E=46I=5FMEMORY=5FXP) =21=3D 0= ) =7B

+ LoongArchAttributes =7C=3D PAGE=5FNO=5FEXEC;
<= br>
+ =7D

+

+ return LoongArchAttributes;=

+=7D

+

+/**

+ =46= inds the length and memory properties of the memory region corresponding = to the specified base address.

+

+ =40param=5B= in=5D BaseAddress To find the base address of the memory region.
+ =40param=5Bin=5D EndAddress To find the end address of the memory= region.

+ =40param=5Bout=5D RegionLength The length of the= memory region found.

+ =40param=5Bout=5D RegionAttributes = Properties of the memory region found.

+

+ =40= retval E=46I=5FSUCCESS The corresponding memory area was successfully fou= nd

+ E=46I=5FNOT=5F=46OUND No memory area found

+**/

+E=46I=5FSTATUS

+GetLoongArchMemoryRe= gion (

+ IN UINTN BaseAddress,

+ IN UINTN End= Address,

+ OUT UINTN *RegionLength,

+ OUT UIN= TN *RegionAttributes

+ )

+=7B

+= PTE *Pte;

+ UINTN Attributes;

+ UINTN Attrib= utesTmp;

+ UINTN MaxAddress;

+ MaxAddress =3D= LShiftU64 (1ULL, MAX=5FVA=5FBITS) - 1;

+ Pte =3D GetPteAdd= ress (BaseAddress);

+

+ if (=21MmuIsInit ()) = =7B

+ return E=46I=5FSUCCESS;

+ =7D

=
+ if (Pte =3D=3D NULL) =7B

+ return E=46I=5FNOT=5F=46O= UND;

+ =7D

+ Attributes =3D GET=5FPAGE=5FATTR= IBUTES (*Pte);

+ if (IS=5FHUGE=5FPAGE (Pte->PteVal)) =7B=

+ *RegionAttributes =3D Attributes & (=7E(PAGE=5FHUGE)= );

+ *RegionLength +=3D HUGE=5FPAGE=5FSIZE;

+= =7D else =7B

+ *RegionLength +=3D E=46I=5FPAGE=5FSIZE;
+ *RegionAttributes =3D Attributes;

+ =7D
<= br>
+

+ while (BaseAddress <=3D MaxAddress) =7B
+ Pte =3D GetPteAddress (BaseAddress);

+ if (Pte = =3D=3D NULL) =7B

+ return E=46I=5FSUCCESS;

+ = =7D

+ AttributesTmp =3D GET=5FPAGE=5FATTRIBUTES (*Pte);
+ if (IS=5FHUGE=5FPAGE (Pte->PteVal)) =7B

+ i= f (AttributesTmp =3D=3D Attributes) =7B

+ *RegionLength +=3D= HUGE=5FPAGE=5FSIZE;

+ =7D

+ BaseAddress +=3D= HUGE=5FPAGE=5FSIZE;

+ =7D else =7B

+ if (Att= ributesTmp =3D=3D Attributes) =7B

+ *RegionLength +=3D E=46= I=5FPAGE=5FSIZE;

+ =7D

+ BaseAddress +=3D E=46= I=5FPAGE=5FSIZE;

+ =7D

+

+ if (= BaseAddress > EndAddress) =7B

+ break;

+ =7D=

+ =7D

+ return E=46I=5FSUCCESS;

+=7D

+

+/**

+ Sets the Attrib= utes of the specified memory region

+

+ =40pa= ram=5Bin=5D BaseAddress The base address of the memory region to set the = Attributes.

+ =40param=5Bin=5D Length The length of the mem= ory region to set the Attributes.

+ =40param=5Bin=5D Attrib= utes The Attributes to be set.

+

+ =40retval = E=46I=5FSUCCESS The Attributes was set successfully

+**/
+E=46I=5FSTATUS

+LoongArchSetMemoryAttributes (=

+ IN E=46I=5FPHYSICAL=5FADDRESS BaseAddress,

+ IN UINTN Length,

+ IN UINTN Attributes

+ )=

+=7B

+

+ if (=21MmuIsInit ()) = =7B

+ return E=46I=5FSUCCESS;

+ =7D

=
+ Attributes =3D EfiAttributeToLoongArchAttribute (Attributes);
+ DEBUG ((DEBUG=5FVERBOSE, =22%a %d %p %p %p.=5Cn=22, =5F=5Ffun= c=5F=5F, =5F=5FLINE=5F=5F, BaseAddress , Length, Attributes));

<= div>+ MemoryMapPageRange (BaseAddress, BaseAddress + Length, Attributes);=

+

+ return E=46I=5FSUCCESS;

+=7D=

+

+/**

+ Sets the non-executab= le Attributes for the specified memory region

+

+ =40param=5Bin=5D BaseAddress The base address of the memory region t= o set the Attributes.

+ =40param=5Bin=5D Length The length = of the memory region to set the Attributes.

+

+ =40retval E=46I=5FSUCCESS The Attributes was set successfully
+**/

+E=46I=5FSTATUS

+LoongArchSetMemor= yRegionNoExec (

+ IN E=46I=5FPHYSICAL=5FADDRESS BaseAddress= ,

+ IN UINTN Length

+ )

+=7B
+ if (MmuIsInit ()) =7B

+ Length =3D E=46I=5FPA= GES=5FTO=5FSIZE (E=46I=5FSIZE=5FTO=5FPAGES (Length));

+ Loo= ngArchSetMemoryAttributes (BaseAddress, Length, E=46I=5FMEMORY=5FXP);
+ =7D

+ return E=46I=5FSUCCESS;

+=7D=

+

+/**

+ Check to see if mmu s= uccessfully initializes and saves the result.

+

+ =40param VOID.

+

+ =40retval E=46I=5FSUC= CESS Initialization succeeded.

+**/

+E=46I=5F= STATUS

+MmuInitialize (VOID)

+=7B

+ if (PcdGet64 (PcdSwapPageDir) =21=3D 0) =7B

+ mMmuInit= ed =3D TRUE;

+ =7D

+

+ return E= =46I=5FSUCCESS;

+=7D

diff --git a/Platform/Lo= ongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.h b/Platform/Loongson/L= oongArchQemuPkg/Library/MmuLib/MmuLibCore.h

new file mode 1= 00644

index 0000000000..7a5e8ea0dd

--- /dev/n= ull

+++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib= /MmuLibCore.h

=40=40 -0,0 +1,40 =40=40

+/** =40= file

+

+ Copyright (c) 2022 Loongson Technolo= gy Corporation Limited. All rights reserved.<BR>

+
+ SPDX-License-Identifier: BSD-2-Clause-Patent

= +

+ =40par Glossary:

+ - Dir - Directory
+**/

+=23ifndef MMU=5FLIB=5FCORE=5FH=5F

=
+=23define MMU=5FLIB=5FCORE=5FH=5F

+/**

= + Iterates through the page directory to initialize it.

+
+ =40param Dst A pointer to the directory of the page to ini= tialize.

+ =40param Num The number of page directories to i= nitialize.

+ =40param Src A pointer to the data used to ini= tialize the page directory.

+

+ =40retval VOI= D.

+**/

+VOID

+PageDirInit (
+ IN VOID *dest,

+ IN UINTN Count,

+ IN VOID *src

+ );

+

+/**
+ Page tables are established from memory-mapped tables.
+

+ =40param MemoryRegion A pointer to a memory-m= apped table entry.

+

+ =40retval E=46I=5FSUCC= ESS The page table was created successfully.

+ =40retval E=46= I=5FOUT=5FO=46=5FRESOURCES Page table establishment failed due to resourc= e exhaustion.

+**/

+E=46I=5FSTATUS

<= div>+=46illTranslationTable (

+ IN MEMORY=5FREGION=5FDESCRI= PTOR *MemoryRegion

+ );

+=23endif // MMU=5FLI= B=5FCORE=5FH=5F

diff --git a/Platform/Loongson/LoongArchQem= uPkg/Library/MmuLib/MmuLibCorePei.c b/Platform/Loongson/LoongArchQemuPkg/= Library/MmuLib/MmuLibCorePei.c

new file mode 100644
index 0000000000..32a7fc0beb

--- /dev/null

=
+++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCorePe= i.c

=40=40 -0,0 +1,231 =40=40

+/** =40file
+ Platform PEI driver

+

+ Copyrig= ht (c) 2022 Loongson Technology Corporation Limited. All rights reserved.= <BR>

+

+ SPDX-License-Identifier: BSD-2= -Clause-Patent

+

+ =40par Glossary:

=
+ - =46wCfg - =46irmeware Config

+ - Tlb - Translation= Lookaside Buffer

+**/

+=23include <Uefi.h= >

+=23include <Library/BaseMemoryLib.h>

<= div>+=23include <Library/MemoryAllocationLib.h>

+=23i= nclude <Library/BaseLib.h>

+=23include <Library/De= bugLib.h>

+=23include =22Library/Cpu.h=22

= +=23include =22pte.h=22

+=23include =22page.h=22

<= div>+=23include =22mmu.h=22

+=23include <Library/Qemu=46= wCfgLib.h>

+=23include =22MmuLibCore.h=22

= +=23include <Library/CacheMaintenanceLib.h>

+
+/**

+ Return the Virtual Memory Map of your platfor= m

+

+ This Virtual Memory Map is used by Memo= ryInitPei Module to initialize the MMU

+ on your platform.<= /div>
+

+ =40param=5Bout=5D VirtualMemoryMap Array = of MEMORY=5FREGION=5FDESCRIPTOR

+ describing a Physical-to-= Virtual Memory

+ mapping. This array must be ended by a
+ zero-filled entry. The allocated memory

+ will= not be freed.

+**/

+VOID

+GetM= emoryMap=46rom=46wCfg (

+ OUT MEMORY=5FREGION=5FDESCRIPTOR = **VirtualMemoryMap

+ )

+=7B

+
+ E=46I=5FSTATUS Status;

+ =46IRMWARE=5FCON=46= IG=5FITEM =46wCfgItem;

+ UINTN =46wCfgSize;

+= LOONGARCH=5FMEMMAP=5FENTRY MemoryMapEntry;

+ LOONGARCH=5FM= EMMAP=5FENTRY *StartEntry;

+ LOONGARCH=5FMEMMAP=5FENTRY *pE= ntry;

+ UINTN Processed;

+ MEMORY=5FREGION=5F= DESCRIPTOR *VirtualMemoryTable;

+ UINTN Index =3D 0;
<= br>
+ ASSERT (VirtualMemoryMap =21=3D NULL);

+
+ VirtualMemoryTable =3D AllocatePool (

+ sizeof (MEM= ORY=5FREGION=5FDESCRIPTOR) *

+ MAX=5FVIRTUAL=5FMEMORY=5FMAP= =5FDESCRIPTORS

+ );

+ VirtualMemoryTable=5BIn= dex=5D.PhysicalBase =3D 0x10000000;

+ VirtualMemoryTable=5B= Index=5D.VirtualBase =3D VirtualMemoryTable=5BIndex=5D.PhysicalBase;
+ VirtualMemoryTable=5BIndex=5D.Length =3D 0x10000000;
+ VirtualMemoryTable=5BIndex=5D.Attributes =3D PAGE=5FVALID =7C PLV= =5FKERNEL =7C CACHE=5FSUC =7C PAGE=5FDIRTY =7C PAGE=5FGLOBAL;

+ ++Index;

+

+ Status =3D Qemu=46wCfg=46in= d=46ile (=22etc/memmap=22, &=46wCfgItem, &=46wCfgSize);

=
+ if (E=46I=5FERROR (Status)) =7B

+ DEBUG ((DEBUG=5FER= ROR, =22%a %d read etc/memmap error Status %d =5Cn=22, =5F=5Ffunc=5F=5F, = =5F=5FLINE=5F=5F, Status));

+ ZeroMem (&VirtualMemoryTa= ble=5BIndex=5D, sizeof (MEMORY=5FREGION=5FDESCRIPTOR));

+ *= VirtualMemoryMap =3D VirtualMemoryTable;

+ return ;
+ =7D

+ if (=46wCfgSize % sizeof MemoryMapEntry =21=3D= 0) =7B

+ DEBUG ((DEBUG=5FERROR, =22no MemoryMapEntry =46wC= fgSize:%d=5Cn=22, =46wCfgSize));

+ =7D

+
+ Qemu=46wCfgSelectItem (=46wCfgItem);

+ StartEnt= ry =3D AllocatePages (E=46I=5FSIZE=5FTO=5FPAGES (=46wCfgSize));

=
+ Qemu=46wCfgReadBytes (=46wCfgSize, StartEntry);

+ fo= r (Processed =3D 0; Processed < (=46wCfgSize / sizeof MemoryMapEntry);= Processed++) =7B

+ pEntry =3D StartEntry + Processed;
+ if (pEntry->Length =3D=3D 0) =7B

+ continue;=

+ =7D

+

+ DEBUG ((DEBUG=5FIN=46= O, =22MemmapEntry Base %p length %p type %d=5Cn=22, pEntry->BaseAddr, = pEntry->Length, pEntry->Type));

+ VirtualMemoryTable=5B= Index=5D.PhysicalBase =3D pEntry->BaseAddr;

+ VirtualMem= oryTable=5BIndex=5D.VirtualBase =3D VirtualMemoryTable=5BIndex=5D.Physica= lBase;

+ VirtualMemoryTable=5BIndex=5D.Length =3D pEntry-&g= t;Length;

+ VirtualMemoryTable=5BIndex=5D.Attributes =3D PA= GE=5FVALID =7C PLV=5FKERNEL =7C CACHE=5FCC =7C PAGE=5FDIRTY =7C PAGE=5FGL= OBAL;

+ ++Index;

+ =7D

+
<= br>
+ =46reePages (StartEntry, E=46I=5FSIZE=5FTO=5FPAGES (=46wCfgSize= ));

+ // End of Table

+ ZeroMem (&Virtual= MemoryTable=5BIndex=5D, sizeof (MEMORY=5FREGION=5FDESCRIPTOR));

=
+ *VirtualMemoryMap =3D VirtualMemoryTable;

+ return ;=

+=7D

+

+/**

+ Cr= eate a page table and initialize the MMU.

+

+= =40param=5B=5D VOID

+

+ =40retval VOID
=
+**/

+E=46IAPI

+VOID

+= ConfigureMmu (VOID)

+=7B

+ PGD *SwapperPageDi= r =3D NULL;

+ PGD *InvalidPgd =3D NULL;

+ PUD= *InvalidPudTable =3D NULL;

+ PMD *InvalidPmdTable =3D NULL= ;

+ PTE *InvalidPteTable =3D NULL;

+ MEMORY=5F= REGION=5FDESCRIPTOR *MemoryTable =3D NULL;

+ RETURN=5FSTATU= S PcdStatus;

+ UINTN PgdShift =3D PGD=5FSHI=46T;

<= div>+ UINTN PgdWide =3D PGD=5FWIDE;

+ UINTN PudShift =3D PU= D=5FSHI=46T;

+ UINTN PudWide =3D PUD=5FWIDE;

= + UINTN PmdShift =3D PMD=5FSHI=46T;

+ UINTN PmdWide =3D PMD= =5FWIDE;

+ UINTN PteShift =3D PTE=5FSHI=46T;

= + UINTN PteWide =3D PTE=5FWIDE;

+ UINTN PageEnable =3D 1 &l= t;< 4;

+ VOID *TlbReEntry;

+

+ SwapperPageDir =3D AllocatePages (E=46I=5FSIZE=5FTO=5FPAGES (PGD=5FTAB= LE=5FSIZE));

+ InvalidPgd =3D AllocatePages (E=46I=5FSIZE=5F= TO=5FPAGES (PGD=5FTABLE=5FSIZE));

+ InvalidPudTable =3D All= ocatePages (E=46I=5FSIZE=5FTO=5FPAGES (PUD=5FTABLE=5FSIZE));

+ InvalidPmdTable =3D AllocatePages (E=46I=5FSIZE=5FTO=5FPAGES (PMD=5FT= ABLE=5FSIZE));

+ InvalidPteTable =3D AllocatePages (E=46I=5F= SIZE=5FTO=5FPAGES (PTE=5FTABLE=5FSIZE));

+ ZeroMem (Invalid= PteTable, PTE=5FTABLE=5FSIZE);

+

+ if ((=21In= validPgd) =7C=7C

+ (=21InvalidPudTable) =7C=7C

+ (=21InvalidPmdTable) =7C=7C

+ (=21InvalidPteTable))
+ =7B

+ goto =46reeTranslationTable;

+ =7D

+

+ /*pgd init*/

+ Pag= eDirInit (SwapperPageDir , ENTRYS=5FPER=5FPGD, InvalidPudTable);
+ /*pgd init*/

+ PageDirInit (InvalidPgd, ENTRYS=5FPE= R=5FPGD, InvalidPudTable);

+ /*pud init*/

+ P= ageDirInit (InvalidPudTable, ENTRYS=5FPER=5FPUD, InvalidPmdTable);
<= br>
+ /*pmd init*/

+ PageDirInit (InvalidPmdTable, ENTR= YS=5FPER=5FPMD, InvalidPteTable);

+ GetMemoryMap=46rom=46wC= fg (&MemoryTable);

+

+ PcdStatus =7C=3D P= cdSet64S (PcdSwapPageDir, (UINTN)SwapperPageDir);

+ PcdStat= us =7C=3D PcdSet64S (PcdInvalidPgd, (UINTN)InvalidPgd);

+ P= cdStatus =7C=3D PcdSet64S (PcdInvalidPud, (UINTN)InvalidPudTable);
<= br>
+ PcdStatus =7C=3D PcdSet64S (PcdInvalidPmd, (UINTN)InvalidPmdTab= le);

+ PcdStatus =7C=3D PcdSet64S (PcdInvalidPte, (UINTN)In= validPteTable);

+ ASSERT=5FRETURN=5FERROR (PcdStatus);
+

+ while (MemoryTable->Length =21=3D 0) =7B
+ DEBUG ((DEBUG=5FVERBOSE, =22%a %d VirtualBase %p VirtualEn= d %p Attributes %p .=5Cn=22, =5F=5Ffunc=5F=5F, =5F=5FLINE=5F=5F,
+ MemoryTable->VirtualBase,

+ (MemoryTable->Len= gth + MemoryTable->VirtualBase),

+ MemoryTable->Attri= butes));

+

+ PcdStatus =3D =46illTranslationT= able (MemoryTable);

+ if (E=46I=5FERROR (PcdStatus)) =7B
+ goto =46reeTranslationTable;

+ =7D

<= div>+ MemoryTable++;

+ =7D

+

+ = TlbReEntry =3D AllocatePages (1);

+ if (TlbReEntry =3D=3D N= ULL) =7B

+ goto =46reeTranslationTable;

+ =7D=

+ CopyMem ((char *)TlbReEntry, HandleTlbRefill, (HandleTlb= RefillEnd - HandleTlbRefill));

+ InvalidateInstructionCache= Range ((VOID *)(UINTN)HandleTlbRefill, (UINTN)(HandleTlbRefillEnd - Handl= eTlbRefill));

+

+ DEBUG ((DEBUG=5FVERBOSE,
+ =22%a %d PteShift %d PteWide %d PmdShift %d PmdWide %d PudS= hift %d PudWide %d PgdShift %d PgdWide %d.=5Cn=22,

+ =5F=5F= func=5F=5F, =5F=5FLINE=5F=5F,

+ PteShift, PteWide, PmdShift= , PmdWide,PudShift, PudWide, PgdShift, PgdWide));

+
+ SetTlbRefill=46uncBase ((UINTN)TlbReEntry);

+ /*se= t page size*/

+ WriteCsrPageSize (DE=46AULT=5FPAGE=5FSIZE);=

+ WriteCsrStlbPageSize (DE=46AULT=5FPAGE=5FSIZE);
+ WriteCsrTlbRefillPageSize (DE=46AULT=5FPAGE=5FSIZE);

+

+ LoongArchWriteqCsrPwctl0 ((PteShift =7C PteWide <&= lt; 5 =7C PmdShift << 10 =7C PmdWide << 15 =7C PudShift <&= lt; 20 =7C PudWide << 25

+ ));

+ LoongA= rchWriteqCsrPwctl1 (PgdShift =7C PgdWide << 6);

+ Loo= ngArchWriteqCsrPgdl ((UINTN)SwapperPageDir);

+ LoongArchWri= teqCsrPgdh ((UINTN)InvalidPgd);

+

+ DEBUG ((D= EBUG=5FIN=46O, =22%a %d Enable Mmu Start PageBassAddress %p.=5Cn=22, =5F=5F= func=5F=5F, =5F=5FLINE=5F=5F, SwapperPageDir));

+ LoongArch= XchgCsrCrmd ( PageEnable, 1 << 4);

+ DEBUG ((DEBUG=5F= IN=46O, =22%a %d Enable Mmu End.=5Cn=22, =5F=5Ffunc=5F=5F, =5F=5FLINE=5F=5F= ));

+

+ return ;

+

+=46reeTranslationTable:

+ if (SwapperPageDir) =7B
<= br>
+ =46reePages (SwapperPageDir, E=46I=5FSIZE=5FTO=5FPAGES (PGD=5FT= ABLE=5FSIZE));

+ =7D

+

+ if (In= validPgd) =7B

+ =46reePages (InvalidPgd, E=46I=5FSIZE=5FTO=5F= PAGES (PGD=5FTABLE=5FSIZE));

+ =7D

+
+ if (InvalidPudTable) =7B

+ =46reePages (InvalidPudT= able, E=46I=5FSIZE=5FTO=5FPAGES (PUD=5FTABLE=5FSIZE));

+ =7D=

+

+ if (InvalidPmdTable) =7B

+= =46reePages (InvalidPmdTable, E=46I=5FSIZE=5FTO=5FPAGES (PMD=5FTABLE=5FS= IZE));

+ =7D

+

+ if (InvalidPte= Table) =7B

+ =46reePages (InvalidPteTable, E=46I=5FSIZE=5FT= O=5FPAGES (PTE=5FTABLE=5FSIZE));

+ =7D

+
+ PcdSet64S (PcdSwapPageDir, (UINTN)0);

+ PcdSet6= 4S (PcdInvalidPgd, (UINTN)0);

+ PcdSet64S (PcdInvalidPud, (= UINTN)0);

+ PcdSet64S (PcdInvalidPmd, (UINTN)0);

<= div>+ PcdSet64S (PcdInvalidPte, (UINTN)0);

+

= + return ;

+=7D

diff --git a/Platform/Loongso= n/LoongArchQemuPkg/Library/MmuLib/mmu.h b/Platform/Loongson/LoongArchQemu= Pkg/Library/MmuLib/mmu.h

new file mode 100644

index 0000000000..8e284a2ecd

--- /dev/null

+= ++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/mmu.h

=40=40 -0,0 +1,190 =40=40

+/** =40file

+
+ Copyright (c) 2022 Loongson Technology Corporation Limited.= All rights reserved.<BR>

+

+ SPDX-Lice= nse-Identifier: BSD-2-Clause-Patent

+

+ =40pa= r Glossary:

+ - Tlb or TLB - Translation Lookaside Buffer
+ - CSR - Cpu State Register

+ - PGDL - Page G= lobal Directory Low

+ - PGDH - Page Global Directory High
+ - TLBIDX - TLB Index

+ - TLBREHI - TLB Refil= l Entry High

+ - PWCTL - Page Walk Control

+ = - STLB - Singular Page Size TLB

+ - PS - Page Size
+**/

+=23ifndef MMU=5FH=5F

+=23define M= MU=5FH=5F

+/*page size 4k*/

+=23define DE=46A= ULT=5FPAGE=5FSIZE 0x0c

+=23define LOONGARCH=5FCSR=5FPGDL 0x= 19 /* Page table base address when VA=5B47=5D =3D 0 */

+=23= define LOONGARCH=5FCSR=5FPGDH 0x1a /* Page table base address when VA=5B4= 7=5D =3D 1 */

+=23define LOONGARCH=5FCSR=5FTLBIDX 0x10 /* T= LB Index, EHINV, PageSize, NP */

+=23define LOONGARCH=5FCSR= =5FTLBEHI 0x11 /* TLB EntryHi */

+=23define LOONGARCH=5FCSR= =5FTLBELO0 0x12 /* TLB EntryLo0 */

+=23define LOONGARCH=5FC= SR=5FTLBELO1 0x13 /* TLB EntryLo1 */

+=23define LOONGARCH=5F= CSR=5FTLBREHI 0x8e /* TLB refill entryhi */

+=23define LOON= GARCH=5FCSR=5FPWCTL0 0x1c /* PWCtl0 */

+=23define LOONGARCH= =5FCSR=5FPWCTL1 0x1d /* PWCtl1 */

+=23define LOONGARCH=5FCS= R=5FSTLBPGSIZE 0x1e

+=23define CSR=5FTLBIDX=5FSIZE=5FMASK 0= x3f000000

+=23define CSR=5FTLBIDX=5FPS=5FSHI=46T 24
+=23define CSR=5FTLBIDX=5FSIZE CSR=5FTLBIDX=5FPS=5FSHI=46T
+

+=23define CSR=5FTLBREHI=5FPS=5FSHI=46T 0
+=23define CSR=5FTLBREHI=5FPS 0x3f

+

+=23= define E=46I=5FMEMORY=5FCACHETYPE=5FMASK (E=46I=5FMEMORY=5FUC =7C =5C
+ E=46I=5FMEMORY=5FWC =7C =5C

+ E=46I=5FMEMORY=5F= WT =7C =5C

+ E=46I=5FMEMORY=5FWB =7C =5C

+ E=46= I=5FMEMORY=5FUCE =5C

+ )

+

+typ= edef struct =7B

+ E=46I=5FPHYSICAL=5FADDRESS PhysicalBase;<= /div>
+ E=46I=5FVIRTUAL=5FADDRESS VirtualBase;

+ UI= NTN Length;

+ UINTN Attributes;

+=7D MEMORY=5F= REGION=5FDESCRIPTOR;

+

+// The total number o= f descriptors, including the final =22end-of-table=22 descriptor.
+=23define MAX=5FVIRTUAL=5FMEMORY=5FMAP=5FDESCRIPTORS (128)
<= br>
+

+extern CHAR8 HandleTlbRefill=5B=5D, HandleTlbRef= illEnd=5B=5D;

+

+/*

+ Invalid c= orresponding TLB entries are based on the address given

+
+ =40param Address The address corresponding to the invalid = page table entry

+

+ =40retval none

=
+*/

+extern

+VOID

+Loongar= chInvalidTlb (

+ UINTN Address

+ );

=
+

+/*

+ Set Tlb Refill function to hardw= are

+

+ =40param A0 The address of tlb refill= function

+

+ =40retval none

+*= /

+extern

+VOID

+SetTlbRefill=46= uncBase (

+ UINTN Address

+ );

= +

+/*

+ Set Cpu Status Register Page Size.
+

+ =40param PageSize Page Size.

= +

+ =40retval none

+*/

+extern<= /div>
+VOID

+WriteCsrPageSize (

+ UIN= TN PageSize

+ );

+

+/*
+ Set Cpu Status Register TLBRE=46ILL Page Size.

+
+ =40param PageSize Page Size.

+

= + =40retval none

+*/

+extern

+V= OID

+WriteCsrTlbRefillPageSize (

+ UINTN Page= Size

+ );

+

+/*

+= Set Cpu Status Register STLB Page Size.

+

+ = =40param PageSize Page Size.

+

+ =40retval VO= ID

+*/

+extern

+VOID

<= div>+WriteCsrStlbPageSize (

+ UINTN PageSize

= +);

+

+/*

+ Write Csr PWCTL0 re= gister.

+

+ =40param Val The value used to wr= ite to the PWCTL0 register

+

+ =40retval none=

+*/

+extern

+VOID

+LoongArchWriteqCsrPwctl0 (

+ UINTN Val

+ )= ;

+

+/*

+ Write Csr PWCTL1 regi= ster.

+

+ =40param Val The value used to writ= e to the PWCTL1 register

+

+ =40retval none
+*/

+extern

+VOID

= +LoongArchWriteqCsrPwctl1 (

+ UINTN Val

+ );<= /div>
+

+/*

+ Write Csr PGDL register= .

+

+ =40param Val The value used to write to= the PGDL register

+

+ =40retval none
+*/

+extern

+VOID

+Loong= ArchWriteqCsrPgdl (

+ UINTN Val

+ );
+

+/*

+ Write Csr PGDH register.
<= br>
+

+ =40param Val The value used to write to the PGD= H register

+

+ =40retval none

+= */

+extern

+VOID

+LoongArchWrit= eqCsrPgdh (

+ UINTN Val

+ );

+<= /div>
+/*

+ Exchange specified bit data with the Cs= r CRMD register.

+

+ =40param=5BIN=5D Val The= value Exchanged with the CSR CRMD register.

+ =40param=5BI= N=5D Mask Specifies the mask for swapping bits

+

<= div>+ =40retval VOID

+*/

+extern

+VOID

+LoongArchXchgCsrCrmd (

+ UINTN Val,<= /div>
+ UINTN Mask

+ );

+

+=23endif // MMU=5FH=5F

diff --git a/Platform/Loongson/L= oongArchQemuPkg/Library/MmuLib/page.h b/Platform/Loongson/LoongArchQemuPk= g/Library/MmuLib/page.h

new file mode 100644

= index 0000000000..6ab07e7900

--- /dev/null

++= + b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/page.h

=40=40 -0,0 +1,280 =40=40

+/** =40file

+
+ Copyright (c) 2022 Loongson Technology Corporation Limited.= All rights reserved.<BR>

+

+ SPDX-Lice= nse-Identifier: BSD-2-Clause-Patent

+

+ =40pa= r Glossary:

+ - Pgd or Pgd or PGD - Page Global Directory
+ - Pud or Pud or PUD - Page Upper Directory

+= - Pmd or Pmd or PMD - Page Middle Directory

+ - Pte or pte= or PTE - Page Table Entry

+ - Val or VAL or val - Value
+ - Dir - Directory

+**/

+=23ifnd= ef PAGE=5FH=5F

+=23define PAGE=5FH=5F

+
=
+=23define MAX=5FVA=5FBITS 47

+=23define PGD=5FWID= E (8)

+=23define PUD=5FWIDE (9)

+=23define PM= D=5FWIDE (9)

+=23define PTE=5FWIDE (9)

+
+=23define ENTRYS=5FPER=5FPGD (1 << PGD=5FWIDE)

=
+=23define ENTRYS=5FPER=5FPUD (1 << PUD=5FWIDE)

= +=23define ENTRYS=5FPER=5FPMD (1 << PMD=5FWIDE)

+=23d= efine ENTRYS=5FPER=5FPTE (1 << PTE=5FWIDE)

+
+=23define PGD=5FSHI=46T (PUD=5FSHI=46T + PUD=5FWIDE)

+=23define PUD=5FSHI=46T (PMD=5FSHI=46T + PMD=5FWIDE)

+=23= define PMD=5FSHI=46T (E=46I=5FPAGE=5FSHI=46T + PTE=5FWIDE)

= +=23define PTE=5FSHI=46T (E=46I=5FPAGE=5FSHI=46T)

+
+=23define PGD=5FSIZE (1UL << PGD=5FSHI=46T)

+= =23define PUD=5FSIZE (1UL << PUD=5FSHI=46T)

+=23defin= e PMD=5FSIZE (1UL << PMD=5FSHI=46T)

+

+= =23define PGD=5FMASK (=7E(PGD=5FSIZE-1))

+=23define PUD=5FM= ASK (=7E(PUD=5FSIZE-1))

+=23define PMD=5FMASK (=7E(PMD=5FSI= ZE-1))

+=23define PAGE=5FMASK (=7E(E=46I=5FPAGE=5FSIZE - 1)= )

+=23define P=46N=5FMASK (=7E(((UINTN)(1) << (E=46I=5F= PAGE=5FSHI=46T)) - 1) & =5C

+ (((UINTN)(1) << (PA= GE=5FP=46N=5FEND=5FSHI=46T)) - 1))

+

+typedef= struct =7B UINTN PgdVal; =7D PGD;

+typedef struct =7B UINT= N PudVal; =7D PUD;

+typedef struct =7B UINTN PmdVal; =7D PM= D;

+typedef struct =7B UINTN PteVal; =7D PTE;

+/**

+ Gets the value of the page global directory table e= ntry.

+

+ =40param x Page global directory st= ruct variables.

+

+ =40retval the value of th= e page global directory table entry.

+ **/

+=23= define PGD=5FVAL(x) ((x).PgdVal)

+/**

+ Gets = the value of the page upper directory table entry.

+
<= br>
+ =40param x Page upper directory struct variables.

+

+ =40retval the value of the page upper directory table = entry.

+ **/

+=23define PUD=5FVAL(x) ((x).Pud= Val)

+/**

+ Gets the value of the page middle= directory table entry.

+

+ =40param x Page m= iddle directory struct variables.

+

+ =40retv= al the value of the page middle directory table entry.

+ **= /

+=23define PMD=5FVAL(x) ((x).PmdVal)

+/**
+ Gets the value of the page table entry.

+
+ =40param x Page table entry struct variables.

+

+ =40retval the value of the page table entry.

=
+ **/

+=23define PTE=5FVAL(x) ((x).PteVal)

+

+=23define PGD=5FTABLE=5FSIZE (ENTRYS=5FPER=5FPGD * si= zeof(PGD))

+=23define PUD=5FTABLE=5FSIZE (ENTRYS=5FPER=5FPU= D * sizeof(PUD))

+=23define PMD=5FTABLE=5FSIZE (ENTRYS=5FPE= R=5FPMD * sizeof(PMD))

+=23define PTE=5FTABLE=5FSIZE (ENTRY= S=5FPER=5FPTE * sizeof(PTE))

+/**

+ Gets the = physical address of the record in the page table entry.

+
+ =40param x Page table entry struct variables.

+

+ =40retval the value of the physical address.
+ **/

+=23define GET=5FPAGE=5FATTRIBUTES(x) (UINTN) =7B= (PTE=5FVAL(x) & =7EP=46N=5FMASK)=7D

+/**

= + Gets the virtual address of the next block of the specified virtual add= ress

+ that is aligned with the size of the global page dir= ectory mapping.

+

+ =40param Address Specifie= s the virtual address.

+ =40param End The end address of th= e memory region.

+

+ =40retval the specified = virtual address of the next block.

+ **/

+=23= define PGD=5FADDRESS=5FEND(Address, End) =5C

+(=7B =5C
+ UINTN Boundary =3D ((Address) + PGD=5FSIZE) & PGD=5FMASK;= =5C

+ (Boundary - 1 < (End) - 1)=3F Boundary: (End); =5C=

+=7D)

+/**

+ Gets the virtual = address of the next block of the specified virtual address

= + that is aligned with the size of the page upper directory mapping.
+

+ =40param Address Specifies the virtual addres= s.

+ =40param End The end address of the memory region.
+

+ =40retval the specified virtual address of t= he next block.

+ **/

+=23define PUD=5FADDRESS= =5FEND(Address, End) =5C

+(=7B =5C

+ UINTN Bo= undary =3D ((Address) + PUD=5FSIZE) & PUD=5FMASK; =5C

+= (Boundary - 1 < (End) - 1)=3F Boundary: (End); =5C

+=7D= )

+/**

+ Gets the virtual address of the next= block of the specified virtual address

+ that is aligned w= ith the size of the page middle directory mapping.

+
<= br>
+ =40param Address Specifies the virtual address.

+= =40param End The end address of the memory region.

+
=
+ =40retval the specified virtual address of the next block.
+ **/

+=23define PMD=5FADDRESS=5FEND(Address, En= d) =5C

+(=7B =5C

+ UINTN Boundary =3D ((Addre= ss) + PMD=5FSIZE) & PMD=5FMASK; =5C

+ (Boundary - 1 <= ; (End) - 1)=3F Boundary: (End); =5C

+=7D)

+/= **

+ Get Specifies the virtual address corresponding to the= index of the page global directory table entry.

+
+ =40param Address Specifies the virtual address.

+
+ =40retval the index of the page global directory table ent= ry.

+ **/

+=23define PGD=5FINDEX(Address) (((= Address) >> PGD=5FSHI=46T) & (ENTRYS=5FPER=5FPGD-1))

<= div>+/**

+ Get Specifies the virtual address corresponding = to the index of the page upper directory table entry.

+
+ =40param Address Specifies the virtual address.

+ =40param End The end address of the memory region.

+
+ =40retval the index of the page upper directory table entry= .

+ **/

+=23define PUD=5FINDEX(Address) (((Ad= dress) >> PUD=5FSHI=46T) & (ENTRYS=5FPER=5FPUD - 1))

<= div>+/**

+ Get Specifies the virtual address corresponding = to the index of the page middle directory table entry.

+
+ =40param Address Specifies the virtual address.

+

+ =40retval the index of the page middle directory tab= le entry.

+ **/

+=23define PMD=5FINDEX(Addres= s) (((Address) >> PMD=5FSHI=46T) & (ENTRYS=5FPER=5FPMD - 1))
+/**

+ Get Specifies the virtual address corres= ponding to the index of the page table entry.

+

+ =40param Address Specifies the virtual address.

+
+ =40retval the index of the page table entry.

+ = **/

+=23define PTE=5FINDEX(Address) (((Address) >> E=46= I=5FPAGE=5FSHI=46T) & (ENTRYS=5FPER=5FPTE - 1))

+
=
+/**

+ Calculates the value of the page table entr= y based on the specified virtual address and properties.

+<= /div>
+ =40param Address Specifies the virtual address.

=
+ =40param Attributes Specifies the Attributes.

+
+ =40retval the value of the page table entry.

+ = **/

+=23define MAKE=5FPTE(Address, Attributes) (PTE)=7B((((= Address) >> E=46I=5FPAGE=5FSHI=46T) << 12) =7C (Attributes))=7D=

+/**

+ Get Global bit from Attributes
<= br>
+

+ =40param Attributes Specifies the Attributes.
+ * */

+=23define GET=5FGLOBALBIT(Attributes) = ((Attributes & PAGE=5FGLOBAL) >> PAGE=5FGLOBAL=5FSHI=46T)
=
+/**

+ Calculates the value of the Huge page table= entry based on the specified virtual address and properties.

+

+ =40param Address Specifies the virtual address.
+ =40param Attributes Specifies the Attributes.

+=

+ =40retval the value of the HUGE page table entry.
<= br>
+ **/

+=23define MAKE=5FHUGE=5FPTE(Address, Attribu= tes) (((((Address) >> PMD=5FSHI=46T) << PMD=5FSHI=46T) =7C =5C=

+ ((Attributes) =7C (GET=5FGLOBALBIT(Attributes) << = PAGE=5FHGLOBAL=5FSHI=46T) =7C =5C

+ PAGE=5FHUGE)))
+

+ /**

+ Check whether the large page = table entry is.

+

+ =40param Val The value of= the page table entry.

+

+ =40retval 1 Is hug= e page table entry.

+ =40retval 0 Isn't huge page table ent= ry.

+ **/

+=23define IS=5FHUGE=5FPAGE(Val) ((= ((Val) & PAGE=5FHUGE) =3D=3D PAGE=5FHUGE) && =5C

+ (((Val) & PAGE=5FHGLOBAL) =3D=3D PAGE=5FHGLOBAL))

+=

+=23define HUGE=5FPAGE=5FSIZE (PMD=5FSIZE)

+=

+ /**

+ Check that the global page directory= table entry is empty.

+

+ =40param pgd the g= lobal page directory struct variables.

+

+ =40= retval 1 Is huge page table entry.

+ =40retval 0 Isn't huge= page table entry.

+ **/

+STATIC

+inline

+UINTN

+pgd=5Fnone (

= + IN PGD pgd

+ )

+=7B

+ return = (PGD=5FVAL(pgd) =3D=3D (UINTN)PcdGet64(PcdInvalidPud));

+=7D=

+

+ /**

+ Check that the page = upper directory table entry is empty.

+

+ =40= param pud Page upper directory struct variables.

+
+ =40retval 1 Is huge page table entry.

+ =40retval 0= Isn't huge page table entry.

+ **/

+STATIC
+inline

+UINTN

+pud=5Fnone (
+ IN PUD pud

+ )

+=7B

+ return (PUD=5FVAL(pud) =3D=3D (UINTN)PcdGet64 (PcdInvalidPmd));
=
+=7D

+

+ /**

+ Check t= hat the page middle directory table entry is empty.

+
=
+ =40param pmd Page middle directory struct variables.

=
+

+ =40retval 1 Is huge page table entry.

+ =40retval 0 Isn't huge page table entry.

+ **/
+STATIC

+inline

+UINTN

+p= md=5Fnone (

+ IN PMD pmd

+ )

+=7B=

+ return (PMD=5FVAL(pmd) =3D=3D (UINTN)PcdGet64(PcdInvalid= Pte));

+=7D

+ /**

+ Check that = the page table entry is empty.

+

+ =40param p= md Page table entry struct variables.

+

+ =40= retval 1 Is huge page table entry.

+ =40retval 0 Isn't huge= page table entry.

+ **/

+STATIC

+inline

+UINTN

+pte=5Fnone (

= + IN PTE pte

+ )

+=7B

+ return = (=21(PTE=5FVAL(pte) & (=7EPAGE=5FGLOBAL)));

+=7D
<= br>
+=23endif // PAGE=5FH=5F

diff --git a/Platform/Loon= gson/LoongArchQemuPkg/Library/MmuLib/pte.h b/Platform/Loongson/LoongArchQ= emuPkg/Library/MmuLib/pte.h

new file mode 100644

<= div>index 0000000000..aacbf81744

--- /dev/null

+++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/pte.h

=
=40=40 -0,0 +1,57 =40=40

+/** =40file

+<= /div>
+ Copyright (c) 2022 Loongson Technology Corporation Limite= d. All rights reserved.<BR>

+

+ SPDX-Li= cense-Identifier: BSD-2-Clause-Patent

+

+ =40= par Glossary:

+ - Tlb or TLB - Translation Lookaside Buffer=

+ - HGLOBAL - Huge Global

+ - P=46N - Page =46= rame number

+ - EXEC - Execute

+ - PLV - Priv= ilege Level

+ - RPLV - Restricted Privilege Level

=
+ - SUC - Strong-ordered UnCached

+ - CC - Coherent Ca= ched

+ - WUC - Weak-ordered UnCached

+**/
+=23ifndef PTE=5FH=5F

+=23define PTE=5FH=5F
+/*Page table property definitions */

+=23define = PAGE=5FVALID=5FSHI=46T 0

+=23define PAGE=5FDIRTY=5FSHI=46T = 1

+=23define PAGE=5FPLV=5FSHI=46T 2 /* 2=7E3, two bits */
+=23define CACHE=5FSHI=46T 4 /* 4=7E5, two bits */

=
+=23define PAGE=5FGLOBAL=5FSHI=46T 6

+=23define PAGE=5F= HUGE=5FSHI=46T 6 /* HUGE is a PMD bit */

+

+=23= define PAGE=5FHGLOBAL=5FSHI=46T 12 /* HGlobal is a PMD bit */

+=23define PAGE=5FP=46N=5FSHI=46T 12

+=23define PAGE=5FP= =46N=5FEND=5FSHI=46T 48

+=23define PAGE=5FNO=5FREAD=5FSHI=46= T 61

+=23define PAGE=5FNO=5FEXEC=5FSHI=46T 62

+=23define PAGE=5FRPLV=5FSHI=46T 63

+

+/* Us= ed by TLB hardware (placed in EntryLo*) */

+=23define PAGE=5F= VALID ((UINTN)(1) << PAGE=5FVALID=5FSHI=46T)

+=23defi= ne PAGE=5FDIRTY ((UINTN)(1) << PAGE=5FDIRTY=5FSHI=46T)

+=23define PAGE=5FPLV ((UINTN)(3) << PAGE=5FPLV=5FSHI=46T)
<= br>
+=23define PAGE=5FGLOBAL ((UINTN)(1) << PAGE=5FGLOBAL=5FSHI= =46T)

+=23define PAGE=5FHUGE ((UINTN)(1) << PAGE=5FHU= GE=5FSHI=46T)

+=23define PAGE=5FHGLOBAL ((UINTN)(1) <<= ; PAGE=5FHGLOBAL=5FSHI=46T)

+=23define PAGE=5FNO=5FREAD ((U= INTN)(1) << PAGE=5FNO=5FREAD=5FSHI=46T)

+=23define PA= GE=5FNO=5FEXEC ((UINTN)(1) << PAGE=5FNO=5FEXEC=5FSHI=46T)

=
+=23define PAGE=5FRPLV ((UINTN)(1) << PAGE=5FRPLV=5FSHI=46T)
+=23define CACHE=5FMASK ((UINTN)(3) << CACHE=5FSHI=46T= )

+=23define P=46N=5FSHI=46T (E=46I=5FPAGE=5FSHI=46T - 12 += PAGE=5FP=46N=5FSHI=46T)

+

+=23define PLV=5FK= ERNEL 0

+=23define PLV=5FUSER 3

+

+=23define PAGE=5FUSER (PLV=5FUSER << PAGE=5FPLV=5FSHI=46T)
+=23define PAGE=5FKERNEL (PLV=5FKERN << PAGE=5FPLV=5FSHI=46= T)

+

+=23define CACHE=5FSUC (0 << CACHE= =5FSHI=46T) /* Strong-ordered UnCached */

+=23define CACHE=5F= CC (1 << CACHE=5FSHI=46T) /* Coherent Cached */

+=23d= efine CACHE=5FWUC (2 << CACHE=5FSHI=46T) /* Weak-ordered UnCached *= /

+=23endif // PTE=5FH=5F

--

2.= 31.1
--636e190d_24bd76bf_1e57b--