Compare commits
	
		
			2 Commits
		
	
	
		
			0b719a4b57
			...
			720236ec3f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 720236ec3f | |||
| 957145ca84 | 
| @@ -10,6 +10,10 @@ find_package(elfio QUIET) | |||||||
| find_package(Boost COMPONENTS coroutine) | find_package(Boost COMPONENTS coroutine) | ||||||
| find_package(jsoncpp) | find_package(jsoncpp) | ||||||
|  |  | ||||||
|  | if(TARGET tcc::tcc) | ||||||
|  |   set(WITH_TCC ON) | ||||||
|  | endif() | ||||||
|  |  | ||||||
| if(WITH_LLVM) | if(WITH_LLVM) | ||||||
|     if(DEFINED ENV{LLVM_HOME}) |     if(DEFINED ENV{LLVM_HOME}) | ||||||
|         find_path (LLVM_DIR LLVM-Config.cmake $ENV{LLVM_HOME}/lib/cmake/llvm) |         find_path (LLVM_DIR LLVM-Config.cmake $ENV{LLVM_HOME}/lib/cmake/llvm) | ||||||
| @@ -177,40 +181,35 @@ 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) | ||||||
|  | 	set(LIB_SOURCES  | ||||||
|     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) | 	FILE(GLOB GEN_SC_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/sysc/register_*.cpp) | ||||||
|     target_compile_definitions(${DBT_RISE_SC_LIB_NAME} PUBLIC WITH_SYSTEMC) | 	list(APPEND LIB_SOURCES ${GEN_SC_SOURCES}) | ||||||
|     target_compile_definitions(${DBT_RISE_SC_LIB_NAME} PRIVATE CORE_${CORE_NAME}) |     add_library(${PROJECT_NAME} ${LIB_SOURCES}) | ||||||
|  |     target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC) | ||||||
|  |     target_compile_definitions(${PROJECT_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 +218,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() | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										72
									
								
								gen_input/templates/CORENAME_sysc.cpp.gtl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								gen_input/templates/CORENAME_sysc.cpp.gtl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  |  * Copyright (C) 2023 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. | ||||||
|  |  * | ||||||
|  |  *******************************************************************************/ | ||||||
|  |  | ||||||
|  | #include "iss_factory.h" | ||||||
|  | #include <iss/arch/${coreDef.name.toLowerCase()}.h> | ||||||
|  | #include <iss/arch/riscv_hart_m_p.h> | ||||||
|  | #include <iss/arch/riscv_hart_mu_p.h> | ||||||
|  | #include "sc_core_adapter.h" | ||||||
|  | #include "core_complex.h" | ||||||
|  |  | ||||||
|  | namespace iss { | ||||||
|  | namespace interp { | ||||||
|  | using namespace sysc; | ||||||
|  | volatile std::array<bool, 2> ${coreDef.name.toLowerCase()}_init = { | ||||||
|  |         iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t { | ||||||
|  |             auto* cc = reinterpret_cast<sysc::tgfs::core_complex*>(data); | ||||||
|  |             auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::${coreDef.name.toLowerCase()}>>(cc); | ||||||
|  |             return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}}; | ||||||
|  |         }), | ||||||
|  |         iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t { | ||||||
|  |             auto* cc = reinterpret_cast<sysc::tgfs::core_complex*>(data); | ||||||
|  |             auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::${coreDef.name.toLowerCase()}>>(cc); | ||||||
|  |             return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}}; | ||||||
|  |         }) | ||||||
|  | }; | ||||||
|  | } | ||||||
|  | #if defined(WITH_TCC) | ||||||
|  | namespace tcc { | ||||||
|  | volatile std::array<bool, 2> ${coreDef.name.toLowerCase()}_init = { | ||||||
|  |         core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple<cpu_ptr, vm_ptr>{ | ||||||
|  |             auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data); | ||||||
|  |             auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::${coreDef.name.toLowerCase()}>>(cc); | ||||||
|  |             return {cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}}; | ||||||
|  |         }), | ||||||
|  |         core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple<cpu_ptr, vm_ptr>{ | ||||||
|  |             auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data); | ||||||
|  |             auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::${coreDef.name.toLowerCase()}>>(cc); | ||||||
|  |             return {cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}}; | ||||||
|  |         }) | ||||||
|  | }; | ||||||
|  | } | ||||||
|  | #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); | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								src-gen/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src-gen/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +1,3 @@ | |||||||
| /iss | /iss | ||||||
| /vm | /vm | ||||||
|  | /sysc | ||||||
| @@ -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}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										88
									
								
								src/sysc/iss_factory.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/sysc/iss_factory.h
									
									
									
									
									
										Normal file
									
								
							| @@ -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)}}; | ||||||
|         }) |         }) | ||||||
| }; | }; | ||||||
| } | } | ||||||
| @@ -57,13 +58,13 @@ namespace tcc { | |||||||
| volatile std::array<bool, 2> tgc_init = { | volatile std::array<bool, 2> tgc_init = { | ||||||
|         core_factory::instance().register_creator("tgc_c|m_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple<cpu_ptr, vm_ptr>{ |         core_factory::instance().register_creator("tgc_c|m_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple<cpu_ptr, vm_ptr>{ | ||||||
|             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 {cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc_c*>(cpu), gdb_port)}}; | ||||||
|         }), |         }), | ||||||
|         core_factory::instance().register_creator("tgc_c|mu_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple<cpu_ptr, vm_ptr>{ |         core_factory::instance().register_creator("tgc_c|mu_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple<cpu_ptr, vm_ptr>{ | ||||||
|             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 {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}}; | ||||||
|         }) |         }) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user