stage2_lookup.cc revision 11793
110037SARM gem5 Developers/*
211586SDylan.Johnson@ARM.com * Copyright (c) 2010-2013, 2016 ARM Limited
310037SARM gem5 Developers * All rights reserved
410037SARM gem5 Developers *
510037SARM gem5 Developers * The license below extends only to copyright in the software and shall
610037SARM gem5 Developers * not be construed as granting a license to any other intellectual
710037SARM gem5 Developers * property including but not limited to intellectual property relating
810037SARM gem5 Developers * to a hardware implementation of the functionality of the software
910037SARM gem5 Developers * licensed hereunder.  You may use the software subject to the license
1010037SARM gem5 Developers * terms below provided that you ensure that this notice is replicated
1110037SARM gem5 Developers * unmodified and in its entirety in all distributions of the software,
1210037SARM gem5 Developers * modified or unmodified, in source code or in binary form.
1310037SARM gem5 Developers *
1410037SARM gem5 Developers * Redistribution and use in source and binary forms, with or without
1510037SARM gem5 Developers * modification, are permitted provided that the following conditions are
1610037SARM gem5 Developers * met: redistributions of source code must retain the above copyright
1710037SARM gem5 Developers * notice, this list of conditions and the following disclaimer;
1810037SARM gem5 Developers * redistributions in binary form must reproduce the above copyright
1910037SARM gem5 Developers * notice, this list of conditions and the following disclaimer in the
2010037SARM gem5 Developers * documentation and/or other materials provided with the distribution;
2110037SARM gem5 Developers * neither the name of the copyright holders nor the names of its
2210037SARM gem5 Developers * contributors may be used to endorse or promote products derived from
2310037SARM gem5 Developers * this software without specific prior written permission.
2410037SARM gem5 Developers *
2510037SARM gem5 Developers * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610037SARM gem5 Developers * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710037SARM gem5 Developers * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810037SARM gem5 Developers * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910037SARM gem5 Developers * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010037SARM gem5 Developers * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110037SARM gem5 Developers * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210037SARM gem5 Developers * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310037SARM gem5 Developers * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410037SARM gem5 Developers * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510037SARM gem5 Developers * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610037SARM gem5 Developers *
3710037SARM gem5 Developers * Authors: Ali Saidi
3810037SARM gem5 Developers *          Giacomo Gabrielli
3910037SARM gem5 Developers */
4010037SARM gem5 Developers
4111793Sbrandon.potter@amd.com#include "arch/arm/stage2_lookup.hh"
4211793Sbrandon.potter@amd.com
4310037SARM gem5 Developers#include "arch/arm/faults.hh"
4410037SARM gem5 Developers#include "arch/arm/system.hh"
4510037SARM gem5 Developers#include "arch/arm/table_walker.hh"
4610037SARM gem5 Developers#include "arch/arm/tlb.hh"
4710037SARM gem5 Developers#include "cpu/base.hh"
4810037SARM gem5 Developers#include "cpu/thread_context.hh"
4910037SARM gem5 Developers#include "debug/Checkpoint.hh"
5010037SARM gem5 Developers#include "debug/TLB.hh"
5110037SARM gem5 Developers#include "debug/TLBVerbose.hh"
5210037SARM gem5 Developers#include "sim/system.hh"
5310037SARM gem5 Developers
5410037SARM gem5 Developersusing namespace ArmISA;
5510037SARM gem5 Developers
5610037SARM gem5 DevelopersFault
5710037SARM gem5 DevelopersStage2LookUp::getTe(ThreadContext *tc, TlbEntry *destTe)
5810037SARM gem5 Developers
5910037SARM gem5 Developers{
6010037SARM gem5 Developers    fault = stage2Tlb->getTE(&stage2Te, &req, tc, mode, this, timing,
6110037SARM gem5 Developers                                   functional, false, tranType);
6210037SARM gem5 Developers    // Call finish if we're done already
6310037SARM gem5 Developers    if ((fault != NoFault) || (stage2Te != NULL)) {
6411586SDylan.Johnson@ARM.com        // Since we directly requested the table entry (which we need later on
6511586SDylan.Johnson@ARM.com        // to merge the attributes) then we've skipped some stage2 permissions
6611586SDylan.Johnson@ARM.com        // checking. So call translate on stage 2 to do the checking. As the
6711586SDylan.Johnson@ARM.com        // entry is now in the TLB this should always hit the cache.
6811586SDylan.Johnson@ARM.com        if (fault == NoFault) {
6911586SDylan.Johnson@ARM.com            if (inAArch64(tc))
7011586SDylan.Johnson@ARM.com                fault = stage2Tlb->checkPermissions64(stage2Te, &req, mode, tc);
7111586SDylan.Johnson@ARM.com            else
7211586SDylan.Johnson@ARM.com                fault = stage2Tlb->checkPermissions(stage2Te, &req, mode);
7311586SDylan.Johnson@ARM.com        }
7411586SDylan.Johnson@ARM.com
7510037SARM gem5 Developers        mergeTe(&req, mode);
7610037SARM gem5 Developers        *destTe = stage1Te;
7710037SARM gem5 Developers    }
7810037SARM gem5 Developers    return fault;
7910037SARM gem5 Developers}
8010037SARM gem5 Developers
8110037SARM gem5 Developersvoid
8210037SARM gem5 DevelopersStage2LookUp::mergeTe(RequestPtr req, BaseTLB::Mode mode)
8310037SARM gem5 Developers{
8410037SARM gem5 Developers    // Check again that we haven't got a fault
8510037SARM gem5 Developers    if (fault == NoFault) {
8610037SARM gem5 Developers        assert(stage2Te != NULL);
8710037SARM gem5 Developers
8810037SARM gem5 Developers        // Now we have the table entries for both stages of translation
8910037SARM gem5 Developers        // merge them and insert the result into the stage 1 TLB. See
9010037SARM gem5 Developers        // CombineS1S2Desc() in pseudocode
9110037SARM gem5 Developers        stage1Te.N             = stage2Te->N;
9210037SARM gem5 Developers        stage1Te.nonCacheable |= stage2Te->nonCacheable;
9310037SARM gem5 Developers        stage1Te.xn           |= stage2Te->xn;
9410037SARM gem5 Developers
9510037SARM gem5 Developers        if (stage1Te.size > stage2Te->size) {
9610037SARM gem5 Developers            // Size mismatch also implies vpn mismatch (this is shifted by
9710037SARM gem5 Developers            // sizebits!).
9810037SARM gem5 Developers            stage1Te.vpn  = s1Req->getVaddr() / (stage2Te->size+1);
9910037SARM gem5 Developers            stage1Te.pfn  = stage2Te->pfn;
10010037SARM gem5 Developers            stage1Te.size = stage2Te->size;
10110037SARM gem5 Developers        } else if (stage1Te.size < stage2Te->size) {
10210037SARM gem5 Developers            // Guest 4K could well be section-backed by host hugepage!  In this
10310037SARM gem5 Developers            // case a 4K entry is added but pfn needs to be adjusted.  New PFN =
10410037SARM gem5 Developers            // offset into section PFN given by stage2 IPA treated as a stage1
10510037SARM gem5 Developers            // page size.
10610037SARM gem5 Developers            stage1Te.pfn = (stage2Te->pfn * ((stage2Te->size+1) / (stage1Te.size+1))) +
10710037SARM gem5 Developers                           (stage2Te->vpn / (stage1Te.size+1));
10810037SARM gem5 Developers            // Size remains smaller of the two.
10910037SARM gem5 Developers        } else {
11010037SARM gem5 Developers            // Matching sizes
11110037SARM gem5 Developers            stage1Te.pfn = stage2Te->pfn;
11210037SARM gem5 Developers        }
11310037SARM gem5 Developers
11410037SARM gem5 Developers        if (stage2Te->mtype == TlbEntry::MemoryType::StronglyOrdered ||
11510037SARM gem5 Developers            stage1Te.mtype  == TlbEntry::MemoryType::StronglyOrdered) {
11610037SARM gem5 Developers            stage1Te.mtype  =  TlbEntry::MemoryType::StronglyOrdered;
11710037SARM gem5 Developers        } else if (stage2Te->mtype == TlbEntry::MemoryType::Device ||
11810037SARM gem5 Developers                   stage1Te.mtype  == TlbEntry::MemoryType::Device) {
11910037SARM gem5 Developers            stage1Te.mtype = TlbEntry::MemoryType::Device;
12010037SARM gem5 Developers        } else {
12110037SARM gem5 Developers            stage1Te.mtype = TlbEntry::MemoryType::Normal;
12210037SARM gem5 Developers        }
12310037SARM gem5 Developers
12410037SARM gem5 Developers        if (stage1Te.mtype == TlbEntry::MemoryType::Normal) {
12510037SARM gem5 Developers
12610037SARM gem5 Developers            if (stage2Te->innerAttrs == 0 ||
12710037SARM gem5 Developers                stage1Te.innerAttrs  == 0) {
12810037SARM gem5 Developers                // either encoding Non-cacheable
12910037SARM gem5 Developers                stage1Te.innerAttrs = 0;
13010037SARM gem5 Developers            } else if (stage2Te->innerAttrs == 2 ||
13110037SARM gem5 Developers                       stage1Te.innerAttrs  == 2) {
13210037SARM gem5 Developers                // either encoding Write-Through cacheable
13310037SARM gem5 Developers                stage1Te.innerAttrs = 2;
13410037SARM gem5 Developers            } else {
13510037SARM gem5 Developers                // both encodings Write-Back
13610037SARM gem5 Developers                stage1Te.innerAttrs = 3;
13710037SARM gem5 Developers            }
13810037SARM gem5 Developers
13910037SARM gem5 Developers            if (stage2Te->outerAttrs == 0 ||
14010037SARM gem5 Developers                stage1Te.outerAttrs  == 0) {
14110037SARM gem5 Developers                // either encoding Non-cacheable
14210037SARM gem5 Developers                stage1Te.outerAttrs = 0;
14310037SARM gem5 Developers            } else if (stage2Te->outerAttrs == 2 ||
14410037SARM gem5 Developers                       stage1Te.outerAttrs  == 2) {
14510037SARM gem5 Developers                // either encoding Write-Through cacheable
14610037SARM gem5 Developers                stage1Te.outerAttrs = 2;
14710037SARM gem5 Developers            } else {
14810037SARM gem5 Developers                // both encodings Write-Back
14910037SARM gem5 Developers                stage1Te.outerAttrs = 3;
15010037SARM gem5 Developers            }
15110037SARM gem5 Developers
15210037SARM gem5 Developers            stage1Te.shareable       |= stage2Te->shareable;
15310037SARM gem5 Developers            stage1Te.outerShareable |= stage2Te->outerShareable;
15410037SARM gem5 Developers            if (stage1Te.innerAttrs == 0 &&
15510037SARM gem5 Developers                stage1Te.outerAttrs == 0) {
15610037SARM gem5 Developers                // something Non-cacheable at each level is outer shareable
15710037SARM gem5 Developers                stage1Te.shareable       = true;
15810037SARM gem5 Developers                stage1Te.outerShareable = true;
15910037SARM gem5 Developers            }
16010037SARM gem5 Developers        } else {
16110037SARM gem5 Developers            stage1Te.shareable       = true;
16210037SARM gem5 Developers            stage1Te.outerShareable = true;
16310037SARM gem5 Developers        }
16410037SARM gem5 Developers        stage1Te.updateAttributes();
16510037SARM gem5 Developers    }
16610037SARM gem5 Developers
16710037SARM gem5 Developers    // if there's a fault annotate it,
16810037SARM gem5 Developers    if (fault != NoFault) {
16910037SARM gem5 Developers        // If the second stage of translation generated a fault add the
17010037SARM gem5 Developers        // details of the original stage 1 virtual address
17110037SARM gem5 Developers        reinterpret_cast<ArmFault *>(fault.get())->annotate(ArmFault::OVA,
17210037SARM gem5 Developers            s1Req->getVaddr());
17310037SARM gem5 Developers    }
17410037SARM gem5 Developers    complete = true;
17510037SARM gem5 Developers}
17610037SARM gem5 Developers
17710037SARM gem5 Developersvoid
17810379Sandreas.hansson@arm.comStage2LookUp::finish(const Fault &_fault, RequestPtr req,
17910037SARM gem5 Developers    ThreadContext *tc, BaseTLB::Mode mode)
18010037SARM gem5 Developers{
18110037SARM gem5 Developers    fault = _fault;
18210037SARM gem5 Developers    // if we haven't got the table entry get it now
18310037SARM gem5 Developers    if ((fault == NoFault) && (stage2Te == NULL)) {
18410037SARM gem5 Developers        fault = stage2Tlb->getTE(&stage2Te, req, tc, mode, this,
18510037SARM gem5 Developers            timing, functional, false, tranType);
18610037SARM gem5 Developers    }
18710037SARM gem5 Developers
18810037SARM gem5 Developers    // Now we have the stage 2 table entry we need to merge it with the stage
18910037SARM gem5 Developers    // 1 entry we were given at the start
19010037SARM gem5 Developers    mergeTe(req, mode);
19110037SARM gem5 Developers
19210037SARM gem5 Developers    if (fault != NoFault) {
19310037SARM gem5 Developers        transState->finish(fault, req, tc, mode);
19410037SARM gem5 Developers    } else if (timing) {
19510037SARM gem5 Developers        // Now notify the original stage 1 translation that we finally have
19610037SARM gem5 Developers        // a result
19710037SARM gem5 Developers        stage1Tlb->translateComplete(s1Req, tc, transState, mode, tranType, true);
19810037SARM gem5 Developers    }
19910037SARM gem5 Developers    // if we have been asked to delete ourselfs do it now
20010037SARM gem5 Developers    if (selfDelete) {
20110037SARM gem5 Developers        delete this;
20210037SARM gem5 Developers    }
20310037SARM gem5 Developers}
20410037SARM gem5 Developers
205