/******************************************************************************* * Copyright (C) 2017, 2018 MINRES Technologies GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. 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. * * 3. Neither the name of the copyright holder 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 HOLDER 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. * *******************************************************************************/ // clang-format off #include #include #include #include #include #include #include "iss_factory.h" #ifndef WIN32 #include #endif #include "sc_core_adapter_if.h" #include #include #include #include #include #include #include #include // clang-format on #define STR(X) #X #define CREATE_CORE(CN) \ if (type == STR(CN)) { std::tie(cpu, vm) = create_core(backend, gdb_port, hart_id); } else #ifdef HAS_SCV #include #else #include using namespace scv_tr; #endif #ifndef CWR_SYSTEMC #define GET_PROP_VALUE(P) P.get_value() #else #define GET_PROP_VALUE(P) P.getValue() #endif #ifdef _MSC_VER // not #if defined(_WIN32) || defined(_WIN64) because we have strncasecmp in mingw #define strncasecmp _strnicmp #define strcasecmp _stricmp #endif namespace sysc { namespace tgfs { using namespace std; using namespace iss; using namespace logging; using namespace sc_core; namespace { iss::debugger::encoder_decoder encdec; std::array lvl = {{'U', 'S', 'H', 'M'}}; } int cmd_sysc(int argc, char *argv[], debugger::out_func of, debugger::data_func df, debugger::target_adapter_if *tgt_adapter) { if (argc > 1) { if (strcasecmp(argv[1], "print_time") == 0) { std::string t = sc_time_stamp().to_string(); of(t.c_str()); std::array buf; encdec.enc_string(t.c_str(), buf.data(), 63); df(buf.data()); return Ok; } else if (strcasecmp(argv[1], "break") == 0) { sc_time t; if (argc == 4) { t = scc::parse_from_string(argv[2], argv[3]); } else if (argc == 3) { t = scc::parse_from_string(argv[2]); } else return Err; // no check needed as it is only called if debug server is active tgt_adapter->add_break_condition([t]() -> unsigned { SCCTRACE() << "Checking condition at " << sc_time_stamp(); return sc_time_stamp() >= t ? std::numeric_limits::max() : 0; }); return Ok; } return Err; } return Err; } using cpu_ptr = std::unique_ptr; using vm_ptr= std::unique_ptr; class core_wrapper { public: core_wrapper(core_complex *owner) : owner(owner) { } void reset(uint64_t addr){vm->reset(addr);} inline void start(){vm->start();} inline std::pair load_file(std::string const& name){ iss::arch_if* cc = cpu->get_arch_if(); return cc->load_file(name);}; std::function get_mode; std::function get_state; std::function get_interrupt_execution; std::function set_interrupt_execution; std::function local_irq; void create_cpu(std::string const& type, std::string const& backend, unsigned gdb_port, uint32_t hart_id){ auto & f = sysc::iss_factory::instance(); if(type.size()==0 || type == "?") { std::cout<<"Available cores: "<(cpu.get()); sc_cpu_if->set_mhartid(hart_id); get_mode = [sc_cpu_if]() { return sc_cpu_if->get_mode(); }; get_state = [sc_cpu_if]() { return sc_cpu_if->get_state(); }; get_interrupt_execution = [sc_cpu_if]() { return sc_cpu_if->get_interrupt_execution(); }; set_interrupt_execution = [sc_cpu_if](bool b) { return sc_cpu_if->set_interrupt_execution(b); }; local_irq = [sc_cpu_if](short s, bool b) { return sc_cpu_if->local_irq(s, b); }; auto *srv = debugger::server::get(); if (srv) tgt_adapter = srv->get_target(); if (tgt_adapter) tgt_adapter->add_custom_command( {"sysc", [this](int argc, char *argv[], debugger::out_func of, debugger::data_func df) -> int { return cmd_sysc(argc, argv, of, df, tgt_adapter); }, "SystemC sub-commands: break