Deleted Added
sdiff udiff text old ( 10621:b7bc5b1084a4 ) new ( 10717:4f8c1bd6fdb8 )
full compact
1/*
2 * Copyright (c) 2010, 2012-2015 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

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

51#include "debug/Drain.hh"
52#include "debug/TLB.hh"
53#include "debug/TLBVerbose.hh"
54#include "sim/system.hh"
55
56using namespace ArmISA;
57
58TableWalker::TableWalker(const Params *p)
59 : MemObject(p), drainManager(NULL),
60 stage2Mmu(NULL), port(NULL), masterId(Request::invldMasterId),
61 isStage2(p->is_stage2), tlb(NULL),
62 currState(NULL), pending(false),
63 numSquashable(p->num_squash_per_cycle),
64 pendingReqs(0),
65 pendingChangeTick(curTick()),
66 doL1DescEvent(this), doL2DescEvent(this),
67 doL0LongDescEvent(this), doL1LongDescEvent(this), doL2LongDescEvent(this),
68 doL3LongDescEvent(this),
69 doProcessEvent(this)
70{
71 sctlr = 0;
72
73 // Cache system-level properties
74 if (FullSystem) {
75 ArmSystem *armSys = dynamic_cast<ArmSystem *>(p->sys);
76 assert(armSys);
77 haveSecurity = armSys->haveSecurity();
78 _haveLPAE = armSys->haveLPAE();
79 _haveVirtualization = armSys->haveVirtualization();
80 physAddrRange = armSys->physAddrRange();
81 _haveLargeAsid64 = armSys->haveLargeAsid64();
82 } else {
83 haveSecurity = _haveLPAE = _haveVirtualization = false;
84 _haveLargeAsid64 = false;
85 physAddrRange = 32;
86 }
87
88}
89
90TableWalker::~TableWalker()
91{
92 ;
93}
94
95void
96TableWalker::setMMU(Stage2MMU *m, MasterID master_id)
97{
98 stage2Mmu = m;
99 port = &m->getPort();
100 masterId = master_id;
101}
102
103void
104TableWalker::init()
105{
106 fatal_if(!stage2Mmu, "Table walker must have a valid stage-2 MMU\n");
107 fatal_if(!port, "Table walker must have a valid port\n");
108 fatal_if(!tlb, "Table walker must have a valid TLB\n");
109}
110
111BaseMasterPort&
112TableWalker::getMasterPort(const std::string &if_name, PortID idx)
113{
114 if (if_name == "port") {
115 if (!isStage2) {
116 return *port;
117 } else {
118 fatal("Cannot access table walker port through stage-two walker\n");
119 }
120 }
121 return MemObject::getMasterPort(if_name, idx);
122}
123
124TableWalker::WalkerState::WalkerState() :
125 tc(nullptr), aarch64(false), el(EL0), physAddrRange(0), req(nullptr),
126 asid(0), vmid(0), isHyp(false), transState(nullptr),
127 vaddr(0), vaddr_tainted(0), isWrite(false), isFetch(false), isSecure(false),
128 secureLookup(false), rwTable(false), userTable(false), xnTable(false),
129 pxnTable(false), stage2Req(false), doingStage2(false),
130 stage2Tran(nullptr), timing(false), functional(false),
131 mode(BaseTLB::Read), tranType(TLB::NormalTran), l2Desc(l1Desc),

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

143 drainManager->signalDrainDone();
144 drainManager = NULL;
145 }
146}
147
148unsigned int
149TableWalker::drain(DrainManager *dm)
150{
151 bool state_queues_not_empty = false;
152
153 for (int i = 0; i < MAX_LOOKUP_LEVELS; ++i) {
154 if (!stateQueues[i].empty()) {
155 state_queues_not_empty = true;
156 break;
157 }
158 }
159
160 if (state_queues_not_empty || pendingQueue.size()) {
161 drainManager = dm;
162 setDrainState(Drainable::Draining);
163 DPRINTF(Drain, "TableWalker not drained\n");
164
165 // return port drain count plus the table walker itself needs to drain
166 return 1;
167 } else {
168 setDrainState(Drainable::Drained);
169 DPRINTF(Drain, "TableWalker free, no need to drain\n");
170
171 // table walker is drained, but its ports may still need to be drained
172 return 0;
173 }
174}
175
176void
177TableWalker::drainResume()
178{
179 Drainable::drainResume();
180 if (params()->sys->isTimingMode() && currState) {
181 delete currState;
182 currState = NULL;
183 pendingChange();
184 }
185}
186
187Fault
188TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint16_t _asid,
189 uint8_t _vmid, bool _isHyp, TLB::Mode _mode,
190 TLB::Translation *_trans, bool _timing, bool _functional,
191 bool secure, TLB::ArmTranslationType tranType)
192{
193 assert(!(_functional && _timing));
194 ++statWalks;

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

959 break;
960 case L3:
961 event = (Event *) &doL3LongDescEvent;
962 break;
963 default:
964 panic("Invalid table lookup level");
965 break;
966 }
967 port->dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t),
968 event, (uint8_t*) &currState->longDesc.data,
969 currState->tc->getCpuPtr()->clockPeriod(), flag);
970 DPRINTF(TLBVerbose,
971 "Adding to walker fifo: queue size before adding: %d\n",
972 stateQueues[start_lookup_level].size());
973 stateQueues[start_lookup_level].push_back(currState);
974 currState = NULL;
975 } else if (!currState->functional) {
976 port->dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t),
977 NULL, (uint8_t*) &currState->longDesc.data,
978 currState->tc->getCpuPtr()->clockPeriod(), flag);
979 doLongDescriptor();
980 f = currState->fault;
981 } else {
982 RequestPtr req = new Request(desc_addr, sizeof(uint64_t), flag,
983 masterId);
984 PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
985 pkt->dataStatic((uint8_t*) &currState->longDesc.data);
986 port->sendFunctional(pkt);
987 doLongDescriptor();
988 delete req;
989 delete pkt;
990 f = currState->fault;
991 }
992
993 return f;
994}

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

1929 flags = flags | TLB::MustBeOne;
1930
1931 if (isTiming) {
1932 Stage2MMU::Stage2Translation *tran = new
1933 Stage2MMU::Stage2Translation(*stage2Mmu, data, event,
1934 currState->vaddr);
1935 currState->stage2Tran = tran;
1936 stage2Mmu->readDataTimed(currState->tc, descAddr, tran, numBytes,
1937 flags);
1938 fault = tran->fault;
1939 } else {
1940 fault = stage2Mmu->readDataUntimed(currState->tc,
1941 currState->vaddr, descAddr, data, numBytes, flags,
1942 currState->functional);
1943 }
1944
1945 if (fault != NoFault) {
1946 currState->fault = fault;
1947 }
1948 if (isTiming) {
1949 if (queueIndex >= 0) {
1950 DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
1951 stateQueues[queueIndex].size());
1952 stateQueues[queueIndex].push_back(currState);
1953 currState = NULL;
1954 }
1955 } else {
1956 (this->*doDescriptor)();
1957 }
1958 } else {
1959 if (isTiming) {
1960 port->dmaAction(MemCmd::ReadReq, descAddr, numBytes, event, data,
1961 currState->tc->getCpuPtr()->clockPeriod(),flags);
1962 if (queueIndex >= 0) {
1963 DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
1964 stateQueues[queueIndex].size());
1965 stateQueues[queueIndex].push_back(currState);
1966 currState = NULL;
1967 }
1968 } else if (!currState->functional) {
1969 port->dmaAction(MemCmd::ReadReq, descAddr, numBytes, NULL, data,
1970 currState->tc->getCpuPtr()->clockPeriod(), flags);
1971 (this->*doDescriptor)();
1972 } else {
1973 RequestPtr req = new Request(descAddr, numBytes, flags, masterId);
1974 req->taskId(ContextSwitchTaskId::DMA);
1975 PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
1976 pkt->dataStatic(data);
1977 port->sendFunctional(pkt);
1978 (this->*doDescriptor)();
1979 delete req;
1980 delete pkt;
1981 }
1982 }
1983 return (isTiming);
1984}
1985

--- 237 unchanged lines hidden ---