Deleted Added
sdiff udiff text old ( 7720:65d338a8dba4 ) new ( 7728:cf9db1c47a77 )
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

--- 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"
45#include "cpu/thread_context.hh"
46
47using namespace ArmISA;
48
49TableWalker::TableWalker(const Params *p)
50 : MemObject(p), port(NULL), tlb(NULL), currState(NULL), pending(false),
51 doL1DescEvent(this), doL2DescEvent(this), doProcessEvent(this)
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{
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);
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),
192 &doL1DescEvent, (uint8_t*)&currState->l1Desc.data,
193 currState->tc->getCpuPtr()->ticks(1));
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),
204 NULL, (uint8_t*)&currState->l1Desc.data,
205 currState->tc->getCpuPtr()->ticks(1), flag);
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),
536 &doL2DescEvent, (uint8_t*)&currState->l2Desc.data,
537 currState->tc->getCpuPtr()->ticks(1));
538 } else {
539 port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t),
540 NULL, (uint8_t*)&currState->l2Desc.data,
541 currState->tc->getCpuPtr()->ticks(1));
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
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
646 currState->req = NULL;
647 currState->tc = NULL;
648 currState->delayed = false;
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
683 currState->req = NULL;
684 currState->tc = NULL;
685 currState->delayed = false;
686
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
700ArmISA::TableWalker *
701ArmTableWalkerParams::create()
702{
703 return new ArmISA::TableWalker(this);
704}
705