summaryrefslogtreecommitdiff
path: root/mem/packet.hh
diff options
context:
space:
mode:
authorAli Saidi <saidi@eecs.umich.edu>2006-04-24 19:31:50 -0400
committerAli Saidi <saidi@eecs.umich.edu>2006-04-24 19:31:50 -0400
commit8f8d09538f58d2e56d7f61b595e64bd06cce8484 (patch)
tree1f11c7191ddfdf7d061764a3746f3c030d6b5271 /mem/packet.hh
parent6dc3b2fa395601852cb3efff302229907b1759f8 (diff)
downloadgem5-8f8d09538f58d2e56d7f61b595e64bd06cce8484.tar.xz
Mostly done with all device models for new memory system. Still need to get timing packets working and get sinic working
after merge from head. Checkpointing may need some work now. Endian-happiness still not complete. SConscript: add all devices back into make file base/inet.hh: dev/etherbus.cc: dev/etherbus.hh: dev/etherdump.cc: dev/etherdump.hh: dev/etherint.hh: dev/etherlink.cc: dev/etherlink.hh: dev/etherpkt.cc: dev/etherpkt.hh: dev/ethertap.cc: dev/ethertap.hh: dev/pktfifo.cc: dev/pktfifo.hh: rename PacketPtr EthPacketPtr so it doesn't conflict with the PacketPtr type in the memory system configs/test/fs.py: add nics to fs.py cpu/cpu_exec_context.cc: remove this check, as it's not valid. We may want to add something else back in to make sure that no one can delete the static virtual ports in the exec context cpu/simple/cpu.cc: cpu/simple/cpu.hh: dev/alpha_console.cc: dev/ide_ctrl.cc: use new methods for accessing packet data dev/ide_disk.cc: add some more dprintfs dev/io_device.cc: delete packets when we are done with them. Update for new packet methods to access data dev/isa_fake.cc: dev/pciconfigall.cc: dev/tsunami_cchip.cc: dev/tsunami_io.cc: dev/tsunami_pchip.cc: dev/uart8250.cc: dev/uart8250.hh: mem/physical.cc: mem/port.cc: dUpdate for new packet methods to access data dev/ns_gige.cc: Update for new memory system dev/ns_gige.hh: python/m5/objects/Ethernet.py: update for new memory system dev/sinic.cc: dev/sinic.hh: Update for new memory system. Untested as need to merge in head because of kernel driver differences between versions mem/packet.hh: Add methods to access data instead of accessing it directly. --HG-- extra : convert_revision : 223f43876afd404e68337270cd9a5e44d0bf553e
Diffstat (limited to 'mem/packet.hh')
-rw-r--r--mem/packet.hh121
1 files changed, 109 insertions, 12 deletions
diff --git a/mem/packet.hh b/mem/packet.hh
index 79fe0ea06..4329094d5 100644
--- a/mem/packet.hh
+++ b/mem/packet.hh
@@ -76,6 +76,26 @@ class Coherence{};
*/
struct Packet
{
+ private:
+ /** A pointer to the data being transfered. It can be differnt sizes
+ at each level of the heirarchy so it belongs in the packet,
+ not request. This may or may not be populated when a responder recieves
+ the packet. If not populated it memory should be allocated.
+ */
+ PacketDataPtr data;
+
+ /** Is the data pointer set to a value that shouldn't be freed when the
+ * packet is destroyed? */
+ bool staticData;
+ /** The data pointer points to a value that should be freed when the packet
+ * is destroyed. */
+ bool dynamicData;
+ /** the data pointer points to an array (thus delete [] ) needs to be called
+ * on it rather than simply delete.*/
+ bool arrayData;
+
+
+ public:
/** The address of the request, could be virtual or physical (depending on
cache configurations). */
Addr addr;
@@ -95,16 +115,7 @@ struct Packet
void *senderState; // virtual base opaque,
// assert(dynamic_cast<Foo>) etc.
- /** A pointer to the data being transfered. It can be differnt sizes
- at each level of the heirarchy so it belongs in the packet,
- not request.
- This pointer may be NULL! If it isn't null when received by the producer
- of data it refers to memory that has not been dynamically allocated.
- Otherwise the producer should simply allocate dynamic memory to use.
- */
- PacketDataPtr data;
-
- /** Indicates the size of the request. */
+ /** Indicates the size of the request. */
int size;
/** A index of the source of the transaction. */
@@ -130,10 +141,96 @@ struct Packet
short getDest() const { return dest; }
Packet()
- : result(Unknown)
+ : data(NULL), staticData(false), dynamicData(false), arrayData(false),
+ result(Unknown)
{}
- void reset() { result = Unknown; }
+ ~Packet()
+ { deleteData(); }
+
+
+ /** Minimally reset a packet so something like simple cpu can reuse it. */
+ void reset() {
+ result = Unknown;
+ if (dynamicData) {
+ deleteData();
+ dynamicData = false;
+ arrayData = false;
+ }
+ }
+
+ /** Set the data pointer to the following value that should not be freed. */
+ template <typename T>
+ void dataStatic(T *p) {
+ assert(!dynamicData);
+ data = (PacketDataPtr)p;
+ staticData = true;
+ }
+
+ /** Set the data pointer to a value that should have delete [] called on it.
+ */
+ template <typename T>
+ void dataDynamicArray(T *p) {
+ assert(!staticData && !dynamicData);
+ data = (PacketDataPtr)p;
+ dynamicData = true;
+ arrayData = true;
+ }
+
+ /** set the data pointer to a value that should have delete called on it. */
+ template <typename T>
+ void dataDynamic(T *p) {
+ assert(!staticData && !dynamicData);
+ data = (PacketDataPtr)p;
+ dynamicData = true;
+ arrayData = false;
+ }
+
+ /** return the value of what is pointed to in the packet. */
+ template <typename T>
+ T get() {
+ assert(staticData || dynamicData);
+ assert(sizeof(T) <= size);
+ return *(T*)data;
+ }
+
+ /** get a pointer to the data ptr. */
+ template <typename T>
+ T* getPtr() {
+ assert(staticData || dynamicData);
+ return (T*)data;
+ }
+
+
+ /** set the value in the data pointer to v. */
+ template <typename T>
+ void set(T v) {
+ assert(sizeof(T) <= size);
+ *(T*)data = v;
+ }
+
+ /** delete the data pointed to in the data pointer. Ok to call to matter how
+ * data was allocted. */
+ void deleteData() {
+ assert(staticData || dynamicData);
+ if (staticData)
+ return;
+
+ if (arrayData)
+ delete [] data;
+ else
+ delete data;
+ }
+
+ /** If there isn't data in the packet, allocate some. */
+ void allocate() {
+ if (data)
+ return;
+ assert(!staticData);
+ dynamicData = true;
+ arrayData = true;
+ data = new uint8_t[size];
+ }
};
#endif //__MEM_PACKET_HH