add SystemC ISS factory
This commit is contained in:
parent
0b719a4b57
commit
957145ca84
|
@ -177,40 +177,32 @@ install(TARGETS tgc-sim
|
||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
if(TARGET scc-sysc)
|
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)
|
project(dbt-rise-tgc_sc VERSION 1.0.0)
|
||||||
|
add_library(${PROJECT_NAME}
|
||||||
add_library(${DBT_RISE_SC_LIB_NAME}
|
|
||||||
src/sysc/core_complex.cpp
|
src/sysc/core_complex.cpp
|
||||||
src/sysc/register_tgc_c.cpp
|
src/sysc/register_tgc_c.cpp
|
||||||
)
|
)
|
||||||
target_include_directories(${DBT_RISE_SC_LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC)
|
||||||
target_compile_definitions(${DBT_RISE_SC_LIB_NAME} PUBLIC WITH_SYSTEMC)
|
target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME})
|
||||||
target_compile_definitions(${DBT_RISE_SC_LIB_NAME} PRIVATE CORE_${CORE_NAME})
|
|
||||||
foreach(F IN LISTS TGC_SOURCES)
|
foreach(F IN LISTS TGC_SOURCES)
|
||||||
if (${F} MATCHES ".*/arch/([^/]*)\.cpp")
|
if (${F} MATCHES ".*/arch/([^/]*)\.cpp")
|
||||||
string(REGEX REPLACE ".*/([^/]*)\.cpp" "\\1" CORE_NAME_LC ${F})
|
string(REGEX REPLACE ".*/([^/]*)\.cpp" "\\1" CORE_NAME_LC ${F})
|
||||||
string(TOUPPER ${CORE_NAME_LC} CORE_NAME)
|
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()
|
endif()
|
||||||
endforeach()
|
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)
|
if(WITH_LLVM)
|
||||||
target_link_libraries(${DBT_RISE_SC_LIB_NAME} PUBLIC ${llvm_libs})
|
target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(LIB_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/sysc/core_complex.h)
|
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}
|
VERSION ${PROJECT_VERSION}
|
||||||
FRAMEWORK FALSE
|
FRAMEWORK FALSE
|
||||||
PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers
|
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
|
EXPORT ${PROJECT_NAME}Targets # for downstream dependencies
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # static lib
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # static lib
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # binaries
|
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)
|
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sysc # headers for mac (note the different component -> different package)
|
||||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # headers
|
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_PROPERTY:${DBT_RISE_SC_LIB_NAME},INTERFACE_INCLUDE_DIRECTORIES>)
|
|
||||||
target_link_libraries(dbt-rise-tgc_sc INTERFACE
|
|
||||||
-Wl,--whole-archive,$<TARGET_FILE:${DBT_RISE_SC_LIB_NAME}>,--no-whole-archive
|
|
||||||
$<TARGET_PROPERTY:${DBT_RISE_SC_LIB_NAME},INTERFACE_LINK_LIBRARIES>
|
|
||||||
scc-sysc)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -321,13 +321,13 @@ std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreD
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace {
|
namespace {
|
||||||
volatile std::array<bool, 2> dummy = {
|
volatile std::array<bool, 2> dummy = {
|
||||||
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|interp", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
core_factory::instance().register_creator<core_factory::CPP>("${coreDef.name.toLowerCase()}|m_p|interp", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
||||||
auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||||
}),
|
}),
|
||||||
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|interp", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
core_factory::instance().register_creator<core_factory::CPP>("${coreDef.name.toLowerCase()}|mu_p|interp", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
||||||
auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
|
|
|
@ -318,13 +318,13 @@ std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreD
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace {
|
namespace {
|
||||||
volatile std::array<bool, 2> dummy = {
|
volatile std::array<bool, 2> dummy = {
|
||||||
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|tcc", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
core_factory::instance().register_creator<core_factory::CPP>("${coreDef.name.toLowerCase()}|m_p|tcc", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
||||||
auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||||
}),
|
}),
|
||||||
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|tcc", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
core_factory::instance().register_creator<core_factory::CPP>("${coreDef.name.toLowerCase()}|mu_p|tcc", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
||||||
auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
|
|
|
@ -80,9 +80,17 @@ class core_factory {
|
||||||
public:
|
public:
|
||||||
static core_factory & instance() { static core_factory bf; return bf; }
|
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<std::string> get_names() {
|
std::vector<std::string> get_names() {
|
||||||
std::vector<std::string> keys{registry.size()};
|
std::vector<std::string> 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_ */
|
#endif /* _ISS_FACTORY_H_ */
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include <iss/debugger/target_adapter_if.h>
|
#include <iss/debugger/target_adapter_if.h>
|
||||||
#include <iss/iss.h>
|
#include <iss/iss.h>
|
||||||
#include <iss/vm_types.h>
|
#include <iss/vm_types.h>
|
||||||
#include <iss/factory.h>
|
#include "iss_factory.h"
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <iss/plugin/loader.h>
|
#include <iss/plugin/loader.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -128,7 +128,9 @@ public:
|
||||||
|
|
||||||
void reset(uint64_t addr){vm->reset(addr);}
|
void reset(uint64_t addr){vm->reset(addr);}
|
||||||
inline void start(){vm->start();}
|
inline void start(){vm->start();}
|
||||||
inline std::pair<uint64_t, bool> load_file(std::string const& name){ return cpu->load_file(name);};
|
inline std::pair<uint64_t, bool> load_file(std::string const& name){
|
||||||
|
iss::arch_if* cc = cpu->get_arch_if();
|
||||||
|
return cc->load_file(name);};
|
||||||
|
|
||||||
std::function<unsigned(void)> get_mode;
|
std::function<unsigned(void)> get_mode;
|
||||||
std::function<uint64_t(void)> get_state;
|
std::function<uint64_t(void)> get_state;
|
||||||
|
@ -137,7 +139,7 @@ public:
|
||||||
std::function<void(short, bool)> local_irq;
|
std::function<void(short, bool)> local_irq;
|
||||||
|
|
||||||
void create_cpu(std::string const& type, std::string const& backend, unsigned gdb_port, uint32_t hart_id){
|
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 == "?") {
|
if(type.size()==0 || type == "?") {
|
||||||
std::cout<<"Available cores: "<<util::join(f.get_names(), ", ")<<std::endl;
|
std::cout<<"Available cores: "<<util::join(f.get_names(), ", ")<<std::endl;
|
||||||
sc_core::sc_stop();
|
sc_core::sc_stop();
|
||||||
|
@ -146,9 +148,9 @@ public:
|
||||||
} else {
|
} else {
|
||||||
auto base_isa = type.substr(0, 5);
|
auto base_isa = type.substr(0, 5);
|
||||||
if(base_isa=="tgc_d" || base_isa=="tgc_e") {
|
if(base_isa=="tgc_d" || base_isa=="tgc_e") {
|
||||||
std::tie(cpu, vm) = f.create(type + "|mu_p_clic_pmp|" + backend, gdb_port);
|
std::tie(cpu, vm) = f.create(type + "|mu_p_clic_pmp|" + backend, gdb_port, owner);
|
||||||
} else {
|
} else {
|
||||||
std::tie(cpu, vm) = f.create(type + "|m_p|" + backend, gdb_port);
|
std::tie(cpu, vm) = f.create(type + "|m_p|" + backend, gdb_port, owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!cpu ){
|
if(!cpu ){
|
||||||
|
@ -157,12 +159,13 @@ public:
|
||||||
if(!vm ){
|
if(!vm ){
|
||||||
SCCFATAL() << "Could not create vm for isa " << type << " and backend " <<backend;
|
SCCFATAL() << "Could not create vm for isa " << type << " and backend " <<backend;
|
||||||
}
|
}
|
||||||
reinterpret_cast<sc_core_adapter_if&>(*cpu).set_mhartid(hart_id);
|
auto* sc_cpu_if = reinterpret_cast<sc_core_adapter_if*>(cpu.get());
|
||||||
get_mode = [this]() { return reinterpret_cast<sc_core_adapter_if&>(*cpu).get_mode(); };
|
sc_cpu_if->set_mhartid(hart_id);
|
||||||
get_state = [this]() { return reinterpret_cast<sc_core_adapter_if&>(*cpu).get_state(); };
|
get_mode = [sc_cpu_if]() { return sc_cpu_if->get_mode(); };
|
||||||
get_interrupt_execution = [this]() { return reinterpret_cast<sc_core_adapter_if&>(*cpu).get_interrupt_execution(); };
|
get_state = [sc_cpu_if]() { return sc_cpu_if->get_state(); };
|
||||||
set_interrupt_execution = [this](bool b) { return reinterpret_cast<sc_core_adapter_if&>(*cpu).set_interrupt_execution(b); };
|
get_interrupt_execution = [sc_cpu_if]() { return sc_cpu_if->get_interrupt_execution(); };
|
||||||
local_irq = [this](short s, bool b) { return reinterpret_cast<sc_core_adapter_if&>(*cpu).local_irq(s, b); };
|
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<debugger::gdb_session>::get();
|
auto *srv = debugger::server<debugger::gdb_session>::get();
|
||||||
if (srv) tgt_adapter = srv->get_target();
|
if (srv) tgt_adapter = srv->get_target();
|
||||||
|
@ -176,7 +179,7 @@ public:
|
||||||
|
|
||||||
core_complex * const owner;
|
core_complex * const owner;
|
||||||
vm_ptr vm{nullptr};
|
vm_ptr vm{nullptr};
|
||||||
cpu_ptr cpu{nullptr};
|
sc_cpu_ptr cpu{nullptr};
|
||||||
iss::debugger::target_adapter_if *tgt_adapter{nullptr};
|
iss::debugger::target_adapter_if *tgt_adapter{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 <iss/iss.h>
|
||||||
|
#include "sc_core_adapter_if.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace sysc {
|
||||||
|
|
||||||
|
using sc_cpu_ptr = std::unique_ptr<sc_core_adapter_if>;
|
||||||
|
using vm_ptr= std::unique_ptr<iss::vm_if>;
|
||||||
|
|
||||||
|
class iss_factory {
|
||||||
|
public:
|
||||||
|
using base_t = std::tuple<sc_cpu_ptr, vm_ptr>;
|
||||||
|
using create_fn = std::function<base_t(unsigned, void*) >;
|
||||||
|
using registry_t = std::unordered_map<std::string, create_fn> ;
|
||||||
|
|
||||||
|
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<std::string> get_names() {
|
||||||
|
std::vector<std::string> keys{registry.size()};
|
||||||
|
std::transform(std::begin(registry), std::end(registry), std::begin(keys), [](std::pair<std::string, create_fn> const& p){
|
||||||
|
return p.first;
|
||||||
|
});
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
registry_t registry;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _ISS_FACTORY_H_ */
|
|
@ -30,7 +30,7 @@
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include <iss/factory.h>
|
#include "iss_factory.h"
|
||||||
#include <iss/arch/tgc_c.h>
|
#include <iss/arch/tgc_c.h>
|
||||||
#include <iss/arch/riscv_hart_m_p.h>
|
#include <iss/arch/riscv_hart_m_p.h>
|
||||||
#include <iss/arch/riscv_hart_mu_p.h>
|
#include <iss/arch/riscv_hart_mu_p.h>
|
||||||
|
@ -39,16 +39,17 @@
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace interp {
|
namespace interp {
|
||||||
|
using namespace sysc;
|
||||||
volatile std::array<bool, 2> tgc_init = {
|
volatile std::array<bool, 2> tgc_init = {
|
||||||
core_factory::instance().register_creator("tgc_c|m_p|interp", [](unsigned gdb_port, void* data) -> std::tuple<cpu_ptr, vm_ptr>{
|
iss_factory::instance().register_creator("tgc_c|m_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
|
||||||
arch::tgc_c* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc_c>>(cc);
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc_c>>(cc);
|
||||||
return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}};
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc_c*>(cpu), gdb_port)}};
|
||||||
}),
|
}),
|
||||||
core_factory::instance().register_creator("tgc_c|mu_p|interp", [](unsigned gdb_port, void* data) -> std::tuple<cpu_ptr, vm_ptr>{
|
iss_factory::instance().register_creator("tgc_c|mu_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
|
||||||
arch::tgc_c* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc_c>>(cc);
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc_c>>(cc);
|
||||||
return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}};
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc_c*>(cpu), gdb_port)}};
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <iss/vm_types.h>
|
#include <iss/vm_types.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace sysc {
|
||||||
template<typename PLAT>
|
template<typename PLAT>
|
||||||
class sc_core_adapter : public PLAT, public sc_core_adapter_if {
|
class sc_core_adapter : public PLAT, public sc_core_adapter_if {
|
||||||
public:
|
public:
|
||||||
|
@ -25,6 +26,8 @@ public:
|
||||||
sc_core_adapter(sysc::tgfs::core_complex *owner)
|
sc_core_adapter(sysc::tgfs::core_complex *owner)
|
||||||
: owner(owner) { }
|
: owner(owner) { }
|
||||||
|
|
||||||
|
iss::arch_if* get_arch_if() override { return this;}
|
||||||
|
|
||||||
void set_mhartid(unsigned id) override { PLAT::set_mhartid(id); }
|
void set_mhartid(unsigned id) override { PLAT::set_mhartid(id); }
|
||||||
|
|
||||||
uint32_t get_mode() override { return this->reg.PRIV; }
|
uint32_t get_mode() override { return this->reg.PRIV; }
|
||||||
|
@ -144,6 +147,5 @@ private:
|
||||||
sysc::tgfs::core_complex *const owner;
|
sysc::tgfs::core_complex *const owner;
|
||||||
sc_core::sc_event wfi_evt;
|
sc_core::sc_event wfi_evt;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _SYSC_SC_CORE_ADAPTER_H_ */
|
#endif /* _SYSC_SC_CORE_ADAPTER_H_ */
|
||||||
|
|
|
@ -16,7 +16,9 @@
|
||||||
#include <iss/vm_types.h>
|
#include <iss/vm_types.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace sysc {
|
||||||
struct sc_core_adapter_if {
|
struct sc_core_adapter_if {
|
||||||
|
virtual iss::arch_if* get_arch_if() = 0;
|
||||||
virtual void set_mhartid(unsigned) = 0;
|
virtual void set_mhartid(unsigned) = 0;
|
||||||
virtual uint32_t get_mode() = 0;
|
virtual uint32_t get_mode() = 0;
|
||||||
virtual uint64_t get_state() = 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 void local_irq(short id, bool value) = 0;
|
||||||
virtual ~sc_core_adapter_if() = default;
|
virtual ~sc_core_adapter_if() = default;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _SYSC_SC_CORE_ADAPTER_IF_H_ */
|
#endif /* _SYSC_SC_CORE_ADAPTER_IF_H_ */
|
||||||
|
|
|
@ -3229,13 +3229,13 @@ namespace {
|
||||||
volatile std::array<bool, 2> dummy = {
|
volatile std::array<bool, 2> dummy = {
|
||||||
core_factory::instance().register_creator("tgc_c|m_p|tcc", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
core_factory::instance().register_creator("tgc_c|m_p|tcc", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::tgc_c>();
|
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::tgc_c>();
|
||||||
auto vm = new tcc::tgc_c::vm_impl<arch::tgc_c>(*cpu, false);
|
auto* vm = new tcc::tgc_c::vm_impl<arch::tgc_c>(*cpu, false);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||||
}),
|
}),
|
||||||
core_factory::instance().register_creator("tgc_c|mu_p|tcc", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
core_factory::instance().register_creator("tgc_c|mu_p|tcc", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::tgc_c>();
|
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::tgc_c>();
|
||||||
auto vm = new tcc::tgc_c::vm_impl<arch::tgc_c>(*cpu, false);
|
auto* vm = new tcc::tgc_c::vm_impl<arch::tgc_c>(*cpu, false);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue