1/* 2 * Copyright (c) 2001-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 96 unchanged lines hidden (view full) --- 105} 106 107Tick 108PhysicalMemory::calculateLatency(Packet *pkt) 109{ 110 return lat; 111} 112 |
113 114 115// Add load-locked to tracking list. Should only be called if the 116// operation is a load and the LOCKED flag is set. |
117void |
118PhysicalMemory::trackLoadLocked(Request *req) 119{ 120 Addr paddr = LockedAddr::mask(req->getPaddr()); 121 122 // first we check if we already have a locked addr for this 123 // xc. Since each xc only gets one, we just update the 124 // existing record with the new address. 125 list<LockedAddr>::iterator i; 126 127 for (i = lockedAddrList.begin(); i != lockedAddrList.end(); ++i) { 128 if (i->matchesContext(req)) { 129 DPRINTF(LLSC, "Modifying lock record: cpu %d thread %d addr %#x\n", 130 req->getCpuNum(), req->getThreadNum(), paddr); 131 i->addr = paddr; 132 return; 133 } 134 } 135 136 // no record for this xc: need to allocate a new one 137 DPRINTF(LLSC, "Adding lock record: cpu %d thread %d addr %#x\n", 138 req->getCpuNum(), req->getThreadNum(), paddr); 139 lockedAddrList.push_front(LockedAddr(req)); 140} 141 142 143// Called on *writes* only... both regular stores and 144// store-conditional operations. Check for conventional stores which 145// conflict with locked addresses, and for success/failure of store 146// conditionals. 147bool 148PhysicalMemory::checkLockedAddrList(Request *req) 149{ 150 Addr paddr = LockedAddr::mask(req->getPaddr()); 151 bool isLocked = req->isLocked(); 152 153 // Initialize return value. Non-conditional stores always 154 // succeed. Assume conditional stores will fail until proven 155 // otherwise. 156 bool success = !isLocked; 157 158 // Iterate over list. Note that there could be multiple matching 159 // records, as more than one context could have done a load locked 160 // to this location. 161 list<LockedAddr>::iterator i = lockedAddrList.begin(); 162 163 while (i != lockedAddrList.end()) { 164 165 if (i->addr == paddr) { 166 // we have a matching address 167 168 if (isLocked && i->matchesContext(req)) { 169 // it's a store conditional, and as far as the memory 170 // system can tell, the requesting context's lock is 171 // still valid. 172 DPRINTF(LLSC, "StCond success: cpu %d thread %d addr %#x\n", 173 req->getCpuNum(), req->getThreadNum(), paddr); 174 success = true; 175 } 176 177 // Get rid of our record of this lock and advance to next 178 DPRINTF(LLSC, "Erasing lock record: cpu %d thread %d addr %#x\n", 179 i->cpuNum, i->threadNum, paddr); 180 i = lockedAddrList.erase(i); 181 } 182 else { 183 // no match: advance to next record 184 ++i; 185 } 186 } 187 188 if (isLocked) { 189 req->setScResult(success ? 1 : 0); 190 } 191 192 return success; 193} 194 195void |
196PhysicalMemory::doFunctionalAccess(Packet *pkt) 197{ 198 assert(pkt->getAddr() + pkt->getSize() <= params()->addrRange.size()); 199 |
200 if (pkt->isRead()) { 201 if (pkt->req->isLocked()) { 202 trackLoadLocked(pkt->req); 203 } |
204 memcpy(pkt->getPtr<uint8_t>(), 205 pmemAddr + pkt->getAddr() - params()->addrRange.start, 206 pkt->getSize()); |
207 } 208 else if (pkt->isWrite()) { 209 if (writeOK(pkt->req)) { 210 memcpy(pmemAddr + pkt->getAddr() - params()->addrRange.start, 211 pkt->getPtr<uint8_t>(), pkt->getSize()); |
212 } |
213 } 214 else if (pkt->isInvalidate()) { 215 //upgrade or invalidate 216 pkt->flags |= SATISFIED; 217 } 218 else { |
219 panic("unimplemented"); 220 } 221 222 pkt->result = Packet::Success; 223} 224 225Port * 226PhysicalMemory::getPort(const std::string &if_name, int idx) 227{ 228 if (if_name == "port" && idx == -1) { 229 if (port != NULL) 230 panic("PhysicalMemory::getPort: additional port requested to memory!"); 231 port = new MemoryPort(name() + "-port", this); 232 return port; 233 } else if (if_name == "functional") { |
234 /* special port for functional writes at startup. And for memtester */ |
235 return new MemoryPort(name() + "-funcport", this); 236 } else { 237 panic("PhysicalMemory::getPort: unknown port %s requested", if_name); 238 } 239} 240 241void 242PhysicalMemory::recvStatusChange(Port::Status status) --- 196 unchanged lines hidden --- |