diff options
Diffstat (limited to 'src/arch/arm/tracers/tarmac_record.hh')
-rw-r--r-- | src/arch/arm/tracers/tarmac_record.hh | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/src/arch/arm/tracers/tarmac_record.hh b/src/arch/arm/tracers/tarmac_record.hh new file mode 100644 index 000000000..f54abf56a --- /dev/null +++ b/src/arch/arm/tracers/tarmac_record.hh @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2017-2018 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Giacomo Travaglini + */ + +/** + * @file: The file contains the informations used to generate records + * for the pre-ARMv8 cores. + */ + +#ifndef __ARCH_ARM_TRACERS_TARMAC_RECORD_HH__ +#define __ARCH_ARM_TRACERS_TARMAC_RECORD_HH__ + +#include "arch/arm/tracers/tarmac_base.hh" +#include "base/printable.hh" +#include "config/the_isa.hh" +#include "cpu/reg_class.hh" +#include "cpu/static_inst.hh" + +namespace Trace { + +class TarmacContext; + +class TarmacTracer; + +/** + * Returns the string representation of the instruction set being + * currently run according to the Tarmac format. + * + * @param isetstate: enum variable (ISetState) specifying an ARM + * instruction set. + * @return instruction set in string format. + */ +std::string +iSetStateToStr(TarmacBaseRecord::ISetState isetstate); + +/** + * Returns the string representation of the ARM Operating Mode + * (CPSR.M[3:0] field) according to the Tarmac format. + * + * @param opMode: ARM operating mode. + * @return operating mode in string format. + */ +std::string +opModeToStr(ArmISA::OperatingMode opMode); + +/** + * TarmacTracer Record: + * Record generated by the TarmacTracer for every executed instruction. + * The record is composed by a set of entries, matching the tracing + * capabilities provided by the Tarmac specifications: + * + * - Instruction Entry + * - Register Entry + * - Memory Entry + */ +class TarmacTracerRecord : public TarmacBaseRecord +{ + public: + /** Instruction Entry */ + struct TraceInstEntry: public InstEntry, Printable + { + TraceInstEntry(const TarmacContext& tarmCtx, bool predicate); + + virtual void print(std::ostream& outs, + int verbosity = 0, + const std::string &prefix = "") const override; + + protected: + /** Number of instructions being traced */ + static uint64_t instCount; + + /** True if instruction is executed in secure mode */ + bool secureMode; + /** + * Instruction size: + * 16 for 16-bit Thumb Instruction + * 32 otherwise (ARM and BigThumb) + */ + uint8_t instSize; + }; + + /** Register Entry */ + struct TraceRegEntry: public RegEntry, Printable + { + public: + TraceRegEntry(const TarmacContext& tarmCtx, const RegId& reg); + + /** + * This updates the register entry using the update table. It is + * a required step after the register entry generation. + * If unupdated, the entry will be marked as invalid. + * The entry update cannot be done automatically at TraceRegEntry + * construction: the entries are extended by consequent Tarmac + * Tracer versions (like V8), and virtual functions should + * be avoided during construction. + */ + void update(const TarmacContext& tarmCtx); + + virtual void print(std::ostream& outs, + int verbosity = 0, + const std::string &prefix = "") const override; + + protected: + /** Register update functions. */ + virtual void + updateMisc(const TarmacContext& tarmCtx, RegIndex regRelIdx); + + virtual void + updateCC(const TarmacContext& tarmCtx, RegIndex regRelIdx); + + virtual void + updateFloat(const TarmacContext& tarmCtx, RegIndex regRelIdx); + + virtual void + updateInt(const TarmacContext& tarmCtx, RegIndex regRelIdx); + + public: + /** True if register entry is valid */ + bool regValid; + /** Register class */ + RegClass regClass; + /** Register arch number */ + RegIndex regRel; + /** Register name to be printed */ + std::string regName; + }; + + /** Memory Entry */ + struct TraceMemEntry: public MemEntry, Printable + { + public: + TraceMemEntry(const TarmacContext& tarmCtx, + uint8_t _size, Addr _addr, uint64_t _data); + + virtual void print(std::ostream& outs, + int verbosity = 0, + const std::string &prefix = "") const override; + + protected: + /** True if memory access is a load */ + bool loadAccess; + }; + + public: + TarmacTracerRecord(Tick _when, ThreadContext *_thread, + const StaticInstPtr _staticInst, TheISA::PCState _pc, + TarmacTracer& _tracer, + const StaticInstPtr _macroStaticInst = NULL); + + virtual void dump() override; + + using InstPtr = std::unique_ptr<TraceInstEntry>; + using MemPtr = std::unique_ptr<TraceMemEntry>; + using RegPtr = std::unique_ptr<TraceRegEntry>; + + protected: + /** Generates an Entry for the executed instruction. */ + virtual void addInstEntry(std::vector<InstPtr>& queue, + const TarmacContext& ptr); + + /** Generates an Entry for every triggered memory access */ + virtual void addMemEntry(std::vector<MemPtr>& queue, + const TarmacContext& ptr); + + /** Generate an Entry for every register being written. */ + virtual void addRegEntry(std::vector<RegPtr>& queue, + const TarmacContext& ptr); + + protected: + /** Generate and update a register entry. */ + template<typename RegEntry> + RegEntry + genRegister(const TarmacContext& tarmCtx, const RegId& reg) + { + RegEntry single_reg(tarmCtx, reg); + single_reg.update(tarmCtx); + + return single_reg; + } + + template<typename RegEntry> + void + mergeCCEntry(std::vector<RegPtr>& queue, const TarmacContext& tarmCtx) + { + // Find all CC Entries and move them at the end of the queue + auto it = std::remove_if( + queue.begin(), queue.end(), + [] (RegPtr& reg) ->bool { return (reg->regClass == CCRegClass); } + ); + + if (it != queue.end()) { + // Remove all CC Entries. + queue.erase(it, queue.end()); + + auto is_cpsr = [] (RegPtr& reg) ->bool + { + return (reg->regClass == MiscRegClass) && + (reg->regRel == ArmISA::MISCREG_CPSR); + }; + + // Looking for the presence of a CPSR register entry. + auto cpsr_it = std::find_if( + queue.begin(), queue.end(), is_cpsr + ); + + // If CPSR entry not present, generate one + if (cpsr_it == queue.end()) { + RegId reg(MiscRegClass, ArmISA::MISCREG_CPSR); + queue.push_back( + m5::make_unique<RegEntry>( + genRegister<RegEntry>(tarmCtx, reg)) + ); + } + } + } + + /** Flush queues to the trace output */ + template<typename Queue> + void flushQueues(Queue& queue); + template<typename Queue, typename... Args> + void flushQueues(Queue& queue, Args & ... args); + + protected: + /** Reference to tracer */ + TarmacTracer& tracer; +}; + +} // namespace Trace + +#endif // __ARCH_ARM_TRACERS_TARMAC_RECORD_HH__ |