summaryrefslogtreecommitdiff
path: root/src/mem/physical.cc
diff options
context:
space:
mode:
authorAli Saidi <saidi@eecs.umich.edu>2007-02-12 13:06:30 -0500
committerAli Saidi <saidi@eecs.umich.edu>2007-02-12 13:06:30 -0500
commitb5a4d95811db487d946200bf103e2af376db7690 (patch)
tree8004993f9ea05c8b78ba34930455fe671dff0e2d /src/mem/physical.cc
parent1f834b569c8a39f44882c2f2010a9f0ecffdaab1 (diff)
downloadgem5-b5a4d95811db487d946200bf103e2af376db7690.tar.xz
rename store conditional stuff as extra data so it can be used for conditional swaps as well
Add support for a twin 64 bit int load Add Memory barrier and write barrier flags as appropriate Make atomic memory ops atomic src/arch/alpha/isa/mem.isa: src/arch/alpha/locked_mem.hh: src/cpu/base_dyn_inst.hh: src/mem/cache/cache_blk.hh: src/mem/cache/cache_impl.hh: rename store conditional stuff as extra data so it can be used for conditional swaps as well src/arch/alpha/types.hh: src/arch/mips/types.hh: src/arch/sparc/types.hh: add a largest read data type for statically allocating read buffers in atomic simple cpu src/arch/isa_parser.py: Add support for a twin 64 bit int load src/arch/sparc/isa/decoder.isa: Make atomic memory ops atomic Add Memory barrier and write barrier flags as appropriate src/arch/sparc/isa/formats/mem/basicmem.isa: add post access code block and define a twinload format for twin loads src/arch/sparc/isa/formats/mem/blockmem.isa: remove old microcoded twin load coad src/arch/sparc/isa/formats/mem/mem.isa: swap.isa replaces the code in loadstore.isa src/arch/sparc/isa/formats/mem/util.isa: add a post access code block src/arch/sparc/isa/includes.isa: need bigint.hh for Twin64_t src/arch/sparc/isa/operands.isa: add a twin 64 int type src/cpu/simple/atomic.cc: src/cpu/simple/atomic.hh: src/cpu/simple/base.hh: src/cpu/simple/timing.cc: add support for twinloads add support for swap and conditional swap instructions rename store conditional stuff as extra data so it can be used for conditional swaps as well src/mem/packet.cc: src/mem/packet.hh: Add support for atomic swap memory commands src/mem/packet_access.hh: Add endian conversion function for Twin64_t type src/mem/physical.cc: src/mem/physical.hh: src/mem/request.hh: Add support for atomic swap memory commands Rename sc code to extradata --HG-- extra : convert_revision : 69d908512fb34a4e28b29a6e58b807fb1a6b1656
Diffstat (limited to 'src/mem/physical.cc')
-rw-r--r--src/mem/physical.cc91
1 files changed, 77 insertions, 14 deletions
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index eccd42bec..381669d4d 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -92,7 +92,7 @@ Addr
PhysicalMemory::new_page()
{
Addr return_addr = pagePtr << LogVMPageSize;
- return_addr += params()->addrRange.start;
+ return_addr += start();
++pagePtr;
return return_addr;
@@ -187,7 +187,7 @@ PhysicalMemory::checkLockedAddrList(Request *req)
}
if (isLocked) {
- req->setScResult(success ? 1 : 0);
+ req->setExtraData(success ? 1 : 0);
}
return success;
@@ -196,16 +196,14 @@ PhysicalMemory::checkLockedAddrList(Request *req)
void
PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
{
- assert(pkt->getAddr() >= params()->addrRange.start &&
- pkt->getAddr() + pkt->getSize() <= params()->addrRange.start +
- params()->addrRange.size());
+ assert(pkt->getAddr() >= start() &&
+ pkt->getAddr() + pkt->getSize() <= start() + size());
if (pkt->isRead()) {
if (pkt->req->isLocked()) {
trackLoadLocked(pkt->req);
}
- memcpy(pkt->getPtr<uint8_t>(),
- pmemAddr + pkt->getAddr() - params()->addrRange.start,
+ memcpy(pkt->getPtr<uint8_t>(), pmemAddr + pkt->getAddr() - start(),
pkt->getSize());
#if TRACING_ON
switch (pkt->getSize()) {
@@ -233,8 +231,8 @@ PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
}
else if (pkt->isWrite()) {
if (writeOK(pkt->req)) {
- memcpy(pmemAddr + pkt->getAddr() - params()->addrRange.start,
- pkt->getPtr<uint8_t>(), pkt->getSize());
+ memcpy(pmemAddr + pkt->getAddr() - start(), pkt->getPtr<uint8_t>(),
+ pkt->getSize());
#if TRACING_ON
switch (pkt->getSize()) {
case sizeof(uint64_t):
@@ -259,12 +257,77 @@ PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
}
#endif
}
- }
- else if (pkt->isInvalidate()) {
+ } else if (pkt->isInvalidate()) {
//upgrade or invalidate
pkt->flags |= SATISFIED;
- }
- else {
+ } else if (pkt->isReadWrite()) {
+ IntReg overwrite_val;
+ bool overwrite_mem;
+ uint64_t condition_val64;
+ uint32_t condition_val32;
+ uint64_t test_val64;
+ uint32_t test_val32;
+
+ assert(sizeof(IntReg) >= pkt->getSize());
+
+ overwrite_mem = true;
+ // keep a copy of our possible write value, and copy what is at the
+ // memory address into the packet
+ memcpy(&overwrite_val, pkt->getPtr<uint8_t>(), pkt->getSize());
+ memcpy(pkt->getPtr<uint8_t>(), pmemAddr + pkt->getAddr() - start(),
+ pkt->getSize());
+
+ if (pkt->req->isCondSwap()) {
+ if (pkt->getSize() == sizeof(uint64_t)) {
+ condition_val64 = htog(pkt->req->getExtraData());
+ memcpy(&test_val64, pmemAddr + pkt->getAddr() - start(), sizeof(uint64_t));
+ overwrite_mem = test_val64 == condition_val64;
+ } else if (pkt->getSize() == sizeof(uint32_t)) {
+ condition_val32 = htog((uint32_t)pkt->req->getExtraData());
+ memcpy(&test_val32, pmemAddr + pkt->getAddr() - start(), sizeof(uint32_t));
+ overwrite_mem = test_val32 == condition_val32;
+ } else
+ panic("Invalid size for conditional read/write\n");
+ }
+
+ if (overwrite_mem)
+ memcpy(pmemAddr + pkt->getAddr() - start(),
+ &overwrite_val, pkt->getSize());
+
+#if TRACING_ON
+ switch (pkt->getSize()) {
+ case sizeof(uint64_t):
+ DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x old data 0x%x\n",
+ pkt->getSize(), pkt->getAddr(),pkt->get<uint64_t>());
+ DPRINTF(MemoryAccess, "New Data 0x%x %s conditional (0x%x) and %s \n",
+ overwrite_mem, pkt->req->isCondSwap() ? "was" : "wasn't",
+ condition_val64, overwrite_mem ? "happened" : "didn't happen");
+ break;
+ case sizeof(uint32_t):
+ DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x old data 0x%x\n",
+ pkt->getSize(), pkt->getAddr(),pkt->get<uint32_t>());
+ DPRINTF(MemoryAccess, "New Data 0x%x %s conditional (0x%x) and %s \n",
+ overwrite_mem, pkt->req->isCondSwap() ? "was" : "wasn't",
+ condition_val32, overwrite_mem ? "happened" : "didn't happen");
+ break;
+ case sizeof(uint16_t):
+ DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x old data 0x%x\n",
+ pkt->getSize(), pkt->getAddr(),pkt->get<uint16_t>());
+ DPRINTF(MemoryAccess, "New Data 0x%x wasn't conditional and happned\n",
+ overwrite_mem);
+ break;
+ case sizeof(uint8_t):
+ DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x old data 0x%x\n",
+ pkt->getSize(), pkt->getAddr(),pkt->get<uint8_t>());
+ DPRINTF(MemoryAccess, "New Data 0x%x wasn't conditional and happned\n",
+ overwrite_mem);
+ break;
+ default:
+ DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x\n",
+ pkt->getSize(), pkt->getAddr());
+ }
+#endif
+ } else {
panic("unimplemented");
}
@@ -315,7 +378,7 @@ PhysicalMemory::getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
{
snoop.clear();
resp.clear();
- resp.push_back(RangeSize(params()->addrRange.start,
+ resp.push_back(RangeSize(start(),
params()->addrRange.size()));
}