From e48285c244a9afb910f3a4a8beb21531cd8a4426 Mon Sep 17 00:00:00 2001 From: Matthew Poremba Date: Wed, 12 Oct 2022 14:48:49 -0700 Subject: [PATCH] arch-vega: Implement PDE2 and PDE1 as PTE Page directory entries (PDEs) can be interpreted as leaf node page table entries (PTEs) if the "p" bit is set. This is used for flexible page sizes in Vega. Currently there is only support for PDE level 0 entries which can be interpreted as 2MB pages. This changeset adds support for PDE1 and PDE2 which can be used to represent 1GB and 512GB pages. PDE1-as-PTE entries can be tested and were verified on applications by allocating >2GB of data. PDE0 is untested due to being too large for simulation, but the implementation is similar to PDE0 and PDE1. Change-Id: I801cbb5ec79110d57d2db760cc689c2e5778f9bb Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/64451 Maintainer: Matt Sinclair Tested-by: kokoro Reviewed-by: Matt Sinclair --- src/arch/amdgpu/vega/pagetable_walker.cc | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/arch/amdgpu/vega/pagetable_walker.cc b/src/arch/amdgpu/vega/pagetable_walker.cc index 2a8238f0fe..96ac0fe179 100644 --- a/src/arch/amdgpu/vega/pagetable_walker.cc +++ b/src/arch/amdgpu/vega/pagetable_walker.cc @@ -245,7 +245,16 @@ Walker::WalkerState::walkStateMachine(PageTableEntry &pte, Addr &nextRead, switch(state) { case PDE2: - fatal_if(pde.p, "Fragment in PDE2 not implemented"); + if (pde.p) { + DPRINTF(GPUPTWalker, "Treating PDE2 as PTE: %#016x frag: %d\n", + (uint64_t)pte, pte.fragment); + entry.pte = pte; + int fragment = pte.fragment; + entry.logBytes = PageShift + std::min(3*9, fragment); + entry.vaddr <<= PageShift; + entry.vaddr = entry.vaddr & ~mask(entry.logBytes); + doEndWalk = true; + } // Read the pde1Addr part1 = ((((uint64_t)pte) >> 6) << 3); @@ -257,7 +266,16 @@ Walker::WalkerState::walkStateMachine(PageTableEntry &pte, Addr &nextRead, nextState = PDE1; break; case PDE1: - fatal_if(pde.p, "Fragment in PDE1 not implemented"); + if (pde.p) { + DPRINTF(GPUPTWalker, "Treating PDE1 as PTE: %#016x frag: %d\n", + (uint64_t)pte, pte.fragment); + entry.pte = pte; + int fragment = pte.fragment; + entry.logBytes = PageShift + std::min(2*9, fragment); + entry.vaddr <<= PageShift; + entry.vaddr = entry.vaddr & ~mask(entry.logBytes); + doEndWalk = true; + } // Read the pde0Addr part1 = ((((uint64_t)pte) >> 6) << 3);