diff options
author | ARM gem5 Developers <none@none> | 2014-01-24 15:29:34 -0600 |
---|---|---|
committer | ARM gem5 Developers <none@none> | 2014-01-24 15:29:34 -0600 |
commit | 612f8f074fa1099cf70faf495d46cc647762a031 (patch) | |
tree | bd1e99c43bf15292395eadd4b7ae3f5c823545c3 /src/arch/arm/vtophys.cc | |
parent | f3585c841e964c98911784a187fc4f081a02a0a6 (diff) | |
download | gem5-612f8f074fa1099cf70faf495d46cc647762a031.tar.xz |
arm: Add support for ARMv8 (AArch64 & AArch32)
Note: AArch64 and AArch32 interworking is not supported. If you use an AArch64
kernel you are restricted to AArch64 user-mode binaries. This will be addressed
in a later patch.
Note: Virtualization is only supported in AArch32 mode. This will also be fixed
in a later patch.
Contributors:
Giacomo Gabrielli (TrustZone, LPAE, system-level AArch64, AArch64 NEON, validation)
Thomas Grocutt (AArch32 Virtualization, AArch64 FP, validation)
Mbou Eyole (AArch64 NEON, validation)
Ali Saidi (AArch64 Linux support, code integration, validation)
Edmund Grimley-Evans (AArch64 FP)
William Wang (AArch64 Linux support)
Rene De Jong (AArch64 Linux support, performance opt.)
Matt Horsnell (AArch64 MP, validation)
Matt Evans (device models, code integration, validation)
Chris Adeniyi-Jones (AArch64 syscall-emulation)
Prakash Ramrakhyani (validation)
Dam Sunwoo (validation)
Chander Sudanthi (validation)
Stephan Diestelhorst (validation)
Andreas Hansson (code integration, performance opt.)
Eric Van Hensbergen (performance opt.)
Gabe Black
Diffstat (limited to 'src/arch/arm/vtophys.cc')
-rw-r--r-- | src/arch/arm/vtophys.cc | 71 |
1 files changed, 18 insertions, 53 deletions
diff --git a/src/arch/arm/vtophys.cc b/src/arch/arm/vtophys.cc index 7c26962cb..bed76acbd 100644 --- a/src/arch/arm/vtophys.cc +++ b/src/arch/arm/vtophys.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 ARM Limited + * Copyright (c) 2010, 2012-2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -45,6 +45,7 @@ #include <string> +#include "arch/arm/faults.hh" #include "arch/arm/table_walker.hh" #include "arch/arm/tlb.hh" #include "arch/arm/vtophys.hh" @@ -65,66 +66,30 @@ ArmISA::vtophys(Addr vaddr) Addr ArmISA::vtophys(ThreadContext *tc, Addr addr) { - SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); - if (!sctlr.m) { - // Translation is currently disabled PA == VA - return addr; - } - bool success; - Addr pa; + Fault fault; + // Set up a functional memory Request to pass to the TLB + // to get it to translate the vaddr to a paddr + Request req(0, addr, 64, 0x40, -1, 0, 0, 0); ArmISA::TLB *tlb; - // Check the TLBs far a translation - // It's possible that there is a validy translation in the tlb + // Check the TLBs for a translation + // It's possible that there is a valid translation in the tlb // that is no loger valid in the page table in memory // so we need to check here first + // + // Calling translateFunctional invokes a table-walk if required + // so we should always succeed tlb = static_cast<ArmISA::TLB*>(tc->getDTBPtr()); - success = tlb->translateFunctional(tc, addr, pa); - if (success) - return pa; + fault = tlb->translateFunctional(&req, tc, BaseTLB::Read, TLB::NormalTran); + if (fault == NoFault) + return req.getPaddr(); tlb = static_cast<ArmISA::TLB*>(tc->getITBPtr()); - success = tlb->translateFunctional(tc, addr, pa); - if (success) - return pa; + fault = tlb->translateFunctional(&req, tc, BaseTLB::Read, TLB::NormalTran); + if (fault == NoFault) + return req.getPaddr(); - // 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; - } - - PortProxy &port = tc->getPhysProxy(); - 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); + panic("Table walkers support functional accesses. We should never get here\n"); } bool |