112641Sgiacomo.travaglini@arm.com/* 212641Sgiacomo.travaglini@arm.com * Copyright (c) 2011,2017-2018 ARM Limited 312641Sgiacomo.travaglini@arm.com * All rights reserved 412641Sgiacomo.travaglini@arm.com * 512641Sgiacomo.travaglini@arm.com * The license below extends only to copyright in the software and shall 612641Sgiacomo.travaglini@arm.com * not be construed as granting a license to any other intellectual 712641Sgiacomo.travaglini@arm.com * property including but not limited to intellectual property relating 812641Sgiacomo.travaglini@arm.com * to a hardware implementation of the functionality of the software 912641Sgiacomo.travaglini@arm.com * licensed hereunder. You may use the software subject to the license 1012641Sgiacomo.travaglini@arm.com * terms below provided that you ensure that this notice is replicated 1112641Sgiacomo.travaglini@arm.com * unmodified and in its entirety in all distributions of the software, 1212641Sgiacomo.travaglini@arm.com * modified or unmodified, in source code or in binary form. 1312641Sgiacomo.travaglini@arm.com * 1412641Sgiacomo.travaglini@arm.com * Redistribution and use in source and binary forms, with or without 1512641Sgiacomo.travaglini@arm.com * modification, are permitted provided that the following conditions are 1612641Sgiacomo.travaglini@arm.com * met: redistributions of source code must retain the above copyright 1712641Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer; 1812641Sgiacomo.travaglini@arm.com * redistributions in binary form must reproduce the above copyright 1912641Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer in the 2012641Sgiacomo.travaglini@arm.com * documentation and/or other materials provided with the distribution; 2112641Sgiacomo.travaglini@arm.com * neither the name of the copyright holders nor the names of its 2212641Sgiacomo.travaglini@arm.com * contributors may be used to endorse or promote products derived from 2312641Sgiacomo.travaglini@arm.com * this software without specific prior written permission. 2412641Sgiacomo.travaglini@arm.com * 2512641Sgiacomo.travaglini@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2612641Sgiacomo.travaglini@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2712641Sgiacomo.travaglini@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2812641Sgiacomo.travaglini@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2912641Sgiacomo.travaglini@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3012641Sgiacomo.travaglini@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3112641Sgiacomo.travaglini@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3212641Sgiacomo.travaglini@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3312641Sgiacomo.travaglini@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3412641Sgiacomo.travaglini@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3512641Sgiacomo.travaglini@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3612641Sgiacomo.travaglini@arm.com * 3712641Sgiacomo.travaglini@arm.com * Authors: Giacomo Gabrielli 3812641Sgiacomo.travaglini@arm.com */ 3912641Sgiacomo.travaglini@arm.com 4012641Sgiacomo.travaglini@arm.com/** 4112641Sgiacomo.travaglini@arm.com * @file This module implements a bridge between TARMAC traces, as generated by 4212641Sgiacomo.travaglini@arm.com * other models, and gem5 (AtomicCPU model). Its goal is to detect possible 4312641Sgiacomo.travaglini@arm.com * inconsistencies between the two models as soon as they occur. The module 4412641Sgiacomo.travaglini@arm.com * takes a TARMAC trace as input, which is used to compare the architectural 4512641Sgiacomo.travaglini@arm.com * state of the two models after each simulated instruction. 4612641Sgiacomo.travaglini@arm.com */ 4712641Sgiacomo.travaglini@arm.com 4812641Sgiacomo.travaglini@arm.com#ifndef __ARCH_ARM_TRACERS_TARMAC_PARSER_HH__ 4912641Sgiacomo.travaglini@arm.com#define __ARCH_ARM_TRACERS_TARMAC_PARSER_HH__ 5012641Sgiacomo.travaglini@arm.com 5112641Sgiacomo.travaglini@arm.com#include <fstream> 5212641Sgiacomo.travaglini@arm.com#include <unordered_map> 5312641Sgiacomo.travaglini@arm.com 5412641Sgiacomo.travaglini@arm.com#include "arch/arm/registers.hh" 5512641Sgiacomo.travaglini@arm.com#include "base/trace.hh" 5612641Sgiacomo.travaglini@arm.com#include "base/types.hh" 5712641Sgiacomo.travaglini@arm.com#include "cpu/static_inst.hh" 5812641Sgiacomo.travaglini@arm.com#include "cpu/thread_context.hh" 5912641Sgiacomo.travaglini@arm.com#include "mem/request.hh" 6012641Sgiacomo.travaglini@arm.com#include "params/TarmacParser.hh" 6112641Sgiacomo.travaglini@arm.com#include "sim/insttracer.hh" 6212641Sgiacomo.travaglini@arm.com#include "tarmac_base.hh" 6312641Sgiacomo.travaglini@arm.com 6412641Sgiacomo.travaglini@arm.comnamespace Trace { 6512641Sgiacomo.travaglini@arm.com 6612641Sgiacomo.travaglini@arm.comclass TarmacParserRecord : public TarmacBaseRecord 6712641Sgiacomo.travaglini@arm.com{ 6812641Sgiacomo.travaglini@arm.com public: 6912641Sgiacomo.travaglini@arm.com /** 7012641Sgiacomo.travaglini@arm.com * Event triggered to check the value of the destination registers. Needed 7112641Sgiacomo.travaglini@arm.com * to handle some cases where registers are modified after the trace record 7212641Sgiacomo.travaglini@arm.com * has been dumped. E.g., the SVC instruction updates the CPSR and SPSR as 7312641Sgiacomo.travaglini@arm.com * part of the fault handling routine. 7412641Sgiacomo.travaglini@arm.com */ 7512641Sgiacomo.travaglini@arm.com struct TarmacParserRecordEvent: public Event 7612641Sgiacomo.travaglini@arm.com { 7712641Sgiacomo.travaglini@arm.com /** 7812641Sgiacomo.travaglini@arm.com * Reference to the TARMAC trace object to which this record belongs. 7912641Sgiacomo.travaglini@arm.com */ 8012641Sgiacomo.travaglini@arm.com TarmacParser& parent; 8112641Sgiacomo.travaglini@arm.com /** Current thread context. */ 8212641Sgiacomo.travaglini@arm.com ThreadContext* thread; 8312641Sgiacomo.travaglini@arm.com /** Current instruction. */ 8412641Sgiacomo.travaglini@arm.com const StaticInstPtr inst; 8512641Sgiacomo.travaglini@arm.com /** PC of the current instruction. */ 8613915Sgabeblack@google.com ArmISA::PCState pc; 8712641Sgiacomo.travaglini@arm.com /** True if a mismatch has been detected for this instruction. */ 8812641Sgiacomo.travaglini@arm.com bool mismatch; 8912641Sgiacomo.travaglini@arm.com /** 9012641Sgiacomo.travaglini@arm.com * True if a mismatch has been detected for this instruction on PC or 9112641Sgiacomo.travaglini@arm.com * opcode. 9212641Sgiacomo.travaglini@arm.com */ 9312641Sgiacomo.travaglini@arm.com bool mismatchOnPcOrOpcode; 9412641Sgiacomo.travaglini@arm.com 9512641Sgiacomo.travaglini@arm.com TarmacParserRecordEvent(TarmacParser& _parent, 9612641Sgiacomo.travaglini@arm.com ThreadContext *_thread, 9712641Sgiacomo.travaglini@arm.com const StaticInstPtr _inst, 9813915Sgabeblack@google.com ArmISA::PCState _pc, 9912641Sgiacomo.travaglini@arm.com bool _mismatch, 10012641Sgiacomo.travaglini@arm.com bool _mismatch_on_pc_or_opcode) : 10112641Sgiacomo.travaglini@arm.com parent(_parent), thread(_thread), inst(_inst), pc(_pc), 10212641Sgiacomo.travaglini@arm.com mismatch(_mismatch), 10312641Sgiacomo.travaglini@arm.com mismatchOnPcOrOpcode(_mismatch_on_pc_or_opcode) 10412641Sgiacomo.travaglini@arm.com { 10512641Sgiacomo.travaglini@arm.com } 10612641Sgiacomo.travaglini@arm.com 10712641Sgiacomo.travaglini@arm.com void process(); 10812641Sgiacomo.travaglini@arm.com const char *description() const; 10912641Sgiacomo.travaglini@arm.com }; 11012641Sgiacomo.travaglini@arm.com 11112641Sgiacomo.travaglini@arm.com struct ParserInstEntry : public InstEntry 11212641Sgiacomo.travaglini@arm.com { 11312641Sgiacomo.travaglini@arm.com public: 11412641Sgiacomo.travaglini@arm.com uint64_t seq_num; 11512641Sgiacomo.travaglini@arm.com }; 11612641Sgiacomo.travaglini@arm.com 11712641Sgiacomo.travaglini@arm.com struct ParserRegEntry : public RegEntry 11812641Sgiacomo.travaglini@arm.com { 11912641Sgiacomo.travaglini@arm.com public: 12012641Sgiacomo.travaglini@arm.com char repr[16]; 12112641Sgiacomo.travaglini@arm.com }; 12212641Sgiacomo.travaglini@arm.com 12312641Sgiacomo.travaglini@arm.com struct ParserMemEntry : public MemEntry 12412641Sgiacomo.travaglini@arm.com { }; 12512641Sgiacomo.travaglini@arm.com 12612641Sgiacomo.travaglini@arm.com static const int MaxLineLength = 256; 12712641Sgiacomo.travaglini@arm.com 12812641Sgiacomo.travaglini@arm.com /** 12912641Sgiacomo.travaglini@arm.com * Print a mismatch header containing the instruction fields as reported 13012641Sgiacomo.travaglini@arm.com * by gem5. 13112641Sgiacomo.travaglini@arm.com */ 13212641Sgiacomo.travaglini@arm.com static void printMismatchHeader(const StaticInstPtr inst, 13313915Sgabeblack@google.com ArmISA::PCState pc); 13412641Sgiacomo.travaglini@arm.com 13512641Sgiacomo.travaglini@arm.com TarmacParserRecord(Tick _when, ThreadContext *_thread, 13613915Sgabeblack@google.com const StaticInstPtr _staticInst, ArmISA::PCState _pc, 13712641Sgiacomo.travaglini@arm.com TarmacParser& _parent, 13812641Sgiacomo.travaglini@arm.com const StaticInstPtr _macroStaticInst = NULL); 13912641Sgiacomo.travaglini@arm.com 14012641Sgiacomo.travaglini@arm.com void dump() override; 14112641Sgiacomo.travaglini@arm.com 14212641Sgiacomo.travaglini@arm.com /** 14312641Sgiacomo.travaglini@arm.com * Performs a memory access to read the value written by a previous write. 14412641Sgiacomo.travaglini@arm.com * @return False if the result of the memory access should be ignored 14512641Sgiacomo.travaglini@arm.com * (faulty memory access, etc.). 14612641Sgiacomo.travaglini@arm.com */ 14712641Sgiacomo.travaglini@arm.com bool readMemNoEffect(Addr addr, uint8_t *data, unsigned size, 14812641Sgiacomo.travaglini@arm.com unsigned flags); 14912641Sgiacomo.travaglini@arm.com 15012641Sgiacomo.travaglini@arm.com private: 15112641Sgiacomo.travaglini@arm.com /** 15212641Sgiacomo.travaglini@arm.com * Advances the TARMAC trace up to the next instruction, 15312641Sgiacomo.travaglini@arm.com * register, or memory access record. The collected data is stored 15412641Sgiacomo.travaglini@arm.com * in one of {inst/reg/mem}_record. 15512641Sgiacomo.travaglini@arm.com * @return False if EOF is reached. 15612641Sgiacomo.travaglini@arm.com */ 15712641Sgiacomo.travaglini@arm.com bool advanceTrace(); 15812641Sgiacomo.travaglini@arm.com 15912641Sgiacomo.travaglini@arm.com /** Returns the string representation of an instruction set state. */ 16012641Sgiacomo.travaglini@arm.com const char *iSetStateToStr(ISetState isetstate) const; 16112641Sgiacomo.travaglini@arm.com 16212641Sgiacomo.travaglini@arm.com /** Buffer for instruction trace records. */ 16312641Sgiacomo.travaglini@arm.com static ParserInstEntry instRecord; 16412641Sgiacomo.travaglini@arm.com 16512641Sgiacomo.travaglini@arm.com /** Buffer for register trace records. */ 16612641Sgiacomo.travaglini@arm.com static ParserRegEntry regRecord; 16712641Sgiacomo.travaglini@arm.com 16812641Sgiacomo.travaglini@arm.com /** Buffer for memory access trace records (stores only). */ 16912641Sgiacomo.travaglini@arm.com static ParserMemEntry memRecord; 17012641Sgiacomo.travaglini@arm.com 17112641Sgiacomo.travaglini@arm.com /** Type of last parsed record. */ 17212641Sgiacomo.travaglini@arm.com static TarmacRecordType currRecordType; 17312641Sgiacomo.travaglini@arm.com 17412641Sgiacomo.travaglini@arm.com /** Buffer used for trace file parsing. */ 17512641Sgiacomo.travaglini@arm.com static char buf[MaxLineLength]; 17612641Sgiacomo.travaglini@arm.com 17712641Sgiacomo.travaglini@arm.com /** List of records of destination registers. */ 17812641Sgiacomo.travaglini@arm.com static std::list<ParserRegEntry> destRegRecords; 17912641Sgiacomo.travaglini@arm.com 18012641Sgiacomo.travaglini@arm.com /** Map from misc. register names to indexes. */ 18112641Sgiacomo.travaglini@arm.com using MiscRegMap = std::unordered_map<std::string, RegIndex>; 18212641Sgiacomo.travaglini@arm.com static MiscRegMap miscRegMap; 18312641Sgiacomo.travaglini@arm.com 18412641Sgiacomo.travaglini@arm.com /** 18512641Sgiacomo.travaglini@arm.com * True if a TARMAC instruction record has already been parsed for this 18612641Sgiacomo.travaglini@arm.com * instruction. 18712641Sgiacomo.travaglini@arm.com */ 18812641Sgiacomo.travaglini@arm.com bool parsingStarted; 18912641Sgiacomo.travaglini@arm.com 19012641Sgiacomo.travaglini@arm.com /** True if a mismatch has been detected for this instruction. */ 19112641Sgiacomo.travaglini@arm.com bool mismatch; 19212641Sgiacomo.travaglini@arm.com 19312641Sgiacomo.travaglini@arm.com /** 19412641Sgiacomo.travaglini@arm.com * True if a mismatch has been detected for this instruction on PC or 19512641Sgiacomo.travaglini@arm.com * opcode. 19612641Sgiacomo.travaglini@arm.com */ 19712641Sgiacomo.travaglini@arm.com bool mismatchOnPcOrOpcode; 19812641Sgiacomo.travaglini@arm.com 19912641Sgiacomo.travaglini@arm.com /** Request for memory write checks. */ 20012749Sgiacomo.travaglini@arm.com RequestPtr memReq; 20112641Sgiacomo.travaglini@arm.com 20212641Sgiacomo.travaglini@arm.com protected: 20312641Sgiacomo.travaglini@arm.com TarmacParser& parent; 20412641Sgiacomo.travaglini@arm.com}; 20512641Sgiacomo.travaglini@arm.com 20612641Sgiacomo.travaglini@arm.com/** 20712641Sgiacomo.travaglini@arm.com * Tarmac Parser: this tracer parses an existing Tarmac trace and it 20812641Sgiacomo.travaglini@arm.com * diffs it with gem5 simulation status, comparing results and 20912641Sgiacomo.travaglini@arm.com * reporting architectural mismatches if any. 21012641Sgiacomo.travaglini@arm.com */ 21112641Sgiacomo.travaglini@arm.comclass TarmacParser : public InstTracer 21212641Sgiacomo.travaglini@arm.com{ 21312641Sgiacomo.travaglini@arm.com friend class TarmacParserRecord; 21412641Sgiacomo.travaglini@arm.com 21512641Sgiacomo.travaglini@arm.com public: 21612641Sgiacomo.travaglini@arm.com typedef TarmacParserParams Params; 21712641Sgiacomo.travaglini@arm.com 21812641Sgiacomo.travaglini@arm.com TarmacParser(const Params *p) : InstTracer(p), startPc(p->start_pc), 21912641Sgiacomo.travaglini@arm.com exitOnDiff(p->exit_on_diff), 22012641Sgiacomo.travaglini@arm.com exitOnInsnDiff(p->exit_on_insn_diff), 22112641Sgiacomo.travaglini@arm.com memWrCheck(p->mem_wr_check), 22212641Sgiacomo.travaglini@arm.com ignoredAddrRange(p->ignore_mem_addr), 22312641Sgiacomo.travaglini@arm.com cpuId(p->cpu_id), 22412641Sgiacomo.travaglini@arm.com macroopInProgress(false) 22512641Sgiacomo.travaglini@arm.com { 22612641Sgiacomo.travaglini@arm.com assert(!(exitOnDiff && exitOnInsnDiff)); 22712641Sgiacomo.travaglini@arm.com 22812641Sgiacomo.travaglini@arm.com trace.open(p->path_to_trace.c_str()); 22912641Sgiacomo.travaglini@arm.com if (startPc == 0x0) { 23012641Sgiacomo.travaglini@arm.com started = true; 23112641Sgiacomo.travaglini@arm.com } else { 23212641Sgiacomo.travaglini@arm.com advanceTraceToStartPc(); 23312641Sgiacomo.travaglini@arm.com started = false; 23412641Sgiacomo.travaglini@arm.com } 23512641Sgiacomo.travaglini@arm.com } 23612641Sgiacomo.travaglini@arm.com 23712641Sgiacomo.travaglini@arm.com virtual ~TarmacParser() 23812641Sgiacomo.travaglini@arm.com { 23912641Sgiacomo.travaglini@arm.com trace.close(); 24012641Sgiacomo.travaglini@arm.com } 24112641Sgiacomo.travaglini@arm.com 24212641Sgiacomo.travaglini@arm.com InstRecord * 24312641Sgiacomo.travaglini@arm.com getInstRecord(Tick when, ThreadContext *tc, const StaticInstPtr staticInst, 24413915Sgabeblack@google.com ArmISA::PCState pc, 24512641Sgiacomo.travaglini@arm.com const StaticInstPtr macroStaticInst = NULL) 24612641Sgiacomo.travaglini@arm.com { 24712641Sgiacomo.travaglini@arm.com if (!started && pc.pc() == startPc) 24812641Sgiacomo.travaglini@arm.com started = true; 24912641Sgiacomo.travaglini@arm.com 25012641Sgiacomo.travaglini@arm.com if (started) 25112641Sgiacomo.travaglini@arm.com return new TarmacParserRecord(when, tc, staticInst, pc, *this, 25212641Sgiacomo.travaglini@arm.com macroStaticInst); 25312641Sgiacomo.travaglini@arm.com else 25412641Sgiacomo.travaglini@arm.com return NULL; 25512641Sgiacomo.travaglini@arm.com } 25612641Sgiacomo.travaglini@arm.com 25712641Sgiacomo.travaglini@arm.com private: 25812641Sgiacomo.travaglini@arm.com /** Helper function to advance the trace up to startPc. */ 25912641Sgiacomo.travaglini@arm.com void advanceTraceToStartPc(); 26012641Sgiacomo.travaglini@arm.com 26112641Sgiacomo.travaglini@arm.com /** TARMAC trace file. */ 26212641Sgiacomo.travaglini@arm.com std::ifstream trace; 26312641Sgiacomo.travaglini@arm.com 26412641Sgiacomo.travaglini@arm.com /** 26512641Sgiacomo.travaglini@arm.com * Tracing starts when the PC gets this value for the first time (ignored 26612641Sgiacomo.travaglini@arm.com * if 0x0). 26712641Sgiacomo.travaglini@arm.com */ 26812641Sgiacomo.travaglini@arm.com Addr startPc; 26912641Sgiacomo.travaglini@arm.com 27012641Sgiacomo.travaglini@arm.com /** 27112641Sgiacomo.travaglini@arm.com * If true, the simulation is stopped as the first mismatch is detected. 27212641Sgiacomo.travaglini@arm.com */ 27312641Sgiacomo.travaglini@arm.com bool exitOnDiff; 27412641Sgiacomo.travaglini@arm.com 27512641Sgiacomo.travaglini@arm.com /** 27612641Sgiacomo.travaglini@arm.com * If true, the simulation is stopped as the first mismatch is detected on 27712641Sgiacomo.travaglini@arm.com * PC or opcode. 27812641Sgiacomo.travaglini@arm.com */ 27912641Sgiacomo.travaglini@arm.com bool exitOnInsnDiff; 28012641Sgiacomo.travaglini@arm.com 28112641Sgiacomo.travaglini@arm.com /** If true, memory write accesses are checked. */ 28212641Sgiacomo.travaglini@arm.com bool memWrCheck; 28312641Sgiacomo.travaglini@arm.com 28412641Sgiacomo.travaglini@arm.com /** Ignored addresses (ignored if empty). */ 28512641Sgiacomo.travaglini@arm.com AddrRange ignoredAddrRange; 28612641Sgiacomo.travaglini@arm.com 28712641Sgiacomo.travaglini@arm.com /** If true, the trace format includes the CPU id. */ 28812641Sgiacomo.travaglini@arm.com bool cpuId; 28912641Sgiacomo.travaglini@arm.com 29012641Sgiacomo.travaglini@arm.com /** True if tracing has started. */ 29112641Sgiacomo.travaglini@arm.com bool started; 29212641Sgiacomo.travaglini@arm.com 29312641Sgiacomo.travaglini@arm.com /** True if a macroop is currently in progress. */ 29412641Sgiacomo.travaglini@arm.com bool macroopInProgress; 29512641Sgiacomo.travaglini@arm.com}; 29612641Sgiacomo.travaglini@arm.com 29712641Sgiacomo.travaglini@arm.com} // namespace Trace 29812641Sgiacomo.travaglini@arm.com 29912641Sgiacomo.travaglini@arm.com#endif // __ARCH_ARM_TRACERS_TARMAC_PARSER_HH__ 300