113,116d112
<
<
< // Add load-locked to tracking list. Should only be called if the
< // operation is a load and the LOCKED flag is set.
118,195d113
< PhysicalMemory::trackLoadLocked(Request *req)
< {
< Addr paddr = LockedAddr::mask(req->getPaddr());
<
< // first we check if we already have a locked addr for this
< // xc. Since each xc only gets one, we just update the
< // existing record with the new address.
< list<LockedAddr>::iterator i;
<
< for (i = lockedAddrList.begin(); i != lockedAddrList.end(); ++i) {
< if (i->matchesContext(req)) {
< DPRINTF(LLSC, "Modifying lock record: cpu %d thread %d addr %#x\n",
< req->getCpuNum(), req->getThreadNum(), paddr);
< i->addr = paddr;
< return;
< }
< }
<
< // no record for this xc: need to allocate a new one
< DPRINTF(LLSC, "Adding lock record: cpu %d thread %d addr %#x\n",
< req->getCpuNum(), req->getThreadNum(), paddr);
< lockedAddrList.push_front(LockedAddr(req));
< }
<
<
< // Called on *writes* only... both regular stores and
< // store-conditional operations. Check for conventional stores which
< // conflict with locked addresses, and for success/failure of store
< // conditionals.
< bool
< PhysicalMemory::checkLockedAddrList(Request *req)
< {
< Addr paddr = LockedAddr::mask(req->getPaddr());
< bool isLocked = req->isLocked();
<
< // Initialize return value. Non-conditional stores always
< // succeed. Assume conditional stores will fail until proven
< // otherwise.
< bool success = !isLocked;
<
< // Iterate over list. Note that there could be multiple matching
< // records, as more than one context could have done a load locked
< // to this location.
< list<LockedAddr>::iterator i = lockedAddrList.begin();
<
< while (i != lockedAddrList.end()) {
<
< if (i->addr == paddr) {
< // we have a matching address
<
< if (isLocked && i->matchesContext(req)) {
< // it's a store conditional, and as far as the memory
< // system can tell, the requesting context's lock is
< // still valid.
< DPRINTF(LLSC, "StCond success: cpu %d thread %d addr %#x\n",
< req->getCpuNum(), req->getThreadNum(), paddr);
< success = true;
< }
<
< // Get rid of our record of this lock and advance to next
< DPRINTF(LLSC, "Erasing lock record: cpu %d thread %d addr %#x\n",
< i->cpuNum, i->threadNum, paddr);
< i = lockedAddrList.erase(i);
< }
< else {
< // no match: advance to next record
< ++i;
< }
< }
<
< if (isLocked) {
< req->setScResult(success ? 1 : 0);
< }
<
< return success;
< }
<
< void
198c116
< assert(pkt->getAddr() + pkt->getSize() < params()->addrRange.size());
---
> assert(pkt->getAddr() + pkt->getSize() <= params()->addrRange.size());
200,203c118,119
< if (pkt->isRead()) {
< if (pkt->req->isLocked()) {
< trackLoadLocked(pkt->req);
< }
---
> switch (pkt->cmd) {
> case Packet::ReadReq:
207,211c123,131
< }
< else if (pkt->isWrite()) {
< if (writeOK(pkt->req)) {
< memcpy(pmemAddr + pkt->getAddr() - params()->addrRange.start,
< pkt->getPtr<uint8_t>(), pkt->getSize());
---
> break;
> case Packet::WriteReq:
> memcpy(pmemAddr + pkt->getAddr() - params()->addrRange.start,
> pkt->getPtr<uint8_t>(),
> pkt->getSize());
> // temporary hack: will need to add real LL/SC implementation
> // for cacheless systems later.
> if (pkt->req->getFlags() & LOCKED) {
> pkt->req->setScResult(1);
213,218c133,134
< }
< else if (pkt->isInvalidate()) {
< //upgrade or invalidate
< pkt->flags |= SATISFIED;
< }
< else {
---
> break;
> default:
234c150
< /* special port for functional writes at startup. And for memtester */
---
> /* special port for functional writes at startup. */