From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) by mx.groups.io with SMTP id smtpd.web10.1080.1678124010583357001 for ; Mon, 06 Mar 2023 09:33:30 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@ventanamicro.com header.s=google header.b=S1X6j0sZ; spf=pass (domain: ventanamicro.com, ip: 209.85.214.175, mailfrom: tphan@ventanamicro.com) Received: by mail-pl1-f175.google.com with SMTP id a2so11257856plm.4 for ; Mon, 06 Mar 2023 09:33:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1678124009; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=7gheENF6oLv95x5ZS0tgE4d4sCNCC0r1JlDJCc10q00=; b=S1X6j0sZhQY4hZcK3/mRt7oZSLVlI9sREYYzoSMwen8HqSRwsUyG72gcpCv0Uj4tjN JOxqRP6oBGCpjhWg2A1rjS7wFJaog5zFVECku/81WUnxhbj8CrhShfmLK0zgBREEmYRn fMzVCf6zUSk09lViMbCBBjkIQtlblfvdrhnvG2AIFMqMMvsnUTv9xwDIESA96cQamuUH Gmr2u1p1T8rBu6GLImjajp/UlIz8iwpSAAWL4bLHbMzmOB5DRHDH3x0seeD6KlkzyOAa 273pNQOgMQGCZgXlSY3ZXZUiDzdLSFr1k7GQeKoZfvIMoP6pKtK1Oq1EHprhbWdXTrGx wJ1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678124009; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7gheENF6oLv95x5ZS0tgE4d4sCNCC0r1JlDJCc10q00=; b=x8BJ4E/TPukHIBYdREV1hSeMNZ9wQ1Ekhw/WxT98pxyWn31zPuR3dscxfcKx5TYoDs HJhUcpfDqiAKtovN/rlh/8GgvaSyLA6Gxtx/fAoT8rqseGON3iuzYpI1lLhKyqAP5fP6 AsZ4PRew2xdUcGiI7f3woSRfhF5AU+04MRpfJuYFDGklsAhkswfyGRQBO9ce9FO6VJnz tOy4ikoJVVRMbsd33xwrgJilqL6JntIvM7mJqgFU3qT9aRQkKW199pqKLmqJlCI91WfN UrHFK1pYi2feRHKnLxgFGofckDdwXnlrglKAtVEURPfsk1sditgj3OEz0uEkm6pjhPsb S7DQ== X-Gm-Message-State: AO0yUKW0GcUqvPD4uTc5PkLVkgkw07x9QGs75PKa1M+aBr0Wo+m5mfS8 eJm6czZIKCW2KTf3F4zNCoWhugdhPsyAXH7RjYV+FQ== X-Google-Smtp-Source: AK7set9CYBVyNJfwGRhb5uLje8UaCTM+jYhaUggFgzb4gSk+E7i7lKKLVrpj4IWNEfdnwIujGO0tkg== X-Received: by 2002:a05:6a21:6d81:b0:cb:cd6a:2e42 with SMTP id wl1-20020a056a216d8100b000cbcd6a2e42mr14518809pzb.29.1678124009353; Mon, 06 Mar 2023 09:33:29 -0800 (PST) Return-Path: Received: from localhost.localdomain (c-174-50-177-95.hsd1.ca.comcast.net. [174.50.177.95]) by smtp.gmail.com with ESMTPSA id v6-20020aa78506000000b005dd975176c3sm6579722pfn.53.2023.03.06.09.33.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Mar 2023 09:33:28 -0800 (PST) From: "Tuan Phan" To: devel@edk2.groups.io Cc: michael.d.kinney@intel.com, gaoliming@byosoft.com.cn, zhiguang.liu@intel.com, sunilvl@ventanamicro.com, git@danielschaefer.me, andrei.warkentin@intel.com, Tuan Phan Subject: [PATCH 3/7] UefiCpuPkg: RISC-V: Support MMU with SV39/48/57 mode Date: Mon, 6 Mar 2023 09:33:12 -0800 Message-Id: <20230306173316.10319-4-tphan@ventanamicro.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230306173316.10319-1-tphan@ventanamicro.com> References: <20230306173316.10319-1-tphan@ventanamicro.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable During CpuDxe initialization, MMU will be setup based on the value get from the PCD satp mode. Default is bare mode. Signed-off-by: Tuan Phan --- UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c | 10 +- UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h | 1 + UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf | 5 + UefiCpuPkg/CpuDxeRiscV64/Mmu.c | 493 +++++++++++++++++++++ UefiCpuPkg/CpuDxeRiscV64/Mmu.h | 33 ++ UefiCpuPkg/CpuDxeRiscV64/MmuCore.S | 29 ++ UefiCpuPkg/UefiCpuPkg.dec | 8 + 7 files changed, 577 insertions(+), 2 deletions(-) create mode 100644 UefiCpuPkg/CpuDxeRiscV64/Mmu.c create mode 100644 UefiCpuPkg/CpuDxeRiscV64/Mmu.h create mode 100644 UefiCpuPkg/CpuDxeRiscV64/MmuCore.S diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxeRiscV64/C= puDxe.c index 7551e0653603..144e4b49ea5a 100644 --- a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c +++ b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c @@ -9,6 +9,7 @@ **/=0D =0D #include "CpuDxe.h"=0D +#include "Mmu.h"=0D =0D //=0D // Global Variables=0D @@ -296,8 +297,7 @@ CpuSetMemoryAttributes ( IN UINT64 Attributes=0D )=0D {=0D - DEBUG ((DEBUG_INFO, "%a: Set memory attributes not supported yet\n", __F= UNCTION__));=0D - return EFI_SUCCESS;=0D + return RiscVSetMemoryAttributes (BaseAddress, Length, Attributes);=0D }=0D =0D /**=0D @@ -340,6 +340,12 @@ InitializeCpu ( //=0D DisableInterrupts ();=0D =0D + //=0D + // Enable MMU=0D + //=0D + Status =3D RiscVConfigureMmu (PcdGet64 (PcdCpuRiscVSatpMode));=0D + ASSERT_EFI_ERROR (Status);=0D +=0D //=0D // Install Boot protocol=0D //=0D diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxeRiscV64/C= puDxe.h index 49f4e119665a..2f2f970a7887 100644 --- a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h +++ b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h @@ -20,6 +20,7 @@ #include =0D #include =0D #include =0D +#include =0D =0D /**=0D Flush CPU data cache. If the instruction cache is fully coherent=0D diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf b/UefiCpuPkg/CpuDxe= RiscV64/CpuDxeRiscV64.inf index e8fa25446aef..6c2d65be789d 100644 --- a/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf +++ b/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf @@ -37,10 +37,14 @@ TimerLib=0D PeCoffGetEntryPointLib=0D RiscVSbiLib=0D + CacheMaintenanceLib=0D =0D [Sources]=0D CpuDxe.c=0D CpuDxe.h=0D + Mmu.c=0D + Mmu.h=0D + MmuCore.S=0D =0D [Protocols]=0D gEfiCpuArchProtocolGuid ## PRODUCES=0D @@ -60,6 +64,7 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList ##= CONSUMES=0D gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize ##= CONSUMES=0D gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ##= CONSUMES=0D + gUefiCpuPkgTokenSpaceGuid.PcdCpuRiscVSatpMode ##= CONSUMES=0D =0D [Depex]=0D TRUE=0D diff --git a/UefiCpuPkg/CpuDxeRiscV64/Mmu.c b/UefiCpuPkg/CpuDxeRiscV64/Mmu.c new file mode 100644 index 000000000000..bec78b0ea514 --- /dev/null +++ b/UefiCpuPkg/CpuDxeRiscV64/Mmu.c @@ -0,0 +1,493 @@ +/** @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.
+* Copyright (c) 2023, Ventana Micro Systems Inc. All Rights Reserved.
+* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Mmu.h" + +#define RISCV_PG_V BIT0 +#define RISCV_PG_R BIT1 +#define RISCV_PG_W BIT2 +#define RISCV_PG_X BIT3 +#define RISCV_PG_G BIT5 +#define RISCV_PG_A BIT6 +#define RISCV_PG_D BIT7 +#define PTE_ATTRIBUTES_MASK 0xE + +#define PTE_PPN_MASK 0x3FFFFFFFFFFC00ULL +#define PTE_PPN_SHIFT 10 +#define RISCV_MMU_PAGE_SHIFT 12 + +STATIC UINTN mMaxRootTableLevel; +STATIC UINTN mBitPerLevel; +STATIC UINTN mTableEntryCount; + +STATIC +BOOLEAN +RiscVMmuEnabled (VOID) +{ + return ((RiscVGetSupervisorAddressTranslationRegister () & + SATP64_MODE) !=3D (SATP_MODE_OFF << SATP64_MODE_SHIFT)); +} + +STATIC +UINTN +RiscVGetRootTranslateTable (VOID) +{ + return (RiscVGetSupervisorAddressTranslationRegister () & SATP64_PPN) << + RISCV_MMU_PAGE_SHIFT; +} + +STATIC +BOOLEAN +IsValidPte ( + IN UINTN Entry + ) +{ + if (!(Entry & RISCV_PG_V) || + (((Entry & (RISCV_PG_R | RISCV_PG_W)) =3D=3D RISCV_PG_W))) { + return FALSE; + } + + return TRUE; +} + +STATIC +UINTN +SetValidPte ( + IN UINTN Entry + ) +{ + /* Set Valid and Global mapping bits */ + return Entry | RISCV_PG_G | RISCV_PG_V; +} + +STATIC +BOOLEAN +IsBlockEntry ( + IN UINTN Entry + ) +{ + return IsValidPte (Entry) && + (Entry & (RISCV_PG_X | RISCV_PG_R)); +} + +STATIC +BOOLEAN +IsTableEntry ( + IN UINTN Entry + ) +{ + return IsValidPte (Entry) && + !IsBlockEntry (Entry); +} + +STATIC +UINTN +SetTableEntry ( + IN UINTN Entry + ) +{ + Entry =3D SetValidPte (Entry); + Entry &=3D ~(RISCV_PG_X | RISCV_PG_W | RISCV_PG_R); + + return Entry; +} + +STATIC +VOID +ReplaceTableEntry ( + IN UINTN *Entry, + IN UINTN Value, + IN UINTN RegionStart, + IN BOOLEAN IsLiveBlockMapping + ) +{ + *Entry =3D Value; + + if (IsLiveBlockMapping && RiscVMmuEnabled ()) { + RiscVLocalTlbFlush (RegionStart); + } +} + +STATIC +UINTN +GetPpnfromPte (UINTN Entry, UINTN Level) +{ + return ((Entry & PTE_PPN_MASK) >> PTE_PPN_SHIFT); +} + +STATIC +UINTN +SetPpnToPte (UINTN Entry, UINTN Address, UINTN Level) +{ + UINTN Ppn; + + Ppn =3D ((Address >> RISCV_MMU_PAGE_SHIFT) << PTE_PPN_SHIFT); + ASSERT (~(Ppn & ~PTE_PPN_MASK)); + Entry &=3D ~PTE_PPN_MASK; + return Entry | Ppn; +} + +STATIC +VOID +FreePageTablesRecursive ( + IN UINTN *TranslationTable, + IN UINTN Level + ) +{ + UINTN Index; + + if (Level < mMaxRootTableLevel - 1) { + for (Index =3D 0; Index < mTableEntryCount; Index++) { + if (IsTableEntry (TranslationTable[Index])) { + FreePageTablesRecursive ( + (UINTN *)(GetPpnfromPte ((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) =3D=3D 0); + + BlockShift =3D (mMaxRootTableLevel - Level - 1) * mBitPerLevel + RISCV_M= MU_PAGE_SHIFT; + BlockMask =3D MAX_ADDRESS >> (64 - BlockShift); + + DEBUG (( + DEBUG_VERBOSE, + "%a(%d): %llx - %llx set %lx clr %lx\n", + __func__, + Level, + RegionStart, + RegionEnd, + AttributeSetMask, + AttributeClearMask + )); + + for ( ; RegionStart < RegionEnd; RegionStart =3D BlockEnd) { + BlockEnd =3D MIN (RegionEnd, (RegionStart | BlockMask) + 1); + Entry =3D &PageTable[(RegionStart >> BlockShift) & (mTableEntryCoun= t - 1)]; + + // + // If RegionStart or BlockEnd is not aligned to the block size at this + // level, we will have to create a table mapping in order to map less + // than a block, and recurse to create the block or page entries at + // the next level. No block mappings are allowed at all at level 0, + // so in that case, we have to recurse unconditionally. + // + if (Level =3D=3D 0 || + (((RegionStart | BlockEnd) & BlockMask) !=3D 0) || IsTableEntry (*= Entry)) + { + ASSERT (Level < mMaxRootTableLevel - 1); + if (!IsTableEntry (*Entry)) { + // + // No table entry exists yet, so we need to allocate a page table + // for the next level. + // + TranslationTable =3D AllocatePages (1); + if (TranslationTable =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + ZeroMem (TranslationTable, EFI_PAGE_SIZE); + + if (IsBlockEntry (*Entry)) { + // + // We are splitting an existing block entry, so we have to popul= ate + // the new table with the attributes of the block entry it repla= ces. + // + Status =3D UpdateRegionMappingRecursive ( + RegionStart & ~BlockMask, + (RegionStart | BlockMask) + 1, + *Entry & PTE_ATTRIBUTES_MASK, + PTE_ATTRIBUTES_MASK, + TranslationTable, + Level + 1, + FALSE + ); + if (EFI_ERROR (Status)) { + // + // The range we passed to UpdateRegionMappingRecursive () is b= lock + // aligned, so it is guaranteed that no further pages were all= ocated + // by it, and so we only have to free the page we allocated he= re. + // + FreePages (TranslationTable, 1); + return Status; + } + } + NextTableIsLive =3D FALSE; + } else { + TranslationTable =3D (UINTN *)(GetPpnfromPte (*Entry, Level) << RI= SCV_MMU_PAGE_SHIFT); + NextTableIsLive =3D TableIsLive; + } + + // + // Recurse to the next level + // + Status =3D UpdateRegionMappingRecursive ( + RegionStart, + BlockEnd, + AttributeSetMask, + AttributeClearMask, + TranslationTable, + Level + 1, + NextTableIsLive + ); + if (EFI_ERROR (Status)) { + if (!IsTableEntry (*Entry)) { + // + // We are creating a new table entry, so on failure, we can free= all + // allocations we made recursively, given that the whole subhier= archy + // has not been wired into the live page tables yet. (This is not + // possible for existing table entries, since we cannot revert t= he + // modifications we made to the subhierarchy it represents.) + // + FreePageTablesRecursive (TranslationTable, Level + 1); + } + return Status; + } + + if (!IsTableEntry (*Entry)) { + EntryValue =3D SetPpnToPte (0, (UINTN)TranslationTable, Level); + EntryValue =3D SetTableEntry (EntryValue); + ReplaceTableEntry ( + Entry, + EntryValue, + RegionStart, + TableIsLive + ); + } + } else { + EntryValue =3D (*Entry & ~AttributeClearMask) | AttributeSetMask; + // + // We don't have page fault exception handler when a virtual page is= accessed and + // the A bit is clear, or is written and the D bit is clear. + // So just set A for read and D for write permission. + // + if (AttributeSetMask & RISCV_PG_R) { + EntryValue |=3D RISCV_PG_A; + } + if (AttributeSetMask & RISCV_PG_W) { + EntryValue |=3D RISCV_PG_D; + } + EntryValue =3D SetPpnToPte (EntryValue, RegionStart, Level); + EntryValue =3D SetValidPte (EntryValue); + ReplaceTableEntry (Entry, EntryValue, RegionStart, TableIsLive); + } + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +UpdateRegionMapping ( + IN UINTN RegionStart, + IN UINTN RegionLength, + IN UINTN AttributeSetMask, + IN UINTN AttributeClearMask, + IN UINTN *RootTable, + IN BOOLEAN TableIsLive + ) +{ + if (((RegionStart | RegionLength) & EFI_PAGE_MASK) !=3D 0) { + return EFI_INVALID_PARAMETER; + } + + return UpdateRegionMappingRecursive ( + RegionStart, + RegionStart + RegionLength, + AttributeSetMask, + AttributeClearMask, + RootTable, + 0, + TableIsLive + ); +} + +STATIC +UINTN +GcdAttributeToPageAttribute ( + IN UINTN GcdAttributes + ) +{ + UINTN RiscVAttributes =3D RISCV_PG_R | RISCV_PG_W | RISCV_PG_X; + + // Determine protection attributes + if (GcdAttributes & EFI_MEMORY_RO) { + RiscVAttributes &=3D ~(RISCV_PG_W); + } + + // Process eXecute Never attribute + if (GcdAttributes & EFI_MEMORY_XP) { + RiscVAttributes &=3D ~RISCV_PG_X; + } + + return RiscVAttributes; +} + +EFI_STATUS +EFIAPI +RiscVSetMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length, + IN UINTN Attributes + ) +{ + UINTN PageAttributesSet =3D GcdAttributeToPageAttribute (Attributes); + + if (!RiscVMmuEnabled ()) { + return EFI_SUCCESS; + } + + DEBUG (( + DEBUG_VERBOSE, + "%a: Set %llX page attribute 0x%X\n", + __func__, + BaseAddress, + PageAttributesSet + )); + + return UpdateRegionMapping ( + BaseAddress, + Length, + PageAttributesSet, + PTE_ATTRIBUTES_MASK, + (UINTN *)RiscVGetRootTranslateTable (), + TRUE + ); +} + +EFI_STATUS +EFIAPI +RiscVConfigureMmu (UINTN SatpMode) +{ + VOID *TranslationTable; + UINTN SatpReg; + UINTN Ppn; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemoryMap; + UINTN NumberOfDescriptors; + UINTN Index; + EFI_STATUS Status; + + switch (SatpMode) { + case SATP_MODE_OFF: + return EFI_SUCCESS; + case SATP_MODE_SV39: + mMaxRootTableLevel =3D 3; + mBitPerLevel =3D 9; + mTableEntryCount =3D 512; + break; + case SATP_MODE_SV48: + mMaxRootTableLevel =3D 4; + mBitPerLevel =3D 9; + mTableEntryCount =3D 512; + break; + case SATP_MODE_SV57: + mMaxRootTableLevel =3D 5; + mBitPerLevel =3D 9; + mTableEntryCount =3D 512; + break; + default: + return EFI_INVALID_PARAMETER; + } + + // Allocate pages for translation table + TranslationTable =3D AllocatePages (1); + if (TranslationTable =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + ZeroMem (TranslationTable, mTableEntryCount * sizeof (UINTN)); + + NumberOfDescriptors =3D 0; + MemoryMap =3D NULL; + Status =3D gDS->GetMemorySpaceMap ( + &NumberOfDescriptors, + &MemoryMap + ); + ASSERT_EFI_ERROR (Status); + + for (Index =3D 0; Index < NumberOfDescriptors; Index++) { + if (MemoryMap[Index].GcdMemoryType =3D=3D EfiGcdMemoryTypeMemoryMapped= Io) { + // Default Read/Write attribute for memory mapped IO + UpdateRegionMapping (MemoryMap[Index].BaseAddress, + MemoryMap[Index].Length, + RISCV_PG_R | RISCV_PG_W, + PTE_ATTRIBUTES_MASK, + TranslationTable, + FALSE); + } else if (MemoryMap[Index].GcdMemoryType =3D=3D EfiGcdMemoryTypeSyste= mMemory) { + // Default Read/Write/Execute attribute for system memory + UpdateRegionMapping (MemoryMap[Index].BaseAddress, + MemoryMap[Index].Length, + RISCV_PG_R | RISCV_PG_W | RISCV_PG_X, + PTE_ATTRIBUTES_MASK, + TranslationTable, + FALSE); + } + } + FreePool ((VOID *)MemoryMap); + + if (GetInterruptState ()) { + DisableInterrupts (); + } + + Ppn =3D (UINTN)TranslationTable >> RISCV_MMU_PAGE_SHIFT; + ASSERT (!(Ppn & ~(SATP64_PPN))); + + SatpReg =3D Ppn; + SatpReg |=3D (SatpMode << + SATP64_MODE_SHIFT) & SATP64_MODE; + RiscVSetSupervisorAddressTranslationRegister (SatpReg); + RiscVLocalTlbFlushAll (); + + if (GetInterruptState ()) { + EnableInterrupts (); + } + + return Status; +} diff --git a/UefiCpuPkg/CpuDxeRiscV64/Mmu.h b/UefiCpuPkg/CpuDxeRiscV64/Mmu.h new file mode 100644 index 000000000000..9ee0a4bfab61 --- /dev/null +++ b/UefiCpuPkg/CpuDxeRiscV64/Mmu.h @@ -0,0 +1,33 @@ +/** @file + + Copyright (c) 2015 - 2016, Linaro Ltd. All rights reserved.
+ Copyright (c) 2023, Ventana Micro Systems Inc. All Rights Reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef MMU_H_ +#define MMU_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 (UINTN SatpMode); + +#endif /* MMU_H_ */ diff --git a/UefiCpuPkg/CpuDxeRiscV64/MmuCore.S b/UefiCpuPkg/CpuDxeRiscV64/= MmuCore.S new file mode 100644 index 000000000000..d0cbd91ffcc0 --- /dev/null +++ b/UefiCpuPkg/CpuDxeRiscV64/MmuCore.S @@ -0,0 +1,29 @@ +/** @file +* +* Copyright (c) 2023, Ventana Micro Systems Inc. All Rights Reserved.
+* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#include +#include + +.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/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 2115aa4387a2..b4e2be2e3880 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -360,6 +360,14 @@ # @Prompt Access to non-SMRAM memory is restricted to reserved, runtime = and ACPI NVS type after SmmReadyToLock.=0D gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmRestrictedMemoryAccess|TRUE|BOOLEAN|0= x3213210F=0D =0D +[PcdsFixedAtBuild.RISCV64]=0D + ## Configure SATP mode for RISCV=0D + # 0 - Bare mode=0D + # 8 - SV39 mode=0D + # 9 - SV48 mode=0D + # 10 - SV57 mode=0D + gUefiCpuPkgTokenSpaceGuid.PcdCpuRiscVSatpMode|0x0|UINT64|0x70000001=0D +=0D [PcdsDynamic, PcdsDynamicEx]=0D ## Contains the pointer to a CPU S3 data buffer of structure ACPI_CPU_DA= TA.=0D # @Prompt The pointer to a CPU S3 data buffer.=0D --=20 2.25.1