Compare commits
	
		
			4 Commits
		
	
	
		
			feature/is
			...
			b4b03f7850
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b4b03f7850 | |||
| 145a0cf68b | |||
| 1cef7de8c7 | |||
| e95f422aab | 
| @@ -32,49 +32,41 @@ add_subdirectory(softfloat) | |||||||
| set(LIB_SOURCES  | set(LIB_SOURCES  | ||||||
|     src/iss/plugin/instruction_count.cpp |     src/iss/plugin/instruction_count.cpp | ||||||
| 	src/iss/arch/tgc_c.cpp | 	src/iss/arch/tgc_c.cpp | ||||||
|  | 	src/vm/tcc/vm_tgc_c.cpp | ||||||
| 	src/vm/interp/vm_tgc_c.cpp | 	src/vm/interp/vm_tgc_c.cpp | ||||||
| 	src/vm/fp_functions.cpp | 	src/vm/fp_functions.cpp | ||||||
| ) | ) | ||||||
|  | if(WITH_TCC) | ||||||
|  | 	list(APPEND LIB_SOURCES src/vm/tcc/vm_tgc_c.cpp) | ||||||
|  | endif() | ||||||
|  |  | ||||||
| # library files | # library files | ||||||
| if(TARGET ${CORE_NAME}_cpp) | FILE(GLOB GEN_ISS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/iss/arch/*.cpp) | ||||||
|     list(APPEND LIB_SOURCES ${${CORE_NAME}_OUTPUT_FILES}) | FILE(GLOB GEN_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/interp/vm_*.cpp) | ||||||
| else() | list(APPEND LIB_SOURCES ${GEN_ISS_SOURCES} ${GEN_VM_SOURCES}) | ||||||
|     FILE(GLOB GEN_ISS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/iss/arch/*.cpp) | foreach(FILEPATH ${GEN_ISS_SOURCES}) | ||||||
|     FILE(GLOB GEN_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/interp/vm_*.cpp) |     get_filename_component(CORE ${FILEPATH} NAME_WE) | ||||||
|     list(APPEND LIB_SOURCES ${GEN_ISS_SOURCES} ${GEN_VM_SOURCES}) |     string(TOUPPER ${CORE} CORE) | ||||||
|     foreach(FILEPATH ${GEN_ISS_SOURCES}) |     list(APPEND LIB_DEFINES CORE_${CORE}) | ||||||
|         get_filename_component(CORE ${FILEPATH} NAME_WE) | endforeach() | ||||||
|         string(TOUPPER ${CORE} CORE) | message("Core defines are ${LIB_DEFINES}") | ||||||
|         list(APPEND LIB_DEFINES CORE_${CORE}) |  | ||||||
|     endforeach() | if(WITH_LLVM) | ||||||
|     message("Defines are ${LIB_DEFINES}") | 	FILE(GLOB LLVM_GEN_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/llvm/vm_*.cpp) | ||||||
|  | 	list(APPEND LIB_SOURCES ${LLVM_GEN_SOURCES}) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WITH_TCC) | ||||||
|  | 	FILE(GLOB TCC_GEN_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/tcc/vm_*.cpp) | ||||||
|  | 	list(APPEND LIB_SOURCES ${TCC_GEN_SOURCES}) | ||||||
| endif() | endif() | ||||||
|  |  | ||||||
| if(TARGET RapidJSON OR TARGET RapidJSON::RapidJSON) | if(TARGET RapidJSON OR TARGET RapidJSON::RapidJSON) | ||||||
|     list(APPEND LIB_SOURCES src/iss/plugin/cycle_estimate.cpp src/iss/plugin/pctrace.cpp) |     list(APPEND LIB_SOURCES src/iss/plugin/cycle_estimate.cpp src/iss/plugin/pctrace.cpp) | ||||||
| endif() | endif() | ||||||
|  |  | ||||||
| if(WITH_LLVM) |  | ||||||
| 	FILE(GLOB LLVM_GEN_SOURCES |  | ||||||
| 	    ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/llvm/vm_*.cpp |  | ||||||
| 	) |  | ||||||
| 	list(APPEND LIB_SOURCES ${LLVM_GEN_SOURCES}) |  | ||||||
| endif() |  | ||||||
|  |  | ||||||
| if(WITH_TCC) |  | ||||||
| 	FILE(GLOB TCC_GEN_SOURCES |  | ||||||
| 	    ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/tcc/vm_*.cpp |  | ||||||
| 	) |  | ||||||
| 	list(APPEND LIB_SOURCES ${TCC_GEN_SOURCES}) |  | ||||||
| endif() |  | ||||||
|  |  | ||||||
| # Define the library | # Define the library | ||||||
| add_library(${PROJECT_NAME} ${LIB_SOURCES}) | add_library(${PROJECT_NAME} ${LIB_SOURCES}) | ||||||
| # list code gen dependencies |  | ||||||
| if(TARGET ${CORE_NAME}_cpp) |  | ||||||
|     add_dependencies(${PROJECT_NAME} ${CORE_NAME}_cpp) |  | ||||||
| endif() |  | ||||||
|  |  | ||||||
| if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") | if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") | ||||||
|      target_compile_options(${PROJECT_NAME} PRIVATE -Wno-shift-count-overflow) |      target_compile_options(${PROJECT_NAME} PRIVATE -Wno-shift-count-overflow) | ||||||
| @@ -185,11 +177,17 @@ install(TARGETS tgc-sim | |||||||
| # | # | ||||||
| ############################################################################### | ############################################################################### | ||||||
| if(TARGET scc-sysc) | if(TARGET scc-sysc) | ||||||
| 	project(dbt-rise-tgc_sc VERSION 1.0.0) | 	if(BUILD_SHARED_LIBS) | ||||||
|  | 		set(THIS_PROJECT_NAME dbt-rise-tgc_sc) | ||||||
|  | 	else() | ||||||
|  | 		set(THIS_PROJECT_NAME dbt-rise-tgc_sc_lib) | ||||||
|  | 	endif() | ||||||
|  | 	project(${THIS_PROJECT_NAME} VERSION 1.0.0) | ||||||
|     add_library(${PROJECT_NAME}  |     add_library(${PROJECT_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(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) | ||||||
|     target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC) |     target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC) | ||||||
|     target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) |     target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) | ||||||
|     foreach(F IN LISTS TGC_SOURCES) |     foreach(F IN LISTS TGC_SOURCES) | ||||||
| @@ -219,5 +217,14 @@ 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(NOT BUILD_SHARED_LIBS) | ||||||
|  | 		add_library(dbt-rise-tgc_sc INTERFACE) | ||||||
|  | 	    target_include_directories(dbt-rise-tgc_sc INTERFACE $<TARGET_PROPERTY:${THIS_PROJECT_NAME},INTERFACE_INCLUDE_DIRECTORIES>) | ||||||
|  | 	    target_include_directories(dbt-rise-tgc_sc INTERFACE $<TARGET_PROPERTY:dbt-rise-tgc,INTERFACE_INCLUDE_DIRECTORIES>) | ||||||
|  | 	    target_link_libraries(dbt-rise-tgc_sc INTERFACE  | ||||||
|  | 	    	-Wl,--whole-archive,$<TARGET_FILE:${THIS_PROJECT_NAME}>,--no-whole-archive | ||||||
|  | 	    	$<TARGET_PROPERTY:${THIS_PROJECT_NAME},INTERFACE_LINK_LIBRARIES> | ||||||
|  | 	    	scc-sysc) | ||||||
|  | 	endif() | ||||||
| endif() | endif() | ||||||
|  |  | ||||||
|   | |||||||
| @@ -304,7 +304,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | |||||||
|     return pc; |     return pc; | ||||||
| } | } | ||||||
|  |  | ||||||
| } | } // namespace ${coreDef.name.toLowerCase()} | ||||||
|  |  | ||||||
| template <> | template <> | ||||||
| std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) { | std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) { | ||||||
| @@ -320,7 +320,7 @@ std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreD | |||||||
| #include <iss/arch/riscv_hart_mu_p.h> | #include <iss/arch/riscv_hart_mu_p.h> | ||||||
| namespace iss { | namespace iss { | ||||||
| namespace { | namespace { | ||||||
| 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("${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); | ||||||
| @@ -336,8 +336,3 @@ std::array<bool, 2> dummy = { | |||||||
| }; | }; | ||||||
| } | } | ||||||
| } | } | ||||||
| extern "C" { |  | ||||||
| 	bool* get_${coreDef.name.toLowerCase()}_interp_creators() { |  | ||||||
| 		return iss::dummy.data(); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -301,7 +301,7 @@ template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(tu_builder& tu) { | |||||||
|     tu("return *next_pc;"); |     tu("return *next_pc;"); | ||||||
| } | } | ||||||
|  |  | ||||||
| } // namespace mnrv32 | } // namespace ${coreDef.name.toLowerCase()} | ||||||
|  |  | ||||||
| template <> | template <> | ||||||
| std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) { | std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) { | ||||||
| @@ -317,7 +317,7 @@ std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreD | |||||||
| #include <iss/arch/riscv_hart_mu_p.h> | #include <iss/arch/riscv_hart_mu_p.h> | ||||||
| namespace iss { | namespace iss { | ||||||
| namespace { | namespace { | ||||||
| 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("${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); | ||||||
| @@ -333,8 +333,3 @@ std::array<bool, 2> dummy = { | |||||||
| }; | }; | ||||||
| } | } | ||||||
| } | } | ||||||
| extern "C" { |  | ||||||
| 	bool* get_${coreDef.name.toLowerCase()}_tcc_creators() { |  | ||||||
| 		return iss::dummy.data(); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -37,10 +37,11 @@ | |||||||
| #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> | ||||||
| #ifndef WIN32 | #ifndef WIN32 | ||||||
| #include <iss/plugin/loader.h> | #include <iss/plugin/loader.h> | ||||||
| #endif | #endif | ||||||
| #include "core_complex.h" | #include "sc_core_adapter_if.h" | ||||||
| #include <iss/arch/tgc_mapper.h> | #include <iss/arch/tgc_mapper.h> | ||||||
| #include <scc/report.h> | #include <scc/report.h> | ||||||
| #include <util/ities.h> | #include <util/ities.h> | ||||||
| @@ -85,136 +86,9 @@ using namespace sc_core; | |||||||
|  |  | ||||||
| namespace { | namespace { | ||||||
| iss::debugger::encoder_decoder encdec; | iss::debugger::encoder_decoder encdec; | ||||||
|  |  | ||||||
| std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}}; | std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}}; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename PLAT> |  | ||||||
| class core_wrapper_t : public PLAT { |  | ||||||
| public: |  | ||||||
|     using reg_t       = typename arch::traits<typename PLAT::core>::reg_t; |  | ||||||
|     using phys_addr_t = typename arch::traits<typename PLAT::core>::phys_addr_t; |  | ||||||
|     using heart_state_t = typename PLAT::hart_state_type; |  | ||||||
|     core_wrapper_t(core_complex *owner) |  | ||||||
|     : owner(owner) { } |  | ||||||
|  |  | ||||||
|     uint32_t get_mode() { return this->reg.PRIV; } |  | ||||||
|  |  | ||||||
|     inline void set_interrupt_execution(bool v) { this->interrupt_sim = v?1:0; } |  | ||||||
|  |  | ||||||
|     inline bool get_interrupt_execution() { return this->interrupt_sim; } |  | ||||||
|  |  | ||||||
|     heart_state_t &get_state() { return this->state; } |  | ||||||
|  |  | ||||||
|     void notify_phase(iss::arch_if::exec_phase p) override { |  | ||||||
|         if (p == iss::arch_if::ISTART) |  | ||||||
|             owner->sync(this->instr_if.get_total_cycles()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     sync_type needed_sync() const override { return PRE_SYNC; } |  | ||||||
|  |  | ||||||
|     void disass_output(uint64_t pc, const std::string instr) override { |  | ||||||
|         if (!owner->disass_output(pc, instr)) { |  | ||||||
|             std::stringstream s; |  | ||||||
|             s << "[p:" << lvl[this->reg.PRIV] << ";s:0x" << std::hex << std::setfill('0') |  | ||||||
|               << std::setw(sizeof(reg_t) * 2) << (reg_t)this->state.mstatus << std::dec << ";c:" |  | ||||||
|               << this->reg.icount + this->cycle_offset << "]"; |  | ||||||
|             SCCDEBUG(owner->name())<<"disass: " |  | ||||||
|                 << "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" << std::setw(40) |  | ||||||
|                 << std::setfill(' ') << std::left << instr << s.str(); |  | ||||||
|         } |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) override { |  | ||||||
|         if (addr.access && access_type::DEBUG) |  | ||||||
|             return owner->read_mem_dbg(addr.val, length, data) ? Ok : Err; |  | ||||||
|         else { |  | ||||||
|             return owner->read_mem(addr.val, length, data, is_fetch(addr.access)) ? Ok : Err; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data) override { |  | ||||||
|         if (addr.access && access_type::DEBUG) |  | ||||||
|             return owner->write_mem_dbg(addr.val, length, data) ? Ok : Err; |  | ||||||
|         else { |  | ||||||
|             auto res = owner->write_mem(addr.val, length, data) ? Ok : Err; |  | ||||||
|             // clear MTIP on mtimecmp write |  | ||||||
|             if (addr.val == 0x2004000) { |  | ||||||
|                 reg_t val; |  | ||||||
|                 this->read_csr(arch::mip, val); |  | ||||||
|                 if (val & (1ULL << 7)) this->write_csr(arch::mip, val & ~(1ULL << 7)); |  | ||||||
|             } |  | ||||||
|             return res; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     status read_csr(unsigned addr, reg_t &val) override { |  | ||||||
| #ifndef CWR_SYSTEMC |  | ||||||
|         if((addr==arch::time || addr==arch::timeh) && owner->mtime_o.get_interface(0)){ |  | ||||||
|             uint64_t time_val; |  | ||||||
|             bool ret = owner->mtime_o->nb_peek(time_val); |  | ||||||
|             if (addr == iss::arch::time) { |  | ||||||
|                 val = static_cast<reg_t>(time_val); |  | ||||||
|             } else if (addr == iss::arch::timeh) { |  | ||||||
|                 if (sizeof(reg_t) != 4) return iss::Err; |  | ||||||
|                 val = static_cast<reg_t>(time_val >> 32); |  | ||||||
|             } |  | ||||||
|             return ret?Ok:Err; |  | ||||||
| #else |  | ||||||
| 		if((addr==arch::time || addr==arch::timeh)){ |  | ||||||
| 			uint64_t time_val = owner->mtime_i.read(); |  | ||||||
| 			if (addr == iss::arch::time) { |  | ||||||
| 				val = static_cast<reg_t>(time_val); |  | ||||||
| 			} else if (addr == iss::arch::timeh) { |  | ||||||
| 				if (sizeof(reg_t) != 4) return iss::Err; |  | ||||||
| 				val = static_cast<reg_t>(time_val >> 32); |  | ||||||
| 			} |  | ||||||
| 			return Ok; |  | ||||||
| #endif |  | ||||||
|         } else { |  | ||||||
|             return PLAT::read_csr(addr, val); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void wait_until(uint64_t flags) override { |  | ||||||
|         SCCDEBUG(owner->name()) << "Sleeping until interrupt"; |  | ||||||
|         while(this->reg.pending_trap == 0 && (this->csr[arch::mip] & this->csr[arch::mie]) == 0) { |  | ||||||
|             sc_core::wait(wfi_evt); |  | ||||||
|         } |  | ||||||
|         PLAT::wait_until(flags); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void local_irq(short id, bool value) { |  | ||||||
|         reg_t mask = 0; |  | ||||||
|         switch (id) { |  | ||||||
|         case 3: // SW |  | ||||||
|             mask = 1 << 3; |  | ||||||
|             break; |  | ||||||
|         case 7: // timer |  | ||||||
|             mask = 1 << 7; |  | ||||||
|             break; |  | ||||||
|         case 11: // external |  | ||||||
|             mask = 1 << 11; |  | ||||||
|             break; |  | ||||||
|         default: |  | ||||||
|             if(id>15) mask = 1 << id; |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|         if (value) { |  | ||||||
|             this->csr[arch::mip] |= mask; |  | ||||||
|             wfi_evt.notify(); |  | ||||||
|         } else |  | ||||||
|             this->csr[arch::mip] &= ~mask; |  | ||||||
|         this->check_interrupt(); |  | ||||||
|         if(value) |  | ||||||
|             SCCTRACE(owner->name()) << "Triggering interrupt " << id << " Pending trap: " << this->reg.pending_trap; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| private: |  | ||||||
|     core_complex *const owner; |  | ||||||
|     sc_event wfi_evt; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| int cmd_sysc(int argc, char *argv[], debugger::out_func of, debugger::data_func df, | int cmd_sysc(int argc, char *argv[], debugger::out_func of, debugger::data_func df, | ||||||
|              debugger::target_adapter_if *tgt_adapter) { |              debugger::target_adapter_if *tgt_adapter) { | ||||||
|     if (argc > 1) { |     if (argc > 1) { | ||||||
| @@ -262,45 +136,34 @@ public: | |||||||
|     std::function<void(bool)> set_interrupt_execution; |     std::function<void(bool)> set_interrupt_execution; | ||||||
|     std::function<void(short, bool)> local_irq; |     std::function<void(short, bool)> local_irq; | ||||||
|  |  | ||||||
|     template<typename PLAT> |  | ||||||
|     std::tuple<cpu_ptr, vm_ptr> create_core(std::string const& backend, unsigned gdb_port, uint32_t hart_id){ |  | ||||||
|         auto* lcpu = new core_wrapper_t<PLAT>(owner); |  | ||||||
|         lcpu->set_mhartid(hart_id); |  | ||||||
|         get_mode = [lcpu]() { return lcpu->get_mode(); }; |  | ||||||
|         get_state = [lcpu]() { return lcpu->get_state().mstatus.backing.val; }; |  | ||||||
|         get_interrupt_execution = [lcpu]() { return lcpu->get_interrupt_execution(); }; |  | ||||||
|         set_interrupt_execution = [lcpu](bool b) { return lcpu->set_interrupt_execution(b); }; |  | ||||||
|         local_irq = [lcpu](short s, bool b) { return lcpu->local_irq(s, b); }; |  | ||||||
|         if(backend == "interp") |  | ||||||
|             return {cpu_ptr{lcpu}, vm_ptr{iss::interp::create(static_cast<typename PLAT::core*>(lcpu), gdb_port)}}; |  | ||||||
| #ifdef WITH_LLVM |  | ||||||
|         if(backend == "llvm") |  | ||||||
|             return {cpu_ptr{lcpu}, vm_ptr{iss::llvm::create(lcpu, gdb_port)}}; |  | ||||||
| #endif |  | ||||||
| #ifdef WITH_TCC |  | ||||||
|         if(backend == "tcc") |  | ||||||
|     s        return {cpu_ptr{lcpu}, vm_ptr{iss::tcc::create(lcpu, gdb_port)}}; |  | ||||||
| #endif |  | ||||||
|         return {nullptr, nullptr}; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     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){ | ||||||
|         CREATE_CORE(tgc_c) |         auto & f = iss::core_factory::instance(); | ||||||
| #ifdef CORE_TGC_B |         if(type.size()==0 || type == "?") { | ||||||
|         CREATE_CORE(tgc_b) |             std::cout<<"Available cores: "<<util::join(f.get_names(), ", ")<<std::endl; | ||||||
| #endif |             sc_core::sc_stop(); | ||||||
| #ifdef CORE_TGC_D |         } else if (type.find('|') != std::string::npos) { | ||||||
|         CREATE_CORE(tgc_d) |             std::tie(cpu, vm) = f.create(type+"|"+backend); | ||||||
| #endif |         } else { | ||||||
| #ifdef CORE_TGC_D_XRB_MAC |             auto base_isa = type.substr(0, 5); | ||||||
|         CREATE_CORE(tgc_d_xrb_mac) |             if(base_isa=="tgc_d" || base_isa=="tgc_e") { | ||||||
| #endif |                 std::tie(cpu, vm) = f.create(type + "|mu_p_clic_pmp|" + backend, gdb_port); | ||||||
| #ifdef CORE_TGC_D_XRB_NN |             } else { | ||||||
|         CREATE_CORE(tgc_d_xrb_nn) |                 std::tie(cpu, vm) = f.create(type + "|m_p|" + backend, gdb_port); | ||||||
| #endif |            } | ||||||
|         { |  | ||||||
|             LOG(ERR) << "Illegal argument value for core type: " << type << std::endl; |  | ||||||
|         } |         } | ||||||
|  |         if(!cpu ){ | ||||||
|  |             SCCFATAL() << "Could not create cpu for isa " << type << " and backend " <<backend; | ||||||
|  |         } | ||||||
|  |         if(!vm ){ | ||||||
|  |             SCCFATAL() << "Could not create vm for isa " << type << " and backend " <<backend; | ||||||
|  |         } | ||||||
|  |         reinterpret_cast<sc_core_adapter_if&>(*cpu).set_mhartid(hart_id); | ||||||
|  |         get_mode = [this]() { return reinterpret_cast<sc_core_adapter_if&>(*cpu).get_mode(); }; | ||||||
|  |         get_state = [this]() { return reinterpret_cast<sc_core_adapter_if&>(*cpu).get_state(); }; | ||||||
|  |         get_interrupt_execution = [this]() { return reinterpret_cast<sc_core_adapter_if&>(*cpu).get_interrupt_execution(); }; | ||||||
|  |         set_interrupt_execution = [this](bool b) { return reinterpret_cast<sc_core_adapter_if&>(*cpu).set_interrupt_execution(b); }; | ||||||
|  |         local_irq = [this](short s, bool b) { return reinterpret_cast<sc_core_adapter_if&>(*cpu).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(); | ||||||
|         if (tgt_adapter) |         if (tgt_adapter) | ||||||
| @@ -634,5 +497,5 @@ bool core_complex::write_mem_dbg(uint64_t addr, unsigned length, const uint8_t * | |||||||
|     gp.set_streaming_width(length); |     gp.set_streaming_width(length); | ||||||
|     return dbus->transport_dbg(gp) == length; |     return dbus->transport_dbg(gp) == length; | ||||||
| } | } | ||||||
| } /* namespace SiFive */ | } /* namespace tgfs */ | ||||||
| } /* namespace sysc */ | } /* namespace sysc */ | ||||||
|   | |||||||
| @@ -1,12 +1,34 @@ | |||||||
| /* | /******************************************************************************* | ||||||
|  * register_tgc_c.cpp |  * Copyright (C) 2023 MINRES Technologies GmbH | ||||||
|  |  * All rights reserved. | ||||||
|  * |  * | ||||||
|  *  Created on: Jul 5, 2023 |  * Redistribution and use in source and binary forms, with or without | ||||||
|  *      Author: eyck |  * 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/factory.h> | ||||||
| #include <iss/arch/tgc_c.h> | #include <iss/arch/tgc_c.h> | ||||||
| @@ -16,18 +38,34 @@ | |||||||
| #include "core_complex.h" | #include "core_complex.h" | ||||||
|  |  | ||||||
| namespace iss { | namespace iss { | ||||||
| namespace { | namespace interp { | ||||||
| volatile std::array<bool, 2> dummy = { | 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>{ |         core_factory::instance().register_creator("tgc_c|m_p|interp", [](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* lcpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc_c>>(cc); |             arch::tgc_c* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc_c>>(cc); | ||||||
|             return {cpu_ptr{lcpu}, vm_ptr{interp::create(lcpu, gdb_port)}}; |             return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}}; | ||||||
|         }), |         }), | ||||||
|         core_factory::instance().register_creator("tgc_c|mu_p|interp", [](unsigned gdb_port, void* data) -> std::tuple<cpu_ptr, vm_ptr>{ |         core_factory::instance().register_creator("tgc_c|mu_p|interp", [](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* lcpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc_c>>(cc); |             arch::tgc_c* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc_c>>(cc); | ||||||
|             return {cpu_ptr{lcpu}, vm_ptr{interp::create(lcpu, gdb_port)}}; |             return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}}; | ||||||
|         }) |         }) | ||||||
| }; | }; | ||||||
| } | } | ||||||
|  | #if defined(WITH_TCC) | ||||||
|  | namespace tcc { | ||||||
|  | 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>{ | ||||||
|  |             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); | ||||||
|  |             return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}}; | ||||||
|  |         }), | ||||||
|  |         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); | ||||||
|  |             arch::tgc_c* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc_c>>(cc); | ||||||
|  |             return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}}; | ||||||
|  |         }) | ||||||
|  | }; | ||||||
|  | } | ||||||
|  | #endif | ||||||
| } | } | ||||||
|   | |||||||
| @@ -11,14 +11,13 @@ | |||||||
|  |  | ||||||
| #include <scc/report.h> | #include <scc/report.h> | ||||||
| #include <util/ities.h> | #include <util/ities.h> | ||||||
| #include "core_complex.h" | #include "sc_core_adapter_if.h" | ||||||
| #include <iss/iss.h> | #include <iss/iss.h> | ||||||
| #include <iss/vm_types.h> | #include <iss/vm_types.h> | ||||||
| #include <iostream> | #include <iostream> | ||||||
|  |  | ||||||
|  |  | ||||||
| template<typename PLAT> | template<typename PLAT> | ||||||
| class sc_core_adapter : public PLAT { | class sc_core_adapter : public PLAT, public sc_core_adapter_if { | ||||||
| public: | public: | ||||||
|     using reg_t       = typename iss::arch::traits<typename PLAT::core>::reg_t; |     using reg_t       = typename iss::arch::traits<typename PLAT::core>::reg_t; | ||||||
|     using phys_addr_t = typename iss::arch::traits<typename PLAT::core>::phys_addr_t; |     using phys_addr_t = typename iss::arch::traits<typename PLAT::core>::phys_addr_t; | ||||||
| @@ -26,13 +25,15 @@ public: | |||||||
|     sc_core_adapter(sysc::tgfs::core_complex *owner) |     sc_core_adapter(sysc::tgfs::core_complex *owner) | ||||||
|     : owner(owner) { } |     : owner(owner) { } | ||||||
|  |  | ||||||
|     uint32_t get_mode() { return this->reg.PRIV; } |     void set_mhartid(unsigned id) override { PLAT::set_mhartid(id); } | ||||||
|  |  | ||||||
|     inline void set_interrupt_execution(bool v) { this->interrupt_sim = v?1:0; } |     uint32_t get_mode() override { return this->reg.PRIV; } | ||||||
|  |  | ||||||
|     inline bool get_interrupt_execution() { return this->interrupt_sim; } |     void set_interrupt_execution(bool v) override { this->interrupt_sim = v?1:0; } | ||||||
|  |  | ||||||
|     heart_state_t &get_state() { return this->state; } |     bool get_interrupt_execution() override { return this->interrupt_sim; } | ||||||
|  |  | ||||||
|  |     uint64_t get_state() override { return this->state.mstatus.backing.val; } | ||||||
|  |  | ||||||
|     void notify_phase(iss::arch_if::exec_phase p) override { |     void notify_phase(iss::arch_if::exec_phase p) override { | ||||||
|         if (p == iss::arch_if::ISTART) |         if (p == iss::arch_if::ISTART) | ||||||
| @@ -88,7 +89,7 @@ public: | |||||||
|                 if (sizeof(reg_t) != 4) return iss::Err; |                 if (sizeof(reg_t) != 4) return iss::Err; | ||||||
|                 val = static_cast<reg_t>(time_val >> 32); |                 val = static_cast<reg_t>(time_val >> 32); | ||||||
|             } |             } | ||||||
|             return ret?Ok:Err; |             return ret?iss::Ok:iss::Err; | ||||||
| #else | #else | ||||||
|         if((addr==iss::arch::time || addr==iss::arch::timeh)){ |         if((addr==iss::arch::time || addr==iss::arch::timeh)){ | ||||||
|             uint64_t time_val = owner->mtime_i.read(); |             uint64_t time_val = owner->mtime_i.read(); | ||||||
| @@ -113,7 +114,7 @@ public: | |||||||
|         PLAT::wait_until(flags); |         PLAT::wait_until(flags); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void local_irq(short id, bool value) { |     void local_irq(short id, bool value) override { | ||||||
|         reg_t mask = 0; |         reg_t mask = 0; | ||||||
|         switch (id) { |         switch (id) { | ||||||
|         case 3: // SW |         case 3: // SW | ||||||
| @@ -141,7 +142,7 @@ public: | |||||||
|  |  | ||||||
| private: | private: | ||||||
|     sysc::tgfs::core_complex *const owner; |     sysc::tgfs::core_complex *const owner; | ||||||
|     sc_event wfi_evt; |     sc_core::sc_event wfi_evt; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										30
									
								
								src/sysc/sc_core_adapter_if.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/sysc/sc_core_adapter_if.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | /* | ||||||
|  |  * sc_core_adapter.h | ||||||
|  |  * | ||||||
|  |  *  Created on: Jul 5, 2023 | ||||||
|  |  *      Author: eyck | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef _SYSC_SC_CORE_ADAPTER_IF_H_ | ||||||
|  | #define _SYSC_SC_CORE_ADAPTER_IF_H_ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include <scc/report.h> | ||||||
|  | #include <util/ities.h> | ||||||
|  | #include "core_complex.h" | ||||||
|  | #include <iss/iss.h> | ||||||
|  | #include <iss/vm_types.h> | ||||||
|  | #include <iostream> | ||||||
|  |  | ||||||
|  | struct sc_core_adapter_if { | ||||||
|  |     virtual void set_mhartid(unsigned) = 0; | ||||||
|  |     virtual uint32_t get_mode() = 0; | ||||||
|  |     virtual uint64_t get_state() = 0; | ||||||
|  |     virtual bool get_interrupt_execution() = 0; | ||||||
|  |     virtual void set_interrupt_execution(bool v) = 0; | ||||||
|  |     virtual void local_irq(short id, bool value) = 0; | ||||||
|  |     virtual ~sc_core_adapter_if() = default; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #endif /* _SYSC_SC_CORE_ADAPTER_IF_H_ */ | ||||||
| @@ -2651,7 +2651,7 @@ std::unique_ptr<vm_if> create<arch::tgc_c>(arch::tgc_c *core, unsigned short por | |||||||
| #include <iss/arch/riscv_hart_mu_p.h> | #include <iss/arch/riscv_hart_mu_p.h> | ||||||
| namespace iss { | namespace iss { | ||||||
| namespace { | namespace { | ||||||
| std::array<bool, 2> dummy = { | volatile std::array<bool, 2> dummy = { | ||||||
|         core_factory::instance().register_creator("tgc_c|m_p|interp", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{ |         core_factory::instance().register_creator("tgc_c|m_p|interp", [](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 interp::tgc_c::vm_impl<arch::tgc_c>(*cpu, false); | 		    auto vm = new interp::tgc_c::vm_impl<arch::tgc_c>(*cpu, false); | ||||||
| @@ -2667,8 +2667,4 @@ std::array<bool, 2> dummy = { | |||||||
| }; | }; | ||||||
| } | } | ||||||
| } | } | ||||||
| extern "C" { |  | ||||||
| 	bool* get_tgc_c_interp_creators() { |  | ||||||
| 		return iss::dummy.data(); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -3210,7 +3210,7 @@ template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(tu_builder& tu) { | |||||||
|     tu("return *next_pc;"); |     tu("return *next_pc;"); | ||||||
| } | } | ||||||
|  |  | ||||||
| } // namespace mnrv32 | } // namespace tgc_c | ||||||
|  |  | ||||||
| template <> | template <> | ||||||
| std::unique_ptr<vm_if> create<arch::tgc_c>(arch::tgc_c *core, unsigned short port, bool dump) { | std::unique_ptr<vm_if> create<arch::tgc_c>(arch::tgc_c *core, unsigned short port, bool dump) { | ||||||
| @@ -3218,7 +3218,7 @@ std::unique_ptr<vm_if> create<arch::tgc_c>(arch::tgc_c *core, unsigned short por | |||||||
|     if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port); |     if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port); | ||||||
|     return std::unique_ptr<vm_if>(ret); |     return std::unique_ptr<vm_if>(ret); | ||||||
| } | } | ||||||
| } // namesapce tcc | } // namespace tcc | ||||||
| } // namespace iss | } // namespace iss | ||||||
|  |  | ||||||
| #include <iss/factory.h> | #include <iss/factory.h> | ||||||
| @@ -3226,7 +3226,7 @@ std::unique_ptr<vm_if> create<arch::tgc_c>(arch::tgc_c *core, unsigned short por | |||||||
| #include <iss/arch/riscv_hart_mu_p.h> | #include <iss/arch/riscv_hart_mu_p.h> | ||||||
| namespace iss { | namespace iss { | ||||||
| namespace { | namespace { | ||||||
| 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); | ||||||
| @@ -3242,8 +3242,3 @@ std::array<bool, 2> dummy = { | |||||||
| }; | }; | ||||||
| } | } | ||||||
| } | } | ||||||
| extern "C" { |  | ||||||
| 	bool* get_tgc_c_tcc_creators() { |  | ||||||
| 		return iss::dummy.data(); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user