16145SN/A/*
28683SN/A * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood
38683SN/A * Copyright (c) 2010 Advanced Micro Devices, Inc.
46145SN/A * All rights reserved.
56145SN/A *
66145SN/A * Redistribution and use in source and binary forms, with or without
76145SN/A * modification, are permitted provided that the following conditions are
86145SN/A * met: redistributions of source code must retain the above copyright
96145SN/A * notice, this list of conditions and the following disclaimer;
106145SN/A * redistributions in binary form must reproduce the above copyright
116145SN/A * notice, this list of conditions and the following disclaimer in the
126145SN/A * documentation and/or other materials provided with the distribution;
136145SN/A * neither the name of the copyright holders nor the names of its
146145SN/A * contributors may be used to endorse or promote products derived from
156145SN/A * this software without specific prior written permission.
166145SN/A *
176145SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186145SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196145SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206145SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216145SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226145SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236145SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246145SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256145SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266145SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276145SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286145SN/A */
296145SN/A
306145SN/A/*
317054SN/A * Recording cache requests made to a ruby cache at certain ruby
327054SN/A * time. Also dump the requests to a gziped file.
336145SN/A */
346145SN/A
3512492Sodanrc@yahoo.com.br#ifndef __MEM_RUBY_SYSTEM_CACHERECORDER_HH__
3612492Sodanrc@yahoo.com.br#define __MEM_RUBY_SYSTEM_CACHERECORDER_HH__
376145SN/A
387456SN/A#include <vector>
397002SN/A
4010302Snilay@cs.wisc.edu#include "base/types.hh"
418683SN/A#include "mem/ruby/common/Address.hh"
428683SN/A#include "mem/ruby/common/DataBlock.hh"
438683SN/A#include "mem/ruby/common/TypeDefines.hh"
4414184Sgabeblack@google.com#include "mem/ruby/protocol/RubyRequestType.hh"
456145SN/A
466890SN/Aclass Sequencer;
476145SN/A
488683SN/A/*!
498683SN/A * Class for recording cache contents. Note that the last element of the
508683SN/A * class is an array of length zero. It is used for creating variable
518683SN/A * length object, so that while writing the data to a file one does not
528683SN/A * need to copy the meta data and the actual data separately.
538683SN/A */
548683SN/Aclass TraceRecord {
558683SN/A  public:
568683SN/A    int m_cntrl_id;
5710302Snilay@cs.wisc.edu    Tick m_time;
5811025Snilay@cs.wisc.edu    Addr m_data_address;
5911025Snilay@cs.wisc.edu    Addr m_pc_address;
608683SN/A    RubyRequestType m_type;
618683SN/A    uint8_t m_data[0];
628683SN/A
638683SN/A    void print(std::ostream& out) const;
648683SN/A};
658683SN/A
667054SN/Aclass CacheRecorder
677054SN/A{
687054SN/A  public:
698683SN/A    CacheRecorder();
708683SN/A    ~CacheRecorder();
716145SN/A
728683SN/A    CacheRecorder(uint8_t* uncompressed_trace,
738683SN/A                  uint64_t uncompressed_trace_size,
7410163SN/A                  std::vector<Sequencer*>& SequencerMap,
7510163SN/A                  uint64_t block_size_bytes);
7611025Snilay@cs.wisc.edu    void addRecord(int cntrl, Addr data_addr, Addr pc_addr,
7711025Snilay@cs.wisc.edu                   RubyRequestType type, Tick time, DataBlock& data);
788683SN/A
7911061Snilay@cs.wisc.edu    uint64_t aggregateRecords(uint8_t **data, uint64_t size);
808683SN/A
818683SN/A    /*!
828683SN/A     * Function for flushing the memory contents of the caches to the
838683SN/A     * main memory. It goes through the recorded contents of the caches,
848683SN/A     * and issues flush requests. Except for the first one, a flush request
858683SN/A     * is issued only after the previous one has completed. This currently
868683SN/A     * requires use of MOESI Hammer protocol since only that protocol
878683SN/A     * supports flush requests.
888683SN/A     */
898683SN/A    void enqueueNextFlushRequest();
908683SN/A
918683SN/A    /*!
928683SN/A     * Function for fetching warming up the memory and the caches. It goes
938683SN/A     * through the recorded contents of the caches, as available in the
948683SN/A     * checkpoint and issues fetch requests. Except for the first one, a
958683SN/A     * fetch request is issued only after the previous one has completed.
968683SN/A     * It should be possible to use this with any protocol.
978683SN/A     */
988683SN/A    void enqueueNextFetchRequest();
996145SN/A
1007054SN/A  private:
1017054SN/A    // Private copy constructor and assignment operator
1027054SN/A    CacheRecorder(const CacheRecorder& obj);
1037054SN/A    CacheRecorder& operator=(const CacheRecorder& obj);
1046145SN/A
1058683SN/A    std::vector<TraceRecord*> m_records;
1068683SN/A    uint8_t* m_uncompressed_trace;
1078683SN/A    uint64_t m_uncompressed_trace_size;
1088683SN/A    std::vector<Sequencer*> m_seq_map;
1098683SN/A    uint64_t m_bytes_read;
1108683SN/A    uint64_t m_records_read;
1118683SN/A    uint64_t m_records_flushed;
11210163SN/A    uint64_t m_block_size_bytes;
1136145SN/A};
1146145SN/A
1158683SN/Ainline bool
1168683SN/AcompareTraceRecords(const TraceRecord* n1, const TraceRecord* n2)
1178683SN/A{
1188683SN/A    return n1->m_time > n2->m_time;
1198683SN/A}
1208683SN/A
1217054SN/Ainline std::ostream&
1228683SN/Aoperator<<(std::ostream& out, const TraceRecord& obj)
1236145SN/A{
1247054SN/A    obj.print(out);
1257054SN/A    out << std::flush;
1267054SN/A    return out;
1276145SN/A}
1286145SN/A
12912492Sodanrc@yahoo.com.br#endif //__MEM_RUBY_SYSTEM_CACHERECORDER_HH__
130