Deleted Added
sdiff udiff text old ( 7406:ddc26bd4ea7d ) new ( 7436:b578349f9371 )
full compact
1/*
2 * Copyright (c) 2010 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

--- 82 unchanged lines hidden (view full) ---

91
92 tc = _tc;
93 transState = _trans;
94 req = _req;
95 fault = NoFault;
96 contextId = _cid;
97 timing = _timing;
98
99 // XXX These should be cached or grabbed from cached copies in
100 // the TLB, all these miscreg reads are expensive
101 vaddr = req->getVaddr() & ~PcModeMask;
102 sctlr = tc->readMiscReg(MISCREG_SCTLR);
103 cpsr = tc->readMiscReg(MISCREG_CPSR);
104 N = tc->readMiscReg(MISCREG_TTBCR);
105 Addr ttbr = 0;
106
107 isFetch = (mode == TLB::Execute);
108 isWrite = (mode == TLB::Write);

--- 35 unchanged lines hidden (view full) ---

144 NULL, (uint8_t*)&l1Desc.data, (Tick)0);
145 doL1Descriptor();
146 }
147
148 return fault;
149}
150
151void
152TableWalker::memAttrs(TlbEntry &te, uint8_t texcb)
153{
154
155 if (sctlr.tre == 0) {
156 switch(texcb) {
157 case 0:
158 case 1:
159 case 4:
160 case 8:
161 te.nonCacheable = true;
162 break;
163 case 16:
164 if (bits(texcb, 1,0) == 0 || bits(texcb, 3,2) == 0)
165 te.nonCacheable = true;
166 break;
167 }
168 } else {
169 PRRR prrr = tc->readMiscReg(MISCREG_PRRR);
170 NMRR nmrr = tc->readMiscReg(MISCREG_NMRR);
171 switch(bits(texcb, 2,0)) {
172 case 0:
173 if (nmrr.ir0 == 0 || nmrr.or0 == 0 || prrr.tr0 != 0x2)
174 te.nonCacheable = true;
175 break;
176 case 1:
177 if (nmrr.ir1 == 0 || nmrr.or1 == 0 || prrr.tr1 != 0x2)
178 te.nonCacheable = true;
179 break;
180 case 2:
181 if (nmrr.ir2 == 0 || nmrr.or2 == 0 || prrr.tr2 != 0x2)
182 te.nonCacheable = true;
183 break;
184 case 3:
185 if (nmrr.ir3 == 0 || nmrr.or3 == 0 || prrr.tr3 != 0x2)
186 te.nonCacheable = true;
187 break;
188 case 4:
189 if (nmrr.ir4 == 0 || nmrr.or4 == 0 || prrr.tr4 != 0x2)
190 te.nonCacheable = true;
191 break;
192 case 5:
193 if (nmrr.ir5 == 0 || nmrr.or5 == 0 || prrr.tr5 != 0x2)
194 te.nonCacheable = true;
195 break;
196 case 6:
197 panic("Imp defined type\n");
198 case 7:
199 if (nmrr.ir7 == 0 || nmrr.or7 == 0 || prrr.tr7 != 0x2)
200 te.nonCacheable = true;
201 break;
202 }
203 }
204}
205
206void
207TableWalker::doL1Descriptor()
208{
209 DPRINTF(TLB, "L1 descriptor for %#x is %#x\n", vaddr, l1Desc.data);
210 TlbEntry te;
211
212 switch (l1Desc.type()) {
213 case L1Descriptor::Ignore:
214 case L1Descriptor::Reserved:
215 tc = NULL;
216 req = NULL;
217 DPRINTF(TLB, "L1 Descriptor Reserved/Ignore, causing fault\n");
218 if (isFetch)
219 fault = new PrefetchAbort(vaddr, ArmFault::Translation0);
220 else
221 fault = new DataAbort(vaddr, NULL, isWrite, ArmFault::Translation0);
222 return;
223 case L1Descriptor::Section:
224 if (sctlr.afe && bits(l1Desc.ap(), 0) == 0)
225 panic("Haven't implemented AFE\n");
226
227 if (l1Desc.supersection()) {
228 panic("Haven't implemented supersections\n");
229 }
230 te.N = 20;
231 te.pfn = l1Desc.pfn();
232 te.size = (1<<te.N) - 1;
233 te.global = !l1Desc.global();
234 te.valid = true;
235 te.vpn = vaddr >> te.N;
236 te.sNp = true;
237 te.xn = l1Desc.xn();
238 te.ap = l1Desc.ap();
239 te.domain = l1Desc.domain();
240 te.asid = contextId;
241 memAttrs(te, l1Desc.texcb());
242
243 DPRINTF(TLB, "Inserting Section Descriptor into TLB\n");
244 DPRINTF(TLB, " - N%d pfn:%#x size: %#x global:%d valid: %d\n",
245 te.N, te.pfn, te.size, te.global, te.valid);
246 DPRINTF(TLB, " - vpn:%#x sNp: %d xn:%d ap:%d domain: %d asid:%d\n",
247 te.vpn, te.sNp, te.xn, te.ap, te.domain, te.asid);
248 DPRINTF(TLB, " - domain from l1 desc: %d data: %#x bits:%d\n",
249 l1Desc.domain(), l1Desc.data, (l1Desc.data >> 5) & 0xF );
250
251 tc = NULL;
252 req = NULL;
253 tlb->insert(vaddr, te);
254
255 return;
256 case L1Descriptor::PageTable:
257 Addr l2desc_addr;
258 l2desc_addr = l1Desc.l2Addr() | (bits(vaddr, 19,12) << 2);
259 DPRINTF(TLB, "L1 descriptor points to page table at: %#x\n", l2desc_addr);
260
261 // Trickbox address check
262 fault = tlb->walkTrickBoxCheck(l2desc_addr, vaddr, sizeof(uint32_t),
263 isFetch, isWrite, l1Desc.domain(), false);
264 if (fault) {
265 tc = NULL;
266 req = NULL;
267 return;

--- 15 unchanged lines hidden (view full) ---

283}
284
285void
286TableWalker::doL2Descriptor()
287{
288 DPRINTF(TLB, "L2 descriptor for %#x is %#x\n", vaddr, l2Desc.data);
289 TlbEntry te;
290
291 if (sctlr.afe && bits(l1Desc.ap(), 0) == 0)
292 panic("Haven't implemented AFE\n");
293
294 if (l2Desc.invalid()) {
295 DPRINTF(TLB, "L2 descriptor invalid, causing fault\n");
296 tc = NULL;
297 req = NULL;
298 if (isFetch)
299 fault = new PrefetchAbort(vaddr, ArmFault::Translation1);
300 else
301 fault = new DataAbort(vaddr, l1Desc.domain(), isWrite, ArmFault::Translation1);
302 return;
303 }
304
305 if (l2Desc.large()) {
306 te.N = 16;
307 te.pfn = l2Desc.pfn();
308 } else {
309 te.N = 12;
310 te.pfn = l2Desc.pfn();
311 }
312
313 te.valid = true;
314 te.size = (1 << te.N) - 1;
315 te.asid = contextId;
316 te.sNp = false;
317 te.vpn = vaddr >> te.N;
318 te.global = l2Desc.global();
319 te.xn = l2Desc.xn();
320 te.ap = l2Desc.ap();
321 te.domain = l1Desc.domain();
322 memAttrs(te, l2Desc.texcb());
323
324 tc = NULL;
325 req = NULL;
326 tlb->insert(vaddr, te);
327}
328
329ArmISA::TableWalker *
330ArmTableWalkerParams::create()
331{
332 return new ArmISA::TableWalker(this);
333}
334