5e2910f642f21a2a59aaf67c8c4013455f4104c3
1 // See LICENSE for license details.
17 processor_t::processor_t(sim_t
* _sim
, mmu_t
* _mmu
, uint32_t _id
)
18 : sim(_sim
), mmu(_mmu
), ext(NULL
), id(_id
), run(false), debug(false),
22 mmu
->set_processor(this);
24 #define DECLARE_INSN(name, match, mask) REGISTER_INSN(this, name, match, mask)
29 processor_t::~processor_t()
35 // the ISA guarantees on boot that the PC is 0x2000 and the the processor
36 // is in supervisor mode, and in 64-bit mode, if supported, with traps
37 // and virtual memory disabled.
39 #ifdef RISCV_ENABLE_64BIT
44 // the following state is undefined upon boot-up,
45 // but we zero it for determinism
60 load_reservation
= -1;
63 void processor_t::set_debug(bool value
)
67 ext
->set_debug(value
);
70 void processor_t::reset(bool value
)
76 state
.reset(); // reset the core
78 ext
->reset(); // reset the extension
81 void processor_t::take_interrupt()
83 uint32_t interrupts
= (state
.sr
& SR_IP
) >> SR_IP_SHIFT
;
84 interrupts
&= (state
.sr
& SR_IM
) >> SR_IM_SHIFT
;
86 if (interrupts
&& (state
.sr
& SR_EI
))
87 for (int i
= 0; ; i
++, interrupts
>>= 1)
89 throw trap_t((1ULL << ((state
.sr
& SR_S64
) ? 63 : 31)) + i
);
92 void processor_t::step(size_t n
)
105 // execute_insn fetches and executes one instruction
106 #define execute_insn(noisy) \
108 mmu_t::insn_fetch_t fetch = _mmu->load_insn(npc); \
109 if(noisy) disasm(fetch.insn.insn); \
110 npc = fetch.func(this, fetch.insn.insn, npc); \
114 // special execute_insn for commit log dumping
115 #ifdef RISCV_ENABLE_COMMITLOG
116 //static disassembler disasmblr;
118 #define execute_insn(noisy) \
120 mmu_t::insn_fetch_t fetch = _mmu->load_insn(npc); \
121 if(noisy) disasm(fetch.insn.insn); \
122 bool in_spvr = state.sr & SR_S; \
123 if (!in_spvr) fprintf(stderr, "\n0x%016" PRIx64 " (0x%08" PRIx32 ") ", npc, fetch.insn.insn.bits()); \
124 /*if (!in_spvr) fprintf(stderr, "\n0x%016" PRIx64 " (0x%08" PRIx32 ") %s ", npc, fetch.insn.insn.bits(), disasmblr.disassemble(fetch.insn.insn).c_str());*/ \
125 npc = fetch.func(this, fetch.insn.insn, npc); \
129 if(debug
) for( ; i
< n
; i
++) // print out instructions as we go
133 // unrolled for speed
134 for( ; n
> 3 && i
< n
-3; i
+=4)
152 // update timer and possibly register a timer interrupt
153 uint32_t old_count
= state
.count
;
155 if(old_count
< state
.compare
&& uint64_t(old_count
) + i
>= state
.compare
)
156 set_interrupt(IRQ_TIMER
, true);
159 void processor_t::take_trap(reg_t pc
, trap_t
& t
)
162 fprintf(stderr
, "core %3d: exception %s, epc 0x%016" PRIx64
"\n",
165 // switch to supervisor, set previous supervisor bit, disable interrupts
166 set_pcr(CSR_STATUS
, (((state
.sr
& ~SR_EI
) | SR_S
) & ~SR_PS
& ~SR_PEI
) |
167 ((state
.sr
& SR_S
) ? SR_PS
: 0) |
168 ((state
.sr
& SR_EI
) ? SR_PEI
: 0));
170 yield_load_reservation();
171 state
.cause
= t
.cause();
173 state
.pc
= state
.evec
;
175 t
.side_effects(&state
); // might set badvaddr etc.
178 void processor_t::deliver_ipi()
181 set_pcr(CSR_CLEAR_IPI
, 1);
184 void processor_t::disasm(insn_t insn
)
186 // the disassembler is stateless, so we share it
187 fprintf(stderr
, "core %3d: 0x%016" PRIx64
" (0x%08" PRIx32
") %s\n",
188 id
, state
.pc
, insn
.bits(), disassembler
.disassemble(insn
).c_str());
191 reg_t
processor_t::set_pcr(int which
, reg_t val
)
193 reg_t old_pcr
= get_pcr(which
);
198 state
.fflags
= val
& (FSR_AEXC
>> FSR_AEXC_SHIFT
);
201 state
.frm
= val
& (FSR_RD
>> FSR_RD_SHIFT
);
204 state
.fflags
= (val
& FSR_AEXC
) >> FSR_AEXC_SHIFT
;
205 state
.frm
= (val
& FSR_RD
) >> FSR_RD_SHIFT
;
208 state
.sr
= (val
& ~SR_IP
) | (state
.sr
& SR_IP
);
209 #ifndef RISCV_ENABLE_64BIT
210 state
.sr
&= ~(SR_S64
| SR_U64
);
212 #ifndef RISCV_ENABLE_FPU
217 state
.sr
&= ~SR_ZERO
;
233 set_interrupt(IRQ_TIMER
, false);
237 state
.ptbr
= val
& ~(PGSIZE
-1);
243 set_interrupt(IRQ_IPI
, val
& 1);
252 if (state
.tohost
== 0)
256 set_interrupt(IRQ_HOST
, val
!= 0);
257 state
.fromhost
= val
;
264 reg_t
processor_t::get_pcr(int which
)
273 return (state
.fflags
<< FSR_AEXC_SHIFT
) | (state
.frm
<< FSR_RD_SHIFT
);
279 return state
.badvaddr
;
288 return state
.compare
;
309 return state
.fromhost
;
315 void processor_t::set_interrupt(int which
, bool on
)
317 uint32_t mask
= (1 << (which
+ SR_IP_SHIFT
)) & SR_IP
;
324 reg_t
illegal_instruction(processor_t
* p
, insn_t insn
, reg_t pc
)
326 throw trap_illegal_instruction();
329 insn_func_t
processor_t::decode_insn(insn_t insn
)
331 bool rv64
= (state
.sr
& SR_S
) ? (state
.sr
& SR_S64
) : (state
.sr
& SR_U64
);
333 auto key
= insn
.bits() & ((1L << opcode_bits
)-1);
334 for (auto it
= opcode_map
.find(key
); it
!= opcode_map
.end() && it
->first
== key
; ++it
)
335 if ((insn
.bits() & it
->second
.mask
) == it
->second
.match
)
336 return rv64
? it
->second
.rv64
: it
->second
.rv32
;
338 return &illegal_instruction
;
341 void processor_t::register_insn(insn_desc_t desc
)
343 assert(desc
.mask
& 1);
344 if (opcode_bits
== 0 || (desc
.mask
& ((1L << opcode_bits
)-1)) != ((1L << opcode_bits
)-1))
347 while ((desc
.mask
& ((1L << (x
+1))-1)) == ((1L << (x
+1))-1) &&
348 (opcode_bits
== 0 || x
<= opcode_bits
))
352 decltype(opcode_map
) new_map
;
353 for (auto it
= opcode_map
.begin(); it
!= opcode_map
.end(); ++it
)
354 new_map
.insert(std::make_pair(it
->second
.match
& ((1L<<x
)-1), it
->second
));
355 opcode_map
= new_map
;
358 opcode_map
.insert(std::make_pair(desc
.match
& ((1L<<opcode_bits
)-1), desc
));
361 void processor_t::register_extension(extension_t
* x
)
363 for (auto insn
: x
->get_instructions())
365 for (auto disasm_insn
: x
->get_disasms())
366 disassembler
.add_insn(disasm_insn
);
368 throw std::logic_error("only one extension may be registered");
370 x
->set_processor(this);