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