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 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 */ 39 40#include "arch/arm/faults.hh" 41#include "arch/arm/table_walker.hh" 42#include "arch/arm/tlb.hh" 43#include "dev/io_device.hh" 44#include "cpu/thread_context.hh" 45 46 47using namespace ArmISA; 48 49TableWalker::TableWalker(const Params *p) 50 : MemObject(p), port(NULL), tlb(NULL), tc(NULL), req(NULL), 51 doL1DescEvent(this), doL2DescEvent(this) 52{} 53 54TableWalker::~TableWalker() 55{ 56 ; 57} 58 59 60unsigned int 61drain(Event *de) 62{ 63 panic("Not implemented\n"); 64} 65 66Port* 67TableWalker::getPort(const std::string &if_name, int idx) 68{ 69 if (if_name == "port") { 70 if (port != NULL) 71 fatal("%s: port already connected to %s", 72 name(), port->getPeer()->name()); 73 System *sys = params()->sys; 74 Tick minb = params()->min_backoff; 75 Tick maxb = params()->max_backoff; 76 port = new DmaPort(this, sys, minb, maxb); 77 return port; 78 } 79 return NULL; 80} 81 82Fault 83TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint8_t _cid, TLB::Mode mode, 84 TLB::Translation *_trans, bool _timing) 85{ 86 // Right now 1 CPU == 1 TLB == 1 TLB walker 87 // In the future we might want to change this as multiple 88 // threads/contexts could share a walker and/or a TLB 89 if (tc || req) 90 panic("Overlapping TLB walks attempted\n"); 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); 109 isPriv = (cpsr.mode != MODE_USER); 110 111 // If translation isn't enabled, we shouldn't be here 112 assert(sctlr.m); 113
| 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 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 */ 39 40#include "arch/arm/faults.hh" 41#include "arch/arm/table_walker.hh" 42#include "arch/arm/tlb.hh" 43#include "dev/io_device.hh" 44#include "cpu/thread_context.hh" 45 46 47using namespace ArmISA; 48 49TableWalker::TableWalker(const Params *p) 50 : MemObject(p), port(NULL), tlb(NULL), tc(NULL), req(NULL), 51 doL1DescEvent(this), doL2DescEvent(this) 52{} 53 54TableWalker::~TableWalker() 55{ 56 ; 57} 58 59 60unsigned int 61drain(Event *de) 62{ 63 panic("Not implemented\n"); 64} 65 66Port* 67TableWalker::getPort(const std::string &if_name, int idx) 68{ 69 if (if_name == "port") { 70 if (port != NULL) 71 fatal("%s: port already connected to %s", 72 name(), port->getPeer()->name()); 73 System *sys = params()->sys; 74 Tick minb = params()->min_backoff; 75 Tick maxb = params()->max_backoff; 76 port = new DmaPort(this, sys, minb, maxb); 77 return port; 78 } 79 return NULL; 80} 81 82Fault 83TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint8_t _cid, TLB::Mode mode, 84 TLB::Translation *_trans, bool _timing) 85{ 86 // Right now 1 CPU == 1 TLB == 1 TLB walker 87 // In the future we might want to change this as multiple 88 // threads/contexts could share a walker and/or a TLB 89 if (tc || req) 90 panic("Overlapping TLB walks attempted\n"); 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); 109 isPriv = (cpsr.mode != MODE_USER); 110 111 // If translation isn't enabled, we shouldn't be here 112 assert(sctlr.m); 113
|
114 if (N == 0 || mbits(vaddr, 31, 32-N)) {
| 114 DPRINTF(TLB, "Begining table walk for address %#x, TTBCR: %#x, bits:%#x\n", 115 vaddr, N, mbits(vaddr, 31, 32-N)); 116 117 if (N == 0 || !mbits(vaddr, 31, 32-N)) { 118 DPRINTF(TLB, " - Selecting TTBR0\n");
|
115 ttbr = tc->readMiscReg(MISCREG_TTBR0); 116 } else {
| 119 ttbr = tc->readMiscReg(MISCREG_TTBR0); 120 } else {
|
117 ttbr = tc->readMiscReg(MISCREG_TTBR0);
| 121 DPRINTF(TLB, " - Selecting TTBR1\n"); 122 ttbr = tc->readMiscReg(MISCREG_TTBR1);
|
118 N = 0; 119 } 120 121 Addr l1desc_addr = mbits(ttbr, 31, 14-N) | (bits(vaddr,31-N,20) << 2);
| 123 N = 0; 124 } 125 126 Addr l1desc_addr = mbits(ttbr, 31, 14-N) | (bits(vaddr,31-N,20) << 2);
|
122 DPRINTF(TLB, "Begining table walk for address %#x at descriptor %#x\n", 123 vaddr, l1desc_addr);
| 127 DPRINTF(TLB, " - Descriptor at address %#x\n", l1desc_addr);
|
124 125 126 // Trickbox address check 127 fault = tlb->walkTrickBoxCheck(l1desc_addr, vaddr, sizeof(uint32_t),
| 128 129 130 // Trickbox address check 131 fault = tlb->walkTrickBoxCheck(l1desc_addr, vaddr, sizeof(uint32_t),
|
128 isFetch, 0, true);
| 132 isFetch, isWrite, 0, true);
|
129 if (fault) { 130 tc = NULL; 131 req = NULL; 132 return fault; 133 } 134 135 if (timing) { 136 port->dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t), 137 &doL1DescEvent, (uint8_t*)&l1Desc.data, (Tick)0); 138 } else { 139 port->dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t), 140 NULL, (uint8_t*)&l1Desc.data, (Tick)0); 141 doL1Descriptor(); 142 } 143 144 return fault; 145} 146 147void 148TableWalker::memAttrs(TlbEntry &te, uint8_t texcb) 149{ 150 151 if (sctlr.tre == 0) { 152 switch(texcb) { 153 case 0: 154 case 1: 155 case 4: 156 case 8: 157 te.nonCacheable = true; 158 break; 159 case 16: 160 if (bits(texcb, 1,0) == 0 || bits(texcb, 3,2) == 0) 161 te.nonCacheable = true; 162 break; 163 } 164 } else { 165 PRRR prrr = tc->readMiscReg(MISCREG_PRRR); 166 NMRR nmrr = tc->readMiscReg(MISCREG_NMRR); 167 switch(bits(texcb, 2,0)) { 168 case 0: 169 if (nmrr.ir0 == 0 || nmrr.or0 == 0 || prrr.tr0 != 0x2) 170 te.nonCacheable = true; 171 break; 172 case 1: 173 if (nmrr.ir1 == 0 || nmrr.or1 == 0 || prrr.tr1 != 0x2) 174 te.nonCacheable = true; 175 break; 176 case 2: 177 if (nmrr.ir2 == 0 || nmrr.or2 == 0 || prrr.tr2 != 0x2) 178 te.nonCacheable = true; 179 break; 180 case 3: 181 if (nmrr.ir3 == 0 || nmrr.or3 == 0 || prrr.tr3 != 0x2) 182 te.nonCacheable = true; 183 break; 184 case 4: 185 if (nmrr.ir4 == 0 || nmrr.or4 == 0 || prrr.tr4 != 0x2) 186 te.nonCacheable = true; 187 break; 188 case 5: 189 if (nmrr.ir5 == 0 || nmrr.or5 == 0 || prrr.tr5 != 0x2) 190 te.nonCacheable = true; 191 break; 192 case 6: 193 panic("Imp defined type\n"); 194 case 7: 195 if (nmrr.ir7 == 0 || nmrr.or7 == 0 || prrr.tr7 != 0x2) 196 te.nonCacheable = true; 197 break; 198 } 199 } 200} 201 202void 203TableWalker::doL1Descriptor() 204{ 205 DPRINTF(TLB, "L1 descriptor for %#x is %#x\n", vaddr, l1Desc.data); 206 TlbEntry te; 207 208 switch (l1Desc.type()) { 209 case L1Descriptor::Ignore: 210 case L1Descriptor::Reserved: 211 tc = NULL; 212 req = NULL;
| 133 if (fault) { 134 tc = NULL; 135 req = NULL; 136 return fault; 137 } 138 139 if (timing) { 140 port->dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t), 141 &doL1DescEvent, (uint8_t*)&l1Desc.data, (Tick)0); 142 } else { 143 port->dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t), 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;
|
213 fault = new DataAbort(vaddr, NULL, isWrite, ArmFault::Translation0);
| 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);
|
214 return; 215 case L1Descriptor::Section: 216 if (sctlr.afe && bits(l1Desc.ap(), 0) == 0) 217 panic("Haven't implemented AFE\n"); 218 219 if (l1Desc.supersection()) { 220 panic("Haven't implemented supersections\n"); 221 } 222 te.N = 20; 223 te.pfn = l1Desc.pfn(); 224 te.size = (1<<te.N) - 1; 225 te.global = !l1Desc.global(); 226 te.valid = true; 227 te.vpn = vaddr >> te.N; 228 te.sNp = true; 229 te.xn = l1Desc.xn(); 230 te.ap = l1Desc.ap(); 231 te.domain = l1Desc.domain(); 232 te.asid = contextId; 233 memAttrs(te, l1Desc.texcb()); 234 235 DPRINTF(TLB, "Inserting Section Descriptor into TLB\n"); 236 DPRINTF(TLB, " - N%d pfn:%#x size: %#x global:%d valid: %d\n", 237 te.N, te.pfn, te.size, te.global, te.valid); 238 DPRINTF(TLB, " - vpn:%#x sNp: %d xn:%d ap:%d domain: %d asid:%d\n", 239 te.vpn, te.sNp, te.xn, te.ap, te.domain, te.asid); 240 DPRINTF(TLB, " - domain from l1 desc: %d data: %#x bits:%d\n", 241 l1Desc.domain(), l1Desc.data, (l1Desc.data >> 5) & 0xF ); 242 243 tc = NULL; 244 req = NULL; 245 tlb->insert(vaddr, te); 246 247 return; 248 case L1Descriptor::PageTable: 249 Addr l2desc_addr; 250 l2desc_addr = l1Desc.l2Addr() | (bits(vaddr, 19,12) << 2); 251 DPRINTF(TLB, "L1 descriptor points to page table at: %#x\n", l2desc_addr); 252 253 // Trickbox address check 254 fault = tlb->walkTrickBoxCheck(l2desc_addr, vaddr, sizeof(uint32_t),
| 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),
|
255 isFetch, l1Desc.domain(), false);
| 263 isFetch, isWrite, l1Desc.domain(), false);
|
256 if (fault) { 257 tc = NULL; 258 req = NULL; 259 return; 260 } 261 262 263 if (timing) { 264 port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t), 265 &doL2DescEvent, (uint8_t*)&l2Desc.data, 0); 266 } else { 267 port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t), 268 NULL, (uint8_t*)&l2Desc.data, 0); 269 doL2Descriptor(); 270 } 271 return; 272 default: 273 panic("A new type in a 2 bit field?\n"); 274 } 275} 276 277void 278TableWalker::doL2Descriptor() 279{ 280 DPRINTF(TLB, "L2 descriptor for %#x is %#x\n", vaddr, l2Desc.data); 281 TlbEntry te; 282 283 if (sctlr.afe && bits(l1Desc.ap(), 0) == 0) 284 panic("Haven't implemented AFE\n"); 285 286 if (l2Desc.invalid()) { 287 DPRINTF(TLB, "L2 descriptor invalid, causing fault\n"); 288 tc = NULL; 289 req = NULL;
| 264 if (fault) { 265 tc = NULL; 266 req = NULL; 267 return; 268 } 269 270 271 if (timing) { 272 port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t), 273 &doL2DescEvent, (uint8_t*)&l2Desc.data, 0); 274 } else { 275 port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t), 276 NULL, (uint8_t*)&l2Desc.data, 0); 277 doL2Descriptor(); 278 } 279 return; 280 default: 281 panic("A new type in a 2 bit field?\n"); 282 } 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;
|
290 fault = new DataAbort(vaddr, l1Desc.domain(), isWrite, ArmFault::Translation1);
| 298 if (isFetch) 299 fault = new PrefetchAbort(vaddr, ArmFault::Translation1); 300 else 301 fault = new DataAbort(vaddr, l1Desc.domain(), isWrite, ArmFault::Translation1);
|
291 return; 292 } 293 294 if (l2Desc.large()) { 295 te.N = 16; 296 te.pfn = l2Desc.pfn(); 297 } else { 298 te.N = 12; 299 te.pfn = l2Desc.pfn(); 300 } 301 302 te.valid = true; 303 te.size = (1 << te.N) - 1; 304 te.asid = contextId; 305 te.sNp = false; 306 te.vpn = vaddr >> te.N; 307 te.global = l2Desc.global(); 308 te.xn = l2Desc.xn(); 309 te.ap = l2Desc.ap(); 310 te.domain = l1Desc.domain(); 311 memAttrs(te, l2Desc.texcb()); 312 313 tc = NULL; 314 req = NULL; 315 tlb->insert(vaddr, te); 316} 317 318ArmISA::TableWalker * 319ArmTableWalkerParams::create() 320{ 321 return new ArmISA::TableWalker(this); 322} 323
| 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
|