diff --git a/src/mem/packet.hh b/src/mem/packet.hh index d6231f48f..2b667d26d 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -767,6 +767,12 @@ class Packet : public Printable } + public: + /** + * @{ + * @name Data accessor mehtods + */ + /** * Set the data pointer to the following value that should not be * freed. Static data allows us to do a single memcpy even if @@ -845,15 +851,50 @@ class Packet : public Printable } /** - * return the value of what is pointed to in the packet. + * Get the data in the packet byte swapped from big endian to + * host endian. + */ + template + T getBE() const; + + /** + * Get the data in the packet byte swapped from little endian to + * host endian. + */ + template + T getLE() const; + + /** + * Get the data in the packet byte swapped from the specified + * endianness. + */ + template + T get(ByteOrder endian) const; + + /** + * Get the data in the packet byte swapped from guest to host + * endian. */ template T get() const; + /** Set the value in the data pointer to v as big endian. */ + template + void setBE(T v); + + /** Set the value in the data pointer to v as little endian. */ + template + void setLE(T v); + /** - * set the value in the data pointer to v. + * Set the value in the data pointer to v using the specified + * endianness. */ template + void set(T v, ByteOrder endian); + + /** Set the value in the data pointer to v as guest endian. */ + template void set(T v); /** @@ -925,6 +966,18 @@ class Packet : public Printable data = new uint8_t[getSize()]; } + /** @} */ + + private: // Private data accessor methods + /** Get the data in the packet without byte swapping. */ + template + T getRaw() const; + + /** Set the value in the data pointer to v without byte swapping. */ + template + void setRaw(T v); + + public: /** * Check a functional request against a memory value stored in * another packet (i.e. an in-transit request or diff --git a/src/mem/packet_access.hh b/src/mem/packet_access.hh index 9e6f1cbb1..1a2db6921 100644 --- a/src/mem/packet_access.hh +++ b/src/mem/packet_access.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2015 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * @@ -27,6 +39,7 @@ * * Authors: Ali Saidi * Nathan Binkert + * Andreas Sandberg */ #include "arch/isa_traits.hh" @@ -37,29 +50,98 @@ #ifndef __MEM_PACKET_ACCESS_HH__ #define __MEM_PACKET_ACCESS_HH__ -// The memory system needs to have an endianness. This is the easiest -// way to deal with it for now. At some point, we will have to remove -// these functions and make the users do their own byte swapping since -// the memory system does not in fact have an endianness. -/** return the value of what is pointed to in the packet. */ template inline T -Packet::get() const +Packet::getRaw() const { assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA)); assert(sizeof(T) <= size); - return TheISA::gtoh(*(T*)data); + return *(T*)data; } -/** set the value in the data pointer to v. */ template inline void -Packet::set(T v) +Packet::setRaw(T v) { assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA)); assert(sizeof(T) <= size); *(T*)data = TheISA::htog(v); } + +template +inline T +Packet::getBE() const +{ + return betoh(getRaw()); +} + +template +inline T +Packet::getLE() const +{ + return letoh(getRaw()); +} + +template +inline T +Packet::get(ByteOrder endian) const +{ + switch (endian) { + case BigEndianByteOrder: + return getBE(); + + case LittleEndianByteOrder: + return getLE(); + + default: + panic("Illegal byte order in Packet::get()\n"); + }; +} + +template +inline T +Packet::get() const +{ + return TheISA::gtoh(getRaw()); +} + +template +inline void +Packet::setBE(T v) +{ + setRaw(htobe(v)); +} + +template +inline void +Packet::setLE(T v) +{ + setRaw(htole(v)); +} + +template +inline void +Packet::set(T v, ByteOrder endian) +{ + switch (endian) { + case BigEndianByteOrder: + return setBE(v); + + case LittleEndianByteOrder: + return setLE(v); + + default: + panic("Illegal byte order in Packet::set()\n"); + }; +} + +template +inline void +Packet::set(T v) +{ + setRaw(TheISA::htog(v)); +} + #endif //__MEM_PACKET_ACCESS_HH__