CacheRecorder.cc revision 11025:4872dbdea907
12381SN/A/*
211600Sandreas.hansson@arm.com * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood
38949Sandreas.hansson@arm.com * Copyright (c) 2010 Advanced Micro Devices, Inc.
48949Sandreas.hansson@arm.com * All rights reserved.
58949Sandreas.hansson@arm.com *
68949Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
78949Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
88949Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
98949Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
108949Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
118949Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
128949Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
138949Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
142592SN/A * contributors may be used to endorse or promote products derived from
1510975Sdavid.hashe@amd.com * this software without specific prior written permission.
162381SN/A *
172381SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182381SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232381SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272381SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282381SN/A */
292381SN/A
302381SN/A#include "debug/RubyCacheTrace.hh"
312381SN/A#include "mem/ruby/system/CacheRecorder.hh"
322381SN/A#include "mem/ruby/system/Sequencer.hh"
332381SN/A#include "mem/ruby/system/System.hh"
342381SN/A
352381SN/Ausing namespace std;
362381SN/A
372381SN/Avoid
382381SN/ATraceRecord::print(ostream& out) const
392381SN/A{
402665Ssaidi@eecs.umich.edu    out << "[TraceRecord: Node, " << m_cntrl_id << ", "
412665Ssaidi@eecs.umich.edu        << m_data_address << ", " << m_pc_address << ", "
422665Ssaidi@eecs.umich.edu        << m_type << ", Time: " << m_time << "]";
432665Ssaidi@eecs.umich.edu}
449031Sandreas.hansson@arm.com
452381SN/ACacheRecorder::CacheRecorder()
462381SN/A    : m_uncompressed_trace(NULL),
472381SN/A      m_uncompressed_trace_size(0),
482381SN/A      m_block_size_bytes(RubySystem::getBlockSizeBytes())
492662Sstever@eecs.umich.edu{
502381SN/A}
512381SN/A
522381SN/ACacheRecorder::CacheRecorder(uint8_t* uncompressed_trace,
532381SN/A                             uint64_t uncompressed_trace_size,
542381SN/A                             std::vector<Sequencer*>& seq_map,
558229Snate@binkert.org                             uint64_t block_size_bytes)
563348Sbinkertn@umich.edu    : m_uncompressed_trace(uncompressed_trace),
573348Sbinkertn@umich.edu      m_uncompressed_trace_size(uncompressed_trace_size),
583348Sbinkertn@umich.edu      m_seq_map(seq_map),  m_bytes_read(0), m_records_read(0),
595735Snate@binkert.org      m_records_flushed(0), m_block_size_bytes(block_size_bytes)
604024Sbinkertn@umich.edu{
615735Snate@binkert.org    if (m_uncompressed_trace != NULL) {
6212334Sgabeblack@google.com        if (m_block_size_bytes < RubySystem::getBlockSizeBytes()) {
635314Sstever@gmail.com            // Block sizes larger than when the trace was recorded are not
646216Snate@binkert.org            // supported, as we cannot reliably turn accesses to smaller blocks
652392SN/A            // into larger ones.
664167Sbinkertn@umich.edu            panic("Recorded cache block size (%d) < current block size (%d) !!",
672394SN/A                    m_block_size_bytes, RubySystem::getBlockSizeBytes());
688737Skoansin.tan@gmail.com        }
693349Sbinkertn@umich.edu    }
702394SN/A}
712812Srdreslin@umich.edu
722812Srdreslin@umich.eduCacheRecorder::~CacheRecorder()
734022Sstever@eecs.umich.edu{
744022Sstever@eecs.umich.edu    if (m_uncompressed_trace != NULL) {
755735Snate@binkert.org        delete [] m_uncompressed_trace;
765735Snate@binkert.org        m_uncompressed_trace = NULL;
774022Sstever@eecs.umich.edu    }
785735Snate@binkert.org    m_seq_map.clear();
795735Snate@binkert.org}
805735Snate@binkert.org
814022Sstever@eecs.umich.eduvoid
824022Sstever@eecs.umich.eduCacheRecorder::enqueueNextFlushRequest()
834022Sstever@eecs.umich.edu{
844022Sstever@eecs.umich.edu    if (m_records_flushed < m_records.size()) {
854473Sstever@eecs.umich.edu        TraceRecord* rec = m_records[m_records_flushed];
865319Sstever@gmail.com        m_records_flushed++;
874022Sstever@eecs.umich.edu        Request* req = new Request(rec->m_data_address,
884022Sstever@eecs.umich.edu                                   m_block_size_bytes, 0,
8911199Sandreas.hansson@arm.com                                   Request::funcMasterId);
9011199Sandreas.hansson@arm.com        MemCmd::Command requestType = MemCmd::FlushReq;
9110883Sali.jafri@arm.com        Packet *pkt = new Packet(req, requestType);
924022Sstever@eecs.umich.edu
934022Sstever@eecs.umich.edu        Sequencer* m_sequencer_ptr = m_seq_map[rec->m_cntrl_id];
944022Sstever@eecs.umich.edu        assert(m_sequencer_ptr != NULL);
954022Sstever@eecs.umich.edu        m_sequencer_ptr->makeRequest(pkt);
9610886Sandreas.hansson@arm.com
974022Sstever@eecs.umich.edu        DPRINTF(RubyCacheTrace, "Flushing %s\n", *rec);
987465Ssteve.reinhardt@amd.com    } else {
994628Sstever@eecs.umich.edu        DPRINTF(RubyCacheTrace, "Flushed all %d records\n", m_records_flushed);
1007465Ssteve.reinhardt@amd.com    }
1017465Ssteve.reinhardt@amd.com}
1024022Sstever@eecs.umich.edu
1034022Sstever@eecs.umich.eduvoid
10410885Sandreas.hansson@arm.comCacheRecorder::enqueueNextFetchRequest()
10510885Sandreas.hansson@arm.com{
1064626Sstever@eecs.umich.edu    if (m_bytes_read < m_uncompressed_trace_size) {
1074626Sstever@eecs.umich.edu        TraceRecord* traceRecord = (TraceRecord*) (m_uncompressed_trace +
1087669Ssteve.reinhardt@amd.com                                                                m_bytes_read);
1094626Sstever@eecs.umich.edu
1104040Ssaidi@eecs.umich.edu        DPRINTF(RubyCacheTrace, "Issuing %s\n", *traceRecord);
1114040Ssaidi@eecs.umich.edu
1125650Sgblack@eecs.umich.edu        for (int rec_bytes_read = 0; rec_bytes_read < m_block_size_bytes;
1135650Sgblack@eecs.umich.edu                rec_bytes_read += RubySystem::getBlockSizeBytes()) {
11411256Santhony.gutierrez@amd.com            Request* req = nullptr;
11511256Santhony.gutierrez@amd.com            MemCmd::Command requestType;
1164870Sstever@eecs.umich.edu
1174870Sstever@eecs.umich.edu            if (traceRecord->m_type == RubyRequestType_LD) {
1184870Sstever@eecs.umich.edu                requestType = MemCmd::ReadReq;
1194870Sstever@eecs.umich.edu                req = new Request(traceRecord->m_data_address + rec_bytes_read,
1204870Sstever@eecs.umich.edu                    RubySystem::getBlockSizeBytes(), 0, Request::funcMasterId);
1214870Sstever@eecs.umich.edu            }   else if (traceRecord->m_type == RubyRequestType_IFETCH) {
1228436SBrad.Beckmann@amd.com                requestType = MemCmd::ReadReq;
1238436SBrad.Beckmann@amd.com                req = new Request(traceRecord->m_data_address + rec_bytes_read,
1245314Sstever@gmail.com                        RubySystem::getBlockSizeBytes(),
1255314Sstever@gmail.com                        Request::INST_FETCH, Request::funcMasterId);
1268184Ssomayeh@cs.wisc.edu            }   else {
12710886Sandreas.hansson@arm.com                requestType = MemCmd::WriteReq;
12810886Sandreas.hansson@arm.com                req = new Request(traceRecord->m_data_address + rec_bytes_read,
1294022Sstever@eecs.umich.edu                    RubySystem::getBlockSizeBytes(), 0, Request::funcMasterId);
1304022Sstever@eecs.umich.edu            }
1314022Sstever@eecs.umich.edu
1324022Sstever@eecs.umich.edu            Packet *pkt = new Packet(req, requestType);
1335735Snate@binkert.org            pkt->dataStatic(traceRecord->m_data + rec_bytes_read);
1345735Snate@binkert.org
1355735Snate@binkert.org            Sequencer* m_sequencer_ptr = m_seq_map[traceRecord->m_cntrl_id];
1364022Sstever@eecs.umich.edu            assert(m_sequencer_ptr != NULL);
1374022Sstever@eecs.umich.edu            m_sequencer_ptr->makeRequest(pkt);
1384626Sstever@eecs.umich.edu        }
1394626Sstever@eecs.umich.edu
1407465Ssteve.reinhardt@amd.com        m_bytes_read += (sizeof(TraceRecord) + m_block_size_bytes);
1414022Sstever@eecs.umich.edu        m_records_read++;
14211284Sandreas.hansson@arm.com    } else {
1434626Sstever@eecs.umich.edu        DPRINTF(RubyCacheTrace, "Fetched all %d records\n", m_records_read);
1444626Sstever@eecs.umich.edu    }
1454626Sstever@eecs.umich.edu}
14611199Sandreas.hansson@arm.com
1474022Sstever@eecs.umich.eduvoid
1484022Sstever@eecs.umich.eduCacheRecorder::addRecord(int cntrl, Addr data_addr, Addr pc_addr,
1496076Sgblack@eecs.umich.edu                         RubyRequestType type, Tick time, DataBlock& data)
1504626Sstever@eecs.umich.edu{
1514870Sstever@eecs.umich.edu    TraceRecord* rec = (TraceRecord*)malloc(sizeof(TraceRecord) +
1525314Sstever@gmail.com                                            m_block_size_bytes);
1538184Ssomayeh@cs.wisc.edu    rec->m_cntrl_id     = cntrl;
15411600Sandreas.hansson@arm.com    rec->m_time         = time;
1554022Sstever@eecs.umich.edu    rec->m_data_address = data_addr;
1564022Sstever@eecs.umich.edu    rec->m_pc_address   = pc_addr;
1574022Sstever@eecs.umich.edu    rec->m_type         = type;
1585735Snate@binkert.org    memcpy(rec->m_data, data.getData(0, m_block_size_bytes),
1595735Snate@binkert.org           m_block_size_bytes);
1605735Snate@binkert.org
1615735Snate@binkert.org    m_records.push_back(rec);
1625735Snate@binkert.org}
1635735Snate@binkert.org
1645735Snate@binkert.orguint64
1654022Sstever@eecs.umich.eduCacheRecorder::aggregateRecords(uint8_t** buf, uint64 total_size)
1665735Snate@binkert.org{
1675735Snate@binkert.org    std::sort(m_records.begin(), m_records.end(), compareTraceRecords);
1684022Sstever@eecs.umich.edu
1695735Snate@binkert.org    int size = m_records.size();
1704022Sstever@eecs.umich.edu    uint64 current_size = 0;
1714022Sstever@eecs.umich.edu    int record_size = sizeof(TraceRecord) + m_block_size_bytes;
1724022Sstever@eecs.umich.edu
1735735Snate@binkert.org    for (int i = 0; i < size; ++i) {
1744022Sstever@eecs.umich.edu        // Determine if we need to expand the buffer size
1754022Sstever@eecs.umich.edu        if (current_size + record_size > total_size) {
1764022Sstever@eecs.umich.edu            uint8_t* new_buf = new (nothrow) uint8_t[total_size * 2];
1774022Sstever@eecs.umich.edu            if (new_buf == NULL) {
1784022Sstever@eecs.umich.edu                fatal("Unable to allocate buffer of size %s\n",
1794022Sstever@eecs.umich.edu                      total_size * 2);
1805735Snate@binkert.org            }
1815735Snate@binkert.org            total_size = total_size * 2;
1825735Snate@binkert.org            uint8_t* old_buf = *buf;
1834022Sstever@eecs.umich.edu            memcpy(new_buf, old_buf, current_size);
1844022Sstever@eecs.umich.edu            *buf = new_buf;
1854022Sstever@eecs.umich.edu            delete [] old_buf;
1864022Sstever@eecs.umich.edu        }
1874022Sstever@eecs.umich.edu
18810583SCurtis.Dunham@arm.com        // Copy the current record into the buffer
18910583SCurtis.Dunham@arm.com        memcpy(&((*buf)[current_size]), m_records[i], record_size);
19010583SCurtis.Dunham@arm.com        current_size += record_size;
19110583SCurtis.Dunham@arm.com
19210583SCurtis.Dunham@arm.com        free(m_records[i]);
19311284Sandreas.hansson@arm.com        m_records[i] = NULL;
19410583SCurtis.Dunham@arm.com    }
19510583SCurtis.Dunham@arm.com
19611199Sandreas.hansson@arm.com    m_records.clear();
19711600Sandreas.hansson@arm.com    return current_size;
19811199Sandreas.hansson@arm.com}
19911199Sandreas.hansson@arm.com