mem: Use const pointers for port proxy write functions

This patch changes the various write functions in the port proxies
to use const pointers for all sources (similar to how memcpy works).

The one unfortunate aspect is the need for a const_cast in the packet,
to avoid having to juggle a const and a non-const data pointer. This
design decision can always be re-evaluated at a later stage.
This commit is contained in:
Andreas Hansson 2014-12-02 06:07:38 -05:00
parent 9779ba2e37
commit 0706a25203
7 changed files with 50 additions and 21 deletions

View file

@ -89,7 +89,7 @@ FSTranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size) const
}
void
FSTranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size) const
FSTranslatingPortProxy::writeBlob(Addr addr, const uint8_t *p, int size) const
{
Addr paddr;
for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
@ -129,7 +129,7 @@ CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
}
void
CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
CopyIn(ThreadContext *tc, Addr dest, const void *source, size_t cplen)
{
uint8_t *src = (uint8_t *)source;
tc->getVirtProxy().writeBlob(dest, src, cplen);
@ -154,7 +154,7 @@ CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
}
void
CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
CopyStringIn(ThreadContext *tc, const char *src, Addr vaddr)
{
FSTranslatingPortProxy &vp = tc->getVirtProxy();
for (ChunkGenerator gen(vaddr, strlen(src), TheISA::PageBytes); !gen.done();

View file

@ -89,7 +89,7 @@ class FSTranslatingPortProxy : public PortProxy
/** Version of writeBlob that translates virt->phys and deals
* with page boundries. */
virtual void writeBlob(Addr addr, uint8_t *p, int size) const;
virtual void writeBlob(Addr addr, const uint8_t *p, int size) const;
/**
* Fill size bytes starting at addr with byte value val.
@ -98,8 +98,8 @@ class FSTranslatingPortProxy : public PortProxy
};
void CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen);
void CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen);
void CopyIn(ThreadContext *tc, Addr dest, const void *source, size_t cplen);
void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen);
void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr);
void CopyStringIn(ThreadContext *tc, const char *src, Addr vaddr);
#endif //__MEM_FS_PORT_PROXY_HH__

View file

@ -813,6 +813,23 @@ class Packet : public Printable
flags.set(STATIC_DATA);
}
/**
* Set the data pointer to the following value that should not be
* freed. This version of the function allows the pointer passed
* to us to be const. To avoid issues down the line we cast the
* constness away, the alternative would be to keep both a const
* and non-const data pointer and cleverly choose between
* them. Note that this is only allowed for static data.
*/
template <typename T>
void
dataStaticConst(const T *p)
{
assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA|ARRAY_DATA));
data = const_cast<PacketDataPtr>(p);
flags.set(STATIC_DATA);
}
/**
* Set the data pointer to a value that should have delete []
* called on it.

View file

@ -41,20 +41,35 @@
#include "mem/port_proxy.hh"
void
PortProxy::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd) const
PortProxy::readBlob(Addr addr, uint8_t *p, int size) const
{
Request req;
for (ChunkGenerator gen(addr, size, _cacheLineSize);
!gen.done(); gen.next()) {
for (ChunkGenerator gen(addr, size, _cacheLineSize); !gen.done();
gen.next()) {
req.setPhys(gen.addr(), gen.size(), 0, Request::funcMasterId);
Packet pkt(&req, cmd);
Packet pkt(&req, MemCmd::ReadReq);
pkt.dataStatic(p);
_port.sendFunctional(&pkt);
p += gen.size();
}
}
void
PortProxy::writeBlob(Addr addr, const uint8_t *p, int size) const
{
Request req;
for (ChunkGenerator gen(addr, size, _cacheLineSize); !gen.done();
gen.next()) {
req.setPhys(gen.addr(), gen.size(), 0, Request::funcMasterId);
Packet pkt(&req, MemCmd::WriteReq);
pkt.dataStaticConst(p);
_port.sendFunctional(&pkt);
p += gen.size();
}
}
void
PortProxy::memsetBlob(Addr addr, uint8_t v, int size) const
{
@ -62,7 +77,7 @@ PortProxy::memsetBlob(Addr addr, uint8_t v, int size) const
uint8_t *buf = new uint8_t[size];
std::memset(buf, v, size);
blobHelper(addr, buf, size, MemCmd::WriteReq);
PortProxy::writeBlob(addr, buf, size);
delete [] buf;
}

View file

@ -91,8 +91,6 @@ class PortProxy
/** Granularity of any transactions issued through this proxy. */
const unsigned int _cacheLineSize;
void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd) const;
public:
PortProxy(MasterPort &port, unsigned int cacheLineSize) :
_port(port), _cacheLineSize(cacheLineSize) { }
@ -101,14 +99,12 @@ class PortProxy
/**
* Read size bytes memory at address and store in p.
*/
virtual void readBlob(Addr addr, uint8_t* p, int size) const
{ blobHelper(addr, p, size, MemCmd::ReadReq); }
virtual void readBlob(Addr addr, uint8_t* p, int size) const;
/**
* Write size bytes from p to address.
*/
virtual void writeBlob(Addr addr, uint8_t* p, int size) const
{ blobHelper(addr, p, size, MemCmd::WriteReq); }
virtual void writeBlob(Addr addr, const uint8_t* p, int size) const;
/**
* Fill size bytes starting at addr with byte value val.

View file

@ -90,7 +90,8 @@ SETranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size) const
bool
SETranslatingPortProxy::tryWriteBlob(Addr addr, uint8_t *p, int size) const
SETranslatingPortProxy::tryWriteBlob(Addr addr, const uint8_t *p,
int size) const
{
int prevSize = 0;
@ -121,7 +122,7 @@ SETranslatingPortProxy::tryWriteBlob(Addr addr, uint8_t *p, int size) const
void
SETranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size) const
SETranslatingPortProxy::writeBlob(Addr addr, const uint8_t *p, int size) const
{
if (!tryWriteBlob(addr, p, size))
fatal("writeBlob(0x%x, ...) failed", addr);

View file

@ -84,13 +84,13 @@ class SETranslatingPortProxy : public PortProxy
virtual ~SETranslatingPortProxy();
bool tryReadBlob(Addr addr, uint8_t *p, int size) const;
bool tryWriteBlob(Addr addr, uint8_t *p, int size) const;
bool tryWriteBlob(Addr addr, const uint8_t *p, int size) const;
bool tryMemsetBlob(Addr addr, uint8_t val, int size) const;
bool tryWriteString(Addr addr, const char *str) const;
bool tryReadString(std::string &str, Addr addr) const;
virtual void readBlob(Addr addr, uint8_t *p, int size) const;
virtual void writeBlob(Addr addr, uint8_t *p, int size) const;
virtual void writeBlob(Addr addr, const uint8_t *p, int size) const;
virtual void memsetBlob(Addr addr, uint8_t val, int size) const;
void writeString(Addr addr, const char *str) const;