table_walker.cc (7436:b578349f9371) | table_walker.cc (7437:5853fbdfba9b) |
---|---|
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 --- 66 unchanged lines hidden (view full) --- 75 Tick maxb = params()->max_backoff; 76 port = new DmaPort(this, sys, minb, maxb); 77 return port; 78 } 79 return NULL; 80} 81 82Fault | 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 --- 66 unchanged lines hidden (view full) --- 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, | 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; | 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 mode = _mode; |
|
98 99 /** @todo 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; --- 267 unchanged lines hidden (view full) --- 373TableWalker::doL1Descriptor() 374{ 375 DPRINTF(TLB, "L1 descriptor for %#x is %#x\n", vaddr, l1Desc.data); 376 TlbEntry te; 377 378 switch (l1Desc.type()) { 379 case L1Descriptor::Ignore: 380 case L1Descriptor::Reserved: | 99 100 /** @todo These should be cached or grabbed from cached copies in 101 the TLB, all these miscreg reads are expensive */ 102 vaddr = req->getVaddr() & ~PcModeMask; 103 sctlr = tc->readMiscReg(MISCREG_SCTLR); 104 cpsr = tc->readMiscReg(MISCREG_CPSR); 105 N = tc->readMiscReg(MISCREG_TTBCR); 106 Addr ttbr = 0; --- 267 unchanged lines hidden (view full) --- 374TableWalker::doL1Descriptor() 375{ 376 DPRINTF(TLB, "L1 descriptor for %#x is %#x\n", vaddr, l1Desc.data); 377 TlbEntry te; 378 379 switch (l1Desc.type()) { 380 case L1Descriptor::Ignore: 381 case L1Descriptor::Reserved: |
381 tc = NULL; 382 req = NULL; | 382 if (!delayed) { 383 tc = NULL; 384 req = NULL; 385 } |
383 DPRINTF(TLB, "L1 Descriptor Reserved/Ignore, causing fault\n"); 384 if (isFetch) 385 fault = new PrefetchAbort(vaddr, ArmFault::Translation0); 386 else 387 fault = new DataAbort(vaddr, NULL, isWrite, 388 ArmFault::Translation0); 389 return; 390 case L1Descriptor::Section: --- 26 unchanged lines hidden (view full) --- 417 DPRINTF(TLB, "Inserting Section Descriptor into TLB\n"); 418 DPRINTF(TLB, " - N%d pfn:%#x size: %#x global:%d valid: %d\n", 419 te.N, te.pfn, te.size, te.global, te.valid); 420 DPRINTF(TLB, " - vpn:%#x sNp: %d xn:%d ap:%d domain: %d asid:%d\n", 421 te.vpn, te.sNp, te.xn, te.ap, te.domain, te.asid); 422 DPRINTF(TLB, " - domain from l1 desc: %d data: %#x bits:%d\n", 423 l1Desc.domain(), l1Desc.data, (l1Desc.data >> 5) & 0xF ); 424 | 386 DPRINTF(TLB, "L1 Descriptor Reserved/Ignore, causing fault\n"); 387 if (isFetch) 388 fault = new PrefetchAbort(vaddr, ArmFault::Translation0); 389 else 390 fault = new DataAbort(vaddr, NULL, isWrite, 391 ArmFault::Translation0); 392 return; 393 case L1Descriptor::Section: --- 26 unchanged lines hidden (view full) --- 420 DPRINTF(TLB, "Inserting Section Descriptor into TLB\n"); 421 DPRINTF(TLB, " - N%d pfn:%#x size: %#x global:%d valid: %d\n", 422 te.N, te.pfn, te.size, te.global, te.valid); 423 DPRINTF(TLB, " - vpn:%#x sNp: %d xn:%d ap:%d domain: %d asid:%d\n", 424 te.vpn, te.sNp, te.xn, te.ap, te.domain, te.asid); 425 DPRINTF(TLB, " - domain from l1 desc: %d data: %#x bits:%d\n", 426 l1Desc.domain(), l1Desc.data, (l1Desc.data >> 5) & 0xF ); 427 |
425 tc = NULL; 426 req = NULL; | 428 if (!timing) { 429 tc = NULL; 430 req = NULL; 431 } |
427 tlb->insert(vaddr, te); 428 429 return; 430 case L1Descriptor::PageTable: 431 Addr l2desc_addr; 432 l2desc_addr = l1Desc.l2Addr() | (bits(vaddr, 19,12) << 2); 433 DPRINTF(TLB, "L1 descriptor points to page table at: %#x\n", 434 l2desc_addr); 435 436 // Trickbox address check 437 fault = tlb->walkTrickBoxCheck(l2desc_addr, vaddr, sizeof(uint32_t), 438 isFetch, isWrite, l1Desc.domain(), false); 439 if (fault) { | 432 tlb->insert(vaddr, te); 433 434 return; 435 case L1Descriptor::PageTable: 436 Addr l2desc_addr; 437 l2desc_addr = l1Desc.l2Addr() | (bits(vaddr, 19,12) << 2); 438 DPRINTF(TLB, "L1 descriptor points to page table at: %#x\n", 439 l2desc_addr); 440 441 // Trickbox address check 442 fault = tlb->walkTrickBoxCheck(l2desc_addr, vaddr, sizeof(uint32_t), 443 isFetch, isWrite, l1Desc.domain(), false); 444 if (fault) { |
440 tc = NULL; 441 req = NULL; 442 return; | 445 if (!timing) { 446 tc = NULL; 447 req = NULL; 448 } 449 return; |
443 } 444 445 446 if (timing) { | 450 } 451 452 453 if (timing) { |
454 delayed = true; |
|
447 port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t), 448 &doL2DescEvent, (uint8_t*)&l2Desc.data, 0); 449 } else { 450 port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t), 451 NULL, (uint8_t*)&l2Desc.data, 0); 452 doL2Descriptor(); 453 } 454 return; --- 5 unchanged lines hidden (view full) --- 460void 461TableWalker::doL2Descriptor() 462{ 463 DPRINTF(TLB, "L2 descriptor for %#x is %#x\n", vaddr, l2Desc.data); 464 TlbEntry te; 465 466 if (l2Desc.invalid()) { 467 DPRINTF(TLB, "L2 descriptor invalid, causing fault\n"); | 455 port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t), 456 &doL2DescEvent, (uint8_t*)&l2Desc.data, 0); 457 } else { 458 port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t), 459 NULL, (uint8_t*)&l2Desc.data, 0); 460 doL2Descriptor(); 461 } 462 return; --- 5 unchanged lines hidden (view full) --- 468void 469TableWalker::doL2Descriptor() 470{ 471 DPRINTF(TLB, "L2 descriptor for %#x is %#x\n", vaddr, l2Desc.data); 472 TlbEntry te; 473 474 if (l2Desc.invalid()) { 475 DPRINTF(TLB, "L2 descriptor invalid, causing fault\n"); |
468 tc = NULL; 469 req = NULL; | 476 if (!delayed) { 477 tc = NULL; 478 req = NULL; 479 } |
470 if (isFetch) 471 fault = new PrefetchAbort(vaddr, ArmFault::Translation1); 472 else 473 fault = new DataAbort(vaddr, l1Desc.domain(), isWrite, 474 ArmFault::Translation1); 475 return; 476 } 477 --- 19 unchanged lines hidden (view full) --- 497 te.sNp = false; 498 te.vpn = vaddr >> te.N; 499 te.global = l2Desc.global(); 500 te.xn = l2Desc.xn(); 501 te.ap = l2Desc.ap(); 502 te.domain = l1Desc.domain(); 503 memAttrs(te, l2Desc.texcb(), l2Desc.shareable()); 504 | 480 if (isFetch) 481 fault = new PrefetchAbort(vaddr, ArmFault::Translation1); 482 else 483 fault = new DataAbort(vaddr, l1Desc.domain(), isWrite, 484 ArmFault::Translation1); 485 return; 486 } 487 --- 19 unchanged lines hidden (view full) --- 507 te.sNp = false; 508 te.vpn = vaddr >> te.N; 509 te.global = l2Desc.global(); 510 te.xn = l2Desc.xn(); 511 te.ap = l2Desc.ap(); 512 te.domain = l1Desc.domain(); 513 memAttrs(te, l2Desc.texcb(), l2Desc.shareable()); 514 |
505 tc = NULL; 506 req = NULL; | 515 if (!delayed) { 516 tc = NULL; 517 req = NULL; 518 } |
507 tlb->insert(vaddr, te); 508} 509 | 519 tlb->insert(vaddr, te); 520} 521 |
522void 523TableWalker::doL1DescriptorWrapper() 524{ 525 delayed = false; 526 527 DPRINTF(TLBVerbose, "calling doL1Descriptor\n"); 528 doL1Descriptor(); 529 530 // Check if fault was generated 531 if (fault != NoFault) { 532 transState->finish(fault, req, tc, mode); 533 534 req = NULL; 535 tc = NULL; 536 delayed = false; 537 } 538 else if (!delayed) { 539 DPRINTF(TLBVerbose, "calling translateTiming again\n"); 540 fault = tlb->translateTiming(req, tc, transState, mode); 541 542 req = NULL; 543 tc = NULL; 544 delayed = false; 545 } 546} 547 548void 549TableWalker::doL2DescriptorWrapper() 550{ 551 assert(delayed); 552 553 DPRINTF(TLBVerbose, "calling doL2Descriptor\n"); 554 doL2Descriptor(); 555 556 // Check if fault was generated 557 if (fault != NoFault) { 558 transState->finish(fault, req, tc, mode); 559 } 560 else { 561 DPRINTF(TLBVerbose, "calling translateTiming again\n"); 562 fault = tlb->translateTiming(req, tc, transState, mode); 563 } 564 565 req = NULL; 566 tc = NULL; 567 delayed = false; 568} 569 |
|
510ArmISA::TableWalker * 511ArmTableWalkerParams::create() 512{ 513 return new ArmISA::TableWalker(this); 514} 515 | 570ArmISA::TableWalker * 571ArmTableWalkerParams::create() 572{ 573 return new ArmISA::TableWalker(this); 574} 575 |