physical.cc (3091:dba513d68c16) | physical.cc (3170:37fd1e73f836) |
---|---|
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 | 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. |
|
113void | 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 |
|
114PhysicalMemory::doFunctionalAccess(Packet *pkt) 115{ 116 assert(pkt->getAddr() + pkt->getSize() < params()->addrRange.size()); 117 118 switch (pkt->cmd) { 119 case Packet::ReadReq: | 196PhysicalMemory::doFunctionalAccess(Packet *pkt) 197{ 198 assert(pkt->getAddr() + pkt->getSize() < params()->addrRange.size()); 199 200 switch (pkt->cmd) { 201 case Packet::ReadReq: |
202 if (pkt->req->isLocked()) { 203 trackLoadLocked(pkt->req); 204 } |
|
120 memcpy(pkt->getPtr<uint8_t>(), 121 pmemAddr + pkt->getAddr() - params()->addrRange.start, 122 pkt->getSize()); 123 break; 124 case Packet::WriteReq: | 205 memcpy(pkt->getPtr<uint8_t>(), 206 pmemAddr + pkt->getAddr() - params()->addrRange.start, 207 pkt->getSize()); 208 break; 209 case Packet::WriteReq: |
125 memcpy(pmemAddr + pkt->getAddr() - params()->addrRange.start, 126 pkt->getPtr<uint8_t>(), 127 pkt->getSize()); 128 // temporary hack: will need to add real LL/SC implementation 129 // for cacheless systems later. 130 if (pkt->req->getFlags() & LOCKED) { 131 pkt->req->setScResult(1); | 210 if (writeOK(pkt->req)) { 211 memcpy(pmemAddr + pkt->getAddr() - params()->addrRange.start, 212 pkt->getPtr<uint8_t>(), pkt->getSize()); |
132 } 133 break; 134 default: 135 panic("unimplemented"); 136 } 137 138 pkt->result = Packet::Success; 139} --- 215 unchanged lines hidden --- | 213 } 214 break; 215 default: 216 panic("unimplemented"); 217 } 218 219 pkt->result = Packet::Success; 220} --- 215 unchanged lines hidden --- |