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