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