Deleted Added
sdiff udiff text old ( 10621:b7bc5b1084a4 ) new ( 10717:4f8c1bd6fdb8 )
full compact
1/*
2 * Copyright (c) 2010, 2012-2014 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), port(this, p->sys), drainManager(NULL),
60 stage2Mmu(NULL), isStage2(p->is_stage2), tlb(NULL),
61 currState(NULL), pending(false), masterId(p->sys->getMasterId(name())),
62 numSquashable(p->num_squash_per_cycle),
63 pendingReqs(0),
64 pendingChangeTick(curTick()),
65 doL1DescEvent(this), doL2DescEvent(this),
66 doL0LongDescEvent(this), doL1LongDescEvent(this), doL2LongDescEvent(this),
67 doL3LongDescEvent(this),
68 doProcessEvent(this)
69{
70 sctlr = 0;
71
72 // Cache system-level properties
73 if (FullSystem) {
74 armSys = dynamic_cast(p->sys);
75 assert(armSys);
76 haveSecurity = armSys->haveSecurity();
77 _haveLPAE = armSys->haveLPAE();
78 _haveVirtualization = armSys->haveVirtualization();
79 physAddrRange = armSys->physAddrRange();
80 _haveLargeAsid64 = armSys->haveLargeAsid64();
81 } else {
82 armSys = NULL;
83 haveSecurity = _haveLPAE = _haveVirtualization = false;
84 _haveLargeAsid64 = false;
85 physAddrRange = 32;
86 }
87
88}
89
90TableWalker::~TableWalker()
91{
92 ;
93}
94
95TableWalker::WalkerState::WalkerState() :
96 tc(nullptr), aarch64(false), el(EL0), physAddrRange(0), req(nullptr),
97 asid(0), vmid(0), isHyp(false), transState(nullptr),
98 vaddr(0), vaddr_tainted(0), isWrite(false), isFetch(false), isSecure(false),
99 secureLookup(false), rwTable(false), userTable(false), xnTable(false),
100 pxnTable(false), stage2Req(false), doingStage2(false),
101 stage2Tran(nullptr), timing(false), functional(false),
102 mode(BaseTLB::Read), tranType(TLB::NormalTran), l2Desc(l1Desc),

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

114 drainManager->signalDrainDone();
115 drainManager = NULL;
116 }
117}
118
119unsigned int
120TableWalker::drain(DrainManager *dm)
121{
122 unsigned int count = port.drain(dm);
123
124 bool state_queues_not_empty = false;
125
126 for (int i = 0; i < MAX_LOOKUP_LEVELS; ++i) {
127 if (!stateQueues[i].empty()) {
128 state_queues_not_empty = true;
129 break;
130 }
131 }
132
133 if (state_queues_not_empty || pendingQueue.size()) {
134 drainManager = dm;
135 setDrainState(Drainable::Draining);
136 DPRINTF(Drain, "TableWalker not drained\n");
137
138 // return port drain count plus the table walker itself needs to drain
139 return count + 1;
140 } else {
141 setDrainState(Drainable::Drained);
142 DPRINTF(Drain, "TableWalker free, no need to drain\n");
143
144 // table walker is drained, but its ports may still need to be drained
145 return count;
146 }
147}
148
149void
150TableWalker::drainResume()
151{
152 Drainable::drainResume();
153 if (params()->sys->isTimingMode() && currState) {
154 delete currState;
155 currState = NULL;
156 pendingChange();
157 }
158}
159
160BaseMasterPort&
161TableWalker::getMasterPort(const std::string &if_name, PortID idx)
162{
163 if (if_name == "port") {
164 return port;
165 }
166 return MemObject::getMasterPort(if_name, idx);
167}
168
169Fault
170TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint16_t _asid,
171 uint8_t _vmid, bool _isHyp, TLB::Mode _mode,
172 TLB::Translation *_trans, bool _timing, bool _functional,
173 bool secure, TLB::ArmTranslationType tranType)
174{
175 assert(!(_functional && _timing));
176 ++statWalks;

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

941 break;
942 case L3:
943 event = (Event *) &doL3LongDescEvent;
944 break;
945 default:
946 panic("Invalid table lookup level");
947 break;
948 }
949 port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t),
950 event, (uint8_t*) &currState->longDesc.data,
951 currState->tc->getCpuPtr()->clockPeriod(), flag);
952 DPRINTF(TLBVerbose,
953 "Adding to walker fifo: queue size before adding: %d\n",
954 stateQueues[start_lookup_level].size());
955 stateQueues[start_lookup_level].push_back(currState);
956 currState = NULL;
957 } else if (!currState->functional) {
958 port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t),
959 NULL, (uint8_t*) &currState->longDesc.data,
960 currState->tc->getCpuPtr()->clockPeriod(), flag);
961 doLongDescriptor();
962 f = currState->fault;
963 } else {
964 RequestPtr req = new Request(desc_addr, sizeof(uint64_t), flag,
965 masterId);
966 PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
967 pkt->dataStatic((uint8_t*) &currState->longDesc.data);
968 port.sendFunctional(pkt);
969 doLongDescriptor();
970 delete req;
971 delete pkt;
972 f = currState->fault;
973 }
974
975 return f;
976}

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

1911 flags = flags | TLB::MustBeOne;
1912
1913 if (isTiming) {
1914 Stage2MMU::Stage2Translation *tran = new
1915 Stage2MMU::Stage2Translation(*stage2Mmu, data, event,
1916 currState->vaddr);
1917 currState->stage2Tran = tran;
1918 stage2Mmu->readDataTimed(currState->tc, descAddr, tran, numBytes,
1919 flags, masterId);
1920 fault = tran->fault;
1921 } else {
1922 fault = stage2Mmu->readDataUntimed(currState->tc,
1923 currState->vaddr, descAddr, data, numBytes, flags, masterId,
1924 currState->functional);
1925 }
1926
1927 if (fault != NoFault) {
1928 currState->fault = fault;
1929 }
1930 if (isTiming) {
1931 if (queueIndex >= 0) {
1932 DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
1933 stateQueues[queueIndex].size());
1934 stateQueues[queueIndex].push_back(currState);
1935 currState = NULL;
1936 }
1937 } else {
1938 (this->*doDescriptor)();
1939 }
1940 } else {
1941 if (isTiming) {
1942 port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, event, data,
1943 currState->tc->getCpuPtr()->clockPeriod(),flags);
1944 if (queueIndex >= 0) {
1945 DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
1946 stateQueues[queueIndex].size());
1947 stateQueues[queueIndex].push_back(currState);
1948 currState = NULL;
1949 }
1950 } else if (!currState->functional) {
1951 port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, NULL, data,
1952 currState->tc->getCpuPtr()->clockPeriod(), flags);
1953 (this->*doDescriptor)();
1954 } else {
1955 RequestPtr req = new Request(descAddr, numBytes, flags, masterId);
1956 req->taskId(ContextSwitchTaskId::DMA);
1957 PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
1958 pkt->dataStatic(data);
1959 port.sendFunctional(pkt);
1960 (this->*doDescriptor)();
1961 delete req;
1962 delete pkt;
1963 }
1964 }
1965 return (isTiming);
1966}
1967

--- 237 unchanged lines hidden ---