table_walker.cc (7720:65d338a8dba4) table_walker.cc (7728:cf9db1c47a77)
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

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

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"
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

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

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/base.hh"
44#include "cpu/thread_context.hh"
45
46using namespace ArmISA;
47
48TableWalker::TableWalker(const Params *p)
45#include "cpu/thread_context.hh"
46
47using namespace ArmISA;
48
49TableWalker::TableWalker(const Params *p)
49 : MemObject(p), port(NULL), tlb(NULL),
50 currState(NULL), doL1DescEvent(this), doL2DescEvent(this)
50 : MemObject(p), port(NULL), tlb(NULL), currState(NULL), pending(false),
51 doL1DescEvent(this), doL2DescEvent(this), doProcessEvent(this)
51{
52 sctlr = 0;
53}
54
55TableWalker::~TableWalker()
56{
57 ;
58}

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

110 currState->vaddr = currState->req->getVaddr();
111 currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR);
112 sctlr = currState->sctlr;
113 currState->N = currState->tc->readMiscReg(MISCREG_TTBCR);
114
115 currState->isFetch = (currState->mode == TLB::Execute);
116 currState->isWrite = (currState->mode == TLB::Write);
117
52{
53 sctlr = 0;
54}
55
56TableWalker::~TableWalker()
57{
58 ;
59}

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

111 currState->vaddr = currState->req->getVaddr();
112 currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR);
113 sctlr = currState->sctlr;
114 currState->N = currState->tc->readMiscReg(MISCREG_TTBCR);
115
116 currState->isFetch = (currState->mode == TLB::Execute);
117 currState->isWrite = (currState->mode == TLB::Write);
118
119
120 if (!currState->timing)
121 return processWalk();
122
123 if (pending) {
124 pendingQueue.push_back(currState);
125 currState = NULL;
126 } else {
127 pending = true;
128 processWalk();
129 }
130
131 return NoFault;
132}
133
134void
135TableWalker::processWalkWrapper()
136{
137 assert(!currState);
138 assert(pendingQueue.size());
139 currState = pendingQueue.front();
140 pendingQueue.pop_front();
141 pending = true;
142 processWalk();
143}
144
145Fault
146TableWalker::processWalk()
147{
118 Addr ttbr = 0;
119
120 // If translation isn't enabled, we shouldn't be here
121 assert(currState->sctlr.m);
122
123 DPRINTF(TLB, "Begining table walk for address %#x, TTBCR: %#x, bits:%#x\n",
124 currState->vaddr, currState->N, mbits(currState->vaddr, 31,
125 32-currState->N));

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

141 // Trickbox address check
142 Fault f;
143 f = tlb->walkTrickBoxCheck(l1desc_addr, currState->vaddr, sizeof(uint32_t),
144 currState->isFetch, currState->isWrite, 0, true);
145 if (f) {
146 if (currState->timing) {
147 currState->transState->finish(f, currState->req,
148 currState->tc, currState->mode);
148 Addr ttbr = 0;
149
150 // If translation isn't enabled, we shouldn't be here
151 assert(currState->sctlr.m);
152
153 DPRINTF(TLB, "Begining table walk for address %#x, TTBCR: %#x, bits:%#x\n",
154 currState->vaddr, currState->N, mbits(currState->vaddr, 31,
155 32-currState->N));

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

171 // Trickbox address check
172 Fault f;
173 f = tlb->walkTrickBoxCheck(l1desc_addr, currState->vaddr, sizeof(uint32_t),
174 currState->isFetch, currState->isWrite, 0, true);
175 if (f) {
176 if (currState->timing) {
177 currState->transState->finish(f, currState->req,
178 currState->tc, currState->mode);
179
180 pending = false;
181 nextWalk(currState->tc);
149 currState = NULL;
150 } else {
151 currState->tc = NULL;
152 currState->req = NULL;
153 }
154 return f;
155 }
156
157 if (currState->timing) {
158 port->dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t),
182 currState = NULL;
183 } else {
184 currState->tc = NULL;
185 currState->req = NULL;
186 }
187 return f;
188 }
189
190 if (currState->timing) {
191 port->dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t),
159 &doL1DescEvent, (uint8_t*)&currState->l1Desc.data, (Tick)0);
192 &doL1DescEvent, (uint8_t*)&currState->l1Desc.data,
193 currState->tc->getCpuPtr()->ticks(1));
160 DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
161 stateQueueL1.size());
162 stateQueueL1.push_back(currState);
163 currState = NULL;
164 } else {
165 Request::Flags flag = 0;
166 if (currState->sctlr.c == 0){
167 flag = Request::UNCACHEABLE;
168 }
169 port->dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t),
194 DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
195 stateQueueL1.size());
196 stateQueueL1.push_back(currState);
197 currState = NULL;
198 } else {
199 Request::Flags flag = 0;
200 if (currState->sctlr.c == 0){
201 flag = Request::UNCACHEABLE;
202 }
203 port->dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t),
170 NULL, (uint8_t*)&currState->l1Desc.data, (Tick)0, flag);
204 NULL, (uint8_t*)&currState->l1Desc.data,
205 currState->tc->getCpuPtr()->ticks(1), flag);
171 doL1Descriptor();
172 f = currState->fault;
173 }
174
175 return f;
176}
177
178void

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

493 }
494 return;
495 }
496
497
498 if (currState->timing) {
499 currState->delayed = true;
500 port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t),
206 doL1Descriptor();
207 f = currState->fault;
208 }
209
210 return f;
211}
212
213void

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

528 }
529 return;
530 }
531
532
533 if (currState->timing) {
534 currState->delayed = true;
535 port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t),
501 &doL2DescEvent, (uint8_t*)&currState->l2Desc.data, 0);
536 &doL2DescEvent, (uint8_t*)&currState->l2Desc.data,
537 currState->tc->getCpuPtr()->ticks(1));
502 } else {
503 port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t),
538 } else {
539 port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t),
504 NULL, (uint8_t*)&currState->l2Desc.data, 0);
540 NULL, (uint8_t*)&currState->l2Desc.data,
541 currState->tc->getCpuPtr()->ticks(1));
505 doL2Descriptor();
506 }
507 return;
508 default:
509 panic("A new type in a 2 bit field?\n");
510 }
511}
512

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

584 doL1Descriptor();
585
586 stateQueueL1.pop_front();
587 // Check if fault was generated
588 if (currState->fault != NoFault) {
589 currState->transState->finish(currState->fault, currState->req,
590 currState->tc, currState->mode);
591
542 doL2Descriptor();
543 }
544 return;
545 default:
546 panic("A new type in a 2 bit field?\n");
547 }
548}
549

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

621 doL1Descriptor();
622
623 stateQueueL1.pop_front();
624 // Check if fault was generated
625 if (currState->fault != NoFault) {
626 currState->transState->finish(currState->fault, currState->req,
627 currState->tc, currState->mode);
628
629 pending = false;
630 nextWalk(currState->tc);
631
592 currState->req = NULL;
593 currState->tc = NULL;
594 currState->delayed = false;
595
596 }
597 else if (!currState->delayed) {
598 // delay is not set so there is no L2 to do
599 DPRINTF(TLBVerbose, "calling translateTiming again\n");
600 currState->fault = tlb->translateTiming(currState->req, currState->tc,
601 currState->transState, currState->mode);
602
632 currState->req = NULL;
633 currState->tc = NULL;
634 currState->delayed = false;
635
636 }
637 else if (!currState->delayed) {
638 // delay is not set so there is no L2 to do
639 DPRINTF(TLBVerbose, "calling translateTiming again\n");
640 currState->fault = tlb->translateTiming(currState->req, currState->tc,
641 currState->transState, currState->mode);
642
643 pending = false;
644 nextWalk(currState->tc);
645
603 currState->req = NULL;
604 currState->tc = NULL;
605 currState->delayed = false;
646 currState->req = NULL;
647 currState->tc = NULL;
648 currState->delayed = false;
606
607 delete currState;
608 } else {
609 // need to do L2 descriptor
610 stateQueueL2.push_back(currState);
611 }
612 currState = NULL;
613}
614

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

628 currState->tc, currState->mode);
629 }
630 else {
631 DPRINTF(TLBVerbose, "calling translateTiming again\n");
632 currState->fault = tlb->translateTiming(currState->req, currState->tc,
633 currState->transState, currState->mode);
634 }
635
649 delete currState;
650 } else {
651 // need to do L2 descriptor
652 stateQueueL2.push_back(currState);
653 }
654 currState = NULL;
655}
656

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

670 currState->tc, currState->mode);
671 }
672 else {
673 DPRINTF(TLBVerbose, "calling translateTiming again\n");
674 currState->fault = tlb->translateTiming(currState->req, currState->tc,
675 currState->transState, currState->mode);
676 }
677
678
679 stateQueueL2.pop_front();
680 pending = false;
681 nextWalk(currState->tc);
682
636 currState->req = NULL;
637 currState->tc = NULL;
638 currState->delayed = false;
639
683 currState->req = NULL;
684 currState->tc = NULL;
685 currState->delayed = false;
686
640 stateQueueL2.pop_front();
641 delete currState;
642 currState = NULL;
643}
644
687 delete currState;
688 currState = NULL;
689}
690
691void
692TableWalker::nextWalk(ThreadContext *tc)
693{
694 if (pendingQueue.size())
695 schedule(doProcessEvent, tc->getCpuPtr()->nextCycle(curTick+1));
696}
697
698
699
645ArmISA::TableWalker *
646ArmTableWalkerParams::create()
647{
648 return new ArmISA::TableWalker(this);
649}
650
700ArmISA::TableWalker *
701ArmTableWalkerParams::create()
702{
703 return new ArmISA::TableWalker(this);
704}
705