vtophys.cc revision 5560
113996Sgiacomo.travaglini@arm.com/*
213996Sgiacomo.travaglini@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
313996Sgiacomo.travaglini@arm.com * All rights reserved.
413996Sgiacomo.travaglini@arm.com *
513996Sgiacomo.travaglini@arm.com * Redistribution and use in source and binary forms, with or without
613996Sgiacomo.travaglini@arm.com * modification, are permitted provided that the following conditions are
713996Sgiacomo.travaglini@arm.com * met: redistributions of source code must retain the above copyright
813996Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer;
913996Sgiacomo.travaglini@arm.com * redistributions in binary form must reproduce the above copyright
1013996Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer in the
1113996Sgiacomo.travaglini@arm.com * documentation and/or other materials provided with the distribution;
1213996Sgiacomo.travaglini@arm.com * neither the name of the copyright holders nor the names of its
1313996Sgiacomo.travaglini@arm.com * contributors may be used to endorse or promote products derived from
1413996Sgiacomo.travaglini@arm.com * this software without specific prior written permission.
1513996Sgiacomo.travaglini@arm.com *
1613996Sgiacomo.travaglini@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713996Sgiacomo.travaglini@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813996Sgiacomo.travaglini@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913996Sgiacomo.travaglini@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013996Sgiacomo.travaglini@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113996Sgiacomo.travaglini@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213996Sgiacomo.travaglini@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313996Sgiacomo.travaglini@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413996Sgiacomo.travaglini@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513996Sgiacomo.travaglini@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613996Sgiacomo.travaglini@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713996Sgiacomo.travaglini@arm.com *
2813996Sgiacomo.travaglini@arm.com * Authors: Ali Saidi
2913996Sgiacomo.travaglini@arm.com */
3013996Sgiacomo.travaglini@arm.com
3113996Sgiacomo.travaglini@arm.com#include <string>
3213996Sgiacomo.travaglini@arm.com
3313996Sgiacomo.travaglini@arm.com#include "arch/sparc/vtophys.hh"
3413996Sgiacomo.travaglini@arm.com#include "arch/sparc/tlb.hh"
3513996Sgiacomo.travaglini@arm.com#include "base/compiler.hh"
3613996Sgiacomo.travaglini@arm.com#include "base/chunk_generator.hh"
3713996Sgiacomo.travaglini@arm.com#include "base/trace.hh"
3813996Sgiacomo.travaglini@arm.com#include "cpu/thread_context.hh"
3913996Sgiacomo.travaglini@arm.com#include "mem/vport.hh"
4013996Sgiacomo.travaglini@arm.com
4113996Sgiacomo.travaglini@arm.comusing namespace std;
4213996Sgiacomo.travaglini@arm.com
4313996Sgiacomo.travaglini@arm.comnamespace SparcISA {
4413996Sgiacomo.travaglini@arm.com
4513996Sgiacomo.travaglini@arm.comAddr
4613996Sgiacomo.travaglini@arm.comvtophys(Addr vaddr)
4713996Sgiacomo.travaglini@arm.com{
4813996Sgiacomo.travaglini@arm.com    // In SPARC it's almost always impossible to turn a VA->PA w/o a
4913996Sgiacomo.travaglini@arm.com    // context The only times we can kinda do it are if we have a
5013996Sgiacomo.travaglini@arm.com    // SegKPM mapping and can find the real address in the tlb or we
5113996Sgiacomo.travaglini@arm.com    // have a physical adddress already (beacuse we are looking at the
5213996Sgiacomo.travaglini@arm.com    // hypervisor) Either case is rare, so we'll just panic.
5313996Sgiacomo.travaglini@arm.com
5413996Sgiacomo.travaglini@arm.com    panic("vtophys() without context on SPARC largly worthless\n");
5513996Sgiacomo.travaglini@arm.com    M5_DUMMY_RETURN;
5613996Sgiacomo.travaglini@arm.com}
5713996Sgiacomo.travaglini@arm.com
5813996Sgiacomo.travaglini@arm.comAddr
5913996Sgiacomo.travaglini@arm.comvtophys(ThreadContext *tc, Addr addr)
6013996Sgiacomo.travaglini@arm.com{
6113996Sgiacomo.travaglini@arm.com    // Here we have many options and are really implementing something like
6213996Sgiacomo.travaglini@arm.com    // a fill handler to find the address since there isn't a multilevel
6313996Sgiacomo.travaglini@arm.com    // table for us to walk around.
6413996Sgiacomo.travaglini@arm.com    //
6513996Sgiacomo.travaglini@arm.com    // 1. We are currently hyperpriv, return the address unmodified
6613996Sgiacomo.travaglini@arm.com    // 2. The mmu is off return(ra->pa)
6713996Sgiacomo.travaglini@arm.com    // 3. We are currently priv, use ctx0* tsbs to find the page
6813996Sgiacomo.travaglini@arm.com    // 4. We are not priv, use ctxN0* tsbs to find the page
6913996Sgiacomo.travaglini@arm.com    // For all accesses we check the tlbs first since it's possible that
7013996Sgiacomo.travaglini@arm.com    // long standing pages (e.g. locked kernel mappings) won't be in the tsb
7113996Sgiacomo.travaglini@arm.com    uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
7213996Sgiacomo.travaglini@arm.com
7313996Sgiacomo.travaglini@arm.com    bool hpriv = bits(tlbdata,0,0);
7413996Sgiacomo.travaglini@arm.com    //bool priv = bits(tlbdata,2,2);
7513996Sgiacomo.travaglini@arm.com    bool addr_mask = bits(tlbdata,3,3);
7613996Sgiacomo.travaglini@arm.com    bool data_real = !bits(tlbdata,5,5);
7713996Sgiacomo.travaglini@arm.com    bool inst_real = !bits(tlbdata,4,4);
7813996Sgiacomo.travaglini@arm.com    bool ctx_zero  = bits(tlbdata,18,16) > 0;
7913996Sgiacomo.travaglini@arm.com    int part_id = bits(tlbdata,15,8);
8013996Sgiacomo.travaglini@arm.com    int pri_context = bits(tlbdata,47,32);
8113996Sgiacomo.travaglini@arm.com    //int sec_context = bits(tlbdata,63,48);
8213996Sgiacomo.travaglini@arm.com
8313996Sgiacomo.travaglini@arm.com    FunctionalPort *mem = tc->getPhysPort();
8413996Sgiacomo.travaglini@arm.com    ITB* itb = tc->getITBPtr();
8513996Sgiacomo.travaglini@arm.com    DTB* dtb = tc->getDTBPtr();
8613996Sgiacomo.travaglini@arm.com    TlbEntry* tbe;
8713996Sgiacomo.travaglini@arm.com    PageTableEntry pte;
8813996Sgiacomo.travaglini@arm.com    Addr tsbs[4];
8913996Sgiacomo.travaglini@arm.com    Addr va_tag;
9013996Sgiacomo.travaglini@arm.com    TteTag ttetag;
9113996Sgiacomo.travaglini@arm.com
9213996Sgiacomo.travaglini@arm.com    if (hpriv)
9313996Sgiacomo.travaglini@arm.com        return addr;
9413996Sgiacomo.travaglini@arm.com
9513996Sgiacomo.travaglini@arm.com    if (addr_mask)
9613996Sgiacomo.travaglini@arm.com        addr = addr & VAddrAMask;
9713996Sgiacomo.travaglini@arm.com
9813996Sgiacomo.travaglini@arm.com    tbe = dtb->lookup(addr, part_id, data_real, ctx_zero ? 0 : pri_context ,
9913996Sgiacomo.travaglini@arm.com                      false);
10013996Sgiacomo.travaglini@arm.com    if (tbe)
10113996Sgiacomo.travaglini@arm.com        goto foundtbe;
10213996Sgiacomo.travaglini@arm.com
10313996Sgiacomo.travaglini@arm.com    tbe = itb->lookup(addr, part_id, inst_real, ctx_zero ? 0 : pri_context,
10413996Sgiacomo.travaglini@arm.com                      false);
10513996Sgiacomo.travaglini@arm.com    if (tbe)
10613996Sgiacomo.travaglini@arm.com        goto foundtbe;
10713996Sgiacomo.travaglini@arm.com
10813996Sgiacomo.travaglini@arm.com    // We didn't find it in the tlbs, so lets look at the TSBs
10913996Sgiacomo.travaglini@arm.com    dtb->GetTsbPtr(tc, addr, ctx_zero ? 0 : pri_context, tsbs);
11013996Sgiacomo.travaglini@arm.com    va_tag = bits(addr, 63, 22);
11113996Sgiacomo.travaglini@arm.com    for (int x = 0; x < 4; x++) {
11213996Sgiacomo.travaglini@arm.com        ttetag = betoh(mem->read<uint64_t>(tsbs[x]));
11313996Sgiacomo.travaglini@arm.com        if (ttetag.valid() && ttetag.va() == va_tag) {
11413996Sgiacomo.travaglini@arm.com            uint64_t entry = mem->read<uint64_t>(tsbs[x]) + sizeof(uint64_t);
11513996Sgiacomo.travaglini@arm.com            // I think it's sun4v at least!
11613996Sgiacomo.travaglini@arm.com            pte.populate(betoh(entry), PageTableEntry::sun4v);
11714187Sgiacomo.travaglini@arm.com            DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TTE\n",
11814187Sgiacomo.travaglini@arm.com                    addr, pte.translate(addr));
11914187Sgiacomo.travaglini@arm.com            goto foundpte;
12014187Sgiacomo.travaglini@arm.com        }
12114187Sgiacomo.travaglini@arm.com    }
12214187Sgiacomo.travaglini@arm.com    panic("couldn't translate %#x\n", addr);
12314187Sgiacomo.travaglini@arm.com
12414187Sgiacomo.travaglini@arm.com  foundtbe:
12514187Sgiacomo.travaglini@arm.com    pte = tbe->pte;
12614187Sgiacomo.travaglini@arm.com    DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TLB\n", addr,
12714187Sgiacomo.travaglini@arm.com            pte.translate(addr));
12814187Sgiacomo.travaglini@arm.com  foundpte:
12914181Sgiacomo.travaglini@arm.com    return pte.translate(addr);
13014181Sgiacomo.travaglini@arm.com}
13114181Sgiacomo.travaglini@arm.com
13213996Sgiacomo.travaglini@arm.com} /* namespace SparcISA */
13313996Sgiacomo.travaglini@arm.com