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
)
27 set_pcr(PCR_SR
, sr
| SR_EF
| SR_EV
);
30 // microthreads don't possess their own microthreads
31 for (int i
=0; i
<MAX_UTS
; i
++)
35 processor_t::~processor_t()
39 void processor_t::reset(bool value
)
45 // the ISA guarantees on boot that the PC is 0x2000 and the the processor
46 // is in supervisor mode, and in 64-bit mode, if supported, with traps
47 // and virtual memory disabled.
48 set_pcr(PCR_SR
, SR_S
| SR_S64
| SR_IM
);
51 // the following state is undefined upon boot-up,
52 // but we zero it for determinism
78 void processor_t::set_fsr(uint32_t val
)
80 fsr
= val
& ~FSR_ZERO
; // clear FSR bits that read as zero
83 void processor_t::vcfg()
85 if (nxpr_use
+ nfpr_use
< 2)
86 vlmax
= nxfpr_bank
* vecbanks_count
;
88 vlmax
= (nxfpr_bank
/ (nxpr_use
+ nfpr_use
- 1)) * vecbanks_count
;
90 vlmax
= std::min(vlmax
, MAX_UTS
);
93 void processor_t::setvl(int vlapp
)
95 vl
= std::min(vlmax
, vlapp
);
98 void processor_t::take_interrupt()
100 uint32_t interrupts
= interrupts_pending
;
101 interrupts
&= (sr
& SR_IM
) >> SR_IM_SHIFT
;
103 if(interrupts
&& (sr
& SR_ET
))
104 for(int i
= 0; ; i
++, interrupts
>>= 1)
106 throw interrupt_t(i
);
109 void processor_t::step(size_t n
, bool noisy
)
124 // execute_insn fetches and executes one instruction
125 #define execute_insn(noisy) \
127 insn = _mmu.load_insn(npc, sr & SR_EC, &func); \
128 if(noisy) disasm(insn,pc); \
129 npc = func(this, insn, npc); \
133 if(noisy
) for( ; i
< n
; i
++) // print out instructions as we go
137 // unrolled for speed
138 for( ; n
> 3 && i
< n
-3; i
+=4)
153 // an exception occurred in the target processor
160 take_trap((1ULL << (8*sizeof(reg_t
)-1)) + t
.i
, noisy
);
162 catch(vt_command_t cmd
)
164 // this microthread has finished
166 assert(cmd
== vt_command_stop
);
172 // update timer and possibly register a timer interrupt
173 uint32_t old_count
= count
;
175 if(old_count
< compare
&& uint64_t(old_count
) + i
>= compare
)
176 interrupts_pending
|= 1 << IRQ_TIMER
;
179 void processor_t::take_trap(reg_t t
, bool noisy
)
184 printf("core %3d: interrupt %lld, pc 0x%016llx\n",
185 id
, (long long)(t
<< 1 >> 1), (unsigned long long)pc
);
187 printf("core %3d: trap %s, pc 0x%016llx\n",
188 id
, trap_name(trap_t(t
)), (unsigned long long)pc
);
191 // switch to supervisor, set previous supervisor bit, disable traps
192 set_pcr(PCR_SR
, (((sr
& ~SR_ET
) | SR_S
) & ~SR_PS
) | ((sr
& SR_S
) ? SR_PS
: 0));
196 badvaddr
= mmu
.get_badvaddr();
199 void processor_t::deliver_ipi()
202 set_pcr(PCR_CLR_IPI
, 1);
205 void processor_t::disasm(insn_t insn
, reg_t pc
)
207 // the disassembler is stateless, so we share it
208 static disassembler disasm
;
209 printf("core %3d: 0x%016llx (0x%08x) %s\n", id
, (unsigned long long)pc
,
210 insn
.bits
, disasm
.disassemble(insn
).c_str());
213 void processor_t::set_pcr(int which
, reg_t val
)
218 sr
= val
& ~SR_ZERO
; // clear SR bits that read as zero
219 #ifndef RISCV_ENABLE_64BIT
220 sr
&= ~(SR_S64
| SR_U64
);
222 #ifndef RISCV_ENABLE_FPU
225 #ifndef RISCV_ENABLE_RVC
228 #ifndef RISCV_ENABLE_VEC
231 // update MMU state and flush TLB
232 mmu
.set_vm_enabled(sr
& SR_VM
);
233 mmu
.set_supervisor(sr
& SR_S
);
235 // set the fixed-point register length
236 xprlen
= ((sr
& SR_S
) ? (sr
& SR_S64
) : (sr
& SR_U64
)) ? 64 : 32;
248 interrupts_pending
&= ~(1 << IRQ_TIMER
);
259 interrupts_pending
|= (1 << IRQ_IPI
);
261 interrupts_pending
&= ~(1 << IRQ_IPI
);
270 vecbanks
= val
& 0xff;
271 vecbanks_count
= __builtin_popcountll(vecbanks
);
283 reg_t
processor_t::get_pcr(int which
)
302 return mmu
.get_ptbr();