diff options
Diffstat (limited to 'riscv/processor.cc')
-rw-r--r-- | riscv/processor.cc | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/riscv/processor.cc b/riscv/processor.cc index 2a53cca..cce526b 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -39,16 +39,19 @@ void processor_t::reset() { run = false; - // the ISA guarantees the following initial state - set_sr(SR_S | SR_SX); - pc = 0; + // 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 + // and virtual memory disabled. we accomplish this by setting EVEC to + // 0x2000 and *enabling* traps, then sending the core an IPI. + set_sr(SR_S | SR_SX | SR_ET | SR_IM); + evec = 0x2000; // the following state is undefined upon boot-up, // but we zero it for determinism memset(XPR,0,sizeof(XPR)); memset(FPR,0,sizeof(FPR)); - evec = 0; + pc = 0; epc = 0; badvaddr = 0; cause = 0; @@ -118,11 +121,13 @@ void processor_t::setvl(int vlapp) void processor_t::take_interrupt() { - uint32_t interrupts = (cause & CAUSE_IP) >> CAUSE_IP_SHIFT; + uint32_t interrupts = interrupts_pending; interrupts &= (sr & SR_IM) >> SR_IM_SHIFT; if(interrupts && (sr & SR_ET)) - throw trap_interrupt; + for(int i = 0; ; i++, interrupts >>= 1) + if(interrupts & 1) + throw (trap_t)(trap_irq0 + i); } void processor_t::step(size_t n, bool noisy) @@ -193,7 +198,7 @@ void processor_t::step(size_t n, bool noisy) uint32_t old_count = count; count += i; if(old_count < compare && uint64_t(old_count) + i >= compare) - cause |= 1 << (TIMER_IRQ+CAUSE_IP_SHIFT); + interrupts_pending |= 1 << TIMER_IRQ; } void processor_t::take_trap(trap_t t, bool noisy) @@ -204,7 +209,7 @@ void processor_t::take_trap(trap_t t, bool noisy) // switch to supervisor, set previous supervisor bit, disable traps set_sr((((sr & ~SR_ET) | SR_S) & ~SR_PS) | ((sr & SR_S) ? SR_PS : 0)); - cause = (cause & ~CAUSE_EXCCODE) | (t << CAUSE_EXCCODE_SHIFT); + cause = t; epc = pc; pc = evec; badvaddr = mmu.get_badvaddr(); @@ -212,7 +217,7 @@ void processor_t::take_trap(trap_t t, bool noisy) void processor_t::deliver_ipi() { - cause |= 1 << (IPI_IRQ+CAUSE_IP_SHIFT); + interrupts_pending |= 1 << IPI_IRQ; run = true; } |