stats: update stats for mmap() change.
[gem5.git] / src / arch / arm / stage2_lookup.cc
1 /*
2 * Copyright (c) 2010-2013 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Ali Saidi
38 * Giacomo Gabrielli
39 */
40
41 #include "arch/arm/faults.hh"
42 #include "arch/arm/stage2_lookup.hh"
43 #include "arch/arm/system.hh"
44 #include "arch/arm/table_walker.hh"
45 #include "arch/arm/tlb.hh"
46 #include "cpu/base.hh"
47 #include "cpu/thread_context.hh"
48 #include "debug/Checkpoint.hh"
49 #include "debug/TLB.hh"
50 #include "debug/TLBVerbose.hh"
51 #include "sim/system.hh"
52
53 using namespace ArmISA;
54
55 Fault
56 Stage2LookUp::getTe(ThreadContext *tc, TlbEntry *destTe)
57
58 {
59 fault = stage2Tlb->getTE(&stage2Te, &req, tc, mode, this, timing,
60 functional, false, tranType);
61 // Call finish if we're done already
62 if ((fault != NoFault) || (stage2Te != NULL)) {
63 mergeTe(&req, mode);
64 *destTe = stage1Te;
65 }
66 return fault;
67 }
68
69 void
70 Stage2LookUp::mergeTe(RequestPtr req, BaseTLB::Mode mode)
71 {
72 // Since we directly requested the table entry (which we need later on to
73 // merge the attributes) then we've skipped some stage 2 permissinos
74 // checking. So call translate on stage 2 to do the checking. As the entry
75 // is now in the TLB this should always hit the cache.
76 if (fault == NoFault) {
77 fault = stage2Tlb->checkPermissions(stage2Te, req, mode);
78 }
79
80 // Check again that we haven't got a fault
81 if (fault == NoFault) {
82 assert(stage2Te != NULL);
83
84 // Now we have the table entries for both stages of translation
85 // merge them and insert the result into the stage 1 TLB. See
86 // CombineS1S2Desc() in pseudocode
87 stage1Te.N = stage2Te->N;
88 stage1Te.nonCacheable |= stage2Te->nonCacheable;
89 stage1Te.xn |= stage2Te->xn;
90
91 if (stage1Te.size > stage2Te->size) {
92 // Size mismatch also implies vpn mismatch (this is shifted by
93 // sizebits!).
94 stage1Te.vpn = s1Req->getVaddr() / (stage2Te->size+1);
95 stage1Te.pfn = stage2Te->pfn;
96 stage1Te.size = stage2Te->size;
97 } else if (stage1Te.size < stage2Te->size) {
98 // Guest 4K could well be section-backed by host hugepage! In this
99 // case a 4K entry is added but pfn needs to be adjusted. New PFN =
100 // offset into section PFN given by stage2 IPA treated as a stage1
101 // page size.
102 stage1Te.pfn = (stage2Te->pfn * ((stage2Te->size+1) / (stage1Te.size+1))) +
103 (stage2Te->vpn / (stage1Te.size+1));
104 // Size remains smaller of the two.
105 } else {
106 // Matching sizes
107 stage1Te.pfn = stage2Te->pfn;
108 }
109
110 if (stage2Te->mtype == TlbEntry::MemoryType::StronglyOrdered ||
111 stage1Te.mtype == TlbEntry::MemoryType::StronglyOrdered) {
112 stage1Te.mtype = TlbEntry::MemoryType::StronglyOrdered;
113 } else if (stage2Te->mtype == TlbEntry::MemoryType::Device ||
114 stage1Te.mtype == TlbEntry::MemoryType::Device) {
115 stage1Te.mtype = TlbEntry::MemoryType::Device;
116 } else {
117 stage1Te.mtype = TlbEntry::MemoryType::Normal;
118 }
119
120 if (stage1Te.mtype == TlbEntry::MemoryType::Normal) {
121
122 if (stage2Te->innerAttrs == 0 ||
123 stage1Te.innerAttrs == 0) {
124 // either encoding Non-cacheable
125 stage1Te.innerAttrs = 0;
126 } else if (stage2Te->innerAttrs == 2 ||
127 stage1Te.innerAttrs == 2) {
128 // either encoding Write-Through cacheable
129 stage1Te.innerAttrs = 2;
130 } else {
131 // both encodings Write-Back
132 stage1Te.innerAttrs = 3;
133 }
134
135 if (stage2Te->outerAttrs == 0 ||
136 stage1Te.outerAttrs == 0) {
137 // either encoding Non-cacheable
138 stage1Te.outerAttrs = 0;
139 } else if (stage2Te->outerAttrs == 2 ||
140 stage1Te.outerAttrs == 2) {
141 // either encoding Write-Through cacheable
142 stage1Te.outerAttrs = 2;
143 } else {
144 // both encodings Write-Back
145 stage1Te.outerAttrs = 3;
146 }
147
148 stage1Te.shareable |= stage2Te->shareable;
149 stage1Te.outerShareable |= stage2Te->outerShareable;
150 if (stage1Te.innerAttrs == 0 &&
151 stage1Te.outerAttrs == 0) {
152 // something Non-cacheable at each level is outer shareable
153 stage1Te.shareable = true;
154 stage1Te.outerShareable = true;
155 }
156 } else {
157 stage1Te.shareable = true;
158 stage1Te.outerShareable = true;
159 }
160 stage1Te.updateAttributes();
161 }
162
163 // if there's a fault annotate it,
164 if (fault != NoFault) {
165 // If the second stage of translation generated a fault add the
166 // details of the original stage 1 virtual address
167 reinterpret_cast<ArmFault *>(fault.get())->annotate(ArmFault::OVA,
168 s1Req->getVaddr());
169 }
170 complete = true;
171 }
172
173 void
174 Stage2LookUp::finish(const Fault &_fault, RequestPtr req,
175 ThreadContext *tc, BaseTLB::Mode mode)
176 {
177 fault = _fault;
178 // if we haven't got the table entry get it now
179 if ((fault == NoFault) && (stage2Te == NULL)) {
180 fault = stage2Tlb->getTE(&stage2Te, req, tc, mode, this,
181 timing, functional, false, tranType);
182 }
183
184 // Now we have the stage 2 table entry we need to merge it with the stage
185 // 1 entry we were given at the start
186 mergeTe(req, mode);
187
188 if (fault != NoFault) {
189 transState->finish(fault, req, tc, mode);
190 } else if (timing) {
191 // Now notify the original stage 1 translation that we finally have
192 // a result
193 stage1Tlb->translateComplete(s1Req, tc, transState, mode, tranType, true);
194 }
195 // if we have been asked to delete ourselfs do it now
196 if (selfDelete) {
197 delete this;
198 }
199 }
200