diff options
author | Ali Saidi <Ali.Saidi@ARM.com> | 2010-10-01 16:03:27 -0500 |
---|---|---|
committer | Ali Saidi <Ali.Saidi@ARM.com> | 2010-10-01 16:03:27 -0500 |
commit | 521d68c82a2399bfe32f282aa58708103369b99c (patch) | |
tree | e1856347d34b43c3064cfbc898f92284527616d2 /src/arch/arm/vtophys.cc | |
parent | 518b5e5b1c71259ce0badc29f98db46a73c59442 (diff) | |
download | gem5-521d68c82a2399bfe32f282aa58708103369b99c.tar.xz |
ARM: Implement functional virtual to physical address translation
for debugging and program introspection.
Diffstat (limited to 'src/arch/arm/vtophys.cc')
-rw-r--r-- | src/arch/arm/vtophys.cc | 86 |
1 files changed, 84 insertions, 2 deletions
diff --git a/src/arch/arm/vtophys.cc b/src/arch/arm/vtophys.cc index 01cbb3e79..1691a387c 100644 --- a/src/arch/arm/vtophys.cc +++ b/src/arch/arm/vtophys.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2010 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2002-2005 The Regents of The University of Michigan * Copyright (c) 2007-2008 The Florida State University * All rights reserved. @@ -33,6 +45,8 @@ #include <string> +#include "arch/arm/table_walker.hh" +#include "arch/arm/tlb.hh" #include "arch/arm/vtophys.hh" #include "base/chunk_generator.hh" #include "base/trace.hh" @@ -45,12 +59,80 @@ using namespace ArmISA; Addr ArmISA::vtophys(Addr vaddr) { - fatal("VTOPHYS: Can't convert vaddr to paddr on ARM without a thread context"); + fatal("VTOPHYS: Can't convert vaddr to paddr on ARM without a thread context"); } Addr ArmISA::vtophys(ThreadContext *tc, Addr addr) { - fatal("VTOPHYS: Unimplemented on ARM\n"); + SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); + if (!sctlr.m) { + // Translation is currently disabled PA == VA + return addr; + } + bool success; + Addr pa; + ArmISA::TLB *tlb; + + // Check the TLBs far a translation + // It's possible that there is a validy translation in the tlb + // that is no loger valid in the page table in memory + // so we need to check here first + tlb = static_cast<ArmISA::TLB*>(tc->getDTBPtr()); + success = tlb->translateFunctional(tc, addr, pa); + if (success) + return pa; + + tlb = static_cast<ArmISA::TLB*>(tc->getITBPtr()); + success = tlb->translateFunctional(tc, addr, pa); + if (success) + return pa; + + // We've failed everything, so we need to do a + // hardware tlb walk without messing with any + // state + + uint32_t N = tc->readMiscReg(MISCREG_TTBCR); + Addr ttbr; + if (N == 0 || !mbits(addr, 31, 32-N)) { + ttbr = tc->readMiscReg(MISCREG_TTBR0); + } else { + ttbr = tc->readMiscReg(MISCREG_TTBR1); + N = 0; + } + + FunctionalPort *port = tc->getPhysPort(); + Addr l1desc_addr = mbits(ttbr, 31, 14-N) | (bits(addr,31-N,20) << 2); + + TableWalker::L1Descriptor l1desc; + l1desc.data = port->read<uint32_t>(l1desc_addr); + if (l1desc.type() == TableWalker::L1Descriptor::Ignore || + l1desc.type() == TableWalker::L1Descriptor::Reserved) { + warn("Unable to translate virtual address: %#x\n", addr); + return -1; + } + if (l1desc.type() == TableWalker::L1Descriptor::Section) + return l1desc.paddr(addr); + + // Didn't find it at the first level, try againt + Addr l2desc_addr = l1desc.l2Addr() | (bits(addr, 19, 12) << 2); + TableWalker::L2Descriptor l2desc; + l2desc.data = port->read<uint32_t>(l2desc_addr); + + if (l2desc.invalid()) { + warn("Unable to translate virtual address: %#x\n", addr); + return -1; + } + + return l2desc.paddr(addr); } +bool +ArmISA::virtvalid(ThreadContext *tc, Addr vaddr) +{ + if (vtophys(tc, vaddr) != -1) + return true; + return false; +} + + |