diff --git a/CMakeLists.txt b/CMakeLists.txt index d7977b3..a2a546f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -177,40 +177,32 @@ install(TARGETS tgc-sim # ############################################################################### if(TARGET scc-sysc) - if(BUILD_SHARED_LIBS) - set(DBT_RISE_SC_LIB_NAME dbt-rise-tgc_sc) - else() - set(DBT_RISE_SC_LIB_NAME dbt-rise-tgc_sc_lib) - set(CREATE_INTERFACE_LIB ON) - endif() project(dbt-rise-tgc_sc VERSION 1.0.0) - - add_library(${DBT_RISE_SC_LIB_NAME} + add_library(${PROJECT_NAME} src/sysc/core_complex.cpp src/sysc/register_tgc_c.cpp ) - target_include_directories(${DBT_RISE_SC_LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) - target_compile_definitions(${DBT_RISE_SC_LIB_NAME} PUBLIC WITH_SYSTEMC) - target_compile_definitions(${DBT_RISE_SC_LIB_NAME} PRIVATE CORE_${CORE_NAME}) + target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC) + target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) foreach(F IN LISTS TGC_SOURCES) if (${F} MATCHES ".*/arch/([^/]*)\.cpp") string(REGEX REPLACE ".*/([^/]*)\.cpp" "\\1" CORE_NAME_LC ${F}) string(TOUPPER ${CORE_NAME_LC} CORE_NAME) - target_compile_definitions(${DBT_RISE_SC_LIB_NAME} PRIVATE CORE_${CORE_NAME}) + target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) endif() endforeach() - target_link_libraries(${DBT_RISE_SC_LIB_NAME} PUBLIC dbt-rise-tgc scc-sysc) + target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc scc-sysc) if(WITH_LLVM) - target_link_libraries(${DBT_RISE_SC_LIB_NAME} PUBLIC ${llvm_libs}) + target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs}) endif() set(LIB_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/sysc/core_complex.h) - set_target_properties(${DBT_RISE_SC_LIB_NAME} PROPERTIES + set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} FRAMEWORK FALSE PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers ) - install(TARGETS ${DBT_RISE_SC_LIB_NAME} COMPONENT ${PROJECT_NAME} + install(TARGETS ${PROJECT_NAME} COMPONENT ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Targets # for downstream dependencies ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # static lib RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # binaries @@ -219,14 +211,5 @@ if(TARGET scc-sysc) PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sysc # headers for mac (note the different component -> different package) INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # headers ) - if(CREATE_INTERFACE_LIB) - add_library(dbt-rise-tgc_sc INTERFACE) - target_include_directories(dbt-rise-tgc_sc INTERFACE - $) - target_link_libraries(dbt-rise-tgc_sc INTERFACE - -Wl,--whole-archive,$,--no-whole-archive - $ - scc-sysc) - endif() endif() diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 5d6cc35..5629249 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -321,13 +321,13 @@ std::unique_ptr create(arch::${coreD namespace iss { namespace { volatile std::array dummy = { - core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|interp", [](unsigned port, void*) -> std::tuple{ + core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|interp", [](unsigned port, void*) -> std::tuple{ auto* cpu = new iss::arch::riscv_hart_m_p(); auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl(*cpu, false); if (port != 0) debugger::server::run_server(vm, port); return {cpu_ptr{cpu}, vm_ptr{vm}}; }), - core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|interp", [](unsigned port, void*) -> std::tuple{ + core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|interp", [](unsigned port, void*) -> std::tuple{ auto* cpu = new iss::arch::riscv_hart_mu_p(); auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl(*cpu, false); if (port != 0) debugger::server::run_server(vm, port); diff --git a/gen_input/templates/tcc/CORENAME.cpp.gtl b/gen_input/templates/tcc/CORENAME.cpp.gtl index 1b000ea..2121964 100644 --- a/gen_input/templates/tcc/CORENAME.cpp.gtl +++ b/gen_input/templates/tcc/CORENAME.cpp.gtl @@ -318,13 +318,13 @@ std::unique_ptr create(arch::${coreD namespace iss { namespace { volatile std::array dummy = { - core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|tcc", [](unsigned port, void*) -> std::tuple{ + core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|tcc", [](unsigned port, void*) -> std::tuple{ auto* cpu = new iss::arch::riscv_hart_m_p(); auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl(*cpu, false); if (port != 0) debugger::server::run_server(vm, port); return {cpu_ptr{cpu}, vm_ptr{vm}}; }), - core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|tcc", [](unsigned port, void*) -> std::tuple{ + core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|tcc", [](unsigned port, void*) -> std::tuple{ auto* cpu = new iss::arch::riscv_hart_mu_p(); auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl(*cpu, false); if (port != 0) debugger::server::run_server(vm, port); diff --git a/src/iss/factory.h b/src/iss/factory.h index 7e45838..c24fefb 100644 --- a/src/iss/factory.h +++ b/src/iss/factory.h @@ -80,9 +80,17 @@ class core_factory { public: static core_factory & instance() { static core_factory bf; return bf; } - bool register_creator(const std::string &, create_fn const&); + bool register_creator(const std::string & className, create_fn const& fn) { + registry[className] = fn; + return true; + } - base_t create(const std::string &, unsigned gdb_port=0, void* init_data=nullptr) const; + base_t create(std::string const& className, unsigned gdb_port=0, void* init_data=nullptr) const { + registry_t::const_iterator regEntry = registry.find(className); + if (regEntry != registry.end()) + return regEntry->second(gdb_port, init_data); + return {nullptr, nullptr}; + } std::vector get_names() { std::vector keys{registry.size()}; @@ -93,18 +101,6 @@ public: } }; -inline bool core_factory::register_creator(const std::string & className, create_fn const& fn) { - registry[className] = fn; - return true; -} - -inline core_factory::base_t core_factory::create(const std::string &className, unsigned gdb_port, void* data) const { - registry_t::const_iterator regEntry = registry.find(className); - if (regEntry != registry.end()) - return regEntry->second(gdb_port, data); - return {nullptr, nullptr}; -} - } #endif /* _ISS_FACTORY_H_ */ diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index e3b0433..be25f53 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -37,7 +37,7 @@ #include #include #include -#include +#include "iss_factory.h" #ifndef WIN32 #include #endif @@ -128,7 +128,9 @@ public: void reset(uint64_t addr){vm->reset(addr);} inline void start(){vm->start();} - inline std::pair load_file(std::string const& name){ return cpu->load_file(name);}; + 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; @@ -137,7 +139,7 @@ public: std::function local_irq; void create_cpu(std::string const& type, std::string const& backend, unsigned gdb_port, uint32_t hart_id){ - auto & f = iss::core_factory::instance(); + auto & f = sysc::iss_factory::instance(); if(type.size()==0 || type == "?") { std::cout<<"Available cores: "<(*cpu).set_mhartid(hart_id); - get_mode = [this]() { return reinterpret_cast(*cpu).get_mode(); }; - get_state = [this]() { return reinterpret_cast(*cpu).get_state(); }; - get_interrupt_execution = [this]() { return reinterpret_cast(*cpu).get_interrupt_execution(); }; - set_interrupt_execution = [this](bool b) { return reinterpret_cast(*cpu).set_interrupt_execution(b); }; - local_irq = [this](short s, bool b) { return reinterpret_cast(*cpu).local_irq(s, b); }; + auto* sc_cpu_if = reinterpret_cast(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(); @@ -176,7 +179,7 @@ public: core_complex * const owner; vm_ptr vm{nullptr}; - cpu_ptr cpu{nullptr}; + sc_cpu_ptr cpu{nullptr}; iss::debugger::target_adapter_if *tgt_adapter{nullptr}; }; diff --git a/src/sysc/iss_factory.h b/src/sysc/iss_factory.h new file mode 100644 index 0000000..f29a5b0 --- /dev/null +++ b/src/sysc/iss_factory.h @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (C) 2021 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. + * + *******************************************************************************/ + +#ifndef _ISS_FACTORY_H_ +#define _ISS_FACTORY_H_ + +#include +#include "sc_core_adapter_if.h" +#include +#include +#include +#include +#include +#include + +namespace sysc { + +using sc_cpu_ptr = std::unique_ptr; +using vm_ptr= std::unique_ptr; + +class iss_factory { +public: + using base_t = std::tuple; + using create_fn = std::function; + using registry_t = std::unordered_map ; + + iss_factory() = default; + iss_factory(const iss_factory &) = delete; + iss_factory & operator=(const iss_factory &) = delete; + + static iss_factory & instance() { static iss_factory bf; return bf; } + + bool register_creator(const std::string & className, create_fn const& fn) { + registry[className] = fn; + return true; + } + + base_t create(std::string const& className, unsigned gdb_port=0, void* init_data=nullptr) const { + registry_t::const_iterator regEntry = registry.find(className); + if (regEntry != registry.end()) + return regEntry->second(gdb_port, init_data); + return {nullptr, nullptr}; + } + + std::vector get_names() { + std::vector keys{registry.size()}; + std::transform(std::begin(registry), std::end(registry), std::begin(keys), [](std::pair const& p){ + return p.first; + }); + return keys; + } +private: + registry_t registry; + +}; + +} + +#endif /* _ISS_FACTORY_H_ */ diff --git a/src/sysc/register_tgc_c.cpp b/src/sysc/register_tgc_c.cpp index 1fe4194..efd46b0 100644 --- a/src/sysc/register_tgc_c.cpp +++ b/src/sysc/register_tgc_c.cpp @@ -30,7 +30,7 @@ * *******************************************************************************/ -#include +#include "iss_factory.h" #include #include #include @@ -39,16 +39,17 @@ namespace iss { namespace interp { +using namespace sysc; volatile std::array tgc_init = { - core_factory::instance().register_creator("tgc_c|m_p|interp", [](unsigned gdb_port, void* data) -> std::tuple{ - auto cc = reinterpret_cast(data); - arch::tgc_c* cpu = new sc_core_adapter>(cc); - return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}}; + iss_factory::instance().register_creator("tgc_c|m_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t { + auto* cc = reinterpret_cast(data); + auto* cpu = new sc_core_adapter>(cc); + return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast(cpu), gdb_port)}}; }), - core_factory::instance().register_creator("tgc_c|mu_p|interp", [](unsigned gdb_port, void* data) -> std::tuple{ - auto cc = reinterpret_cast(data); - arch::tgc_c* cpu = new sc_core_adapter>(cc); - return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}}; + iss_factory::instance().register_creator("tgc_c|mu_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t { + auto* cc = reinterpret_cast(data); + auto* cpu = new sc_core_adapter>(cc); + return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast(cpu), gdb_port)}}; }) }; } diff --git a/src/sysc/sc_core_adapter.h b/src/sysc/sc_core_adapter.h index 77c293f..bbd1465 100644 --- a/src/sysc/sc_core_adapter.h +++ b/src/sysc/sc_core_adapter.h @@ -16,6 +16,7 @@ #include #include +namespace sysc { template class sc_core_adapter : public PLAT, public sc_core_adapter_if { public: @@ -25,6 +26,8 @@ public: sc_core_adapter(sysc::tgfs::core_complex *owner) : owner(owner) { } + iss::arch_if* get_arch_if() override { return this;} + void set_mhartid(unsigned id) override { PLAT::set_mhartid(id); } uint32_t get_mode() override { return this->reg.PRIV; } @@ -144,6 +147,5 @@ private: sysc::tgfs::core_complex *const owner; sc_core::sc_event wfi_evt; }; - - +} #endif /* _SYSC_SC_CORE_ADAPTER_H_ */ diff --git a/src/sysc/sc_core_adapter_if.h b/src/sysc/sc_core_adapter_if.h index 5445ee0..05a2c61 100644 --- a/src/sysc/sc_core_adapter_if.h +++ b/src/sysc/sc_core_adapter_if.h @@ -16,7 +16,9 @@ #include #include +namespace sysc { struct sc_core_adapter_if { + virtual iss::arch_if* get_arch_if() = 0; virtual void set_mhartid(unsigned) = 0; virtual uint32_t get_mode() = 0; virtual uint64_t get_state() = 0; @@ -25,6 +27,5 @@ struct sc_core_adapter_if { virtual void local_irq(short id, bool value) = 0; virtual ~sc_core_adapter_if() = default; }; - - +} #endif /* _SYSC_SC_CORE_ADAPTER_IF_H_ */ diff --git a/src/vm/tcc/vm_tgc_c.cpp b/src/vm/tcc/vm_tgc_c.cpp index 371aa95..fee3a87 100644 --- a/src/vm/tcc/vm_tgc_c.cpp +++ b/src/vm/tcc/vm_tgc_c.cpp @@ -3229,13 +3229,13 @@ namespace { volatile std::array dummy = { core_factory::instance().register_creator("tgc_c|m_p|tcc", [](unsigned port, void*) -> std::tuple{ auto* cpu = new iss::arch::riscv_hart_m_p(); - auto vm = new tcc::tgc_c::vm_impl(*cpu, false); + auto* vm = new tcc::tgc_c::vm_impl(*cpu, false); if (port != 0) debugger::server::run_server(vm, port); return {cpu_ptr{cpu}, vm_ptr{vm}}; }), core_factory::instance().register_creator("tgc_c|mu_p|tcc", [](unsigned port, void*) -> std::tuple{ auto* cpu = new iss::arch::riscv_hart_mu_p(); - auto vm = new tcc::tgc_c::vm_impl(*cpu, false); + auto* vm = new tcc::tgc_c::vm_impl(*cpu, false); if (port != 0) debugger::server::run_server(vm, port); return {cpu_ptr{cpu}, vm_ptr{vm}}; })