fixes build system to handle TCC properly
This commit is contained in:
parent
145a0cf68b
commit
b4b03f7850
|
@ -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("Core 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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -38,28 +38,34 @@
|
||||||
#include "core_complex.h"
|
#include "core_complex.h"
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace {
|
namespace interp {
|
||||||
volatile std::array<bool, 4> 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* cpu = 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{cpu}, vm_ptr{interp::create(cpu, 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* cpu = 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{cpu}, vm_ptr{interp::create(cpu, 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>{
|
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);
|
arch::tgc_c* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc_c>>(cc);
|
||||||
return {cpu_ptr{cpu}, vm_ptr{tcc::create(cpu, gdb_port)}};
|
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>{
|
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);
|
arch::tgc_c* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc_c>>(cc);
|
||||||
return {cpu_ptr{cpu}, vm_ptr{tcc::create(cpu, gdb_port)}};
|
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)
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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_ */
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue