112642Sgiacomo.travaglini@arm.com/* 212642Sgiacomo.travaglini@arm.com * Copyright (c) 2017-2018 ARM Limited 312642Sgiacomo.travaglini@arm.com * All rights reserved 412642Sgiacomo.travaglini@arm.com * 512642Sgiacomo.travaglini@arm.com * The license below extends only to copyright in the software and shall 612642Sgiacomo.travaglini@arm.com * not be construed as granting a license to any other intellectual 712642Sgiacomo.travaglini@arm.com * property including but not limited to intellectual property relating 812642Sgiacomo.travaglini@arm.com * to a hardware implementation of the functionality of the software 912642Sgiacomo.travaglini@arm.com * licensed hereunder. You may use the software subject to the license 1012642Sgiacomo.travaglini@arm.com * terms below provided that you ensure that this notice is replicated 1112642Sgiacomo.travaglini@arm.com * unmodified and in its entirety in all distributions of the software, 1212642Sgiacomo.travaglini@arm.com * modified or unmodified, in source code or in binary form. 1312642Sgiacomo.travaglini@arm.com * 1412642Sgiacomo.travaglini@arm.com * Redistribution and use in source and binary forms, with or without 1512642Sgiacomo.travaglini@arm.com * modification, are permitted provided that the following conditions are 1612642Sgiacomo.travaglini@arm.com * met: redistributions of source code must retain the above copyright 1712642Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer; 1812642Sgiacomo.travaglini@arm.com * redistributions in binary form must reproduce the above copyright 1912642Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer in the 2012642Sgiacomo.travaglini@arm.com * documentation and/or other materials provided with the distribution; 2112642Sgiacomo.travaglini@arm.com * neither the name of the copyright holders nor the names of its 2212642Sgiacomo.travaglini@arm.com * contributors may be used to endorse or promote products derived from 2312642Sgiacomo.travaglini@arm.com * this software without specific prior written permission. 2412642Sgiacomo.travaglini@arm.com * 2512642Sgiacomo.travaglini@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2612642Sgiacomo.travaglini@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2712642Sgiacomo.travaglini@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2812642Sgiacomo.travaglini@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2912642Sgiacomo.travaglini@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3012642Sgiacomo.travaglini@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3112642Sgiacomo.travaglini@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3212642Sgiacomo.travaglini@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3312642Sgiacomo.travaglini@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3412642Sgiacomo.travaglini@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3512642Sgiacomo.travaglini@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3612642Sgiacomo.travaglini@arm.com * 3712642Sgiacomo.travaglini@arm.com * Authors: Giacomo Travaglini 3812642Sgiacomo.travaglini@arm.com */ 3912642Sgiacomo.travaglini@arm.com 4012642Sgiacomo.travaglini@arm.com#include "arch/arm/tracers/tarmac_record_v8.hh" 4112642Sgiacomo.travaglini@arm.com 4212642Sgiacomo.travaglini@arm.com#include "arch/arm/insts/static_inst.hh" 4312642Sgiacomo.travaglini@arm.com#include "arch/arm/tlb.hh" 4412642Sgiacomo.travaglini@arm.com#include "arch/arm/tracers/tarmac_tracer.hh" 4512642Sgiacomo.travaglini@arm.com 4612642Sgiacomo.travaglini@arm.comnamespace Trace { 4712642Sgiacomo.travaglini@arm.com 4812642Sgiacomo.travaglini@arm.comTarmacTracerRecordV8::TraceInstEntryV8::TraceInstEntryV8( 4912642Sgiacomo.travaglini@arm.com const TarmacContext& tarmCtx, 5012642Sgiacomo.travaglini@arm.com bool predicate) 5112642Sgiacomo.travaglini@arm.com : TraceInstEntry(tarmCtx, predicate), 5212642Sgiacomo.travaglini@arm.com TraceEntryV8(tarmCtx.tarmacCpuName()), 5312642Sgiacomo.travaglini@arm.com paddr(0), 5412642Sgiacomo.travaglini@arm.com paddrValid(false) 5512642Sgiacomo.travaglini@arm.com{ 5612642Sgiacomo.travaglini@arm.com const auto thread = tarmCtx.thread; 5712642Sgiacomo.travaglini@arm.com 5812642Sgiacomo.travaglini@arm.com // Evaluate physical address 5913915Sgabeblack@google.com ArmISA::TLB* dtb = static_cast<TLB*>(thread->getDTBPtr()); 6012642Sgiacomo.travaglini@arm.com paddrValid = dtb->translateFunctional(thread, addr, paddr); 6112642Sgiacomo.travaglini@arm.com} 6212642Sgiacomo.travaglini@arm.com 6312642Sgiacomo.travaglini@arm.comTarmacTracerRecordV8::TraceMemEntryV8::TraceMemEntryV8( 6412642Sgiacomo.travaglini@arm.com const TarmacContext& tarmCtx, 6512642Sgiacomo.travaglini@arm.com uint8_t _size, Addr _addr, uint64_t _data) 6612642Sgiacomo.travaglini@arm.com : TraceMemEntry(tarmCtx, _size, _addr, _data), 6712642Sgiacomo.travaglini@arm.com TraceEntryV8(tarmCtx.tarmacCpuName()), 6812642Sgiacomo.travaglini@arm.com paddr(_addr) 6912642Sgiacomo.travaglini@arm.com{ 7012642Sgiacomo.travaglini@arm.com const auto thread = tarmCtx.thread; 7112642Sgiacomo.travaglini@arm.com 7212642Sgiacomo.travaglini@arm.com // Evaluate physical address 7313915Sgabeblack@google.com ArmISA::TLB* dtb = static_cast<TLB*>(thread->getDTBPtr()); 7412642Sgiacomo.travaglini@arm.com dtb->translateFunctional(thread, addr, paddr); 7512642Sgiacomo.travaglini@arm.com} 7612642Sgiacomo.travaglini@arm.com 7712642Sgiacomo.travaglini@arm.comTarmacTracerRecordV8::TraceRegEntryV8::TraceRegEntryV8( 7812642Sgiacomo.travaglini@arm.com const TarmacContext& tarmCtx, 7912642Sgiacomo.travaglini@arm.com const RegId& reg) 8012642Sgiacomo.travaglini@arm.com : TraceRegEntry(tarmCtx, reg), 8112642Sgiacomo.travaglini@arm.com TraceEntryV8(tarmCtx.tarmacCpuName()), 8212642Sgiacomo.travaglini@arm.com regWidth(64) 8312642Sgiacomo.travaglini@arm.com{ 8412642Sgiacomo.travaglini@arm.com} 8512642Sgiacomo.travaglini@arm.com 8612642Sgiacomo.travaglini@arm.comvoid 8712642Sgiacomo.travaglini@arm.comTarmacTracerRecordV8::TraceRegEntryV8::updateInt( 8812642Sgiacomo.travaglini@arm.com const TarmacContext& tarmCtx, 8912642Sgiacomo.travaglini@arm.com RegIndex regRelIdx 9012642Sgiacomo.travaglini@arm.com) 9112642Sgiacomo.travaglini@arm.com{ 9212642Sgiacomo.travaglini@arm.com // Do not trace pseudo register accesses: invalid 9312642Sgiacomo.travaglini@arm.com // register entry. 9412642Sgiacomo.travaglini@arm.com if (regRelIdx > NUM_ARCH_INTREGS) { 9512642Sgiacomo.travaglini@arm.com regValid = false; 9612642Sgiacomo.travaglini@arm.com return; 9712642Sgiacomo.travaglini@arm.com } 9812642Sgiacomo.travaglini@arm.com 9912642Sgiacomo.travaglini@arm.com TraceRegEntry::updateInt(tarmCtx, regRelIdx); 10012642Sgiacomo.travaglini@arm.com 10112642Sgiacomo.travaglini@arm.com if ((regRelIdx != PCReg) || (regRelIdx != StackPointerReg) || 10212642Sgiacomo.travaglini@arm.com (regRelIdx != FramePointerReg) || (regRelIdx != ReturnAddressReg)) { 10312642Sgiacomo.travaglini@arm.com 10412642Sgiacomo.travaglini@arm.com const auto* arm_inst = static_cast<const ArmStaticInst*>( 10512642Sgiacomo.travaglini@arm.com tarmCtx.staticInst.get() 10612642Sgiacomo.travaglini@arm.com ); 10712642Sgiacomo.travaglini@arm.com 10812642Sgiacomo.travaglini@arm.com regWidth = (arm_inst->getIntWidth()); 10912642Sgiacomo.travaglini@arm.com if (regWidth == 32) { 11012642Sgiacomo.travaglini@arm.com regName = "W" + std::to_string(regRelIdx); 11112642Sgiacomo.travaglini@arm.com } else { 11212642Sgiacomo.travaglini@arm.com regName = "X" + std::to_string(regRelIdx); 11312642Sgiacomo.travaglini@arm.com } 11412642Sgiacomo.travaglini@arm.com } 11512642Sgiacomo.travaglini@arm.com} 11612642Sgiacomo.travaglini@arm.com 11712642Sgiacomo.travaglini@arm.comvoid 11812642Sgiacomo.travaglini@arm.comTarmacTracerRecordV8::TraceRegEntryV8::updateMisc( 11912642Sgiacomo.travaglini@arm.com const TarmacContext& tarmCtx, 12012642Sgiacomo.travaglini@arm.com RegIndex regRelIdx 12112642Sgiacomo.travaglini@arm.com) 12212642Sgiacomo.travaglini@arm.com{ 12312642Sgiacomo.travaglini@arm.com TraceRegEntry::updateMisc(tarmCtx, regRelIdx); 12412642Sgiacomo.travaglini@arm.com // System registers are 32bit wide 12512642Sgiacomo.travaglini@arm.com regWidth = 32; 12612642Sgiacomo.travaglini@arm.com} 12712642Sgiacomo.travaglini@arm.com 12812642Sgiacomo.travaglini@arm.comvoid 12912642Sgiacomo.travaglini@arm.comTarmacTracerRecordV8::addInstEntry(std::vector<InstPtr>& queue, 13012642Sgiacomo.travaglini@arm.com const TarmacContext& tarmCtx) 13112642Sgiacomo.travaglini@arm.com{ 13212642Sgiacomo.travaglini@arm.com // Generate an instruction entry in the record and 13312642Sgiacomo.travaglini@arm.com // add it to the Instruction Queue 13412642Sgiacomo.travaglini@arm.com queue.push_back( 13512642Sgiacomo.travaglini@arm.com m5::make_unique<TraceInstEntryV8>(tarmCtx, predicate) 13612642Sgiacomo.travaglini@arm.com ); 13712642Sgiacomo.travaglini@arm.com} 13812642Sgiacomo.travaglini@arm.com 13912642Sgiacomo.travaglini@arm.comvoid 14012642Sgiacomo.travaglini@arm.comTarmacTracerRecordV8::addMemEntry(std::vector<MemPtr>& queue, 14112642Sgiacomo.travaglini@arm.com const TarmacContext& tarmCtx) 14212642Sgiacomo.travaglini@arm.com{ 14312642Sgiacomo.travaglini@arm.com // Generate a memory entry in the record if the record 14412642Sgiacomo.travaglini@arm.com // implies a valid memory access, and add it to the 14512642Sgiacomo.travaglini@arm.com // Memory Queue 14612642Sgiacomo.travaglini@arm.com if (getMemValid()) { 14712642Sgiacomo.travaglini@arm.com queue.push_back( 14812642Sgiacomo.travaglini@arm.com m5::make_unique<TraceMemEntryV8>(tarmCtx, 14912642Sgiacomo.travaglini@arm.com static_cast<uint8_t>(getSize()), 15012642Sgiacomo.travaglini@arm.com getAddr(), getIntData()) 15112642Sgiacomo.travaglini@arm.com ); 15212642Sgiacomo.travaglini@arm.com } 15312642Sgiacomo.travaglini@arm.com} 15412642Sgiacomo.travaglini@arm.com 15512642Sgiacomo.travaglini@arm.comvoid 15612642Sgiacomo.travaglini@arm.comTarmacTracerRecordV8::addRegEntry(std::vector<RegPtr>& queue, 15712642Sgiacomo.travaglini@arm.com const TarmacContext& tarmCtx) 15812642Sgiacomo.travaglini@arm.com{ 15912642Sgiacomo.travaglini@arm.com // Generate an entry for every ARM register being 16012642Sgiacomo.travaglini@arm.com // written by the current instruction 16112642Sgiacomo.travaglini@arm.com for (auto reg = 0; reg < staticInst->numDestRegs(); ++reg) { 16212642Sgiacomo.travaglini@arm.com 16312642Sgiacomo.travaglini@arm.com RegId reg_id = staticInst->destRegIdx(reg); 16412642Sgiacomo.travaglini@arm.com 16512642Sgiacomo.travaglini@arm.com // Creating a single register change entry 16612642Sgiacomo.travaglini@arm.com auto single_reg = genRegister<TraceRegEntryV8>(tarmCtx, reg_id); 16712642Sgiacomo.travaglini@arm.com 16812642Sgiacomo.travaglini@arm.com // Copying the entry and adding it to the "list" 16912642Sgiacomo.travaglini@arm.com // of entries to be dumped to trace. 17012642Sgiacomo.travaglini@arm.com queue.push_back( 17112642Sgiacomo.travaglini@arm.com m5::make_unique<TraceRegEntryV8>(single_reg) 17212642Sgiacomo.travaglini@arm.com ); 17312642Sgiacomo.travaglini@arm.com } 17412642Sgiacomo.travaglini@arm.com 17512642Sgiacomo.travaglini@arm.com // Gem5 is treating CPSR flags as separate registers (CC registers), 17612642Sgiacomo.travaglini@arm.com // in contrast with Tarmac specification: we need to merge the gem5 CC 17712642Sgiacomo.travaglini@arm.com // entries altogether with the CPSR register and produce a single entry. 17812642Sgiacomo.travaglini@arm.com mergeCCEntry<TraceRegEntryV8>(queue, tarmCtx); 17912642Sgiacomo.travaglini@arm.com} 18012642Sgiacomo.travaglini@arm.com 18112642Sgiacomo.travaglini@arm.comvoid 18212642Sgiacomo.travaglini@arm.comTarmacTracerRecordV8::TraceInstEntryV8::print( 18312642Sgiacomo.travaglini@arm.com std::ostream& outs, 18412642Sgiacomo.travaglini@arm.com int verbosity, 18512642Sgiacomo.travaglini@arm.com const std::string &prefix) const 18612642Sgiacomo.travaglini@arm.com{ 18712642Sgiacomo.travaglini@arm.com // If there is a valid vaddr->paddr translation, print the 18812642Sgiacomo.travaglini@arm.com // physical address, otherwise print the virtual address only. 18912642Sgiacomo.travaglini@arm.com std::string paddr_str = paddrValid? csprintf(":%012x",paddr) : 19012642Sgiacomo.travaglini@arm.com std::string(); 19112642Sgiacomo.travaglini@arm.com 19212642Sgiacomo.travaglini@arm.com // Pad the opcode. 19312642Sgiacomo.travaglini@arm.com std::string opcode_str = csprintf("%0*x", instSize >> 2, opcode); 19412642Sgiacomo.travaglini@arm.com 19512642Sgiacomo.travaglini@arm.com // Print the instruction record formatted according 19612642Sgiacomo.travaglini@arm.com // to the Tarmac specification 19712642Sgiacomo.travaglini@arm.com ccprintf(outs, "%s clk %s %s (%u) %08x%s %s %s %s_%s : %s\n", 19812642Sgiacomo.travaglini@arm.com curTick(), /* Tick time */ 19912642Sgiacomo.travaglini@arm.com cpuName, /* Cpu name */ 20012642Sgiacomo.travaglini@arm.com taken? "IT" : "IS", /* Instruction taken/skipped */ 20112642Sgiacomo.travaglini@arm.com instCount, /* Instruction count */ 20212642Sgiacomo.travaglini@arm.com addr, /* Instruction virt address */ 20312642Sgiacomo.travaglini@arm.com paddr_str, /* Instruction phys address */ 20412642Sgiacomo.travaglini@arm.com opcode_str, /* Instruction opcode */ 20512642Sgiacomo.travaglini@arm.com iSetStateToStr(isetstate), /* Instruction Set */ 20612642Sgiacomo.travaglini@arm.com opModeToStr(mode), /* Exception level */ 20712642Sgiacomo.travaglini@arm.com secureMode? "s" : "ns", /* Security */ 20812642Sgiacomo.travaglini@arm.com disassemble); /* Instruction disass */ 20912642Sgiacomo.travaglini@arm.com} 21012642Sgiacomo.travaglini@arm.com 21112642Sgiacomo.travaglini@arm.comvoid 21212642Sgiacomo.travaglini@arm.comTarmacTracerRecordV8::TraceMemEntryV8::print( 21312642Sgiacomo.travaglini@arm.com std::ostream& outs, 21412642Sgiacomo.travaglini@arm.com int verbosity, 21512642Sgiacomo.travaglini@arm.com const std::string &prefix) const 21612642Sgiacomo.travaglini@arm.com{ 21712642Sgiacomo.travaglini@arm.com // Print the memory record formatted according 21812642Sgiacomo.travaglini@arm.com // to the Tarmac specification 21912642Sgiacomo.travaglini@arm.com ccprintf(outs, "%s clk %s M%s%d %08x:%012x %0*x\n", 22012642Sgiacomo.travaglini@arm.com curTick(), /* Tick time */ 22112642Sgiacomo.travaglini@arm.com cpuName, /* Cpu name */ 22212642Sgiacomo.travaglini@arm.com loadAccess? "R" : "W", /* Access type */ 22312642Sgiacomo.travaglini@arm.com size, /* Access size */ 22412642Sgiacomo.travaglini@arm.com addr, /* Virt Memory address */ 22512642Sgiacomo.travaglini@arm.com paddr, /* Phys Memory address */ 22612642Sgiacomo.travaglini@arm.com size*2, /* Padding with access size */ 22712642Sgiacomo.travaglini@arm.com data); /* Memory data */ 22812642Sgiacomo.travaglini@arm.com} 22912642Sgiacomo.travaglini@arm.com 23012642Sgiacomo.travaglini@arm.comvoid 23112642Sgiacomo.travaglini@arm.comTarmacTracerRecordV8::TraceRegEntryV8::print( 23212642Sgiacomo.travaglini@arm.com std::ostream& outs, 23312642Sgiacomo.travaglini@arm.com int verbosity, 23412642Sgiacomo.travaglini@arm.com const std::string &prefix) const 23512642Sgiacomo.travaglini@arm.com{ 23612642Sgiacomo.travaglini@arm.com // Print the register record formatted according 23712642Sgiacomo.travaglini@arm.com // to the Tarmac specification 23812642Sgiacomo.travaglini@arm.com if (regValid) { 23912642Sgiacomo.travaglini@arm.com ccprintf(outs, "%s clk %s R %s %0*x\n", 24012642Sgiacomo.travaglini@arm.com curTick(), /* Tick time */ 24112642Sgiacomo.travaglini@arm.com cpuName, /* Cpu name */ 24212642Sgiacomo.travaglini@arm.com regName, /* Register name */ 24312642Sgiacomo.travaglini@arm.com regWidth >> 2, /* Register value padding */ 24412642Sgiacomo.travaglini@arm.com valueLo); /* Register value */ 24512642Sgiacomo.travaglini@arm.com } 24612642Sgiacomo.travaglini@arm.com} 24712642Sgiacomo.travaglini@arm.com 24812642Sgiacomo.travaglini@arm.com} // namespace Trace 249