From mboxrd@z Thu Jan  1 00:00:00 1970
Received: from mail-qv1-f51.google.com (mail-qv1-f51.google.com [209.85.219.51])
 by mx.groups.io with SMTP id smtpd.web10.1424.1684952204910000197
 for <devel@edk2.groups.io>;
 Wed, 24 May 2023 11:16:45 -0700
Authentication-Results: mx.groups.io;
 dkim=fail reason="signature has expired" header.i=@ventanamicro.com header.s=google header.b=Kl+iIsxt;
 spf=pass (domain: ventanamicro.com, ip: 209.85.219.51, mailfrom: tphan@ventanamicro.com)
Received: by mail-qv1-f51.google.com with SMTP id 6a1803df08f44-62385a3106dso318626d6.2
        for <devel@edk2.groups.io>; Wed, 24 May 2023 11:16:44 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=ventanamicro.com; s=google; t=1684952204; x=1687544204;
        h=mime-version:content-language:accept-language:in-reply-to
         :references:message-id:date:thread-index:thread-topic:subject:cc:to
         :from:from:to:cc:subject:date:message-id:reply-to;
        bh=/eSrfgqC+prSvsu/Ymv/FdN5knH7gkzCPQD6sVI2xO4=;
        b=Kl+iIsxtAjUAFXI9hEZVPL5UewXEpk/qD7ZPSR0tUgOe2xgFa5/ZCv/2zyjaeheckD
         /RE4JdwI9VsgZR7gGPC9WQEYE1X8HWkvYcbI4lrTqCnsvZnmIvTXWm1ZzDSKQ0Md4gAY
         mSGsCHLa3PQ5jc/mA5ui+zARNMj5J0xUWvMpIs2/3UaxkTkGTo1tBZ551wEQSa8IGOS5
         L91+mkIEjm4+unoA6+WpWScaQPq+UZrqOh8D21Q7jY6qkXbkxxFQziU5gRLj3EBQ6d3j
         3DnaIkhKE/fk4di1ELO7t6PGTMQlalnQupdNPnRMtGDxcBCa55IR+DDX4AlUqDIBarJl
         XjMg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20221208; t=1684952204; x=1687544204;
        h=mime-version:content-language:accept-language:in-reply-to
         :references:message-id:date:thread-index:thread-topic:subject:cc:to
         :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
        bh=/eSrfgqC+prSvsu/Ymv/FdN5knH7gkzCPQD6sVI2xO4=;
        b=HKRsQiMyQRHfffRSJXXbgsg/bd68KHPTgShu0jRnBF7/hCl83186ZpSIbkdgZdqbEF
         J5bxVR0ybeKzhKsL1iIjC85JF5Zsj4qPQm9UHrorh80NA+LxTp3q1YM/udTexdpBJloi
         9ri9R+CohDG+aZqggKeT/RvdmJRFfRmD0gtN41DjlmYK+fQv3OgggAHmgre7q8B1nJIg
         rf9AhQ+LaJ5FhblrcblSMOIA+xs7VHEQSa9iZ6C1bZZvukhasd9fqVtbub/jj24VRVoY
         N8+g2h+JWJ341kXChUUXWRcSqkCj4ESWFUaHVJEUtN8CU/McawfLvmLiiJ4RzAj6fdeW
         l+BA==
X-Gm-Message-State: AC+VfDx+ZxAkd5x3bAxO6sp0COciXaPYagvz7JmAy1vWR3MHNG0XoFjp
	32NuNKCotHrPAxfvmB1y3IMHN0aqxd5IAJWdMUI=
X-Google-Smtp-Source: ACHHUZ5ZfkiAfmQjJ+Kmumi67ZrauCSYnrsv59gK8BB7y+5cwnx+HcTIt6smtV04dUW7+mLYdoPzVQ==
X-Received: by 2002:ad4:5ced:0:b0:5c8:403a:22f8 with SMTP id iv13-20020ad45ced000000b005c8403a22f8mr29298750qvb.5.1684952203749;
        Wed, 24 May 2023 11:16:43 -0700 (PDT)
Return-Path: <tphan@ventanamicro.com>
Received: from MN2PR13MB3022.namprd13.prod.outlook.com ([2603:1036:302:405e::5])
        by smtp.gmail.com with ESMTPSA id cz10-20020a056214088a00b0062120b054easm3730598qvb.20.2023.05.24.11.16.43
        (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);
        Wed, 24 May 2023 11:16:43 -0700 (PDT)
From: "Tuan Phan" <tphan@ventanamicro.com>
To: "Ni, Ray" <ray.ni@intel.com>, "devel@edk2.groups.io"
	<devel@edk2.groups.io>, "lichao@loongson.cn" <lichao@loongson.cn>, Ard
 Biesheuvel <ardb@kernel.org>
CC: "Kinney, Michael D" <michael.d.kinney@intel.com>, "Gao, Liming"
	<gaoliming@byosoft.com.cn>, "Liu, Zhiguang" <zhiguang.liu@intel.com>,
	"sunilvl@ventanamicro.com" <sunilvl@ventanamicro.com>,
	"git@danielschaefer.me" <git@danielschaefer.me>, "Warkentin, Andrei"
	<andrei.warkentin@intel.com>
Subject: Re: [edk2-devel] [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode
Thread-Topic: [edk2-devel] [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU with
 SV39/48/57 mode
Thread-Index: AQHZbwMga4CTCPv2R0CJThklTy+FM69o692AgACA1QCAAIyRiA==
X-MS-Exchange-MessageSentRepresentingType: 1
Date: Wed, 24 May 2023 18:16:26 +0000
Message-ID: 
	<MN2PR13MB30225A5769E6AF33496072E0A7419@MN2PR13MB3022.namprd13.prod.outlook.com>
References: <20230414185815.2994-1-tphan@ventanamicro.com>
 <20230414185815.2994-4-tphan@ventanamicro.com>
 <f815659f-17c1-356e-4b6a-2313e9080049@loongson.cn>
 <MN6PR11MB82448B11DE60CDAEB1E4BE088C419@MN6PR11MB8244.namprd11.prod.outlook.com>
In-Reply-To: 
	<MN6PR11MB82448B11DE60CDAEB1E4BE088C419@MN6PR11MB8244.namprd11.prod.outlook.com>
Accept-Language: en-US
X-MS-Has-Attach: 
X-MS-Exchange-Organization-SCL: -1
X-MS-TNEF-Correlator: 
X-MS-Exchange-Organization-RecordReviewCfmType: 0
MIME-Version: 1.0
Content-Language: en-US
Content-Type: multipart/alternative;
	boundary="_000_MN2PR13MB30225A5769E6AF33496072E0A7419MN2PR13MB3022namp_"

--_000_MN2PR13MB30225A5769E6AF33496072E0A7419MN2PR13MB3022namp_
Content-Type: text/plain; charset="iso-2022-jp"
Content-Transfer-Encoding: quoted-printable

Agree it makes more sense to put the MMU library into UefiCpuPkg.

From: Ni, Ray <ray.ni@intel.com>
Date: Wednesday, May 24, 2023 at 2:52 AM
To: devel@edk2.groups.io <devel@edk2.groups.io>, lichao@loongson.cn <lichao=
@loongson.cn>, tphan@ventanamicro.com <tphan@ventanamicro.com>, Ard Biesheu=
vel <ardb@kernel.org>
Cc: Kinney, Michael D <michael.d.kinney@intel.com>, Gao, Liming <gaoliming@=
byosoft.com.cn>, Liu, Zhiguang <zhiguang.liu@intel.com>, sunilvl@ventanamic=
ro.com <sunilvl@ventanamicro.com>, git@danielschaefer.me <git@danielschaefe=
r.me>, Warkentin, Andrei <andrei.warkentin@intel.com>
Subject: RE: [edk2-devel] [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU wi=
th SV39/48/57 mode
X86 version is in UefiCpuPkg.
So be consistent, I would prefer the LoongArch64 version be in UefiCpuPkg a=
s well.
I know that ARM has similar code (I didn=1B$B!G=1B(Bt check in detail, +@Ar=
d Biesheuvel<mailto:ardb@kernel.org>).

The trending is to abstract the memory attribute implementation behind Memo=
ryAttribute PPI/Protocol for using by other modules.


Thanks,
Ray

From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Chao Li
Sent: Wednesday, May 24, 2023 10:11 AM
To: devel@edk2.groups.io; tphan@ventanamicro.com
Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@=
byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>; sunilvl@ventanamic=
ro.com; git@danielschaefer.me; Warkentin, Andrei <andrei.warkentin@intel.co=
m>; Ni, Ray <ray.ni@intel.com>
Subject: Re: [edk2-devel] [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU wi=
th SV39/48/57 mode


Dear all,

I'm also porting MMU library of LoongArch64 to EDK2, I added it in to UefiC=
puPkg and make it possible to use the same headers for both the no-IA32 and=
 no-X64 platforms, and I also saw that IA32 and X64 added the CpuPageTableL=
ib to UefiCpuPkg, this library are similar to MMU libraries. I have a quest=
ion, should the MMU library be in the MdePkg or UefiCpuPkg?

Thanks,
Chao
=1B$B:_=1B(B 2023/4/15 02:58, Tuan Phan =1B$B<LF;=1B(B:

During CpuDxe initialization, MMU will be setup with the highest

mode that HW supports.



Signed-off-by: Tuan Phan <tphan@ventanamicro.com><mailto:tphan@ventanamicro=
.com>

---

 MdePkg/Include/Library/BaseRiscVMmuLib.h      |  39 ++

 .../Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c | 569 ++++++++++++++++++

 .../BaseRiscVMmuLib/BaseRiscVMmuLib.inf       |  25 +

 MdePkg/Library/BaseRiscVMmuLib/RiscVMmuCore.S |  31 +

 OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc           |   1 +

 OvmfPkg/RiscVVirt/Sec/Memory.c                |  18 +-

 UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c             |   9 +-

 UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h             |   2 +

 UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf    |   2 +

 9 files changed, 678 insertions(+), 18 deletions(-)

 create mode 100644 MdePkg/Include/Library/BaseRiscVMmuLib.h

 create mode 100644 MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c

 create mode 100644 MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.inf

 create mode 100644 MdePkg/Library/BaseRiscVMmuLib/RiscVMmuCore.S



diff --git a/MdePkg/Include/Library/BaseRiscVMmuLib.h b/MdePkg/Include/Libr=
ary/BaseRiscVMmuLib.h

new file mode 100644

index 000000000000..f71d6a4a1e7b

--- /dev/null

+++ b/MdePkg/Include/Library/BaseRiscVMmuLib.h

@@ -0,0 +1,39 @@

+/** @file

+

+  Copyright (c) 2015 - 2016, Linaro Ltd. All rights reserved.<BR>

+  Copyright (c) 2023, Ventana Micro Systems Inc. All Rights Reserved.<BR>

+

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

+

+**/

+

+#ifndef BASE_RISCV_MMU_LIB_H_

+#define BASE_RISCV_MMU_LIB_H_

+

+VOID

+EFIAPI

+RiscVLocalTlbFlushAll (

+  VOID

+  );

+

+VOID

+EFIAPI

+RiscVLocalTlbFlush (

+  UINTN  VirtAddr

+  );

+

+EFI_STATUS

+EFIAPI

+RiscVSetMemoryAttributes (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length,

+  IN UINT64                Attributes

+  );

+

+EFI_STATUS

+EFIAPI

+RiscVConfigureMmu (

+  VOID

+  );

+

+#endif /* BASE_RISCV_MMU_LIB_H_ */

diff --git a/MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c b/MdePkg/Libr=
ary/BaseRiscVMmuLib/BaseRiscVMmuLib.c

new file mode 100644

index 000000000000..230f34261d8b

--- /dev/null

+++ b/MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c

@@ -0,0 +1,569 @@

+/** @file

+*  MMU implementation for RISC-V

+*

+*  Copyright (c) 2011-2020, ARM Limited. All rights reserved.

+*  Copyright (c) 2016, Linaro Limited. All rights reserved.

+*  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>

+*  Copyright (c) 2023, Ventana Micro Systems Inc. All Rights Reserved.<BR>

+*

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

+*

+**/

+

+#include <PiDxe.h>

+#include <Uefi.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/BaseRiscVMmuLib.h>

+#include <Library/CacheMaintenanceLib.h>

+#include <Library/DebugLib.h>

+#include <Library/DxeServicesTableLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/PcdLib.h>

+#include <Register/RiscV64/RiscVEncoding.h>

+

+#define RISCV_PG_V           BIT0

+#define RISCV_PG_R           BIT1

+#define RISCV_PG_W           BIT2

+#define RISCV_PG_X           BIT3

+#define RISCV_PG_G           BIT5

+#define RISCV_PG_A           BIT6

+#define RISCV_PG_D           BIT7

+#define PTE_ATTRIBUTES_MASK  0xE

+

+#define PTE_PPN_MASK          0x3FFFFFFFFFFC00ULL

+#define PTE_PPN_SHIFT         10

+#define RISCV_MMU_PAGE_SHIFT  12

+

+STATIC UINTN  mMaxRootTableLevel;

+STATIC UINTN  mBitPerLevel;

+STATIC UINTN  mTableEntryCount;

+

+STATIC

+BOOLEAN

+RiscVMmuEnabled (

+  VOID

+  )

+{

+  return ((RiscVGetSupervisorAddressTranslationRegister () &

+           SATP64_MODE) !=3D (SATP_MODE_OFF << SATP64_MODE_SHIFT));

+}

+

+STATIC

+UINTN

+RiscVGetRootTranslateTable (

+  VOID

+  )

+{

+  return (RiscVGetSupervisorAddressTranslationRegister () & SATP64_PPN) <<

+         RISCV_MMU_PAGE_SHIFT;

+}

+

+STATIC

+BOOLEAN

+IsValidPte (

+  IN  UINTN  Entry

+  )

+{

+  if (!(Entry & RISCV_PG_V) ||

+      (((Entry & (RISCV_PG_R | RISCV_PG_W)) =3D=3D RISCV_PG_W)))

+  {

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+STATIC

+UINTN

+SetValidPte (

+  IN  UINTN  Entry

+  )

+{

+  /* Set Valid and Global mapping bits */

+  return Entry | RISCV_PG_G | RISCV_PG_V;

+}

+

+STATIC

+BOOLEAN

+IsBlockEntry (

+  IN  UINTN  Entry

+  )

+{

+  return IsValidPte (Entry) &&

+         (Entry & (RISCV_PG_X | RISCV_PG_R));

+}

+

+STATIC

+BOOLEAN

+IsTableEntry (

+  IN  UINTN  Entry

+  )

+{

+  return IsValidPte (Entry) &&

+         !IsBlockEntry (Entry);

+}

+

+STATIC

+UINTN

+SetTableEntry (

+  IN  UINTN  Entry

+  )

+{

+  Entry  =3D SetValidPte (Entry);

+  Entry &=3D ~(RISCV_PG_X | RISCV_PG_W | RISCV_PG_R);

+

+  return Entry;

+}

+

+STATIC

+VOID

+ReplaceTableEntry (

+  IN  UINTN    *Entry,

+  IN  UINTN    Value,

+  IN  UINTN    RegionStart,

+  IN  BOOLEAN  IsLiveBlockMapping

+  )

+{

+  *Entry =3D Value;

+

+  if (IsLiveBlockMapping && RiscVMmuEnabled ()) {

+    RiscVLocalTlbFlush (RegionStart);

+  }

+}

+

+STATIC

+UINTN

+GetPpnfromPte (

+  UINTN  Entry,

+  UINTN  Level

+  )

+{

+  return ((Entry & PTE_PPN_MASK) >> PTE_PPN_SHIFT);

+}

+

+STATIC

+UINTN

+SetPpnToPte (

+  UINTN  Entry,

+  UINTN  Address,

+  UINTN  Level

+  )

+{

+  UINTN  Ppn;

+

+  Ppn =3D ((Address >> RISCV_MMU_PAGE_SHIFT) << PTE_PPN_SHIFT);

+  ASSERT (~(Ppn & ~PTE_PPN_MASK));

+  Entry &=3D ~PTE_PPN_MASK;

+  return Entry | Ppn;

+}

+

+STATIC

+VOID

+FreePageTablesRecursive (

+  IN  UINTN  *TranslationTable,

+  IN  UINTN  Level

+  )

+{

+  UINTN  Index;

+

+  if (Level < mMaxRootTableLevel - 1) {

+    for (Index =3D 0; Index < mTableEntryCount; Index++) {

+      if (IsTableEntry (TranslationTable[Index])) {

+        FreePageTablesRecursive (

+                                 (UINTN *)(GetPpnfromPte ((TranslationTabl=
e[Index]), Level) <<

+                                           RISCV_MMU_PAGE_SHIFT),

+                                 Level + 1

+                                 );

+      }

+    }

+  }

+

+  FreePages (TranslationTable, 1);

+}

+

+STATIC

+EFI_STATUS

+UpdateRegionMappingRecursive (

+  IN  UINTN    RegionStart,

+  IN  UINTN    RegionEnd,

+  IN  UINTN    AttributeSetMask,

+  IN  UINTN    AttributeClearMask,

+  IN  UINTN    *PageTable,

+  IN  UINTN    Level,

+  IN  BOOLEAN  TableIsLive

+  )

+{

+  EFI_STATUS  Status;

+  UINTN       BlockShift;

+  UINTN       BlockMask;

+  UINTN       BlockEnd;

+  UINTN       *Entry;

+  UINTN       EntryValue;

+  UINTN       *TranslationTable;

+  BOOLEAN     NextTableIsLive;

+

+  ASSERT (Level < mMaxRootTableLevel);

+  ASSERT (((RegionStart | RegionEnd) & EFI_PAGE_MASK) =3D=3D 0);

+

+  BlockShift =3D (mMaxRootTableLevel - Level - 1) * mBitPerLevel + RISCV_M=
MU_PAGE_SHIFT;

+  BlockMask  =3D MAX_ADDRESS >> (64 - BlockShift);

+

+  DEBUG (

+         (

+          DEBUG_VERBOSE,

+          "%a(%d): %llx - %llx set %lx clr %lx\n",

+          __func__,

+          Level,

+          RegionStart,

+          RegionEnd,

+          AttributeSetMask,

+          AttributeClearMask

+         )

+         );

+

+  for ( ; RegionStart < RegionEnd; RegionStart =3D BlockEnd) {

+    BlockEnd =3D MIN (RegionEnd, (RegionStart | BlockMask) + 1);

+    Entry    =3D &PageTable[(RegionStart >> BlockShift) & (mTableEntryCoun=
t - 1)];

+

+    //

+    // If RegionStart or BlockEnd is not aligned to the block size at this

+    // level, we will have to create a table mapping in order to map less

+    // than a block, and recurse to create the block or page entries at

+    // the next level. No block mappings are allowed at all at level 0,

+    // so in that case, we have to recurse unconditionally.

+    //

+    if ((Level =3D=3D 0) ||

+        (((RegionStart | BlockEnd) & BlockMask) !=3D 0) || IsTableEntry (*=
Entry))

+    {

+      ASSERT (Level < mMaxRootTableLevel - 1);

+      if (!IsTableEntry (*Entry)) {

+        //

+        // No table entry exists yet, so we need to allocate a page table

+        // for the next level.

+        //

+        TranslationTable =3D AllocatePages (1);

+        if (TranslationTable =3D=3D NULL) {

+          return EFI_OUT_OF_RESOURCES;

+        }

+

+        ZeroMem (TranslationTable, EFI_PAGE_SIZE);

+

+        if (IsBlockEntry (*Entry)) {

+          //

+          // We are splitting an existing block entry, so we have to popul=
ate

+          // the new table with the attributes of the block entry it repla=
ces.

+          //

+          Status =3D UpdateRegionMappingRecursive (

+                                                 RegionStart & ~BlockMask,

+                                                 (RegionStart | BlockMask)=
 + 1,

+                                                 *Entry & PTE_ATTRIBUTES_M=
ASK,

+                                                 PTE_ATTRIBUTES_MASK,

+                                                 TranslationTable,

+                                                 Level + 1,

+                                                 FALSE

+                                                 );

+          if (EFI_ERROR (Status)) {

+            //

+            // The range we passed to UpdateRegionMappingRecursive () is b=
lock

+            // aligned, so it is guaranteed that no further pages were all=
ocated

+            // by it, and so we only have to free the page we allocated he=
re.

+            //

+            FreePages (TranslationTable, 1);

+            return Status;

+          }

+        }

+

+        NextTableIsLive =3D FALSE;

+      } else {

+        TranslationTable =3D (UINTN *)(GetPpnfromPte (*Entry, Level) << RI=
SCV_MMU_PAGE_SHIFT);

+        NextTableIsLive  =3D TableIsLive;

+      }

+

+      //

+      // Recurse to the next level

+      //

+      Status =3D UpdateRegionMappingRecursive (

+                                             RegionStart,

+                                             BlockEnd,

+                                             AttributeSetMask,

+                                             AttributeClearMask,

+                                             TranslationTable,

+                                             Level + 1,

+                                             NextTableIsLive

+                                             );

+      if (EFI_ERROR (Status)) {

+        if (!IsTableEntry (*Entry)) {

+          //

+          // We are creating a new table entry, so on failure, we can free=
 all

+          // allocations we made recursively, given that the whole subhier=
archy

+          // has not been wired into the live page tables yet. (This is no=
t

+          // possible for existing table entries, since we cannot revert t=
he

+          // modifications we made to the subhierarchy it represents.)

+          //

+          FreePageTablesRecursive (TranslationTable, Level + 1);

+        }

+

+        return Status;

+      }

+

+      if (!IsTableEntry (*Entry)) {

+        EntryValue =3D SetPpnToPte (0, (UINTN)TranslationTable, Level);

+        EntryValue =3D SetTableEntry (EntryValue);

+        ReplaceTableEntry (

+                           Entry,

+                           EntryValue,

+                           RegionStart,

+                           TableIsLive

+                           );

+      }

+    } else {

+      EntryValue =3D (*Entry & ~AttributeClearMask) | AttributeSetMask;

+      //

+      // We don't have page fault exception handler when a virtual page is=
 accessed and

+      // the A bit is clear, or is written and the D bit is clear.

+      // So just set A for read and D for write permission.

+      //

+      if (AttributeSetMask & RISCV_PG_R) {

+        EntryValue |=3D RISCV_PG_A;

+      }

+

+      if (AttributeSetMask & RISCV_PG_W) {

+        EntryValue |=3D RISCV_PG_D;

+      }

+

+      EntryValue =3D SetPpnToPte (EntryValue, RegionStart, Level);

+      EntryValue =3D SetValidPte (EntryValue);

+      ReplaceTableEntry (Entry, EntryValue, RegionStart, TableIsLive);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+UpdateRegionMapping (

+  IN  UINTN    RegionStart,

+  IN  UINTN    RegionLength,

+  IN  UINTN    AttributeSetMask,

+  IN  UINTN    AttributeClearMask,

+  IN  UINTN    *RootTable,

+  IN  BOOLEAN  TableIsLive

+  )

+{

+  if (((RegionStart | RegionLength) & EFI_PAGE_MASK) !=3D 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return UpdateRegionMappingRecursive (

+                                       RegionStart,

+                                       RegionStart + RegionLength,

+                                       AttributeSetMask,

+                                       AttributeClearMask,

+                                       RootTable,

+                                       0,

+                                       TableIsLive

+                                       );

+}

+

+STATIC

+UINTN

+GcdAttributeToPageAttribute (

+  IN UINTN  GcdAttributes

+  )

+{

+  UINTN  RiscVAttributes =3D RISCV_PG_R | RISCV_PG_W | RISCV_PG_X;

+

+  // Determine protection attributes

+  if (GcdAttributes & EFI_MEMORY_RO) {

+    RiscVAttributes &=3D ~(RISCV_PG_W);

+  }

+

+  // Process eXecute Never attribute

+  if (GcdAttributes & EFI_MEMORY_XP) {

+    RiscVAttributes &=3D ~RISCV_PG_X;

+  }

+

+  return RiscVAttributes;

+}

+

+EFI_STATUS

+EFIAPI

+RiscVSetMemoryAttributes (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINTN                 Length,

+  IN UINTN                 Attributes

+  )

+{

+  UINTN  PageAttributesSet =3D GcdAttributeToPageAttribute (Attributes);

+

+  if (!RiscVMmuEnabled ()) {

+    return EFI_SUCCESS;

+  }

+

+  DEBUG (

+         (

+          DEBUG_VERBOSE,

+          "%a: Set %llX page attribute 0x%X\n",

+          __func__,

+          BaseAddress,

+          PageAttributesSet

+         )

+         );

+

+  return UpdateRegionMapping (

+                              BaseAddress,

+                              Length,

+                              PageAttributesSet,

+                              PTE_ATTRIBUTES_MASK,

+                              (UINTN *)RiscVGetRootTranslateTable (),

+                              TRUE

+                              );

+}

+

+STATIC

+EFI_STATUS

+RiscVMmuSetSatpMode  (

+  UINTN  SatpMode

+  )

+{

+  VOID                             *TranslationTable;

+  UINTN                            SatpReg;

+  UINTN                            Ppn;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *MemoryMap;

+  UINTN                            NumberOfDescriptors;

+  UINTN                            Index;

+  EFI_STATUS                       Status;

+

+  switch (SatpMode) {

+    case SATP_MODE_OFF:

+      return EFI_SUCCESS;

+    case SATP_MODE_SV39:

+      mMaxRootTableLevel =3D 3;

+      mBitPerLevel       =3D 9;

+      mTableEntryCount   =3D 512;

+      break;

+    case SATP_MODE_SV48:

+      mMaxRootTableLevel =3D 4;

+      mBitPerLevel       =3D 9;

+      mTableEntryCount   =3D 512;

+      break;

+    case SATP_MODE_SV57:

+      mMaxRootTableLevel =3D 5;

+      mBitPerLevel       =3D 9;

+      mTableEntryCount   =3D 512;

+      break;

+    default:

+      return EFI_INVALID_PARAMETER;

+  }

+

+  // Allocate pages for translation table

+  TranslationTable =3D AllocatePages (1);

+  if (TranslationTable =3D=3D NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  ZeroMem (TranslationTable, mTableEntryCount * sizeof (UINTN));

+

+  NumberOfDescriptors =3D 0;

+  MemoryMap           =3D NULL;

+  Status              =3D gDS->GetMemorySpaceMap (

+                                                &NumberOfDescriptors,

+                                                &MemoryMap

+                                                );

+  ASSERT_EFI_ERROR (Status);

+

+  for (Index =3D 0; Index < NumberOfDescriptors; Index++) {

+    if (MemoryMap[Index].GcdMemoryType =3D=3D EfiGcdMemoryTypeMemoryMapped=
Io) {

+      // Default Read/Write attribute for memory mapped IO

+      UpdateRegionMapping (

+                           MemoryMap[Index].BaseAddress,

+                           MemoryMap[Index].Length,

+                           RISCV_PG_R | RISCV_PG_W,

+                           PTE_ATTRIBUTES_MASK,

+                           TranslationTable,

+                           FALSE

+                           );

+    } else if (MemoryMap[Index].GcdMemoryType =3D=3D EfiGcdMemoryTypeSyste=
mMemory) {

+      // Default Read/Write/Execute attribute for system memory

+      UpdateRegionMapping (

+                           MemoryMap[Index].BaseAddress,

+                           MemoryMap[Index].Length,

+                           RISCV_PG_R | RISCV_PG_W | RISCV_PG_X,

+                           PTE_ATTRIBUTES_MASK,

+                           TranslationTable,

+                           FALSE

+                           );

+    }

+  }

+

+  FreePool ((VOID *)MemoryMap);

+

+  if (GetInterruptState ()) {

+    DisableInterrupts ();

+  }

+

+  Ppn =3D (UINTN)TranslationTable >> RISCV_MMU_PAGE_SHIFT;

+  ASSERT (!(Ppn & ~(SATP64_PPN)));

+

+  SatpReg  =3D Ppn;

+  SatpReg |=3D (SatpMode <<

+              SATP64_MODE_SHIFT) & SATP64_MODE;

+  RiscVSetSupervisorAddressTranslationRegister (SatpReg);

+  /* Check if HW support the setup satp mode */

+  if (SatpReg !=3D RiscVGetSupervisorAddressTranslationRegister ()) {

+    DEBUG (

+           (

+            DEBUG_VERBOSE,

+            "%a: HW does not support SATP mode:%d\n",

+            __func__,

+            SatpMode

+           )

+           );

+    FreePageTablesRecursive (TranslationTable, 0);

+    return EFI_DEVICE_ERROR;

+  }

+

+  RiscVLocalTlbFlushAll ();

+

+  if (GetInterruptState ()) {

+    EnableInterrupts ();

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+RiscVConfigureMmu (

+  VOID

+  )

+{

+  EFI_STATUS  Status =3D EFI_SUCCESS;

+  INTN        ModeSupport[] =3D { SATP_MODE_SV57, SATP_MODE_SV48, SATP_MOD=
E_SV39 };

+  INTN        Idx;

+

+  /* Try to setup MMU with highest mode as possible */

+  for (Idx =3D 0; Idx < ARRAY_SIZE (ModeSupport); Idx++) {

+    Status =3D RiscVMmuSetSatpMode (ModeSupport[Idx]);

+    if (Status =3D=3D EFI_DEVICE_ERROR) {

+      continue;

+    } else if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    DEBUG (

+           (

+            DEBUG_INFO,

+            "%a: SATP mode %d successfully configured\n",

+            __func__,

+            ModeSupport[Idx]

+           )

+           );

+    break;

+  }

+

+  return Status;

+}

diff --git a/MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.inf b/MdePkg/Li=
brary/BaseRiscVMmuLib/BaseRiscVMmuLib.inf

new file mode 100644

index 000000000000..8ee0127c2144

--- /dev/null

+++ b/MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.inf

@@ -0,0 +1,25 @@

+## @file

+#

+#  Copyright (c) 2023, Ventana Micro Systems Inc. All Rights Reserved.<BR>

+#

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

+#

+##

+

+[Defines]

+  INF_VERSION         =3D 0x0001001b

+  BASE_NAME           =3D BaseRiscVMmuLib

+  FILE_GUID           =3D d3bc42ee-c9eb-4339-ba11-06747083d3ae

+  MODULE_TYPE         =3D BASE

+  VERSION_STRING      =3D 1.0

+  LIBRARY_CLASS       =3D RiscVMmuLib

+

+[Sources]

+  BaseRiscVMmuLib.c

+  RiscVMmuCore.S

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

diff --git a/MdePkg/Library/BaseRiscVMmuLib/RiscVMmuCore.S b/MdePkg/Library=
/BaseRiscVMmuLib/RiscVMmuCore.S

new file mode 100644

index 000000000000..42eec4cbdf83

--- /dev/null

+++ b/MdePkg/Library/BaseRiscVMmuLib/RiscVMmuCore.S

@@ -0,0 +1,31 @@

+/** @file

+*

+*  Copyright (c) 2023, Ventana Micro Systems Inc. All Rights Reserved.<BR>

+*

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

+*

+**/

+

+#include <Base.h>

+#include <Register/RiscV64/RiscVImpl.h>

+

+.text

+  .align 3

+

+//

+// Local tlb flush all.

+//

+//

+ASM_FUNC (RiscVLocalTlbFlushAll)

+sfence.vma

+ret

+

+//

+// Local tlb flush at a virtual address

+// @retval a0 : virtual address.

+//

+ASM_FUNC (

+  RiscVLocalTlbFlush

+  )

+sfence.vma a0

+ret

diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVV=
irt.dsc.inc

index 731f54f73f81..083a182655d3 100644

--- a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc

+++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc

@@ -83,6 +83,7 @@

   # RISC-V Architectural Libraries

   CpuExceptionHandlerLib|UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandler=
Lib/BaseRiscV64CpuExceptionHandlerLib.inf

   RiscVSbiLib|MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf

+  RiscVMmuLib|MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.inf

   PlatformBootManagerLib|OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/=
PlatformBootManagerLib.inf

   ResetSystemLib|OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemL=
ib.inf



diff --git a/OvmfPkg/RiscVVirt/Sec/Memory.c b/OvmfPkg/RiscVVirt/Sec/Memory.=
c

index 0e2690c73687..69041f6404a4 100644

--- a/OvmfPkg/RiscVVirt/Sec/Memory.c

+++ b/OvmfPkg/RiscVVirt/Sec/Memory.c

@@ -85,21 +85,6 @@ AddMemoryRangeHob (

   AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));

 }



-/**

-  Configure MMU

-**/

-STATIC

-VOID

-InitMmu (

-  )

-{

-  //

-  // Set supervisor translation mode to Bare mode

-  //

-  RiscVSetSupervisorAddressTranslationRegister ((UINT64)SATP_MODE_OFF << 6=
0);

-  DEBUG ((DEBUG_INFO, "%a: Set Supervisor address mode to bare-metal mode.=
\n", __func__));

-}

-

 /**

   Publish system RAM and reserve memory regions.



@@ -327,7 +312,8 @@ MemoryPeimInitialization (



   AddReservedMemoryMap (FdtPointer);



-  InitMmu ();

+  /* Make sure SEC is booting with bare mode*/

+  ASSERT ((RiscVGetSupervisorAddressTranslationRegister () & SATP64_MODE) =
=3D=3D (SATP_MODE_OFF << SATP64_MODE_SHIFT));



   BuildMemoryTypeInformationHob ();



diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxeRiscV64/C=
puDxe.c

index 25fe3f54c325..2af3b6223450 100644

--- a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c

+++ b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c

@@ -296,8 +296,7 @@ CpuSetMemoryAttributes (

   IN UINT64                 Attributes

   )

 {

-  DEBUG ((DEBUG_INFO, "%a: Set memory attributes not supported yet\n", __f=
unc__));

-  return EFI_SUCCESS;

+  return RiscVSetMemoryAttributes (BaseAddress, Length, Attributes);

 }



 /**

@@ -340,6 +339,12 @@ InitializeCpu (

   //

   DisableInterrupts ();



+  //

+  // Enable MMU

+  //

+  Status =3D RiscVConfigureMmu ();

+  ASSERT_EFI_ERROR (Status);

+

   //

   // Install Boot protocol

   //

diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxeRiscV64/C=
puDxe.h

index 49f4e119665a..68e6d038b66e 100644

--- a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h

+++ b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h

@@ -15,11 +15,13 @@

 #include <Protocol/Cpu.h>

 #include <Protocol/RiscVBootProtocol.h>

 #include <Library/BaseRiscVSbiLib.h>

+#include <Library/BaseRiscVMmuLib.h>

 #include <Library/BaseLib.h>

 #include <Library/CpuExceptionHandlerLib.h>

 #include <Library/DebugLib.h>

 #include <Library/UefiBootServicesTableLib.h>

 #include <Library/UefiDriverEntryPoint.h>

+#include <Register/RiscV64/RiscVEncoding.h>



 /**

   Flush CPU data cache. If the instruction cache is fully coherent

diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf b/UefiCpuPkg/CpuDxe=
RiscV64/CpuDxeRiscV64.inf

index e8fa25446aef..9d9a5ef8f247 100644

--- a/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf

+++ b/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf

@@ -37,6 +37,8 @@

   TimerLib

   PeCoffGetEntryPointLib

   RiscVSbiLib

+  RiscVMmuLib

+  CacheMaintenanceLib



 [Sources]

   CpuDxe.c


--_000_MN2PR13MB30225A5769E6AF33496072E0A7419MN2PR13MB3022namp_
Content-Type: text/html; charset="iso-2022-jp"
Content-Transfer-Encoding: quoted-printable

<html xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:schemas-micr=
osoft-com:office:office" xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" xmlns=3D"http:=
//www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Diso-2022-=
jp">
<meta name=3D"Generator" content=3D"Microsoft Word 15 (filtered medium)">
<!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
	{font-family:"Cambria Math";
	panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
	{font-family:Calibri;
	panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
	{font-family:Consolas;
	panose-1:2 11 6 9 2 2 4 3 2 4;}
@font-face
	{font-family:"Microsoft YaHei";
	panose-1:2 11 5 3 2 2 4 2 2 4;}
@font-face
	{font-family:"\@Microsoft YaHei";}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin:0in;
	font-size:10.0pt;
	font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
	{mso-style-priority:99;
	color:blue;
	text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
	{mso-style-priority:99;
	color:purple;
	text-decoration:underline;}
pre
	{mso-style-priority:99;
	mso-style-link:"HTML Preformatted Char";
	margin:0in;
	font-size:10.0pt;
	font-family:"Courier New";}
p.msonormal0, li.msonormal0, div.msonormal0
	{mso-style-name:msonormal;
	mso-margin-top-alt:auto;
	margin-right:0in;
	mso-margin-bottom-alt:auto;
	margin-left:0in;
	font-size:10.0pt;
	font-family:"Calibri",sans-serif;}
span.HTMLPreformattedChar
	{mso-style-name:"HTML Preformatted Char";
	mso-style-priority:99;
	mso-style-link:"HTML Preformatted";
	font-family:Consolas;}
span.EmailStyle20
	{mso-style-type:personal;
	font-family:"Calibri",sans-serif;
	color:windowtext;}
span.EmailStyle23
	{mso-style-type:personal-reply;
	font-family:"Calibri",sans-serif;
	color:windowtext;}
.MsoChpDefault
	{mso-style-type:export-only;
	font-size:10.0pt;
	mso-ligatures:none;}
@page WordSection1
	{size:8.5in 11.0in;
	margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
	{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext=3D"edit">
<o:idmap v:ext=3D"edit" data=3D"1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang=3D"EN-US" link=3D"blue" vlink=3D"purple" style=3D"word-wrap:brea=
k-word">
<div class=3D"WordSection1">
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt">Agree it makes more=
 sense to put the MMU library into UefiCpuPkg.<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt"><o:p>&nbsp;</o:p></=
span></p>
<div style=3D"border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in =
0in 0in">
<p class=3D"MsoNormal" style=3D"margin-bottom:12.0pt"><b><span style=3D"fon=
t-size:12.0pt;color:black">From:
</span></b><span style=3D"font-size:12.0pt;color:black">Ni, Ray &lt;ray.ni@=
intel.com&gt;<br>
<b>Date: </b>Wednesday, May 24, 2023 at 2:52 AM<br>
<b>To: </b>devel@edk2.groups.io &lt;devel@edk2.groups.io&gt;, lichao@loongs=
on.cn &lt;lichao@loongson.cn&gt;, tphan@ventanamicro.com &lt;tphan@ventanam=
icro.com&gt;, Ard Biesheuvel &lt;ardb@kernel.org&gt;<br>
<b>Cc: </b>Kinney, Michael D &lt;michael.d.kinney@intel.com&gt;, Gao, Limin=
g &lt;gaoliming@byosoft.com.cn&gt;, Liu, Zhiguang &lt;zhiguang.liu@intel.co=
m&gt;, sunilvl@ventanamicro.com &lt;sunilvl@ventanamicro.com&gt;, git@danie=
lschaefer.me &lt;git@danielschaefer.me&gt;, Warkentin, Andrei
 &lt;andrei.warkentin@intel.com&gt;<br>
<b>Subject: </b>RE: [edk2-devel] [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support=
 MMU with SV39/48/57 mode<o:p></o:p></span></p>
</div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt">X86 version is in U=
efiCpuPkg.<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt">So be consistent, I=
 would prefer the LoongArch64 version be in UefiCpuPkg as well.<o:p></o:p><=
/span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt">I know that ARM has=
 similar code (I didn=1B$B!G=1B(Bt check in detail, +<a id=3D"OWAAM03DE82E0=
29B74AA8AC5778E62E4A5CEC" href=3D"mailto:ardb@kernel.org"><span style=3D"fo=
nt-family:&quot;Calibri&quot;,sans-serif;text-decoration:none">@Ard
 Biesheuvel</span></a>).<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt">&nbsp;<o:p></o:p></=
span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt">The trending is to =
abstract the memory attribute implementation behind MemoryAttribute PPI/Pro=
tocol for using by other modules.<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt">&nbsp;<o:p></o:p></=
span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt">&nbsp;<o:p></o:p></=
span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt">Thanks,<br>
Ray<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt">&nbsp;<o:p></o:p></=
span></p>
<div>
<div style=3D"border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in =
0in 0in">
<p class=3D"MsoNormal"><b><span style=3D"font-size:11.0pt">From:</span></b>=
<span style=3D"font-size:11.0pt"> devel@edk2.groups.io &lt;devel@edk2.group=
s.io&gt;
<b>On Behalf Of </b>Chao Li<br>
<b>Sent:</b> Wednesday, May 24, 2023 10:11 AM<br>
<b>To:</b> devel@edk2.groups.io; tphan@ventanamicro.com<br>
<b>Cc:</b> Kinney, Michael D &lt;michael.d.kinney@intel.com&gt;; Gao, Limin=
g &lt;gaoliming@byosoft.com.cn&gt;; Liu, Zhiguang &lt;zhiguang.liu@intel.co=
m&gt;; sunilvl@ventanamicro.com; git@danielschaefer.me; Warkentin, Andrei &=
lt;andrei.warkentin@intel.com&gt;; Ni, Ray &lt;ray.ni@intel.com&gt;<br>
<b>Subject:</b> Re: [edk2-devel] [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support=
 MMU with SV39/48/57 mode<o:p></o:p></span></p>
</div>
</div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt">&nbsp;<o:p></o:p></=
span></p>
<p><span style=3D"font-size:10.0pt">Dear all,</span><o:p></o:p></p>
<p><span style=3D"font-size:10.0pt">I'm also porting MMU library of LoongAr=
ch64 to EDK2, I added it in to UefiCpuPkg and make it possible to use the s=
ame headers for both the no-IA32 and no-X64 platforms, and I also saw that =
IA32 and X64 added the CpuPageTableLib
 to UefiCpuPkg, this library are similar to MMU libraries. I have a questio=
n, should the MMU library be in the MdePkg or UefiCpuPkg?</span><o:p></o:p>=
</p>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt">&nbsp;<o:p></o:p></=
span></p>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:8.5pt">Thanks,<br>
Chao</span><span style=3D"font-size:11.0pt"><o:p></o:p></span></p>
</div>
</div>
<div>
<p class=3D"MsoNormal"><span lang=3D"ZH-CN" style=3D"font-size:11.0pt;font-=
family:&quot;Microsoft YaHei&quot;,sans-serif;mso-fareast-language:ZH-CN">=
=1B$B:_=1B(B</span><span style=3D"font-size:11.0pt"> 2023/4/15 02:58, Tuan =
Phan
</span><span lang=3D"ZH-CN" style=3D"font-size:11.0pt;font-family:&quot;Mic=
rosoft YaHei&quot;,sans-serif;mso-fareast-language:ZH-CN">=1B$B<LF;=1B(B</s=
pan><span style=3D"font-size:11.0pt">:<o:p></o:p></span></p>
</div>
<blockquote style=3D"margin-top:5.0pt;margin-bottom:5.0pt">
<pre>During CpuDxe initialization, MMU will be setup with the highest<o:p><=
/o:p></pre>
<pre>mode that HW supports.<o:p></o:p></pre>
<pre>&nbsp;<o:p></o:p></pre>
<pre>Signed-off-by: Tuan Phan <a href=3D"mailto:tphan@ventanamicro.com">&lt=
;tphan@ventanamicro.com&gt;</a><o:p></o:p></pre>
<pre>---<o:p></o:p></pre>
<pre> MdePkg/Include/Library/BaseRiscVMmuLib.h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
; |&nbsp; 39 ++<o:p></o:p></pre>
<pre> .../Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c | 569 +++++++++++++++++=
+<o:p></o:p></pre>
<pre> .../BaseRiscVMmuLib/BaseRiscVMmuLib.inf&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp; |&nbsp; 25 +<o:p></o:p></pre>
<pre> MdePkg/Library/BaseRiscVMmuLib/RiscVMmuCore.S |&nbsp; 31 +<o:p></o:p>=
</pre>
<pre> OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; 1 +<o:p></o:p></pre>
<pre> OvmfPkg/RiscVVirt/Sec/Memory.c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; 18 +-<o:p></o:p=
></pre>
<pre> UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; 9 +-<o:p></o:p></pre>
<pre> UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; 2 +<o:p></o:p></pre>
<pre> UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf&nbsp;&nbsp;&nbsp; |&nbsp;&=
nbsp; 2 +<o:p></o:p></pre>
<pre> 9 files changed, 678 insertions(+), 18 deletions(-)<o:p></o:p></pre>
<pre> create mode 100644 MdePkg/Include/Library/BaseRiscVMmuLib.h<o:p></o:p=
></pre>
<pre> create mode 100644 MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c<o=
:p></o:p></pre>
<pre> create mode 100644 MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.inf=
<o:p></o:p></pre>
<pre> create mode 100644 MdePkg/Library/BaseRiscVMmuLib/RiscVMmuCore.S<o:p>=
</o:p></pre>
<pre>&nbsp;<o:p></o:p></pre>
<pre>diff --git a/MdePkg/Include/Library/BaseRiscVMmuLib.h b/MdePkg/Include=
/Library/BaseRiscVMmuLib.h<o:p></o:p></pre>
<pre>new file mode 100644<o:p></o:p></pre>
<pre>index 000000000000..f71d6a4a1e7b<o:p></o:p></pre>
<pre>--- /dev/null<o:p></o:p></pre>
<pre>+++ b/MdePkg/Include/Library/BaseRiscVMmuLib.h<o:p></o:p></pre>
<pre>@@ -0,0 +1,39 @@<o:p></o:p></pre>
<pre>+/** @file<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; Copyright (c) 2015 - 2016, Linaro Ltd. All rights reserved.&lt=
;BR&gt;<o:p></o:p></pre>
<pre>+&nbsp; Copyright (c) 2023, Ventana Micro Systems Inc. All Rights Rese=
rved.&lt;BR&gt;<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; SPDX-License-Identifier: BSD-2-Clause-Patent<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+**/<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+#ifndef BASE_RISCV_MMU_LIB_H_<o:p></o:p></pre>
<pre>+#define BASE_RISCV_MMU_LIB_H_<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+VOID<o:p></o:p></pre>
<pre>+EFIAPI<o:p></o:p></pre>
<pre>+RiscVLocalTlbFlushAll (<o:p></o:p></pre>
<pre>+&nbsp; VOID<o:p></o:p></pre>
<pre>+&nbsp; );<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+VOID<o:p></o:p></pre>
<pre>+EFIAPI<o:p></o:p></pre>
<pre>+RiscVLocalTlbFlush (<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp; VirtAddr<o:p></o:p></pre>
<pre>+&nbsp; );<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+EFI_STATUS<o:p></o:p></pre>
<pre>+EFIAPI<o:p></o:p></pre>
<pre>+RiscVSetMemoryAttributes (<o:p></o:p></pre>
<pre>+&nbsp; IN EFI_PHYSICAL_ADDRESS&nbsp; BaseAddress,<o:p></o:p></pre>
<pre>+&nbsp; IN UINT64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Length,<o:p></o:p></pre>
<pre>+&nbsp; IN UINT64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Attributes<o:p></o:p></pre>
<pre>+&nbsp; );<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+EFI_STATUS<o:p></o:p></pre>
<pre>+EFIAPI<o:p></o:p></pre>
<pre>+RiscVConfigureMmu (<o:p></o:p></pre>
<pre>+&nbsp; VOID<o:p></o:p></pre>
<pre>+&nbsp; );<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+#endif /* BASE_RISCV_MMU_LIB_H_ */<o:p></o:p></pre>
<pre>diff --git a/MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c b/MdePkg=
/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c<o:p></o:p></pre>
<pre>new file mode 100644<o:p></o:p></pre>
<pre>index 000000000000..230f34261d8b<o:p></o:p></pre>
<pre>--- /dev/null<o:p></o:p></pre>
<pre>+++ b/MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c<o:p></o:p></pre=
>
<pre>@@ -0,0 +1,569 @@<o:p></o:p></pre>
<pre>+/** @file<o:p></o:p></pre>
<pre>+*&nbsp; MMU implementation for RISC-V<o:p></o:p></pre>
<pre>+*<o:p></o:p></pre>
<pre>+*&nbsp; Copyright (c) 2011-2020, ARM Limited. All rights reserved.<o:=
p></o:p></pre>
<pre>+*&nbsp; Copyright (c) 2016, Linaro Limited. All rights reserved.<o:p>=
</o:p></pre>
<pre>+*&nbsp; Copyright (c) 2017, Intel Corporation. All rights reserved.&l=
t;BR&gt;<o:p></o:p></pre>
<pre>+*&nbsp; Copyright (c) 2023, Ventana Micro Systems Inc. All Rights Res=
erved.&lt;BR&gt;<o:p></o:p></pre>
<pre>+*<o:p></o:p></pre>
<pre>+*&nbsp; SPDX-License-Identifier: BSD-2-Clause-Patent<o:p></o:p></pre>
<pre>+*<o:p></o:p></pre>
<pre>+**/<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+#include &lt;PiDxe.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Uefi.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Library/BaseLib.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Library/BaseMemoryLib.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Library/BaseRiscVMmuLib.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Library/CacheMaintenanceLib.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Library/DebugLib.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Library/DxeServicesTableLib.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Library/UefiBootServicesTableLib.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Library/MemoryAllocationLib.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Library/PcdLib.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Register/RiscV64/RiscVEncoding.h&gt;<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+#define RISCV_PG_V&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; BIT0<o:p></o:p></pre>
<pre>+#define RISCV_PG_R&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; BIT1<o:p></o:p></pre>
<pre>+#define RISCV_PG_W&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; BIT2<o:p></o:p></pre>
<pre>+#define RISCV_PG_X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; BIT3<o:p></o:p></pre>
<pre>+#define RISCV_PG_G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; BIT5<o:p></o:p></pre>
<pre>+#define RISCV_PG_A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; BIT6<o:p></o:p></pre>
<pre>+#define RISCV_PG_D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; BIT7<o:p></o:p></pre>
<pre>+#define PTE_ATTRIBUTES_MASK&nbsp; 0xE<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+#define PTE_PPN_MASK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp; 0x3FFFFFFFFFFC00ULL<o:p></o:p></pre>
<pre>+#define PTE_PPN_SHIFT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
 10<o:p></o:p></pre>
<pre>+#define RISCV_MMU_PAGE_SHIFT&nbsp; 12<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC UINTN&nbsp; mMaxRootTableLevel;<o:p></o:p></pre>
<pre>+STATIC UINTN&nbsp; mBitPerLevel;<o:p></o:p></pre>
<pre>+STATIC UINTN&nbsp; mTableEntryCount;<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+BOOLEAN<o:p></o:p></pre>
<pre>+RiscVMmuEnabled (<o:p></o:p></pre>
<pre>+&nbsp; VOID<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; return ((RiscVGetSupervisorAddressTranslationRegister () &amp;=
<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SATP64_M=
ODE) !=3D (SATP_MODE_OFF &lt;&lt; SATP64_MODE_SHIFT));<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+UINTN<o:p></o:p></pre>
<pre>+RiscVGetRootTranslateTable (<o:p></o:p></pre>
<pre>+&nbsp; VOID<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; return (RiscVGetSupervisorAddressTranslationRegister () &amp; =
SATP64_PPN) &lt;&lt;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RISCV_MMU_PAGE_SHIFT=
;<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+BOOLEAN<o:p></o:p></pre>
<pre>+IsValidPte (<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp; Entry<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; if (!(Entry &amp; RISCV_PG_V) ||<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((Entry &amp; (RISCV_PG_R | RISCV_PG_=
W)) =3D=3D RISCV_PG_W)))<o:p></o:p></pre>
<pre>+&nbsp; {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; return FALSE;<o:p></o:p></pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; return TRUE;<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+UINTN<o:p></o:p></pre>
<pre>+SetValidPte (<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp; Entry<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; /* Set Valid and Global mapping bits */<o:p></o:p></pre>
<pre>+&nbsp; return Entry | RISCV_PG_G | RISCV_PG_V;<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+BOOLEAN<o:p></o:p></pre>
<pre>+IsBlockEntry (<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp; Entry<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; return IsValidPte (Entry) &amp;&amp;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Entry &amp; (RISCV_=
PG_X | RISCV_PG_R));<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+BOOLEAN<o:p></o:p></pre>
<pre>+IsTableEntry (<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp; Entry<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; return IsValidPte (Entry) &amp;&amp;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !IsBlockEntry (Entry=
);<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+UINTN<o:p></o:p></pre>
<pre>+SetTableEntry (<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp; Entry<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; Entry&nbsp; =3D SetValidPte (Entry);<o:p></o:p></pre>
<pre>+&nbsp; Entry &amp;=3D ~(RISCV_PG_X | RISCV_PG_W | RISCV_PG_R);<o:p></=
o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; return Entry;<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+VOID<o:p></o:p></pre>
<pre>+ReplaceTableEntry (<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; *Entry,<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; Value,<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; RegionStart,<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; BOOLEAN&nbsp; IsLiveBlockMapping<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; *Entry =3D Value;<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; if (IsLiveBlockMapping &amp;&amp; RiscVMmuEnabled ()) {<o:p></=
o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; RiscVLocalTlbFlush (RegionStart);<o:p></o:p></pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+UINTN<o:p></o:p></pre>
<pre>+GetPpnfromPte (<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp; Entry,<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp; Level<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; return ((Entry &amp; PTE_PPN_MASK) &gt;&gt; PTE_PPN_SHIFT);<o:=
p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+UINTN<o:p></o:p></pre>
<pre>+SetPpnToPte (<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp; Entry,<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp; Address,<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp; Level<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp; Ppn;<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; Ppn =3D ((Address &gt;&gt; RISCV_MMU_PAGE_SHIFT) &lt;&lt; PTE_=
PPN_SHIFT);<o:p></o:p></pre>
<pre>+&nbsp; ASSERT (~(Ppn &amp; ~PTE_PPN_MASK));<o:p></o:p></pre>
<pre>+&nbsp; Entry &amp;=3D ~PTE_PPN_MASK;<o:p></o:p></pre>
<pre>+&nbsp; return Entry | Ppn;<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+VOID<o:p></o:p></pre>
<pre>+FreePageTablesRecursive (<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp; *TranslationTable,<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp; Level<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp; Index;<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; if (Level &lt; mMaxRootTableLevel - 1) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; for (Index =3D 0; Index &lt; mTableEntryCount; Ind=
ex++) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (IsTableEntry (TranslationTable[Ind=
ex])) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FreePageTablesRecursive (<=
o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (UINTN *)(GetPpnfromPte ((=
TranslationTable[Index]), Level) &lt;&lt;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RISCV_MMU_PAGE_SHIFT),<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Level + 1<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; FreePages (TranslationTable, 1);<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+EFI_STATUS<o:p></o:p></pre>
<pre>+UpdateRegionMappingRecursive (<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; RegionStart,<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; RegionEnd,<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; AttributeSetMask,<o:p></o:p><=
/pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; AttributeClearMask,<o:p></o:p=
></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; *PageTable,<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; Level,<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; BOOLEAN&nbsp; TableIsLive<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; EFI_STATUS&nbsp; Status;<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;BlockShift;<o:p></o:=
p></pre>
<pre>+&nbsp; UINTN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BlockMask;<o:p></o:p=
></pre>
<pre>+&nbsp; UINTN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BlockEnd;<o:p></o:p>=
</pre>
<pre>+&nbsp; UINTN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *Entry;<o:p></o:p></=
pre>
<pre>+&nbsp; UINTN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntryValue;<o:p></o:=
p></pre>
<pre>+&nbsp; UINTN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *TranslationTable;<o=
:p></o:p></pre>
<pre>+&nbsp; BOOLEAN&nbsp;&nbsp;&nbsp;&nbsp; NextTableIsLive;<o:p></o:p></p=
re>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; ASSERT (Level &lt; mMaxRootTableLevel);<o:p></o:p></pre>
<pre>+&nbsp; ASSERT (((RegionStart | RegionEnd) &amp; EFI_PAGE_MASK) =3D=3D=
 0);<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; BlockShift =3D (mMaxRootTableLevel - Level - 1) * mBitPerLevel=
 + RISCV_MMU_PAGE_SHIFT;<o:p></o:p></pre>
<pre>+&nbsp; BlockMask&nbsp; =3D MAX_ADDRESS &gt;&gt; (64 - BlockShift);<o:=
p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; DEBUG (<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEBUG_VERBOSE,=
<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;%a(%d): =
%llx - %llx set %lx clr %lx\n&quot;,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __func__,<o:p>=
</o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Level,<o:p></o=
:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RegionStart,<o=
:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RegionEnd,<o:p=
></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AttributeSetMa=
sk,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AttributeClear=
Mask<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; for ( ; RegionStart &lt; RegionEnd; RegionStart =3D BlockEnd) =
{<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; BlockEnd =3D MIN (RegionEnd, (RegionStart | BlockM=
ask) + 1);<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; Entry&nbsp;&nbsp;&nbsp; =3D &amp;PageTable[(Region=
Start &gt;&gt; BlockShift) &amp; (mTableEntryCount - 1)];<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; //<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; // If RegionStart or BlockEnd is not aligned to th=
e block size at this<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; // level, we will have to create a table mapping i=
n order to map less<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; // than a block, and recurse to create the block o=
r page entries at<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; // the next level. No block mappings are allowed a=
t all at level 0,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; // so in that case, we have to recurse uncondition=
ally.<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; //<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; if ((Level =3D=3D 0) ||<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((RegionStart | BlockEnd)=
 &amp; BlockMask) !=3D 0) || IsTableEntry (*Entry))<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;ASSERT (Level &lt; mMaxRootTableLevel =
- 1);<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!IsTableEntry (*Entry)) {<o:p></o:=
p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // No table entry exists y=
et, so we need to allocate a page table<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // for the next level.<o:p=
></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TranslationTable =3D Alloc=
atePages (1);<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (TranslationTable =3D=
=3D NULL) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EFI_OUT=
_OF_RESOURCES;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ZeroMem (TranslationTable,=
 EFI_PAGE_SIZE);<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (IsBlockEntry (*Entry))=
 {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<o:p></o:p><=
/pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // We are spli=
tting an existing block entry, so we have to populate<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // the new tab=
le with the attributes of the block entry it replaces.<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<o:p></o:p><=
/pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Status =3D Upd=
ateRegionMappingRecursive (<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Regio=
nStart &amp; ~BlockMask,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Regi=
onStart | BlockMask) + 1,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *Entr=
y &amp; PTE_ATTRIBUTES_MASK,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PTE_A=
TTRIBUTES_MASK,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trans=
lationTable,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Level=
 + 1,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FALSE=
<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );<o:=
p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (EFI_ERROR =
(Status)) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //=
<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //=
 The range we passed to UpdateRegionMappingRecursive () is block<o:p></o:p>=
</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //=
 aligned, so it is guaranteed that no further pages were allocated<o:p></o:=
p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //=
 by it, and so we only have to free the page we allocated here.<o:p></o:p><=
/pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //=
<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fr=
eePages (TranslationTable, 1);<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; re=
turn Status;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></=
pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NextTableIsLive =3D FALSE;=
<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TranslationTable =3D (UINT=
N *)(GetPpnfromPte (*Entry, Level) &lt;&lt; RISCV_MMU_PAGE_SHIFT);<o:p></o:=
p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NextTableIsLive&nbsp; =3D =
TableIsLive;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Recurse to the next level<o:p></o:p=
></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Status =3D UpdateRegionMappingRecursiv=
e (<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RegionStart,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BlockEnd,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AttributeSetMask,<o:p></o:p><=
/pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AttributeClearMask,<o:p></o:p=
></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TranslationTable,<o:p></o:p><=
/pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Level + 1,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NextTableIsLive<o:p></o:p></p=
re>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (EFI_ERROR (Status)) {<o:p></o:p></=
pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!IsTableEntry (*Entry)=
) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<o:p></o:p><=
/pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // We are crea=
ting a new table entry, so on failure, we can free all<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // allocations=
 we made recursively, given that the whole subhierarchy<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // has not bee=
n wired into the live page tables yet. (This is not<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // possible fo=
r existing table entries, since we cannot revert the<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // modificatio=
ns we made to the subhierarchy it represents.)<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<o:p></o:p><=
/pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FreePageTables=
Recursive (TranslationTable, Level + 1);<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Status;<o:p></o:p><=
/pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!IsTableEntry (*Entry)) {<o:p></o:=
p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;EntryValue =3D SetPpnToPte=
 (0, (UINTN)TranslationTable, Level);<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntryValue =3D SetTableEnt=
ry (EntryValue);<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ReplaceTableEntry (<o:p></=
o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; Entry,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; EntryValue,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; RegionStart,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; TableIsLive<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; );<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; } else {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntryValue =3D (*Entry &amp; ~Attribut=
eClearMask) | AttributeSetMask;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // We don't have page fault exception =
handler when a virtual page is accessed and<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // the A bit is clear, or is written a=
nd the D bit is clear.<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // So just set A for read and D for wr=
ite permission.<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (AttributeSetMask &amp; RISCV_PG_R)=
 {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntryValue |=3D RISCV_PG_A=
;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (AttributeSetMask &amp; RISCV_PG_W)=
 {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntryValue |=3D RISCV_PG_D=
;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntryValue =3D SetPpnToPte (EntryValue=
, RegionStart, Level);<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntryValue =3D SetValidPte (EntryValue=
);<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ReplaceTableEntry (Entry, EntryValue, =
RegionStart, TableIsLive);<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; return EFI_SUCCESS;<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+EFI_STATUS<o:p></o:p></pre>
<pre>+UpdateRegionMapping (<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; RegionStart,<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; RegionLength,<o:p></o:p></pre=
>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; AttributeSetMask,<o:p></o:p><=
/pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; AttributeClearMask,<o:p></o:p=
></pre>
<pre>+&nbsp; IN&nbsp; UINTN&nbsp;&nbsp;&nbsp; *RootTable,<o:p></o:p></pre>
<pre>+&nbsp; IN&nbsp; BOOLEAN&nbsp; TableIsLive<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; if (((RegionStart | RegionLength) &amp; EFI_PAGE_MASK) !=3D 0)=
 {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; return EFI_INVALID_PARAMETER;<o:p></o:p></pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; return UpdateRegionMappingRecursive (<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; RegionStart,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; RegionStart + RegionLength,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; AttributeSetMask,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; AttributeClearMask,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;RootTable,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; 0,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; TableIsLive<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; );<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+UINTN<o:p></o:p></pre>
<pre>+GcdAttributeToPageAttribute (<o:p></o:p></pre>
<pre>+&nbsp; IN UINTN&nbsp; GcdAttributes<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp; RiscVAttributes =3D RISCV_PG_R | RISCV_PG_W | RISC=
V_PG_X;<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; // Determine protection attributes<o:p></o:p></pre>
<pre>+&nbsp; if (GcdAttributes &amp; EFI_MEMORY_RO) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; RiscVAttributes &amp;=3D ~(RISCV_PG_W);<o:p></o:p>=
</pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; // Process eXecute Never attribute<o:p></o:p></pre>
<pre>+&nbsp; if (GcdAttributes &amp; EFI_MEMORY_XP) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; RiscVAttributes &amp;=3D ~RISCV_PG_X;<o:p></o:p></=
pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; return RiscVAttributes;<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+EFI_STATUS<o:p></o:p></pre>
<pre>+EFIAPI<o:p></o:p></pre>
<pre>+RiscVSetMemoryAttributes (<o:p></o:p></pre>
<pre>+&nbsp; IN EFI_PHYSICAL_ADDRESS&nbsp; BaseAddress,<o:p></o:p></pre>
<pre>+&nbsp; IN UINTN&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Length,<o:p></o:p></pre>
<pre>+&nbsp; IN UINTN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Attributes<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp; PageAttributesSet =3D GcdAttributeToPageAttribute =
(Attributes);<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; if (!RiscVMmuEnabled ()) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; return EFI_SUCCESS;<o:p></o:p></pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; DEBUG (<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEBUG_VERBOSE,=
<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;%a: Set =
%llX page attribute 0x%X\n&quot;,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __func__,<o:p>=
</o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BaseAddress,<o=
:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PageAttributes=
Set<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; return UpdateRegionMapping (<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BaseAddress,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Length,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PageAttributesSet,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PTE_ATTRIBUTES_MASK,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (UINTN *)RiscVGetRootTranslateTable (),<o:p>=
</o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TRUE<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+STATIC<o:p></o:p></pre>
<pre>+EFI_STATUS<o:p></o:p></pre>
<pre>+RiscVMmuSetSatpMode&nbsp; (<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp; SatpMode<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; VOID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *TranslationTable;<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SatpReg;<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ppn;<o:p></o:p></pre>
<pre>+&nbsp; EFI_GCD_MEMORY_SPACE_DESCRIPTOR&nbsp; *MemoryMap;<o:p></o:p></=
pre>
<pre>+&nbsp; UINTN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NumberOfDescriptors;<o:p></o:p></pre>
<pre>+&nbsp; UINTN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Index;<o:p></o:p></pre>
<pre>+&nbsp; EFI_STATUS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp; Status;<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; switch (SatpMode) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; case SATP_MODE_OFF:<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EFI_SUCCESS;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; case SATP_MODE_SV39:<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mMaxRootTableLevel =3D 3;<o:p></o:p></=
pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mBitPerLevel&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp; =3D 9;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mTableEntryCount&nbsp;&nbsp; =3D 512;<=
o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; case SATP_MODE_SV48:<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mMaxRootTableLevel =3D 4;<o:p></o:p></=
pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mBitPerLevel&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp; =3D 9;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mTableEntryCount&nbsp;&nbsp; =3D 512;<=
o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; case SATP_MODE_SV57:<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mMaxRootTableLevel =3D 5;<o:p></o:p></=
pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mBitPerLevel&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp; =3D 9;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mTableEntryCount&nbsp;&nbsp; =3D 512;<=
o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; default:<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EFI_INVALID_PARAMETER;<o:p></o:=
p></pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; // Allocate pages for translation table<o:p></o:p></pre>
<pre>+&nbsp; TranslationTable =3D AllocatePages (1);<o:p></o:p></pre>
<pre>+&nbsp; if (TranslationTable =3D=3D NULL) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; return EFI_OUT_OF_RESOURCES;<o:p></o:p></pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; ZeroMem (TranslationTable, mTableEntryCount * sizeof (UINTN));=
<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; NumberOfDescriptors =3D 0;<o:p></o:p></pre>
<pre>+&nbsp; MemoryMap&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp; =3D NULL;<o:p></o:p></pre>
<pre>+&nbsp; Status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp; =3D gDS-&gt;GetMemorySpaceMap (<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;Number=
OfDescriptors,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;Memory=
Map<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );<o:p></o:=
p></pre>
<pre>+&nbsp; ASSERT_EFI_ERROR (Status);<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; for (Index =3D 0; Index &lt; NumberOfDescriptors; Index++) {<o=
:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; if (MemoryMap[Index].GcdMemoryType =3D=3D EfiGcdMe=
moryTypeMemoryMappedIo) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Default Read/Write attribute for me=
mory mapped IO<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UpdateRegionMapping (<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; MemoryMap[Index].BaseAddress,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; MemoryMap[Index].Length,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; RISCV_PG_R | RISCV_PG_W,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; PTE_ATTRIBUTES_MASK,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; TranslationTable,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; FALSE<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; );<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; } else if (MemoryMap[Index].GcdMemoryType =3D=3D E=
fiGcdMemoryTypeSystemMemory) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;// Default Read/Write/Execute attribut=
e for system memory<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UpdateRegionMapping (<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; MemoryMap[Index].BaseAddress,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; MemoryMap[Index].Length,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; RISCV_PG_R | RISCV_PG_W | RISCV_PG_X,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; PTE_ATTRIBUTES_MASK,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; TranslationTable,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; FALSE<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; );<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; FreePool ((VOID *)MemoryMap);<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; if (GetInterruptState ()) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; DisableInterrupts ();<o:p></o:p></pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; Ppn =3D (UINTN)TranslationTable &gt;&gt; RISCV_MMU_PAGE_SHIFT;=
<o:p></o:p></pre>
<pre>+&nbsp; ASSERT (!(Ppn &amp; ~(SATP64_PPN)));<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; SatpReg&nbsp; =3D Ppn;<o:p></o:p></pre>
<pre>+&nbsp; SatpReg |=3D (SatpMode &lt;&lt;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; SATP64_MODE_SHIFT) &amp; SATP64_MODE;<o:p></o:p></pre>
<pre>+&nbsp; RiscVSetSupervisorAddressTranslationRegister (SatpReg);<o:p></=
o:p></pre>
<pre>+&nbsp; /* Check if HW support the setup satp mode */<o:p></o:p></pre>
<pre>+&nbsp; if (SatpReg !=3D RiscVGetSupervisorAddressTranslationRegister =
()) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; DEBUG (<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (<o:p></=
o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DE=
BUG_VERBOSE,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &q=
uot;%a: HW does not support SATP mode:%d\n&quot;,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __=
func__,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sa=
tpMode<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<o:p></=
o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );<o:p><=
/o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; FreePageTablesRecursive (TranslationTable, 0);<o:p=
></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; return EFI_DEVICE_ERROR;<o:p></o:p></pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; RiscVLocalTlbFlushAll ();<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; if (GetInterruptState ()) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; EnableInterrupts ();<o:p></o:p></pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; return Status;<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+EFI_STATUS<o:p></o:p></pre>
<pre>+EFIAPI<o:p></o:p></pre>
<pre>+RiscVConfigureMmu (<o:p></o:p></pre>
<pre>+&nbsp; VOID<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+{<o:p></o:p></pre>
<pre>+&nbsp; EFI_STATUS&nbsp; Status =3D EFI_SUCCESS;<o:p></o:p></pre>
<pre>+&nbsp; INTN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ModeSupport[] =
=3D { SATP_MODE_SV57, SATP_MODE_SV48, SATP_MODE_SV39 };<o:p></o:p></pre>
<pre>+&nbsp; INTN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Idx;<o:p></o:p>=
</pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; /* Try to setup MMU with highest mode as possible */<o:p></o:p=
></pre>
<pre>+&nbsp; for (Idx =3D 0; Idx &lt; ARRAY_SIZE (ModeSupport); Idx++) {<o:=
p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; Status =3D RiscVMmuSetSatpMode (ModeSupport[Idx]);=
<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; if (Status =3D=3D EFI_DEVICE_ERROR) {<o:p></o:p></=
pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp; &nbsp;} else if (EFI_ERROR (Status)) {<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Status;<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; DEBUG (<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (<o:p></=
o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DE=
BUG_INFO,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &q=
uot;%a: SATP mode %d successfully configured\n&quot;,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __=
func__,<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mo=
deSupport[Idx]<o:p></o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<o:p></=
o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );<o:p><=
/o:p></pre>
<pre>+&nbsp;&nbsp;&nbsp; break;<o:p></o:p></pre>
<pre>+&nbsp; }<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+&nbsp; return Status;<o:p></o:p></pre>
<pre>+}<o:p></o:p></pre>
<pre>diff --git a/MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.inf b/MdeP=
kg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.inf<o:p></o:p></pre>
<pre>new file mode 100644<o:p></o:p></pre>
<pre>index 000000000000..8ee0127c2144<o:p></o:p></pre>
<pre>--- /dev/null<o:p></o:p></pre>
<pre>+++ b/MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.inf<o:p></o:p></p=
re>
<pre>@@ -0,0 +1,25 @@<o:p></o:p></pre>
<pre>+## @file<o:p></o:p></pre>
<pre>+#<o:p></o:p></pre>
<pre>+#&nbsp; Copyright (c) 2023, Ventana Micro Systems Inc. All Rights Res=
erved.&lt;BR&gt;<o:p></o:p></pre>
<pre>+#<o:p></o:p></pre>
<pre>+#&nbsp; SPDX-License-Identifier: BSD-2-Clause-Patent<o:p></o:p></pre>
<pre>+#<o:p></o:p></pre>
<pre>+##<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+[Defines]<o:p></o:p></pre>
<pre>+&nbsp; INF_VERSION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
=3D 0x0001001b<o:p></o:p></pre>
<pre>+&nbsp; BASE_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp; =3D BaseRiscVMmuLib<o:p></o:p></pre>
<pre>+&nbsp; FILE_GUID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp; =3D d3bc42ee-c9eb-4339-ba11-06747083d3ae<o:p></o:p></pre>
<pre>+&nbsp; MODULE_TYPE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
=3D BASE<o:p></o:p></pre>
<pre>+&nbsp; VERSION_STRING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =3D 1.0<o:p></o:p=
></pre>
<pre>+&nbsp; LIBRARY_CLASS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =3D RiscVMmu=
Lib<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+[Sources]<o:p></o:p></pre>
<pre>+&nbsp; BaseRiscVMmuLib.c<o:p></o:p></pre>
<pre>+&nbsp; RiscVMmuCore.S<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+[Packages]<o:p></o:p></pre>
<pre>+&nbsp; MdePkg/MdePkg.dec<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+[LibraryClasses]<o:p></o:p></pre>
<pre>+&nbsp; BaseLib<o:p></o:p></pre>
<pre>diff --git a/MdePkg/Library/BaseRiscVMmuLib/RiscVMmuCore.S b/MdePkg/Li=
brary/BaseRiscVMmuLib/RiscVMmuCore.S<o:p></o:p></pre>
<pre>new file mode 100644<o:p></o:p></pre>
<pre>index 000000000000..42eec4cbdf83<o:p></o:p></pre>
<pre>--- /dev/null<o:p></o:p></pre>
<pre>+++ b/MdePkg/Library/BaseRiscVMmuLib/RiscVMmuCore.S<o:p></o:p></pre>
<pre>@@ -0,0 +1,31 @@<o:p></o:p></pre>
<pre>+/** @file<o:p></o:p></pre>
<pre>+*<o:p></o:p></pre>
<pre>+*&nbsp; Copyright (c) 2023, Ventana Micro Systems Inc. All Rights Res=
erved.&lt;BR&gt;<o:p></o:p></pre>
<pre>+*<o:p></o:p></pre>
<pre>+*&nbsp; SPDX-License-Identifier: BSD-2-Clause-Patent<o:p></o:p></pre>
<pre>+*<o:p></o:p></pre>
<pre>+**/<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+#include &lt;Base.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Register/RiscV64/RiscVImpl.h&gt;<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+.text<o:p></o:p></pre>
<pre>+&nbsp; .align 3<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+//<o:p></o:p></pre>
<pre>+// Local tlb flush all.<o:p></o:p></pre>
<pre>+//<o:p></o:p></pre>
<pre>+//<o:p></o:p></pre>
<pre>+ASM_FUNC (RiscVLocalTlbFlushAll)<o:p></o:p></pre>
<pre>+sfence.vma<o:p></o:p></pre>
<pre>+ret<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>+//<o:p></o:p></pre>
<pre>+// Local tlb flush at a virtual address<o:p></o:p></pre>
<pre>+// @retval a0 : virtual address.<o:p></o:p></pre>
<pre>+//<o:p></o:p></pre>
<pre>+ASM_FUNC (<o:p></o:p></pre>
<pre>+&nbsp; RiscVLocalTlbFlush<o:p></o:p></pre>
<pre>+&nbsp; )<o:p></o:p></pre>
<pre>+sfence.vma a0<o:p></o:p></pre>
<pre>+ret<o:p></o:p></pre>
<pre>diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/R=
iscVVirt.dsc.inc<o:p></o:p></pre>
<pre>index 731f54f73f81..083a182655d3 100644<o:p></o:p></pre>
<pre>--- a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc<o:p></o:p></pre>
<pre>+++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc<o:p></o:p></pre>
<pre>@@ -83,6 +83,7 @@<o:p></o:p></pre>
<pre>&nbsp;&nbsp; # RISC-V Architectural Libraries<o:p></o:p></pre>
<pre>&nbsp;&nbsp; CpuExceptionHandlerLib|UefiCpuPkg/Library/BaseRiscV64CpuE=
xceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf<o:p></o:p></pre>
<pre>&nbsp;&nbsp; RiscVSbiLib|MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLi=
b.inf<o:p></o:p></pre>
<pre>+&nbsp; RiscVMmuLib|MdePkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.inf=
<o:p></o:p></pre>
<pre>&nbsp;&nbsp; PlatformBootManagerLib|OvmfPkg/RiscVVirt/Library/Platform=
BootManagerLib/PlatformBootManagerLib.inf<o:p></o:p></pre>
<pre>&nbsp;&nbsp; ResetSystemLib|OvmfPkg/RiscVVirt/Library/ResetSystemLib/B=
aseResetSystemLib.inf<o:p></o:p></pre>
<pre> <o:p></o:p></pre>
<pre>diff --git a/OvmfPkg/RiscVVirt/Sec/Memory.c b/OvmfPkg/RiscVVirt/Sec/Me=
mory.c<o:p></o:p></pre>
<pre>index 0e2690c73687..69041f6404a4 100644<o:p></o:p></pre>
<pre>--- a/OvmfPkg/RiscVVirt/Sec/Memory.c<o:p></o:p></pre>
<pre>+++ b/OvmfPkg/RiscVVirt/Sec/Memory.c<o:p></o:p></pre>
<pre>@@ -85,21 +85,6 @@ AddMemoryRangeHob (<o:p></o:p></pre>
<pre>&nbsp;&nbsp; AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - =
MemoryBase));<o:p></o:p></pre>
<pre> }<o:p></o:p></pre>
<pre> <o:p></o:p></pre>
<pre>-/**<o:p></o:p></pre>
<pre>-&nbsp; Configure MMU<o:p></o:p></pre>
<pre>-**/<o:p></o:p></pre>
<pre>-STATIC<o:p></o:p></pre>
<pre>-VOID<o:p></o:p></pre>
<pre>-InitMmu (<o:p></o:p></pre>
<pre>-&nbsp; )<o:p></o:p></pre>
<pre>-{<o:p></o:p></pre>
<pre>-&nbsp; //<o:p></o:p></pre>
<pre>-&nbsp; // Set supervisor translation mode to Bare mode<o:p></o:p></pr=
e>
<pre>-&nbsp; //<o:p></o:p></pre>
<pre>-&nbsp; RiscVSetSupervisorAddressTranslationRegister ((UINT64)SATP_MOD=
E_OFF &lt;&lt; 60);<o:p></o:p></pre>
<pre>-&nbsp; DEBUG ((DEBUG_INFO, &quot;%a: Set Supervisor address mode to b=
are-metal mode.\n&quot;, __func__));<o:p></o:p></pre>
<pre>-}<o:p></o:p></pre>
<pre>-<o:p></o:p></pre>
<pre> /**<o:p></o:p></pre>
<pre>&nbsp;&nbsp; Publish system RAM and reserve memory regions.<o:p></o:p>=
</pre>
<pre> <o:p></o:p></pre>
<pre>@@ -327,7 +312,8 @@ MemoryPeimInitialization (<o:p></o:p></pre>
<pre> <o:p></o:p></pre>
<pre>&nbsp;&nbsp;&nbsp;AddReservedMemoryMap (FdtPointer);<o:p></o:p></pre>
<pre> <o:p></o:p></pre>
<pre>-&nbsp; InitMmu ();<o:p></o:p></pre>
<pre>+&nbsp; /* Make sure SEC is booting with bare mode*/<o:p></o:p></pre>
<pre>+&nbsp; ASSERT ((RiscVGetSupervisorAddressTranslationRegister () &amp;=
 SATP64_MODE) =3D=3D (SATP_MODE_OFF &lt;&lt; SATP64_MODE_SHIFT));<o:p></o:p=
></pre>
<pre> <o:p></o:p></pre>
<pre>&nbsp;&nbsp;&nbsp;BuildMemoryTypeInformationHob ();<o:p></o:p></pre>
<pre> <o:p></o:p></pre>
<pre>diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxeRisc=
V64/CpuDxe.c<o:p></o:p></pre>
<pre>index 25fe3f54c325..2af3b6223450 100644<o:p></o:p></pre>
<pre>--- a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c<o:p></o:p></pre>
<pre>+++ b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c<o:p></o:p></pre>
<pre>@@ -296,8 +296,7 @@ CpuSetMemoryAttributes (<o:p></o:p></pre>
<pre>&nbsp;&nbsp; IN UINT64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Attributes<o:p></o:p></pre=
>
<pre>&nbsp;&nbsp; )<o:p></o:p></pre>
<pre> {<o:p></o:p></pre>
<pre>-&nbsp; DEBUG ((DEBUG_INFO, &quot;%a: Set memory attributes not suppor=
ted yet\n&quot;, __func__));<o:p></o:p></pre>
<pre>-&nbsp; return EFI_SUCCESS;<o:p></o:p></pre>
<pre>+&nbsp; return RiscVSetMemoryAttributes (BaseAddress, Length, Attribut=
es);<o:p></o:p></pre>
<pre> }<o:p></o:p></pre>
<pre> <o:p></o:p></pre>
<pre>&nbsp;/**<o:p></o:p></pre>
<pre>@@ -340,6 +339,12 @@ InitializeCpu (<o:p></o:p></pre>
<pre>&nbsp;&nbsp; //<o:p></o:p></pre>
<pre>&nbsp;&nbsp; DisableInterrupts ();<o:p></o:p></pre>
<pre> <o:p></o:p></pre>
<pre>+&nbsp; //<o:p></o:p></pre>
<pre>+&nbsp; // Enable MMU<o:p></o:p></pre>
<pre>+&nbsp; //<o:p></o:p></pre>
<pre>+&nbsp; Status =3D RiscVConfigureMmu ();<o:p></o:p></pre>
<pre>+&nbsp; ASSERT_EFI_ERROR (Status);<o:p></o:p></pre>
<pre>+<o:p></o:p></pre>
<pre>&nbsp;&nbsp; //<o:p></o:p></pre>
<pre>&nbsp;&nbsp; // Install Boot protocol<o:p></o:p></pre>
<pre>&nbsp;&nbsp; //<o:p></o:p></pre>
<pre>diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxeRisc=
V64/CpuDxe.h<o:p></o:p></pre>
<pre>index 49f4e119665a..68e6d038b66e 100644<o:p></o:p></pre>
<pre>--- a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h<o:p></o:p></pre>
<pre>+++ b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h<o:p></o:p></pre>
<pre>@@ -15,11 +15,13 @@<o:p></o:p></pre>
<pre> #include &lt;Protocol/Cpu.h&gt;<o:p></o:p></pre>
<pre> #include &lt;Protocol/RiscVBootProtocol.h&gt;<o:p></o:p></pre>
<pre> #include &lt;Library/BaseRiscVSbiLib.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Library/BaseRiscVMmuLib.h&gt;<o:p></o:p></pre>
<pre> #include &lt;Library/BaseLib.h&gt;<o:p></o:p></pre>
<pre> #include &lt;Library/CpuExceptionHandlerLib.h&gt;<o:p></o:p></pre>
<pre> #include &lt;Library/DebugLib.h&gt;<o:p></o:p></pre>
<pre> #include &lt;Library/UefiBootServicesTableLib.h&gt;<o:p></o:p></pre>
<pre> #include &lt;Library/UefiDriverEntryPoint.h&gt;<o:p></o:p></pre>
<pre>+#include &lt;Register/RiscV64/RiscVEncoding.h&gt;<o:p></o:p></pre>
<pre> <o:p></o:p></pre>
<pre>&nbsp;/**<o:p></o:p></pre>
<pre>&nbsp;&nbsp; Flush CPU data cache. If the instruction cache is fully c=
oherent<o:p></o:p></pre>
<pre>diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf b/UefiCpuPkg/C=
puDxeRiscV64/CpuDxeRiscV64.inf<o:p></o:p></pre>
<pre>index e8fa25446aef..9d9a5ef8f247 100644<o:p></o:p></pre>
<pre>--- a/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf<o:p></o:p></pre>
<pre>+++ b/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf<o:p></o:p></pre>
<pre>@@ -37,6 +37,8 @@<o:p></o:p></pre>
<pre>&nbsp;&nbsp; TimerLib<o:p></o:p></pre>
<pre>&nbsp;&nbsp; PeCoffGetEntryPointLib<o:p></o:p></pre>
<pre>&nbsp;&nbsp; RiscVSbiLib<o:p></o:p></pre>
<pre>+&nbsp; RiscVMmuLib<o:p></o:p></pre>
<pre>+&nbsp; CacheMaintenanceLib<o:p></o:p></pre>
<pre> <o:p></o:p></pre>
<pre>&nbsp;[Sources]<o:p></o:p></pre>
<pre>&nbsp;&nbsp; CpuDxe.c<o:p></o:p></pre>
</blockquote>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt"><o:p></o:p></span><=
/p>
</div>
</div>
</body>
</html>

--_000_MN2PR13MB30225A5769E6AF33496072E0A7419MN2PR13MB3022namp_--