table_walker.cc (10621:b7bc5b1084a4) table_walker.cc (10717:4f8c1bd6fdb8)
1/*
1/*
2 * Copyright (c) 2010, 2012-2014 ARM Limited
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)
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())),
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),
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) {
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) {
74 armSys = dynamic_cast(p->sys);
75 ArmSystem *armSys = dynamic_cast<ArmSystem *>(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 {
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 {
82 armSys = NULL;
83 haveSecurity = _haveLPAE = _haveVirtualization = false;
84 _haveLargeAsid64 = false;
85 physAddrRange = 32;
86 }
87
88}
89
90TableWalker::~TableWalker()
91{
92 ;
93}
94
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
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{
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{
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
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
139 return count + 1;
166 return 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
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
145 return count;
172 return 0;
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
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
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 }
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 }
949 port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t),
967 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) {
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) {
958 port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t),
976 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);
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);
968 port.sendFunctional(pkt);
986 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,
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,
1919 flags, masterId);
1937 flags);
1920 fault = tran->fault;
1921 } else {
1922 fault = stage2Mmu->readDataUntimed(currState->tc,
1938 fault = tran->fault;
1939 } else {
1940 fault = stage2Mmu->readDataUntimed(currState->tc,
1923 currState->vaddr, descAddr, data, numBytes, flags, masterId,
1941 currState->vaddr, descAddr, data, numBytes, flags,
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 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) {
1942 port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, event, data,
1960 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) {
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) {
1951 port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, NULL, data,
1969 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);
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);
1959 port.sendFunctional(pkt);
1977 port->sendFunctional(pkt);
1960 (this->*doDescriptor)();
1961 delete req;
1962 delete pkt;
1963 }
1964 }
1965 return (isTiming);
1966}
1967

--- 237 unchanged lines hidden ---
1978 (this->*doDescriptor)();
1979 delete req;
1980 delete pkt;
1981 }
1982 }
1983 return (isTiming);
1984}
1985

--- 237 unchanged lines hidden ---