Browse Source

correct HTIF reset behavior

cores' reset signals can be independently toggled
eos18-bringup
Andrew Waterman 14 years ago
parent
commit
07d126d57e
  1. 13
      riscv/htif.cc
  2. 27
      riscv/processor.cc
  3. 5
      riscv/processor.h

13
riscv/htif.cc

@ -129,17 +129,8 @@ int htif_t::wait_for_packet()
assert(p.data_size == 1); assert(p.data_size == 1);
if (pcr_reg == PCR_RESET) if (pcr_reg == PCR_RESET)
{ {
if (p.data[0] & 1) reset = p.data[0] & 1;
{ sim->procs[pcr_coreid]->reset(reset);
sim->procs[pcr_coreid]->reset();
if (pcr_coreid == 0 && sim->procs[0]->running())
sim->stop();
}
else if (!sim->procs[pcr_coreid]->running())
{
reset = false;
sim->procs[pcr_coreid]->deliver_ipi();
}
} }
else else
{ {

27
riscv/processor.cc

@ -12,7 +12,7 @@
processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id) processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id)
: sim(*_sim), mmu(*_mmu), id(_id), utidx(0) : sim(*_sim), mmu(*_mmu), id(_id), utidx(0)
{ {
reset(); reset(true);
// create microthreads // create microthreads
for (int i=0; i<MAX_UTS; i++) for (int i=0; i<MAX_UTS; i++)
@ -23,7 +23,7 @@ processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id,
uint32_t _utidx) uint32_t _utidx)
: sim(*_sim), mmu(*_mmu), id(_id) : sim(*_sim), mmu(*_mmu), id(_id)
{ {
reset(); reset(true);
set_pcr(PCR_SR, sr | SR_EF | SR_EV); set_pcr(PCR_SR, sr | SR_EF | SR_EV);
utidx = _utidx; utidx = _utidx;
@ -36,23 +36,24 @@ processor_t::~processor_t()
{ {
} }
void processor_t::reset() void processor_t::reset(bool value)
{ {
run = false; if (run == !value)
return;
run = !value;
// the ISA guarantees on boot that the PC is 0x2000 and the the processor // the ISA guarantees on boot that the PC is 0x2000 and the the processor
// is in supervisor mode, and in 64-bit mode, if supported, with traps // is in supervisor mode, and in 64-bit mode, if supported, with traps
// and virtual memory disabled. we accomplish this by setting EVEC to // and virtual memory disabled.
// 0x2000 and *enabling* traps, then sending the core an IPI. set_pcr(PCR_SR, SR_S | SR_S64 | SR_IM);
set_pcr(PCR_SR, SR_S | SR_S64 | SR_ET | SR_IM); pc = 0x2000;
evec = 0x2000;
// the following state is undefined upon boot-up, // the following state is undefined upon boot-up,
// but we zero it for determinism // but we zero it for determinism
XPR.reset(); XPR.reset();
FPR.reset(); FPR.reset();
pc = 0; evec = 0;
epc = 0; epc = 0;
badvaddr = 0; badvaddr = 0;
cause = 0; cause = 0;
@ -165,12 +166,6 @@ void processor_t::step(size_t n, bool noisy)
assert(cmd == vt_command_stop); assert(cmd == vt_command_stop);
break; break;
} }
catch(halt_t t)
{
// sleep until IPI
reset();
return;
}
cycle += i; cycle += i;
@ -203,8 +198,8 @@ void processor_t::take_trap(reg_t t, bool noisy)
void processor_t::deliver_ipi() void processor_t::deliver_ipi()
{ {
if (run)
set_pcr(PCR_CLR_IPI, 1); set_pcr(PCR_CLR_IPI, 1);
run = true;
} }
void processor_t::disasm(insn_t insn, reg_t pc) void processor_t::disasm(insn_t insn, reg_t pc)

5
riscv/processor.h

@ -20,7 +20,7 @@ public:
processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id); processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id);
~processor_t(); ~processor_t();
void reset(); void reset(bool value);
void step(size_t n, bool noisy); // run for n cycles void step(size_t n, bool noisy); // run for n cycles
void deliver_ipi(); // register an interprocessor interrupt void deliver_ipi(); // register an interprocessor interrupt
bool running() { return run; } bool running() { return run; }
@ -58,8 +58,7 @@ private:
// # of bits in an XPR (32 or 64). (redundant with sr) // # of bits in an XPR (32 or 64). (redundant with sr)
int xprlen; int xprlen;
// is this processor running? (deliver_ipi() sets this) bool run; // !reset
bool run;
// functions // functions
void take_interrupt(); // take a trap if any interrupts are pending void take_interrupt(); // take a trap if any interrupts are pending

Loading…
Cancel
Save