* [PATCH v2 0/6] RISC-V MMU support @ 2023-04-14 18:58 Tuan Phan 2023-04-14 18:58 ` [PATCH v2 1/6] MdePkg/BaseLib: RISC-V: Support getting satp register value Tuan Phan ` (6 more replies) 0 siblings, 7 replies; 17+ messages in thread From: Tuan Phan @ 2023-04-14 18:58 UTC (permalink / raw) To: devel Cc: michael.d.kinney, gaoliming, zhiguang.liu, sunilvl, git, andrei.warkentin, Tuan Phan RISC-V: Add MMU support This series adds MMU support for RISC-V. Only SV39/48/57 modes are supported and tested. The MMU is required to support setting page attribute which is the first basic step to support security booting on RISC-V. There are three parts: 1. Add MMU base library. MMU will be enabled during CpuDxe initialization. 2. Fix OvmfPkg/VirtNorFlashDxe that failed to add flash base address to GCD if already done. 3. Fix all resources should be populated in HOB or added to GCD by driver before accessing when MMU enabled. Changes in v2: - Move MMU core to a library. - Setup SATP mode as highest possible that HW supports. Tuan Phan (6): MdePkg/BaseLib: RISC-V: Support getting satp register value MdePkg/Register: RISC-V: Add satp mode bits shift definition UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode OvmfPkg/RiscVVirt: VirtNorFlashPlatformLib: Fix wrong flash size OvmfPkg/VirtNorFlashDxe: Not add memory space if it exists OvmfPkg/RiscVVirt: SEC: Add IO memory resource hob for platform devices MdePkg/Include/Library/BaseLib.h | 5 + MdePkg/Include/Library/BaseRiscVMmuLib.h | 39 ++ .../Include/Register/RiscV64/RiscVEncoding.h | 7 +- MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S | 8 + .../Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c | 569 ++++++++++++++++++ .../BaseRiscVMmuLib/BaseRiscVMmuLib.inf | 25 + MdePkg/Library/BaseRiscVMmuLib/RiscVMmuCore.S | 31 + .../VirtNorFlashStaticLib.c | 3 +- OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc | 1 + OvmfPkg/RiscVVirt/Sec/Memory.c | 18 +- OvmfPkg/RiscVVirt/Sec/Platform.c | 62 ++ OvmfPkg/RiscVVirt/Sec/SecMain.inf | 1 + OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c | 25 +- UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c | 9 +- UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h | 2 + UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf | 2 + 16 files changed, 776 insertions(+), 31 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 -- 2.25.1 ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 1/6] MdePkg/BaseLib: RISC-V: Support getting satp register value 2023-04-14 18:58 [PATCH v2 0/6] RISC-V MMU support Tuan Phan @ 2023-04-14 18:58 ` Tuan Phan 2023-04-18 16:02 ` Andrei Warkentin 2023-04-14 18:58 ` [PATCH v2 2/6] MdePkg/Register: RISC-V: Add satp mode bits shift definition Tuan Phan ` (5 subsequent siblings) 6 siblings, 1 reply; 17+ messages in thread From: Tuan Phan @ 2023-04-14 18:58 UTC (permalink / raw) To: devel Cc: michael.d.kinney, gaoliming, zhiguang.liu, sunilvl, git, andrei.warkentin, Tuan Phan Add an API to retrieve satp register value. Signed-off-by: Tuan Phan <tphan@ventanamicro.com> --- MdePkg/Include/Library/BaseLib.h | 5 +++++ MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 8f2df76c29a3..5d7067ee854e 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -181,6 +181,11 @@ RiscVSetSupervisorAddressTranslationRegister ( IN UINT64 ); +UINT64 +RiscVGetSupervisorAddressTranslationRegister ( + VOID + ); + UINT64 RiscVReadTimer ( VOID diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S b/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S index ac8f92f38aed..c9cf60c1664b 100644 --- a/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S +++ b/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S @@ -21,3 +21,11 @@ ASM_FUNC (RiscVSetSupervisorAddressTranslationRegister) csrw CSR_SATP, a0 ret + +// +// Get the value of Supervisor Address Translation and +// Protection Register. +// +ASM_FUNC (RiscVGetSupervisorAddressTranslationRegister) + csrr a0, CSR_SATP + ret -- 2.25.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/6] MdePkg/BaseLib: RISC-V: Support getting satp register value 2023-04-14 18:58 ` [PATCH v2 1/6] MdePkg/BaseLib: RISC-V: Support getting satp register value Tuan Phan @ 2023-04-18 16:02 ` Andrei Warkentin 0 siblings, 0 replies; 17+ messages in thread From: Andrei Warkentin @ 2023-04-18 16:02 UTC (permalink / raw) To: Tuan Phan, devel@edk2.groups.io Cc: Kinney, Michael D, Gao, Liming, Liu, Zhiguang, sunilvl@ventanamicro.com, git@danielschaefer.me Looks reasonable to me. Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com> > -----Original Message----- > From: Tuan Phan <tphan@ventanamicro.com> > Sent: Friday, April 14, 2023 1:58 PM > To: devel@edk2.groups.io > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming > <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>; > sunilvl@ventanamicro.com; git@danielschaefer.me; Warkentin, Andrei > <andrei.warkentin@intel.com>; Tuan Phan <tphan@ventanamicro.com> > Subject: [PATCH v2 1/6] MdePkg/BaseLib: RISC-V: Support getting satp > register value > > Add an API to retrieve satp register value. > > Signed-off-by: Tuan Phan <tphan@ventanamicro.com> > --- > MdePkg/Include/Library/BaseLib.h | 5 +++++ > MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S | 8 ++++++++ > 2 files changed, 13 insertions(+) > > diff --git a/MdePkg/Include/Library/BaseLib.h > b/MdePkg/Include/Library/BaseLib.h > index 8f2df76c29a3..5d7067ee854e 100644 > --- a/MdePkg/Include/Library/BaseLib.h > +++ b/MdePkg/Include/Library/BaseLib.h > @@ -181,6 +181,11 @@ RiscVSetSupervisorAddressTranslationRegister ( > IN UINT64 > > ); > > > > +UINT64 > > +RiscVGetSupervisorAddressTranslationRegister ( > > + VOID > > + ); > > + > > UINT64 > > RiscVReadTimer ( > > VOID > > diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S > b/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S > index ac8f92f38aed..c9cf60c1664b 100644 > --- a/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S > +++ b/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S > @@ -21,3 +21,11 @@ > ASM_FUNC (RiscVSetSupervisorAddressTranslationRegister) > > csrw CSR_SATP, a0 > > ret > > + > > +// > > +// Get the value of Supervisor Address Translation and > > +// Protection Register. > > +// > > +ASM_FUNC (RiscVGetSupervisorAddressTranslationRegister) > > + csrr a0, CSR_SATP > > + ret > > -- > 2.25.1 ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 2/6] MdePkg/Register: RISC-V: Add satp mode bits shift definition 2023-04-14 18:58 [PATCH v2 0/6] RISC-V MMU support Tuan Phan 2023-04-14 18:58 ` [PATCH v2 1/6] MdePkg/BaseLib: RISC-V: Support getting satp register value Tuan Phan @ 2023-04-14 18:58 ` Tuan Phan 2023-04-18 16:05 ` Andrei Warkentin 2023-04-14 18:58 ` [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode Tuan Phan ` (4 subsequent siblings) 6 siblings, 1 reply; 17+ messages in thread From: Tuan Phan @ 2023-04-14 18:58 UTC (permalink / raw) To: devel Cc: michael.d.kinney, gaoliming, zhiguang.liu, sunilvl, git, andrei.warkentin, Tuan Phan The satp mode bits shift is used cross modules. It should be defined in one place. Signed-off-by: Tuan Phan <tphan@ventanamicro.com> --- MdePkg/Include/Register/RiscV64/RiscVEncoding.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/MdePkg/Include/Register/RiscV64/RiscVEncoding.h b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h index 5c2989b797bf..2bde8db478ff 100644 --- a/MdePkg/Include/Register/RiscV64/RiscVEncoding.h +++ b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h @@ -58,9 +58,10 @@ #define PRV_S 1UL #define PRV_M 3UL -#define SATP64_MODE 0xF000000000000000ULL -#define SATP64_ASID 0x0FFFF00000000000ULL -#define SATP64_PPN 0x00000FFFFFFFFFFFULL +#define SATP64_MODE 0xF000000000000000ULL +#define SATP64_MODE_SHIFT 60 +#define SATP64_ASID 0x0FFFF00000000000ULL +#define SATP64_PPN 0x00000FFFFFFFFFFFULL #define SATP_MODE_OFF 0UL #define SATP_MODE_SV32 1UL -- 2.25.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v2 2/6] MdePkg/Register: RISC-V: Add satp mode bits shift definition 2023-04-14 18:58 ` [PATCH v2 2/6] MdePkg/Register: RISC-V: Add satp mode bits shift definition Tuan Phan @ 2023-04-18 16:05 ` Andrei Warkentin 0 siblings, 0 replies; 17+ messages in thread From: Andrei Warkentin @ 2023-04-18 16:05 UTC (permalink / raw) To: Tuan Phan, devel@edk2.groups.io Cc: Kinney, Michael D, Gao, Liming, Liu, Zhiguang, sunilvl@ventanamicro.com, git@danielschaefer.me Looks reasonable to me (but my email view of the patch is corrupted... so please follow up with a link to a Github branch) Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com> > -----Original Message----- > From: Tuan Phan <tphan@ventanamicro.com> > Sent: Friday, April 14, 2023 1:58 PM > To: devel@edk2.groups.io > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming > <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>; > sunilvl@ventanamicro.com; git@danielschaefer.me; Warkentin, Andrei > <andrei.warkentin@intel.com>; Tuan Phan <tphan@ventanamicro.com> > Subject: [PATCH v2 2/6] MdePkg/Register: RISC-V: Add satp mode bits shift > definition > > The satp mode bits shift is used cross modules. It should be defined in one > place. > > Signed-off-by: Tuan Phan <tphan@ventanamicro.com> > --- > MdePkg/Include/Register/RiscV64/RiscVEncoding.h | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/MdePkg/Include/Register/RiscV64/RiscVEncoding.h > b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h > index 5c2989b797bf..2bde8db478ff 100644 > --- a/MdePkg/Include/Register/RiscV64/RiscVEncoding.h > +++ b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h > @@ -58,9 +58,10 @@ > #define PRV_S 1UL #define PRV_M 3UL -#define SATP64_MODE > 0xF000000000000000ULL-#define SATP64_ASID 0x0FFFF00000000000ULL- > #define SATP64_PPN 0x00000FFFFFFFFFFFULL+#define SATP64_MODE > 0xF000000000000000ULL+#define SATP64_MODE_SHIFT 60+#define > SATP64_ASID 0x0FFFF00000000000ULL+#define SATP64_PPN > 0x00000FFFFFFFFFFFULL #define SATP_MODE_OFF 0UL #define > SATP_MODE_SV32 1UL-- > 2.25.1 ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode 2023-04-14 18:58 [PATCH v2 0/6] RISC-V MMU support Tuan Phan 2023-04-14 18:58 ` [PATCH v2 1/6] MdePkg/BaseLib: RISC-V: Support getting satp register value Tuan Phan 2023-04-14 18:58 ` [PATCH v2 2/6] MdePkg/Register: RISC-V: Add satp mode bits shift definition Tuan Phan @ 2023-04-14 18:58 ` Tuan Phan 2023-05-24 2:10 ` [edk2-devel] " Chao Li 2023-04-14 18:58 ` [PATCH v2 4/6] OvmfPkg/RiscVVirt: VirtNorFlashPlatformLib: Fix wrong flash size Tuan Phan ` (3 subsequent siblings) 6 siblings, 1 reply; 17+ messages in thread From: Tuan Phan @ 2023-04-14 18:58 UTC (permalink / raw) To: devel Cc: michael.d.kinney, gaoliming, zhiguang.liu, sunilvl, git, andrei.warkentin, Tuan Phan During CpuDxe initialization, MMU will be setup with the highest mode that HW supports. Signed-off-by: Tuan Phan <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/Library/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/Library/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) != (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)) == 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 = SetValidPte (Entry); + Entry &= ~(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 = 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 = ((Address >> RISCV_MMU_PAGE_SHIFT) << PTE_PPN_SHIFT); + ASSERT (~(Ppn & ~PTE_PPN_MASK)); + Entry &= ~PTE_PPN_MASK; + return Entry | Ppn; +} + +STATIC +VOID +FreePageTablesRecursive ( + IN UINTN *TranslationTable, + IN UINTN Level + ) +{ + UINTN Index; + + if (Level < mMaxRootTableLevel - 1) { + for (Index = 0; Index < mTableEntryCount; Index++) { + if (IsTableEntry (TranslationTable[Index])) { + FreePageTablesRecursive ( + (UINTN *)(GetPpnfromPte ((TranslationTable[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) == 0); + + BlockShift = (mMaxRootTableLevel - Level - 1) * mBitPerLevel + RISCV_MMU_PAGE_SHIFT; + BlockMask = 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 = BlockEnd) { + BlockEnd = MIN (RegionEnd, (RegionStart | BlockMask) + 1); + Entry = &PageTable[(RegionStart >> BlockShift) & (mTableEntryCount - 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 == 0) || + (((RegionStart | BlockEnd) & BlockMask) != 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 = AllocatePages (1); + if (TranslationTable == 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 populate + // the new table with the attributes of the block entry it replaces. + // + Status = UpdateRegionMappingRecursive ( + RegionStart & ~BlockMask, + (RegionStart | BlockMask) + 1, + *Entry & PTE_ATTRIBUTES_MASK, + PTE_ATTRIBUTES_MASK, + TranslationTable, + Level + 1, + FALSE + ); + if (EFI_ERROR (Status)) { + // + // The range we passed to UpdateRegionMappingRecursive () is block + // aligned, so it is guaranteed that no further pages were allocated + // by it, and so we only have to free the page we allocated here. + // + FreePages (TranslationTable, 1); + return Status; + } + } + + NextTableIsLive = FALSE; + } else { + TranslationTable = (UINTN *)(GetPpnfromPte (*Entry, Level) << RISCV_MMU_PAGE_SHIFT); + NextTableIsLive = TableIsLive; + } + + // + // Recurse to the next level + // + Status = 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 subhierarchy + // has not been wired into the live page tables yet. (This is not + // possible for existing table entries, since we cannot revert the + // modifications we made to the subhierarchy it represents.) + // + FreePageTablesRecursive (TranslationTable, Level + 1); + } + + return Status; + } + + if (!IsTableEntry (*Entry)) { + EntryValue = SetPpnToPte (0, (UINTN)TranslationTable, Level); + EntryValue = SetTableEntry (EntryValue); + ReplaceTableEntry ( + Entry, + EntryValue, + RegionStart, + TableIsLive + ); + } + } else { + EntryValue = (*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 |= RISCV_PG_A; + } + + if (AttributeSetMask & RISCV_PG_W) { + EntryValue |= RISCV_PG_D; + } + + EntryValue = SetPpnToPte (EntryValue, RegionStart, Level); + EntryValue = 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) != 0) { + return EFI_INVALID_PARAMETER; + } + + return UpdateRegionMappingRecursive ( + RegionStart, + RegionStart + RegionLength, + AttributeSetMask, + AttributeClearMask, + RootTable, + 0, + TableIsLive + ); +} + +STATIC +UINTN +GcdAttributeToPageAttribute ( + IN UINTN GcdAttributes + ) +{ + UINTN RiscVAttributes = RISCV_PG_R | RISCV_PG_W | RISCV_PG_X; + + // Determine protection attributes + if (GcdAttributes & EFI_MEMORY_RO) { + RiscVAttributes &= ~(RISCV_PG_W); + } + + // Process eXecute Never attribute + if (GcdAttributes & EFI_MEMORY_XP) { + RiscVAttributes &= ~RISCV_PG_X; + } + + return RiscVAttributes; +} + +EFI_STATUS +EFIAPI +RiscVSetMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length, + IN UINTN Attributes + ) +{ + UINTN PageAttributesSet = 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 = 3; + mBitPerLevel = 9; + mTableEntryCount = 512; + break; + case SATP_MODE_SV48: + mMaxRootTableLevel = 4; + mBitPerLevel = 9; + mTableEntryCount = 512; + break; + case SATP_MODE_SV57: + mMaxRootTableLevel = 5; + mBitPerLevel = 9; + mTableEntryCount = 512; + break; + default: + return EFI_INVALID_PARAMETER; + } + + // Allocate pages for translation table + TranslationTable = AllocatePages (1); + if (TranslationTable == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem (TranslationTable, mTableEntryCount * sizeof (UINTN)); + + NumberOfDescriptors = 0; + MemoryMap = NULL; + Status = gDS->GetMemorySpaceMap ( + &NumberOfDescriptors, + &MemoryMap + ); + ASSERT_EFI_ERROR (Status); + + for (Index = 0; Index < NumberOfDescriptors; Index++) { + if (MemoryMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) { + // 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 == EfiGcdMemoryTypeSystemMemory) { + // 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 = (UINTN)TranslationTable >> RISCV_MMU_PAGE_SHIFT; + ASSERT (!(Ppn & ~(SATP64_PPN))); + + SatpReg = Ppn; + SatpReg |= (SatpMode << + SATP64_MODE_SHIFT) & SATP64_MODE; + RiscVSetSupervisorAddressTranslationRegister (SatpReg); + /* Check if HW support the setup satp mode */ + if (SatpReg != 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 = EFI_SUCCESS; + INTN ModeSupport[] = { SATP_MODE_SV57, SATP_MODE_SV48, SATP_MODE_SV39 }; + INTN Idx; + + /* Try to setup MMU with highest mode as possible */ + for (Idx = 0; Idx < ARRAY_SIZE (ModeSupport); Idx++) { + Status = RiscVMmuSetSatpMode (ModeSupport[Idx]); + if (Status == 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/Library/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 = 0x0001001b + BASE_NAME = BaseRiscVMmuLib + FILE_GUID = d3bc42ee-c9eb-4339-ba11-06747083d3ae + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = 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/RiscVVirt.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/BaseRiscV64CpuExceptionHandlerLib/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/BaseResetSystemLib.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 << 60); - 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) == (SATP_MODE_OFF << SATP64_MODE_SHIFT)); BuildMemoryTypeInformationHob (); diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.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", __func__)); - return EFI_SUCCESS; + return RiscVSetMemoryAttributes (BaseAddress, Length, Attributes); } /** @@ -340,6 +339,12 @@ InitializeCpu ( // DisableInterrupts (); + // + // Enable MMU + // + Status = RiscVConfigureMmu (); + ASSERT_EFI_ERROR (Status); + // // Install Boot protocol // diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.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/CpuDxeRiscV64/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 -- 2.25.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode 2023-04-14 18:58 ` [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode Tuan Phan @ 2023-05-24 2:10 ` Chao Li 2023-05-24 9:51 ` Ni, Ray 0 siblings, 1 reply; 17+ messages in thread From: Chao Li @ 2023-05-24 2:10 UTC (permalink / raw) To: devel, tphan Cc: michael.d.kinney, gaoliming, zhiguang.liu, sunilvl, git, andrei.warkentin, Ni, Ray [-- Attachment #1: Type: text/plain, Size: 24984 bytes --] Dear all, I'm also porting MMU library of LoongArch64 to EDK2, I added it in to UefiCpuPkg 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 CpuPageTableLib to UefiCpuPkg, this library are similar to MMU libraries. I have a question, should the MMU library be in the MdePkg or UefiCpuPkg? Thanks, Chao 在 2023/4/15 02:58, Tuan Phan 写道: > During CpuDxe initialization, MMU will be setup with the highest > mode that HW supports. > > Signed-off-by: Tuan Phan<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/Library/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/Library/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) != (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)) == 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 = SetValidPte (Entry); > + Entry &= ~(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 = 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 = ((Address >> RISCV_MMU_PAGE_SHIFT) << PTE_PPN_SHIFT); > + ASSERT (~(Ppn & ~PTE_PPN_MASK)); > + Entry &= ~PTE_PPN_MASK; > + return Entry | Ppn; > +} > + > +STATIC > +VOID > +FreePageTablesRecursive ( > + IN UINTN *TranslationTable, > + IN UINTN Level > + ) > +{ > + UINTN Index; > + > + if (Level < mMaxRootTableLevel - 1) { > + for (Index = 0; Index < mTableEntryCount; Index++) { > + if (IsTableEntry (TranslationTable[Index])) { > + FreePageTablesRecursive ( > + (UINTN *)(GetPpnfromPte ((TranslationTable[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) == 0); > + > + BlockShift = (mMaxRootTableLevel - Level - 1) * mBitPerLevel + RISCV_MMU_PAGE_SHIFT; > + BlockMask = 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 = BlockEnd) { > + BlockEnd = MIN (RegionEnd, (RegionStart | BlockMask) + 1); > + Entry = &PageTable[(RegionStart >> BlockShift) & (mTableEntryCount - 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 == 0) || > + (((RegionStart | BlockEnd) & BlockMask) != 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 = AllocatePages (1); > + if (TranslationTable == 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 populate > + // the new table with the attributes of the block entry it replaces. > + // > + Status = UpdateRegionMappingRecursive ( > + RegionStart & ~BlockMask, > + (RegionStart | BlockMask) + 1, > + *Entry & PTE_ATTRIBUTES_MASK, > + PTE_ATTRIBUTES_MASK, > + TranslationTable, > + Level + 1, > + FALSE > + ); > + if (EFI_ERROR (Status)) { > + // > + // The range we passed to UpdateRegionMappingRecursive () is block > + // aligned, so it is guaranteed that no further pages were allocated > + // by it, and so we only have to free the page we allocated here. > + // > + FreePages (TranslationTable, 1); > + return Status; > + } > + } > + > + NextTableIsLive = FALSE; > + } else { > + TranslationTable = (UINTN *)(GetPpnfromPte (*Entry, Level) << RISCV_MMU_PAGE_SHIFT); > + NextTableIsLive = TableIsLive; > + } > + > + // > + // Recurse to the next level > + // > + Status = 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 subhierarchy > + // has not been wired into the live page tables yet. (This is not > + // possible for existing table entries, since we cannot revert the > + // modifications we made to the subhierarchy it represents.) > + // > + FreePageTablesRecursive (TranslationTable, Level + 1); > + } > + > + return Status; > + } > + > + if (!IsTableEntry (*Entry)) { > + EntryValue = SetPpnToPte (0, (UINTN)TranslationTable, Level); > + EntryValue = SetTableEntry (EntryValue); > + ReplaceTableEntry ( > + Entry, > + EntryValue, > + RegionStart, > + TableIsLive > + ); > + } > + } else { > + EntryValue = (*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 |= RISCV_PG_A; > + } > + > + if (AttributeSetMask & RISCV_PG_W) { > + EntryValue |= RISCV_PG_D; > + } > + > + EntryValue = SetPpnToPte (EntryValue, RegionStart, Level); > + EntryValue = 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) != 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + return UpdateRegionMappingRecursive ( > + RegionStart, > + RegionStart + RegionLength, > + AttributeSetMask, > + AttributeClearMask, > + RootTable, > + 0, > + TableIsLive > + ); > +} > + > +STATIC > +UINTN > +GcdAttributeToPageAttribute ( > + IN UINTN GcdAttributes > + ) > +{ > + UINTN RiscVAttributes = RISCV_PG_R | RISCV_PG_W | RISCV_PG_X; > + > + // Determine protection attributes > + if (GcdAttributes & EFI_MEMORY_RO) { > + RiscVAttributes &= ~(RISCV_PG_W); > + } > + > + // Process eXecute Never attribute > + if (GcdAttributes & EFI_MEMORY_XP) { > + RiscVAttributes &= ~RISCV_PG_X; > + } > + > + return RiscVAttributes; > +} > + > +EFI_STATUS > +EFIAPI > +RiscVSetMemoryAttributes ( > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > + IN UINTN Length, > + IN UINTN Attributes > + ) > +{ > + UINTN PageAttributesSet = 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 = 3; > + mBitPerLevel = 9; > + mTableEntryCount = 512; > + break; > + case SATP_MODE_SV48: > + mMaxRootTableLevel = 4; > + mBitPerLevel = 9; > + mTableEntryCount = 512; > + break; > + case SATP_MODE_SV57: > + mMaxRootTableLevel = 5; > + mBitPerLevel = 9; > + mTableEntryCount = 512; > + break; > + default: > + return EFI_INVALID_PARAMETER; > + } > + > + // Allocate pages for translation table > + TranslationTable = AllocatePages (1); > + if (TranslationTable == NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + ZeroMem (TranslationTable, mTableEntryCount * sizeof (UINTN)); > + > + NumberOfDescriptors = 0; > + MemoryMap = NULL; > + Status = gDS->GetMemorySpaceMap ( > + &NumberOfDescriptors, > + &MemoryMap > + ); > + ASSERT_EFI_ERROR (Status); > + > + for (Index = 0; Index < NumberOfDescriptors; Index++) { > + if (MemoryMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) { > + // 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 == EfiGcdMemoryTypeSystemMemory) { > + // 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 = (UINTN)TranslationTable >> RISCV_MMU_PAGE_SHIFT; > + ASSERT (!(Ppn & ~(SATP64_PPN))); > + > + SatpReg = Ppn; > + SatpReg |= (SatpMode << > + SATP64_MODE_SHIFT) & SATP64_MODE; > + RiscVSetSupervisorAddressTranslationRegister (SatpReg); > + /* Check if HW support the setup satp mode */ > + if (SatpReg != 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 = EFI_SUCCESS; > + INTN ModeSupport[] = { SATP_MODE_SV57, SATP_MODE_SV48, SATP_MODE_SV39 }; > + INTN Idx; > + > + /* Try to setup MMU with highest mode as possible */ > + for (Idx = 0; Idx < ARRAY_SIZE (ModeSupport); Idx++) { > + Status = RiscVMmuSetSatpMode (ModeSupport[Idx]); > + if (Status == 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/Library/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 = 0x0001001b > + BASE_NAME = BaseRiscVMmuLib > + FILE_GUID = d3bc42ee-c9eb-4339-ba11-06747083d3ae > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = 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/RiscVVirt.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/BaseRiscV64CpuExceptionHandlerLib/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/BaseResetSystemLib.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 << 60); > - 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) == (SATP_MODE_OFF << SATP64_MODE_SHIFT)); > > BuildMemoryTypeInformationHob (); > > diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.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", __func__)); > - return EFI_SUCCESS; > + return RiscVSetMemoryAttributes (BaseAddress, Length, Attributes); > } > > /** > @@ -340,6 +339,12 @@ InitializeCpu ( > // > DisableInterrupts (); > > + // > + // Enable MMU > + // > + Status = RiscVConfigureMmu (); > + ASSERT_EFI_ERROR (Status); > + > // > // Install Boot protocol > // > diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.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/CpuDxeRiscV64/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 [-- Attachment #2: Type: text/html, Size: 24518 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode 2023-05-24 2:10 ` [edk2-devel] " Chao Li @ 2023-05-24 9:51 ` Ni, Ray 2023-05-24 18:16 ` Tuan Phan 0 siblings, 1 reply; 17+ messages in thread From: Ni, Ray @ 2023-05-24 9:51 UTC (permalink / raw) To: devel@edk2.groups.io, lichao@loongson.cn, tphan@ventanamicro.com, Ard Biesheuvel Cc: Kinney, Michael D, Gao, Liming, Liu, Zhiguang, sunilvl@ventanamicro.com, git@danielschaefer.me, Warkentin, Andrei [-- Attachment #1: Type: text/plain, Size: 26653 bytes --] X86 version is in UefiCpuPkg. So be consistent, I would prefer the LoongArch64 version be in UefiCpuPkg as well. I know that ARM has similar code (I didn’t check in detail, +@Ard Biesheuvel<mailto:ardb@kernel.org>). The trending is to abstract the memory attribute implementation behind MemoryAttribute 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@ventanamicro.com; git@danielschaefer.me; Warkentin, Andrei <andrei.warkentin@intel.com>; Ni, Ray <ray.ni@intel.com> Subject: Re: [edk2-devel] [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode Dear all, I'm also porting MMU library of LoongArch64 to EDK2, I added it in to UefiCpuPkg 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 CpuPageTableLib to UefiCpuPkg, this library are similar to MMU libraries. I have a question, should the MMU library be in the MdePkg or UefiCpuPkg? Thanks, Chao 在 2023/4/15 02:58, Tuan Phan 写道: 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/Library/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/Library/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) != (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)) == 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 = SetValidPte (Entry); + Entry &= ~(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 = 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 = ((Address >> RISCV_MMU_PAGE_SHIFT) << PTE_PPN_SHIFT); + ASSERT (~(Ppn & ~PTE_PPN_MASK)); + Entry &= ~PTE_PPN_MASK; + return Entry | Ppn; +} + +STATIC +VOID +FreePageTablesRecursive ( + IN UINTN *TranslationTable, + IN UINTN Level + ) +{ + UINTN Index; + + if (Level < mMaxRootTableLevel - 1) { + for (Index = 0; Index < mTableEntryCount; Index++) { + if (IsTableEntry (TranslationTable[Index])) { + FreePageTablesRecursive ( + (UINTN *)(GetPpnfromPte ((TranslationTable[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) == 0); + + BlockShift = (mMaxRootTableLevel - Level - 1) * mBitPerLevel + RISCV_MMU_PAGE_SHIFT; + BlockMask = 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 = BlockEnd) { + BlockEnd = MIN (RegionEnd, (RegionStart | BlockMask) + 1); + Entry = &PageTable[(RegionStart >> BlockShift) & (mTableEntryCount - 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 == 0) || + (((RegionStart | BlockEnd) & BlockMask) != 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 = AllocatePages (1); + if (TranslationTable == 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 populate + // the new table with the attributes of the block entry it replaces. + // + Status = UpdateRegionMappingRecursive ( + RegionStart & ~BlockMask, + (RegionStart | BlockMask) + 1, + *Entry & PTE_ATTRIBUTES_MASK, + PTE_ATTRIBUTES_MASK, + TranslationTable, + Level + 1, + FALSE + ); + if (EFI_ERROR (Status)) { + // + // The range we passed to UpdateRegionMappingRecursive () is block + // aligned, so it is guaranteed that no further pages were allocated + // by it, and so we only have to free the page we allocated here. + // + FreePages (TranslationTable, 1); + return Status; + } + } + + NextTableIsLive = FALSE; + } else { + TranslationTable = (UINTN *)(GetPpnfromPte (*Entry, Level) << RISCV_MMU_PAGE_SHIFT); + NextTableIsLive = TableIsLive; + } + + // + // Recurse to the next level + // + Status = 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 subhierarchy + // has not been wired into the live page tables yet. (This is not + // possible for existing table entries, since we cannot revert the + // modifications we made to the subhierarchy it represents.) + // + FreePageTablesRecursive (TranslationTable, Level + 1); + } + + return Status; + } + + if (!IsTableEntry (*Entry)) { + EntryValue = SetPpnToPte (0, (UINTN)TranslationTable, Level); + EntryValue = SetTableEntry (EntryValue); + ReplaceTableEntry ( + Entry, + EntryValue, + RegionStart, + TableIsLive + ); + } + } else { + EntryValue = (*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 |= RISCV_PG_A; + } + + if (AttributeSetMask & RISCV_PG_W) { + EntryValue |= RISCV_PG_D; + } + + EntryValue = SetPpnToPte (EntryValue, RegionStart, Level); + EntryValue = 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) != 0) { + return EFI_INVALID_PARAMETER; + } + + return UpdateRegionMappingRecursive ( + RegionStart, + RegionStart + RegionLength, + AttributeSetMask, + AttributeClearMask, + RootTable, + 0, + TableIsLive + ); +} + +STATIC +UINTN +GcdAttributeToPageAttribute ( + IN UINTN GcdAttributes + ) +{ + UINTN RiscVAttributes = RISCV_PG_R | RISCV_PG_W | RISCV_PG_X; + + // Determine protection attributes + if (GcdAttributes & EFI_MEMORY_RO) { + RiscVAttributes &= ~(RISCV_PG_W); + } + + // Process eXecute Never attribute + if (GcdAttributes & EFI_MEMORY_XP) { + RiscVAttributes &= ~RISCV_PG_X; + } + + return RiscVAttributes; +} + +EFI_STATUS +EFIAPI +RiscVSetMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length, + IN UINTN Attributes + ) +{ + UINTN PageAttributesSet = 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 = 3; + mBitPerLevel = 9; + mTableEntryCount = 512; + break; + case SATP_MODE_SV48: + mMaxRootTableLevel = 4; + mBitPerLevel = 9; + mTableEntryCount = 512; + break; + case SATP_MODE_SV57: + mMaxRootTableLevel = 5; + mBitPerLevel = 9; + mTableEntryCount = 512; + break; + default: + return EFI_INVALID_PARAMETER; + } + + // Allocate pages for translation table + TranslationTable = AllocatePages (1); + if (TranslationTable == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem (TranslationTable, mTableEntryCount * sizeof (UINTN)); + + NumberOfDescriptors = 0; + MemoryMap = NULL; + Status = gDS->GetMemorySpaceMap ( + &NumberOfDescriptors, + &MemoryMap + ); + ASSERT_EFI_ERROR (Status); + + for (Index = 0; Index < NumberOfDescriptors; Index++) { + if (MemoryMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) { + // 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 == EfiGcdMemoryTypeSystemMemory) { + // 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 = (UINTN)TranslationTable >> RISCV_MMU_PAGE_SHIFT; + ASSERT (!(Ppn & ~(SATP64_PPN))); + + SatpReg = Ppn; + SatpReg |= (SatpMode << + SATP64_MODE_SHIFT) & SATP64_MODE; + RiscVSetSupervisorAddressTranslationRegister (SatpReg); + /* Check if HW support the setup satp mode */ + if (SatpReg != 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 = EFI_SUCCESS; + INTN ModeSupport[] = { SATP_MODE_SV57, SATP_MODE_SV48, SATP_MODE_SV39 }; + INTN Idx; + + /* Try to setup MMU with highest mode as possible */ + for (Idx = 0; Idx < ARRAY_SIZE (ModeSupport); Idx++) { + Status = RiscVMmuSetSatpMode (ModeSupport[Idx]); + if (Status == 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/Library/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 = 0x0001001b + BASE_NAME = BaseRiscVMmuLib + FILE_GUID = d3bc42ee-c9eb-4339-ba11-06747083d3ae + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = 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/RiscVVirt.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/BaseRiscV64CpuExceptionHandlerLib/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/BaseResetSystemLib.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 << 60); - 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) == (SATP_MODE_OFF << SATP64_MODE_SHIFT)); BuildMemoryTypeInformationHob (); diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.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", __func__)); - return EFI_SUCCESS; + return RiscVSetMemoryAttributes (BaseAddress, Length, Attributes); } /** @@ -340,6 +339,12 @@ InitializeCpu ( // DisableInterrupts (); + // + // Enable MMU + // + Status = RiscVConfigureMmu (); + ASSERT_EFI_ERROR (Status); + // // Install Boot protocol // diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.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/CpuDxeRiscV64/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 [-- Attachment #2: Type: text/html, Size: 67297 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode 2023-05-24 9:51 ` Ni, Ray @ 2023-05-24 18:16 ` Tuan Phan 0 siblings, 0 replies; 17+ messages in thread From: Tuan Phan @ 2023-05-24 18:16 UTC (permalink / raw) To: Ni, Ray, devel@edk2.groups.io, lichao@loongson.cn, Ard Biesheuvel Cc: Kinney, Michael D, Gao, Liming, Liu, Zhiguang, sunilvl@ventanamicro.com, git@danielschaefer.me, Warkentin, Andrei [-- Attachment #1: Type: text/plain, Size: 27360 bytes --] 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 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 X86 version is in UefiCpuPkg. So be consistent, I would prefer the LoongArch64 version be in UefiCpuPkg as well. I know that ARM has similar code (I didn’t check in detail, +@Ard Biesheuvel<mailto:ardb@kernel.org>). The trending is to abstract the memory attribute implementation behind MemoryAttribute 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@ventanamicro.com; git@danielschaefer.me; Warkentin, Andrei <andrei.warkentin@intel.com>; Ni, Ray <ray.ni@intel.com> Subject: Re: [edk2-devel] [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode Dear all, I'm also porting MMU library of LoongArch64 to EDK2, I added it in to UefiCpuPkg 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 CpuPageTableLib to UefiCpuPkg, this library are similar to MMU libraries. I have a question, should the MMU library be in the MdePkg or UefiCpuPkg? Thanks, Chao 在 2023/4/15 02:58, Tuan Phan 写道: 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/Library/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/Library/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) != (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)) == 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 = SetValidPte (Entry); + Entry &= ~(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 = 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 = ((Address >> RISCV_MMU_PAGE_SHIFT) << PTE_PPN_SHIFT); + ASSERT (~(Ppn & ~PTE_PPN_MASK)); + Entry &= ~PTE_PPN_MASK; + return Entry | Ppn; +} + +STATIC +VOID +FreePageTablesRecursive ( + IN UINTN *TranslationTable, + IN UINTN Level + ) +{ + UINTN Index; + + if (Level < mMaxRootTableLevel - 1) { + for (Index = 0; Index < mTableEntryCount; Index++) { + if (IsTableEntry (TranslationTable[Index])) { + FreePageTablesRecursive ( + (UINTN *)(GetPpnfromPte ((TranslationTable[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) == 0); + + BlockShift = (mMaxRootTableLevel - Level - 1) * mBitPerLevel + RISCV_MMU_PAGE_SHIFT; + BlockMask = 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 = BlockEnd) { + BlockEnd = MIN (RegionEnd, (RegionStart | BlockMask) + 1); + Entry = &PageTable[(RegionStart >> BlockShift) & (mTableEntryCount - 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 == 0) || + (((RegionStart | BlockEnd) & BlockMask) != 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 = AllocatePages (1); + if (TranslationTable == 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 populate + // the new table with the attributes of the block entry it replaces. + // + Status = UpdateRegionMappingRecursive ( + RegionStart & ~BlockMask, + (RegionStart | BlockMask) + 1, + *Entry & PTE_ATTRIBUTES_MASK, + PTE_ATTRIBUTES_MASK, + TranslationTable, + Level + 1, + FALSE + ); + if (EFI_ERROR (Status)) { + // + // The range we passed to UpdateRegionMappingRecursive () is block + // aligned, so it is guaranteed that no further pages were allocated + // by it, and so we only have to free the page we allocated here. + // + FreePages (TranslationTable, 1); + return Status; + } + } + + NextTableIsLive = FALSE; + } else { + TranslationTable = (UINTN *)(GetPpnfromPte (*Entry, Level) << RISCV_MMU_PAGE_SHIFT); + NextTableIsLive = TableIsLive; + } + + // + // Recurse to the next level + // + Status = 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 subhierarchy + // has not been wired into the live page tables yet. (This is not + // possible for existing table entries, since we cannot revert the + // modifications we made to the subhierarchy it represents.) + // + FreePageTablesRecursive (TranslationTable, Level + 1); + } + + return Status; + } + + if (!IsTableEntry (*Entry)) { + EntryValue = SetPpnToPte (0, (UINTN)TranslationTable, Level); + EntryValue = SetTableEntry (EntryValue); + ReplaceTableEntry ( + Entry, + EntryValue, + RegionStart, + TableIsLive + ); + } + } else { + EntryValue = (*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 |= RISCV_PG_A; + } + + if (AttributeSetMask & RISCV_PG_W) { + EntryValue |= RISCV_PG_D; + } + + EntryValue = SetPpnToPte (EntryValue, RegionStart, Level); + EntryValue = 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) != 0) { + return EFI_INVALID_PARAMETER; + } + + return UpdateRegionMappingRecursive ( + RegionStart, + RegionStart + RegionLength, + AttributeSetMask, + AttributeClearMask, + RootTable, + 0, + TableIsLive + ); +} + +STATIC +UINTN +GcdAttributeToPageAttribute ( + IN UINTN GcdAttributes + ) +{ + UINTN RiscVAttributes = RISCV_PG_R | RISCV_PG_W | RISCV_PG_X; + + // Determine protection attributes + if (GcdAttributes & EFI_MEMORY_RO) { + RiscVAttributes &= ~(RISCV_PG_W); + } + + // Process eXecute Never attribute + if (GcdAttributes & EFI_MEMORY_XP) { + RiscVAttributes &= ~RISCV_PG_X; + } + + return RiscVAttributes; +} + +EFI_STATUS +EFIAPI +RiscVSetMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length, + IN UINTN Attributes + ) +{ + UINTN PageAttributesSet = 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 = 3; + mBitPerLevel = 9; + mTableEntryCount = 512; + break; + case SATP_MODE_SV48: + mMaxRootTableLevel = 4; + mBitPerLevel = 9; + mTableEntryCount = 512; + break; + case SATP_MODE_SV57: + mMaxRootTableLevel = 5; + mBitPerLevel = 9; + mTableEntryCount = 512; + break; + default: + return EFI_INVALID_PARAMETER; + } + + // Allocate pages for translation table + TranslationTable = AllocatePages (1); + if (TranslationTable == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem (TranslationTable, mTableEntryCount * sizeof (UINTN)); + + NumberOfDescriptors = 0; + MemoryMap = NULL; + Status = gDS->GetMemorySpaceMap ( + &NumberOfDescriptors, + &MemoryMap + ); + ASSERT_EFI_ERROR (Status); + + for (Index = 0; Index < NumberOfDescriptors; Index++) { + if (MemoryMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) { + // 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 == EfiGcdMemoryTypeSystemMemory) { + // 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 = (UINTN)TranslationTable >> RISCV_MMU_PAGE_SHIFT; + ASSERT (!(Ppn & ~(SATP64_PPN))); + + SatpReg = Ppn; + SatpReg |= (SatpMode << + SATP64_MODE_SHIFT) & SATP64_MODE; + RiscVSetSupervisorAddressTranslationRegister (SatpReg); + /* Check if HW support the setup satp mode */ + if (SatpReg != 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 = EFI_SUCCESS; + INTN ModeSupport[] = { SATP_MODE_SV57, SATP_MODE_SV48, SATP_MODE_SV39 }; + INTN Idx; + + /* Try to setup MMU with highest mode as possible */ + for (Idx = 0; Idx < ARRAY_SIZE (ModeSupport); Idx++) { + Status = RiscVMmuSetSatpMode (ModeSupport[Idx]); + if (Status == 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/Library/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 = 0x0001001b + BASE_NAME = BaseRiscVMmuLib + FILE_GUID = d3bc42ee-c9eb-4339-ba11-06747083d3ae + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = 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/RiscVVirt.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/BaseRiscV64CpuExceptionHandlerLib/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/BaseResetSystemLib.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 << 60); - 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) == (SATP_MODE_OFF << SATP64_MODE_SHIFT)); BuildMemoryTypeInformationHob (); diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.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", __func__)); - return EFI_SUCCESS; + return RiscVSetMemoryAttributes (BaseAddress, Length, Attributes); } /** @@ -340,6 +339,12 @@ InitializeCpu ( // DisableInterrupts (); + // + // Enable MMU + // + Status = RiscVConfigureMmu (); + ASSERT_EFI_ERROR (Status); + // // Install Boot protocol // diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.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/CpuDxeRiscV64/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 [-- Attachment #2: Type: text/html, Size: 69593 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 4/6] OvmfPkg/RiscVVirt: VirtNorFlashPlatformLib: Fix wrong flash size 2023-04-14 18:58 [PATCH v2 0/6] RISC-V MMU support Tuan Phan ` (2 preceding siblings ...) 2023-04-14 18:58 ` [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode Tuan Phan @ 2023-04-14 18:58 ` Tuan Phan 2023-04-14 18:58 ` [PATCH v2 5/6] OvmfPkg/VirtNorFlashDxe: Not add memory space if it exists Tuan Phan ` (2 subsequent siblings) 6 siblings, 0 replies; 17+ messages in thread From: Tuan Phan @ 2023-04-14 18:58 UTC (permalink / raw) To: devel Cc: michael.d.kinney, gaoliming, zhiguang.liu, sunilvl, git, andrei.warkentin, Tuan Phan The size should be for single region, not the whole firmware FD. Signed-off-by: Tuan Phan <tphan@ventanamicro.com> --- .../Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c b/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c index fdc2ccb6294e..33f3a01b06f4 100644 --- a/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c +++ b/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c @@ -24,7 +24,8 @@ VIRT_NOR_FLASH_DESCRIPTION mNorFlashDevice = { FixedPcdGet32 (PcdOvmfFdBaseAddress), FixedPcdGet64 (PcdFlashNvStorageVariableBase), - FixedPcdGet32 (PcdOvmfFirmwareFdSize), + FixedPcdGet32 (PcdOvmfFirmwareFdSize) - + (FixedPcdGet64 (PcdFlashNvStorageVariableBase) - FixedPcdGet32 (PcdOvmfFdBaseAddress)), QEMU_NOR_BLOCK_SIZE }; -- 2.25.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 5/6] OvmfPkg/VirtNorFlashDxe: Not add memory space if it exists 2023-04-14 18:58 [PATCH v2 0/6] RISC-V MMU support Tuan Phan ` (3 preceding siblings ...) 2023-04-14 18:58 ` [PATCH v2 4/6] OvmfPkg/RiscVVirt: VirtNorFlashPlatformLib: Fix wrong flash size Tuan Phan @ 2023-04-14 18:58 ` Tuan Phan 2023-04-14 18:58 ` [PATCH v2 6/6] OvmfPkg/RiscVVirt: SEC: Add IO memory resource hob for platform devices Tuan Phan 2023-04-18 16:03 ` [PATCH v2 0/6] RISC-V MMU support Andrei Warkentin 6 siblings, 0 replies; 17+ messages in thread From: Tuan Phan @ 2023-04-14 18:58 UTC (permalink / raw) To: devel Cc: michael.d.kinney, gaoliming, zhiguang.liu, sunilvl, git, andrei.warkentin, Tuan Phan The flash base address can be added to GCD before this driver run. So only add it if it has not been done. Signed-off-by: Tuan Phan <tphan@ventanamicro.com> --- OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c | 25 +++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c index 6b9ef261335e..bbd1697a51dd 100644 --- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c +++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c @@ -372,10 +372,11 @@ NorFlashFvbInitialize ( IN NOR_FLASH_INSTANCE *Instance ) { - EFI_STATUS Status; - UINT32 FvbNumLba; - EFI_BOOT_MODE BootMode; - UINTN RuntimeMmioRegionSize; + EFI_STATUS Status; + UINT32 FvbNumLba; + EFI_BOOT_MODE BootMode; + UINTN RuntimeMmioRegionSize; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Desc; DEBUG ((DEBUG_BLKIO, "NorFlashFvbInitialize\n")); ASSERT ((Instance != NULL)); @@ -390,13 +391,19 @@ NorFlashFvbInitialize ( // is written as the base of the flash region (ie: Instance->DeviceBaseAddress) RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size; - Status = gDS->AddMemorySpace ( - EfiGcdMemoryTypeMemoryMappedIo, + Status = gDS->GetMemorySpaceDescriptor ( Instance->DeviceBaseAddress, - RuntimeMmioRegionSize, - EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + &Desc ); - ASSERT_EFI_ERROR (Status); + if (Status == EFI_NOT_FOUND) { + Status = gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + Instance->DeviceBaseAddress, + RuntimeMmioRegionSize, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + } Status = gDS->SetMemorySpaceAttributes ( Instance->DeviceBaseAddress, -- 2.25.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 6/6] OvmfPkg/RiscVVirt: SEC: Add IO memory resource hob for platform devices 2023-04-14 18:58 [PATCH v2 0/6] RISC-V MMU support Tuan Phan ` (4 preceding siblings ...) 2023-04-14 18:58 ` [PATCH v2 5/6] OvmfPkg/VirtNorFlashDxe: Not add memory space if it exists Tuan Phan @ 2023-04-14 18:58 ` Tuan Phan 2023-04-18 16:03 ` [PATCH v2 0/6] RISC-V MMU support Andrei Warkentin 6 siblings, 0 replies; 17+ messages in thread From: Tuan Phan @ 2023-04-14 18:58 UTC (permalink / raw) To: devel Cc: michael.d.kinney, gaoliming, zhiguang.liu, sunilvl, git, andrei.warkentin, Tuan Phan Normally, DXE driver would add device resource to GCD before start using. But some key resources such as uart, flash base address are being accessing directly in some core modules. Those resources should be populated to HOB in SEC phase so they are added to GCD before anyone can access them. Signed-off-by: Tuan Phan <tphan@ventanamicro.com> --- OvmfPkg/RiscVVirt/Sec/Platform.c | 62 +++++++++++++++++++++++++++++++ OvmfPkg/RiscVVirt/Sec/SecMain.inf | 1 + 2 files changed, 63 insertions(+) diff --git a/OvmfPkg/RiscVVirt/Sec/Platform.c b/OvmfPkg/RiscVVirt/Sec/Platform.c index 3645c27b0b12..944b82c84a6e 100644 --- a/OvmfPkg/RiscVVirt/Sec/Platform.c +++ b/OvmfPkg/RiscVVirt/Sec/Platform.c @@ -21,6 +21,63 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include <libfdt.h> #include <Guid/FdtHob.h> +/** + Build memory map I/O range resource HOB using the + base address and size. + + @param MemoryBase Memory map I/O base. + @param MemorySize Memory map I/O size. + +**/ +STATIC +VOID +AddIoMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ) +{ + /* Align to EFI_PAGE_SIZE */ + MemorySize = ALIGN_VALUE (MemorySize, EFI_PAGE_SIZE); + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_TESTED, + MemoryBase, + MemorySize + ); +} + +/** + Populate IO resources from FDT that not added to GCD by its + driver in the DXE phase. + + @param FdtBase Fdt base address + @param Compatible Compatible string + +**/ +STATIC +VOID +PopulateIoResources ( + VOID *FdtBase, + CONST CHAR8* Compatible + ) +{ + UINT64 *Reg; + INT32 Node, LenP; + + Node = fdt_node_offset_by_compatible (FdtBase, -1, Compatible); + while (Node != -FDT_ERR_NOTFOUND) { + Reg = (UINT64 *)fdt_getprop (FdtBase, Node, "reg", &LenP); + if (Reg) { + ASSERT (LenP == (2 * sizeof (UINT64))); + AddIoMemoryBaseSizeHob (SwapBytes64 (Reg[0]), SwapBytes64 (Reg[1])); + } + Node = fdt_node_offset_by_compatible (FdtBase, Node, Compatible); + } +} + /** @retval EFI_SUCCESS The address of FDT is passed in HOB. EFI_UNSUPPORTED Can't locate FDT. @@ -80,5 +137,10 @@ PlatformPeimInitialization ( BuildFvHob (PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize)); + PopulateIoResources (Base, "ns16550a"); + PopulateIoResources (Base, "qemu,fw-cfg-mmio"); + PopulateIoResources (Base, "virtio,mmio"); + AddIoMemoryBaseSizeHob (PcdGet32 (PcdOvmfFdBaseAddress), PcdGet32 (PcdOvmfFirmwareFdSize)); + return EFI_SUCCESS; } diff --git a/OvmfPkg/RiscVVirt/Sec/SecMain.inf b/OvmfPkg/RiscVVirt/Sec/SecMain.inf index aed35d3af596..e1f562264eea 100644 --- a/OvmfPkg/RiscVVirt/Sec/SecMain.inf +++ b/OvmfPkg/RiscVVirt/Sec/SecMain.inf @@ -61,6 +61,7 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize [Guids] gFdtHobGuid -- 2.25.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v2 0/6] RISC-V MMU support 2023-04-14 18:58 [PATCH v2 0/6] RISC-V MMU support Tuan Phan ` (5 preceding siblings ...) 2023-04-14 18:58 ` [PATCH v2 6/6] OvmfPkg/RiscVVirt: SEC: Add IO memory resource hob for platform devices Tuan Phan @ 2023-04-18 16:03 ` Andrei Warkentin 2023-04-19 22:37 ` [edk2-devel] " Tuan Phan 6 siblings, 1 reply; 17+ messages in thread From: Andrei Warkentin @ 2023-04-18 16:03 UTC (permalink / raw) To: Tuan Phan, devel@edk2.groups.io Cc: Kinney, Michael D, Gao, Liming, Liu, Zhiguang, sunilvl@ventanamicro.com, git@danielschaefer.me Hi Tuan, Do you mind sharing the GitHub branch as well? It would help with the review immensely. A > -----Original Message----- > From: Tuan Phan <tphan@ventanamicro.com> > Sent: Friday, April 14, 2023 1:58 PM > To: devel@edk2.groups.io > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming > <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>; > sunilvl@ventanamicro.com; git@danielschaefer.me; Warkentin, Andrei > <andrei.warkentin@intel.com>; Tuan Phan <tphan@ventanamicro.com> > Subject: [PATCH v2 0/6] RISC-V MMU support > > RISC-V: Add MMU support > > This series adds MMU support for RISC-V. Only SV39/48/57 modes are > supported and tested. The MMU is required to support setting page > attribute which is the first basic step to support security booting on RISC-V. > > There are three parts: > 1. Add MMU base library. MMU will be enabled during CpuDxe initialization. > 2. Fix OvmfPkg/VirtNorFlashDxe that failed to add flash base address to GCD > if already done. > 3. Fix all resources should be populated in HOB or added to GCD by driver > before accessing when MMU enabled. > > Changes in v2: > - Move MMU core to a library. > - Setup SATP mode as highest possible that HW supports. > > Tuan Phan (6): > MdePkg/BaseLib: RISC-V: Support getting satp register value > MdePkg/Register: RISC-V: Add satp mode bits shift definition > UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode > OvmfPkg/RiscVVirt: VirtNorFlashPlatformLib: Fix wrong flash size > OvmfPkg/VirtNorFlashDxe: Not add memory space if it exists > OvmfPkg/RiscVVirt: SEC: Add IO memory resource hob for platform > devices > > MdePkg/Include/Library/BaseLib.h | 5 + > MdePkg/Include/Library/BaseRiscVMmuLib.h | 39 ++ > .../Include/Register/RiscV64/RiscVEncoding.h | 7 +- > MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S | 8 + > .../Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c | 569 > ++++++++++++++++++ > .../BaseRiscVMmuLib/BaseRiscVMmuLib.inf | 25 + > MdePkg/Library/BaseRiscVMmuLib/RiscVMmuCore.S | 31 + > .../VirtNorFlashStaticLib.c | 3 +- > OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc | 1 + > OvmfPkg/RiscVVirt/Sec/Memory.c | 18 +- > OvmfPkg/RiscVVirt/Sec/Platform.c | 62 ++ > OvmfPkg/RiscVVirt/Sec/SecMain.inf | 1 + > OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c | 25 +- > UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c | 9 +- > UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h | 2 + > UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf | 2 + > 16 files changed, 776 insertions(+), 31 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 > > -- > 2.25.1 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/6] RISC-V MMU support 2023-04-18 16:03 ` [PATCH v2 0/6] RISC-V MMU support Andrei Warkentin @ 2023-04-19 22:37 ` Tuan Phan 2023-05-08 17:19 ` Andrei Warkentin 0 siblings, 1 reply; 17+ messages in thread From: Tuan Phan @ 2023-04-19 22:37 UTC (permalink / raw) To: devel@edk2.groups.io, andrei.warkentin@intel.com Cc: Kinney, Michael D, Gao, Liming, Liu, Zhiguang, sunilvl@ventanamicro.com, git@danielschaefer.me [-- Attachment #1: Type: text/plain, Size: 3682 bytes --] Hi Andrei, Here you go: https://github.com/pttuan/edk2/tree/tphan/riscv_mmu Will put the link in the cover letter next round. From: devel@edk2.groups.io <devel@edk2.groups.io> on behalf of Andrei Warkentin <andrei.warkentin@intel.com> Date: Tuesday, April 18, 2023 at 9:04 AM To: Tuan Phan <tphan@ventanamicro.com>, devel@edk2.groups.io <devel@edk2.groups.io> 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> Subject: Re: [edk2-devel] [PATCH v2 0/6] RISC-V MMU support Hi Tuan, Do you mind sharing the GitHub branch as well? It would help with the review immensely. A > -----Original Message----- > From: Tuan Phan <tphan@ventanamicro.com> > Sent: Friday, April 14, 2023 1:58 PM > To: devel@edk2.groups.io > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming > <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>; > sunilvl@ventanamicro.com; git@danielschaefer.me; Warkentin, Andrei > <andrei.warkentin@intel.com>; Tuan Phan <tphan@ventanamicro.com> > Subject: [PATCH v2 0/6] RISC-V MMU support > > RISC-V: Add MMU support > > This series adds MMU support for RISC-V. Only SV39/48/57 modes are > supported and tested. The MMU is required to support setting page > attribute which is the first basic step to support security booting on RISC-V. > > There are three parts: > 1. Add MMU base library. MMU will be enabled during CpuDxe initialization. > 2. Fix OvmfPkg/VirtNorFlashDxe that failed to add flash base address to GCD > if already done. > 3. Fix all resources should be populated in HOB or added to GCD by driver > before accessing when MMU enabled. > > Changes in v2: > - Move MMU core to a library. > - Setup SATP mode as highest possible that HW supports. > > Tuan Phan (6): > MdePkg/BaseLib: RISC-V: Support getting satp register value > MdePkg/Register: RISC-V: Add satp mode bits shift definition > UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode > OvmfPkg/RiscVVirt: VirtNorFlashPlatformLib: Fix wrong flash size > OvmfPkg/VirtNorFlashDxe: Not add memory space if it exists > OvmfPkg/RiscVVirt: SEC: Add IO memory resource hob for platform > devices > > MdePkg/Include/Library/BaseLib.h | 5 + > MdePkg/Include/Library/BaseRiscVMmuLib.h | 39 ++ > .../Include/Register/RiscV64/RiscVEncoding.h | 7 +- > MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S | 8 + > .../Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c | 569 > ++++++++++++++++++ > .../BaseRiscVMmuLib/BaseRiscVMmuLib.inf | 25 + > MdePkg/Library/BaseRiscVMmuLib/RiscVMmuCore.S | 31 + > .../VirtNorFlashStaticLib.c | 3 +- > OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc | 1 + > OvmfPkg/RiscVVirt/Sec/Memory.c | 18 +- > OvmfPkg/RiscVVirt/Sec/Platform.c | 62 ++ > OvmfPkg/RiscVVirt/Sec/SecMain.inf | 1 + > OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c | 25 +- > UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c | 9 +- > UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h | 2 + > UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf | 2 + > 16 files changed, 776 insertions(+), 31 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 > > -- > 2.25.1 [-- Attachment #2: Type: text/html, Size: 7252 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/6] RISC-V MMU support 2023-04-19 22:37 ` [edk2-devel] " Tuan Phan @ 2023-05-08 17:19 ` Andrei Warkentin 2023-05-23 21:59 ` Tuan Phan 0 siblings, 1 reply; 17+ messages in thread From: Andrei Warkentin @ 2023-05-08 17:19 UTC (permalink / raw) To: devel@edk2.groups.io, tphan@ventanamicro.com Cc: Kinney, Michael D, Gao, Liming, Liu, Zhiguang, sunilvl@ventanamicro.com, git@danielschaefer.me [-- Attachment #1: Type: text/plain, Size: 5157 bytes --] Apologies for the late review. I added my comments on GH. Aside from a request for more context for https://github.com/tianocore/edk2/commit/b7387dae40cc3a72562c6461d007d20087ab7414#comments, I think this patch set from a functionality standpoint looks good enough to be submitted. Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Tuan Phan Sent: Wednesday, April 19, 2023 5:37 PM To: devel@edk2.groups.io; Warkentin, Andrei <andrei.warkentin@intel.com> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>; sunilvl@ventanamicro.com; git@danielschaefer.me Subject: Re: [edk2-devel] [PATCH v2 0/6] RISC-V MMU support Hi Andrei, Here you go: https://github.com/pttuan/edk2/tree/tphan/riscv_mmu Will put the link in the cover letter next round. From: devel@edk2.groups.io<mailto:devel@edk2.groups.io> <devel@edk2.groups.io<mailto:devel@edk2.groups.io>> on behalf of Andrei Warkentin <andrei.warkentin@intel.com<mailto:andrei.warkentin@intel.com>> Date: Tuesday, April 18, 2023 at 9:04 AM To: Tuan Phan <tphan@ventanamicro.com<mailto:tphan@ventanamicro.com>>, devel@edk2.groups.io<mailto:devel@edk2.groups.io> <devel@edk2.groups.io<mailto:devel@edk2.groups.io>> Cc: Kinney, Michael D <michael.d.kinney@intel.com<mailto:michael.d.kinney@intel.com>>, Gao, Liming <gaoliming@byosoft.com.cn<mailto:gaoliming@byosoft.com.cn>>, Liu, Zhiguang <zhiguang.liu@intel.com<mailto:zhiguang.liu@intel.com>>, sunilvl@ventanamicro.com<mailto:sunilvl@ventanamicro.com> <sunilvl@ventanamicro.com<mailto:sunilvl@ventanamicro.com>>, git@danielschaefer.me<mailto:git@danielschaefer.me> <git@danielschaefer.me<mailto:git@danielschaefer.me>> Subject: Re: [edk2-devel] [PATCH v2 0/6] RISC-V MMU support Hi Tuan, Do you mind sharing the GitHub branch as well? It would help with the review immensely. A > -----Original Message----- > From: Tuan Phan <tphan@ventanamicro.com<mailto:tphan@ventanamicro.com>> > Sent: Friday, April 14, 2023 1:58 PM > To: devel@edk2.groups.io<mailto:devel@edk2.groups.io> > Cc: Kinney, Michael D <michael.d.kinney@intel.com<mailto:michael.d.kinney@intel.com>>; Gao, Liming > <gaoliming@byosoft.com.cn<mailto:gaoliming@byosoft.com.cn>>; Liu, Zhiguang <zhiguang.liu@intel.com<mailto:zhiguang.liu@intel.com>>; > sunilvl@ventanamicro.com<mailto:sunilvl@ventanamicro.com>; git@danielschaefer.me<mailto:git@danielschaefer.me>; Warkentin, Andrei > <andrei.warkentin@intel.com<mailto:andrei.warkentin@intel.com>>; Tuan Phan <tphan@ventanamicro.com<mailto:tphan@ventanamicro.com>> > Subject: [PATCH v2 0/6] RISC-V MMU support > > RISC-V: Add MMU support > > This series adds MMU support for RISC-V. Only SV39/48/57 modes are > supported and tested. The MMU is required to support setting page > attribute which is the first basic step to support security booting on RISC-V. > > There are three parts: > 1. Add MMU base library. MMU will be enabled during CpuDxe initialization. > 2. Fix OvmfPkg/VirtNorFlashDxe that failed to add flash base address to GCD > if already done. > 3. Fix all resources should be populated in HOB or added to GCD by driver > before accessing when MMU enabled. > > Changes in v2: > - Move MMU core to a library. > - Setup SATP mode as highest possible that HW supports. > > Tuan Phan (6): > MdePkg/BaseLib: RISC-V: Support getting satp register value > MdePkg/Register: RISC-V: Add satp mode bits shift definition > UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode > OvmfPkg/RiscVVirt: VirtNorFlashPlatformLib: Fix wrong flash size > OvmfPkg/VirtNorFlashDxe: Not add memory space if it exists > OvmfPkg/RiscVVirt: SEC: Add IO memory resource hob for platform > devices > > MdePkg/Include/Library/BaseLib.h | 5 + > MdePkg/Include/Library/BaseRiscVMmuLib.h | 39 ++ > .../Include/Register/RiscV64/RiscVEncoding.h | 7 +- > MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S | 8 + > .../Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c | 569 > ++++++++++++++++++ > .../BaseRiscVMmuLib/BaseRiscVMmuLib.inf | 25 + > MdePkg/Library/BaseRiscVMmuLib/RiscVMmuCore.S | 31 + > .../VirtNorFlashStaticLib.c | 3 +- > OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc | 1 + > OvmfPkg/RiscVVirt/Sec/Memory.c | 18 +- > OvmfPkg/RiscVVirt/Sec/Platform.c | 62 ++ > OvmfPkg/RiscVVirt/Sec/SecMain.inf | 1 + > OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c | 25 +- > UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c | 9 +- > UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h | 2 + > UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf | 2 + > 16 files changed, 776 insertions(+), 31 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 > > -- > 2.25.1 [-- Attachment #2: Type: text/html, Size: 10333 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/6] RISC-V MMU support 2023-05-08 17:19 ` Andrei Warkentin @ 2023-05-23 21:59 ` Tuan Phan 2023-05-24 4:17 ` Sunil V L 0 siblings, 1 reply; 17+ messages in thread From: Tuan Phan @ 2023-05-23 21:59 UTC (permalink / raw) To: Warkentin, Andrei Cc: devel@edk2.groups.io, Kinney, Michael D, Gao, Liming, Liu, Zhiguang, sunilvl@ventanamicro.com, git@danielschaefer.me [-- Attachment #1: Type: text/plain, Size: 5040 bytes --] Thanks Andrei, Sunil, any comments or it is good to go. As this patchset spans across MdePkg, UefiCpuPkg and OvmfPkg, do I need to separate it so each package maintainer can merge independently? On Mon, May 8, 2023 at 10:19 AM Warkentin, Andrei < andrei.warkentin@intel.com> wrote: > Apologies for the late review. I added my comments on GH. Aside from a > request for more context for > https://github.com/tianocore/edk2/commit/b7387dae40cc3a72562c6461d007d20087ab7414#comments, > I think this patch set from a functionality standpoint looks good enough to > be submitted. > > > > Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com> > > > > *From:* devel@edk2.groups.io <devel@edk2.groups.io> *On Behalf Of *Tuan > Phan > *Sent:* Wednesday, April 19, 2023 5:37 PM > *To:* devel@edk2.groups.io; Warkentin, Andrei <andrei.warkentin@intel.com> > *Cc:* Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming < > gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>; > sunilvl@ventanamicro.com; git@danielschaefer.me > *Subject:* Re: [edk2-devel] [PATCH v2 0/6] RISC-V MMU support > > > > Hi Andrei, > > Here you go: https://github.com/pttuan/edk2/tree/tphan/riscv_mmu > > Will put the link in the cover letter next round. > > > > *From: *devel@edk2.groups.io <devel@edk2.groups.io> on behalf of Andrei > Warkentin <andrei.warkentin@intel.com> > *Date: *Tuesday, April 18, 2023 at 9:04 AM > *To: *Tuan Phan <tphan@ventanamicro.com>, devel@edk2.groups.io < > devel@edk2.groups.io> > *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> > *Subject: *Re: [edk2-devel] [PATCH v2 0/6] RISC-V MMU support > > Hi Tuan, > > Do you mind sharing the GitHub branch as well? It would help with the > review immensely. > > A > > > -----Original Message----- > > From: Tuan Phan <tphan@ventanamicro.com> > > Sent: Friday, April 14, 2023 1:58 PM > > To: devel@edk2.groups.io > > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming > > <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>; > > sunilvl@ventanamicro.com; git@danielschaefer.me; Warkentin, Andrei > > <andrei.warkentin@intel.com>; Tuan Phan <tphan@ventanamicro.com> > > Subject: [PATCH v2 0/6] RISC-V MMU support > > > > RISC-V: Add MMU support > > > > This series adds MMU support for RISC-V. Only SV39/48/57 modes are > > supported and tested. The MMU is required to support setting page > > attribute which is the first basic step to support security booting on > RISC-V. > > > > There are three parts: > > 1. Add MMU base library. MMU will be enabled during CpuDxe > initialization. > > 2. Fix OvmfPkg/VirtNorFlashDxe that failed to add flash base address to > GCD > > if already done. > > 3. Fix all resources should be populated in HOB or added to GCD by driver > > before accessing when MMU enabled. > > > > Changes in v2: > > - Move MMU core to a library. > > - Setup SATP mode as highest possible that HW supports. > > > > Tuan Phan (6): > > MdePkg/BaseLib: RISC-V: Support getting satp register value > > MdePkg/Register: RISC-V: Add satp mode bits shift definition > > UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode > > OvmfPkg/RiscVVirt: VirtNorFlashPlatformLib: Fix wrong flash size > > OvmfPkg/VirtNorFlashDxe: Not add memory space if it exists > > OvmfPkg/RiscVVirt: SEC: Add IO memory resource hob for platform > > devices > > > > MdePkg/Include/Library/BaseLib.h | 5 + > > MdePkg/Include/Library/BaseRiscVMmuLib.h | 39 ++ > > .../Include/Register/RiscV64/RiscVEncoding.h | 7 +- > > MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S | 8 + > > .../Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c | 569 > > ++++++++++++++++++ > > .../BaseRiscVMmuLib/BaseRiscVMmuLib.inf | 25 + > > MdePkg/Library/BaseRiscVMmuLib/RiscVMmuCore.S | 31 + > > .../VirtNorFlashStaticLib.c | 3 +- > > OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc | 1 + > > OvmfPkg/RiscVVirt/Sec/Memory.c | 18 +- > > OvmfPkg/RiscVVirt/Sec/Platform.c | 62 ++ > > OvmfPkg/RiscVVirt/Sec/SecMain.inf | 1 + > > OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c | 25 +- > > UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c | 9 +- > > UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h | 2 + > > UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf | 2 + > > 16 files changed, 776 insertions(+), 31 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 > > > > -- > > 2.25.1 > > > > > > [-- Attachment #2: Type: text/html, Size: 9678 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/6] RISC-V MMU support 2023-05-23 21:59 ` Tuan Phan @ 2023-05-24 4:17 ` Sunil V L 0 siblings, 0 replies; 17+ messages in thread From: Sunil V L @ 2023-05-24 4:17 UTC (permalink / raw) To: Tuan Phan Cc: Warkentin, Andrei, devel@edk2.groups.io, Kinney, Michael D, Gao, Liming, Liu, Zhiguang, git@danielschaefer.me On Tue, May 23, 2023 at 02:59:50PM -0700, Tuan Phan wrote: > Thanks Andrei, > Sunil, any comments or it is good to go. As this patchset spans across > MdePkg, UefiCpuPkg and OvmfPkg, do I need to separate it so each package > maintainer can merge independently? > Hi Tuan, I don't see an issue when a patch set spans across multiple modules as long as corresponding maintainers review/ack. However, it is better if the change in single patch is restricted to one module/package. In your series, PATCH 3/6 is spread across 3 different modules. Could you separate the change for each package? Also, while all other patches affects RISC-V only, PATCH 5/6 in your series is a generic change which affects other architectures. Ard is the maintainer for this and he should to agree for the change. Did I miss a response to his question for this patch? Thanks! Sunil ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2023-05-24 18:16 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-04-14 18:58 [PATCH v2 0/6] RISC-V MMU support Tuan Phan 2023-04-14 18:58 ` [PATCH v2 1/6] MdePkg/BaseLib: RISC-V: Support getting satp register value Tuan Phan 2023-04-18 16:02 ` Andrei Warkentin 2023-04-14 18:58 ` [PATCH v2 2/6] MdePkg/Register: RISC-V: Add satp mode bits shift definition Tuan Phan 2023-04-18 16:05 ` Andrei Warkentin 2023-04-14 18:58 ` [PATCH v2 3/6] UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode Tuan Phan 2023-05-24 2:10 ` [edk2-devel] " Chao Li 2023-05-24 9:51 ` Ni, Ray 2023-05-24 18:16 ` Tuan Phan 2023-04-14 18:58 ` [PATCH v2 4/6] OvmfPkg/RiscVVirt: VirtNorFlashPlatformLib: Fix wrong flash size Tuan Phan 2023-04-14 18:58 ` [PATCH v2 5/6] OvmfPkg/VirtNorFlashDxe: Not add memory space if it exists Tuan Phan 2023-04-14 18:58 ` [PATCH v2 6/6] OvmfPkg/RiscVVirt: SEC: Add IO memory resource hob for platform devices Tuan Phan 2023-04-18 16:03 ` [PATCH v2 0/6] RISC-V MMU support Andrei Warkentin 2023-04-19 22:37 ` [edk2-devel] " Tuan Phan 2023-05-08 17:19 ` Andrei Warkentin 2023-05-23 21:59 ` Tuan Phan 2023-05-24 4:17 ` Sunil V L
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox