[WIP] add next increment for TCC
This commit is contained in:
parent
ae1c0b99fe
commit
264053a8d6
|
@ -172,6 +172,8 @@ struct ${coreDef.name.toLowerCase()}: public arch_if {
|
||||||
|
|
||||||
inline bool should_stop() { return interrupt_sim; }
|
inline bool should_stop() { return interrupt_sim; }
|
||||||
|
|
||||||
|
inline uint64_t stop_code() { return interrupt_sim; }
|
||||||
|
|
||||||
inline phys_addr_t v2p(const iss::addr_t& addr){
|
inline phys_addr_t v2p(const iss::addr_t& addr){
|
||||||
if (addr.space != traits<${coreDef.name.toLowerCase()}>::MEM || addr.type == iss::address_type::PHYSICAL ||
|
if (addr.space != traits<${coreDef.name.toLowerCase()}>::MEM || addr.type == iss::address_type::PHYSICAL ||
|
||||||
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL) {
|
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL) {
|
||||||
|
@ -204,7 +206,7 @@ protected:
|
||||||
|
|
||||||
std::array<address_type, 4> addr_mode;
|
std::array<address_type, 4> addr_mode;
|
||||||
|
|
||||||
bool interrupt_sim=false;
|
uint64_t interrupt_sim=0;
|
||||||
<%
|
<%
|
||||||
def fcsr = allRegs.find {it.name=='FCSR'}
|
def fcsr = allRegs.find {it.name=='FCSR'}
|
||||||
if(fcsr != null) {%>
|
if(fcsr != null) {%>
|
||||||
|
|
|
@ -60,7 +60,7 @@ public:
|
||||||
using phys_addr_t = typename super::phys_addr_t;
|
using phys_addr_t = typename super::phys_addr_t;
|
||||||
using code_word_t = typename super::code_word_t;
|
using code_word_t = typename super::code_word_t;
|
||||||
using addr_t = typename super::addr_t;
|
using addr_t = typename super::addr_t;
|
||||||
using ICmpInst = typename super::ICmpInst;
|
using tu_builder = typename super::tu_builder;
|
||||||
|
|
||||||
vm_impl();
|
vm_impl();
|
||||||
|
|
||||||
|
@ -77,11 +77,10 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using vm_base<ARCH>::get_reg_ptr;
|
using vm_base<ARCH>::get_reg_ptr;
|
||||||
using translation_unit = typename vm_base<ARCH>::translation_unit;
|
|
||||||
|
|
||||||
using this_class = vm_impl<ARCH>;
|
using this_class = vm_impl<ARCH>;
|
||||||
using compile_ret_t = std::tuple<continuation_e>;
|
using compile_ret_t = std::tuple<continuation_e>;
|
||||||
using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr, translation_unit&);
|
using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr, tu_builder&);
|
||||||
|
|
||||||
inline const char *name(size_t index){return traits<ARCH>::reg_aliases.at(index);}
|
inline const char *name(size_t index){return traits<ARCH>::reg_aliases.at(index);}
|
||||||
|
|
||||||
|
@ -89,21 +88,21 @@ protected:
|
||||||
super::setup_module(m);
|
super::setup_module(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
compile_ret_t gen_single_inst_behavior(virt_addr_t &, unsigned int &, translation_unit&) override;
|
compile_ret_t gen_single_inst_behavior(virt_addr_t &, unsigned int &, tu_builder&) override;
|
||||||
|
|
||||||
void gen_trap_behavior(translation_unit& tu) override;
|
void gen_trap_behavior(tu_builder& tu) override;
|
||||||
|
|
||||||
void gen_raise_trap(translation_unit& tu, uint16_t trap_id, uint16_t cause);
|
void gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause);
|
||||||
|
|
||||||
void gen_leave_trap(translation_unit& tu, unsigned lvl);
|
void gen_leave_trap(tu_builder& tu, unsigned lvl);
|
||||||
|
|
||||||
void gen_wait(translation_unit& tu, unsigned type);
|
void gen_wait(tu_builder& tu, unsigned type);
|
||||||
|
|
||||||
inline void gen_trap_check(translation_unit& tu) {
|
inline void gen_trap_check(tu_builder& tu) {
|
||||||
tu<<" if(*trap_state!=0) goto trap_entry;";
|
tu("if(*trap_state!=0) goto trap_entry;");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void gen_set_pc(translation_unit& tu, virt_addr_t pc, unsigned reg_num) {
|
inline void gen_set_pc(tu_builder& tu, virt_addr_t pc, unsigned reg_num) {
|
||||||
switch(reg_num){
|
switch(reg_num){
|
||||||
case traits<ARCH>::NEXT_PC:
|
case traits<ARCH>::NEXT_PC:
|
||||||
tu("*next_pc = {:#x};", pc.val);
|
tu("*next_pc = {:#x};", pc.val);
|
||||||
|
@ -191,14 +190,14 @@ private:
|
||||||
|
|
||||||
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
|
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
|
||||||
/* instruction ${idx}: ${instr.name} */
|
/* instruction ${idx}: ${instr.name} */
|
||||||
compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, translation_unit& tu){<%instr.code.eachLine{%>
|
compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, tu_builder& tu){<%instr.code.eachLine{%>
|
||||||
${it}<%}%>
|
${it}<%}%>
|
||||||
}
|
}
|
||||||
<%}%>
|
<%}%>
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* end opcode definitions
|
* end opcode definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr, translation_unit& tu) {
|
compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr, tu_builder& tu) {
|
||||||
vm_impl::gen_sync(tu, iss::PRE_SYNC, instr_descr.size());
|
vm_impl::gen_sync(tu, iss::PRE_SYNC, instr_descr.size());
|
||||||
pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
||||||
gen_raise_trap(tu, 0, 2); // illegal instruction trap
|
gen_raise_trap(tu, 0, 2); // illegal instruction trap
|
||||||
|
@ -230,7 +229,7 @@ vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
std::tuple<continuation_e>
|
std::tuple<continuation_e>
|
||||||
vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, translation_unit& tu) {
|
vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, tu_builder& tu) {
|
||||||
// we fetch at max 4 byte, alignment is 2
|
// we fetch at max 4 byte, alignment is 2
|
||||||
enum {TRAP_ID=1<<16};
|
enum {TRAP_ID=1<<16};
|
||||||
code_word_t insn = 0;
|
code_word_t insn = 0;
|
||||||
|
@ -259,23 +258,24 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||||
return (this->*f)(pc, insn, tu);
|
return (this->*f)(pc, insn, tu);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(translation_unit& tu, uint16_t trap_id, uint16_t cause) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) {
|
||||||
tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id);
|
tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id);
|
||||||
tu << tu.create_store(tu.gen_const(32, std::numeric_limits<uint32_t>::max()),traits<ARCH>::LAST_BRANCH);
|
tu.create_store(tu.gen_const(32, std::numeric_limits<uint32_t>::max()),traits<ARCH>::LAST_BRANCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(translation_unit& tu, unsigned lvl) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {
|
||||||
tu("leave_trap(core_ptr, {});", lvl);
|
tu("leave_trap(core_ptr, {});", lvl);
|
||||||
tu(" *next_pc = {};", tu.create_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8));
|
tu.create_store(tu.create_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8),traits<ARCH>::NEXT_PC);
|
||||||
tu << tu.create_store(tu.gen_const(32, std::numeric_limits<uint32_t>::max()),traits<ARCH>::LAST_BRANCH);
|
tu.create_store(tu.gen_const(32, std::numeric_limits<uint32_t>::max()),traits<ARCH>::LAST_BRANCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_wait(translation_unit& tu, unsigned type) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_wait(tu_builder& tu, unsigned type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(translation_unit& tu) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(tu_builder& tu) {
|
||||||
tu<<"trap_entry:";
|
tu("trap_entry:");
|
||||||
tu("enter_trap(core_ptr, *trap_state, *pc);");
|
tu("enter_trap(core_ptr, *trap_state, *pc);");
|
||||||
|
tu.create_store(tu.gen_const(32, std::numeric_limits<uint32_t>::max()),traits<ARCH>::LAST_BRANCH);
|
||||||
tu("return *next_pc;");
|
tu("return *next_pc;");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,8 @@ struct mnrv32: public arch_if {
|
||||||
|
|
||||||
inline bool should_stop() { return interrupt_sim; }
|
inline bool should_stop() { return interrupt_sim; }
|
||||||
|
|
||||||
|
inline uint64_t stop_code() { return interrupt_sim; }
|
||||||
|
|
||||||
inline phys_addr_t v2p(const iss::addr_t& addr){
|
inline phys_addr_t v2p(const iss::addr_t& addr){
|
||||||
if (addr.space != traits<mnrv32>::MEM || addr.type == iss::address_type::PHYSICAL ||
|
if (addr.space != traits<mnrv32>::MEM || addr.type == iss::address_type::PHYSICAL ||
|
||||||
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL) {
|
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL) {
|
||||||
|
@ -238,7 +240,7 @@ protected:
|
||||||
|
|
||||||
std::array<address_type, 4> addr_mode;
|
std::array<address_type, 4> addr_mode;
|
||||||
|
|
||||||
bool interrupt_sim=false;
|
uint64_t interrupt_sim=0;
|
||||||
|
|
||||||
uint32_t get_fcsr(){return 0;}
|
uint32_t get_fcsr(){return 0;}
|
||||||
void set_fcsr(uint32_t val){}
|
void set_fcsr(uint32_t val){}
|
||||||
|
|
|
@ -1082,7 +1082,10 @@ iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned lengt
|
||||||
LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
|
LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
|
||||||
<< "), stopping simulation";
|
<< "), stopping simulation";
|
||||||
}
|
}
|
||||||
throw(iss::simulation_stopped(hostvar));
|
this->reg.trap_state=std::numeric_limits<uint32_t>::max();
|
||||||
|
this->interrupt_sim=hostvar;
|
||||||
|
break;
|
||||||
|
//throw(iss::simulation_stopped(hostvar));
|
||||||
case 0x0101: {
|
case 0x0101: {
|
||||||
char c = static_cast<char>(hostvar & 0xff);
|
char c = static_cast<char>(hostvar & 0xff);
|
||||||
if (c == '\n' || c == 0) {
|
if (c == '\n' || c == 0) {
|
||||||
|
@ -1313,6 +1316,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
|
||||||
this->reg.trap_state = 0;
|
this->reg.trap_state = 0;
|
||||||
std::array<char, 32> buffer;
|
std::array<char, 32> buffer;
|
||||||
sprintf(buffer.data(), "0x%016lx", addr);
|
sprintf(buffer.data(), "0x%016lx", addr);
|
||||||
|
if((flags&0xffffffff) != 0xffffffff)
|
||||||
CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '"
|
CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '"
|
||||||
<< (trap_id ? irq_str[cause] : trap_str[cause]) << "' (" << trap_id << ")"
|
<< (trap_id ? irq_str[cause] : trap_str[cause]) << "' (" << trap_id << ")"
|
||||||
<< " at address " << buffer.data() << " occurred, changing privilege level from "
|
<< " at address " << buffer.data() << " occurred, changing privilege level from "
|
||||||
|
|
|
@ -102,7 +102,7 @@ public:
|
||||||
|
|
||||||
uint32_t get_mode() { return this->reg.machine_state; }
|
uint32_t get_mode() { return this->reg.machine_state; }
|
||||||
|
|
||||||
inline void set_interrupt_execution(bool v) { this->interrupt_sim = v; }
|
inline void set_interrupt_execution(bool v) { this->interrupt_sim = v?1:0; }
|
||||||
|
|
||||||
inline bool get_interrupt_execution() { return this->interrupt_sim; }
|
inline bool get_interrupt_execution() { return this->interrupt_sim; }
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue