summaryrefslogtreecommitdiff
path: root/src/arch/arm/vtophys.cc
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2010-10-01 16:03:27 -0500
committerAli Saidi <Ali.Saidi@ARM.com>2010-10-01 16:03:27 -0500
commit521d68c82a2399bfe32f282aa58708103369b99c (patch)
treee1856347d34b43c3064cfbc898f92284527616d2 /src/arch/arm/vtophys.cc
parent518b5e5b1c71259ce0badc29f98db46a73c59442 (diff)
downloadgem5-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.cc86
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;
+}
+
+