12 processor_t::processor_t(sim_t
* _sim
, mmu_t
* _mmu
, uint32_t _id
)
13 : sim(*_sim
), mmu(*_mmu
), id(_id
), utidx(0)
17 // create microthreads
18 for (int i
=0; i
<MAX_UTS
; i
++)
19 uts
[i
] = new processor_t(&sim
, &mmu
, id
, i
);
22 processor_t::processor_t(sim_t
* _sim
, mmu_t
* _mmu
, uint32_t _id
,
24 : sim(*_sim
), mmu(*_mmu
), id(_id
), utidx(_utidx
)
27 set_sr(sr
| SR_EF
| SR_EV
);
29 // microthreads don't possess their own microthreads
30 for (int i
=0; i
<MAX_UTS
; i
++)
34 processor_t::~processor_t()
38 void processor_t::reset()
42 // the ISA guarantees the following initial state
46 // the following state is undefined upon boot-up,
47 // but we zero it for determinism
48 memset(XPR
,0,sizeof(XPR
));
49 memset(FPR
,0,sizeof(FPR
));
73 void processor_t::set_sr(uint32_t val
)
75 sr
= val
& ~SR_ZERO
; // clear SR bits that read as zero
77 #ifndef RISCV_ENABLE_64BIT
78 sr
&= ~(SR_SX
| SR_UX
); // SX=UX=0 for RV32 implementations
80 #ifndef RISCV_ENABLE_FPU
83 #ifndef RISCV_ENABLE_RVC
86 #ifndef RISCV_ENABLE_VEC
90 // update MMU state and flush TLB
91 mmu
.set_vm_enabled(sr
& SR_VM
);
92 mmu
.set_supervisor(sr
& SR_S
);
95 // set the fixed-point register length
96 xprlen
= ((sr
& SR_S
) ? (sr
& SR_SX
) : (sr
& SR_UX
)) ? 64 : 32;
99 void processor_t::set_fsr(uint32_t val
)
101 fsr
= val
& ~FSR_ZERO
; // clear FSR bits that read as zero
104 void processor_t::vcfg()
106 if (nxpr_use
+ nfpr_use
< 2)
107 vlmax
= nxfpr_bank
* vecbanks_count
;
109 vlmax
= (nxfpr_bank
/ (nxpr_use
+ nfpr_use
- 1)) * vecbanks_count
;
111 vlmax
= std::min(vlmax
, MAX_UTS
);
114 void processor_t::setvl(int vlapp
)
116 vl
= std::min(vlmax
, vlapp
);
119 void processor_t::take_interrupt()
121 uint32_t interrupts
= (cause
& CAUSE_IP
) >> CAUSE_IP_SHIFT
;
122 interrupts
&= (sr
& SR_IM
) >> SR_IM_SHIFT
;
124 if(interrupts
&& (sr
& SR_ET
))
125 throw trap_interrupt
;
128 void processor_t::step(size_t n
, bool noisy
)
143 // execute_insn fetches and executes one instruction
144 #define execute_insn(noisy) \
146 insn = _mmu.load_insn(npc, sr & SR_EC, &func); \
147 if(noisy) disasm(insn,pc); \
148 npc = func(this, insn, npc); \
152 if(noisy
) for( ; i
< n
; i
++) // print out instructions as we go
156 // unrolled for speed
157 for( ; n
> 3 && i
< n
-3; i
+=4)
172 // an exception occurred in the target processor
176 catch(vt_command_t cmd
)
178 // this microthread has finished
180 assert(cmd
== vt_command_stop
);
192 // update timer and possibly register a timer interrupt
193 uint32_t old_count
= count
;
195 if(old_count
< compare
&& uint64_t(old_count
) + i
>= compare
)
196 cause
|= 1 << (TIMER_IRQ
+CAUSE_IP_SHIFT
);
199 void processor_t::take_trap(trap_t t
, bool noisy
)
202 printf("core %3d: trap %s, pc 0x%016llx\n",
203 id
, trap_name(t
), (unsigned long long)pc
);
205 // switch to supervisor, set previous supervisor bit, disable traps
206 set_sr((((sr
& ~SR_ET
) | SR_S
) & ~SR_PS
) | ((sr
& SR_S
) ? SR_PS
: 0));
207 cause
= (cause
& ~CAUSE_EXCCODE
) | (t
<< CAUSE_EXCCODE_SHIFT
);
210 badvaddr
= mmu
.get_badvaddr();
213 void processor_t::deliver_ipi()
215 cause
|= 1 << (IPI_IRQ
+CAUSE_IP_SHIFT
);
219 void processor_t::disasm(insn_t insn
, reg_t pc
)
221 printf("core %3d: 0x%016llx (0x%08x) ",id
,(unsigned long long)pc
,insn
.bits
);
223 #ifdef RISCV_HAVE_LIBOPCODES
224 disassemble_info info
;
225 INIT_DISASSEMBLE_INFO(info
, stdout
, fprintf
);
226 info
.flavour
= bfd_target_unknown_flavour
;
227 info
.arch
= bfd_arch_mips
;
228 info
.mach
= 101; // XXX bfd_mach_mips_riscv requires modified bfd.h
229 info
.endian
= BFD_ENDIAN_LITTLE
;
230 info
.buffer
= (bfd_byte
*)&insn
;
231 info
.buffer_length
= sizeof(insn
);
232 info
.buffer_vma
= pc
;
234 int ret
= print_insn_little_mips(pc
, &info
);
235 assert(ret
== insn_length(insn
.bits
));