From 8a5c0e51c3fe386cf2cf4f40d1cb103d3a9f95fd Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Fri, 11 Nov 2011 00:02:01 -0800 Subject: [PATCH] Changed supervisor mode - initial PC is 0x2000 - PCRs renumbered - clearing IPIs now requires a write to a different PCR - IRQs are each given their own cause # --- riscv/decode.h | 5 ----- riscv/insns/mfpcr.h | 25 ++++++------------------- riscv/insns/mtpcr.h | 26 ++++++++++++++------------ riscv/processor.cc | 23 ++++++++++++++--------- riscv/processor.h | 5 +++-- riscv/sim.cc | 5 +++++ riscv/trap.h | 20 +++++++++----------- 7 files changed, 51 insertions(+), 58 deletions(-) diff --git a/riscv/decode.h b/riscv/decode.h index f78c8f4..9c364f6 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -48,11 +48,6 @@ const int JUMP_ALIGN_BITS = 1; #define IPI_IRQ 5 #define TIMER_IRQ 7 -#define CAUSE_EXCCODE 0x000000FF -#define CAUSE_IP 0x0000FF00 -#define CAUSE_EXCCODE_SHIFT 0 -#define CAUSE_IP_SHIFT 8 - #define FP_RD_NE 0 #define FP_RD_0 1 #define FP_RD_DN 2 diff --git a/riscv/insns/mfpcr.h b/riscv/insns/mfpcr.h index 7de089e..c686669 100644 --- a/riscv/insns/mfpcr.h +++ b/riscv/insns/mfpcr.h @@ -26,15 +26,6 @@ switch(insn.rtype.rs2) val = cause; break; case 7: - val = 0; - cause &= ~(1 << (IPI_IRQ+CAUSE_IP_SHIFT)); - break; - - case 8: - val = mmu.memsz >> PGSHIFT; - break; - - case 9: val = mmu.get_ptbr(); break; @@ -42,23 +33,19 @@ switch(insn.rtype.rs2) val = id; break; - case 11: - val = vecbanks; - break; - case 12: - val = sim.num_cores(); + val = pcr_k0; + break; + case 13: + val = pcr_k1; break; case 17: val = sim.get_fromhost(); break; - case 24: - val = pcr_k0; - break; - case 25: - val = pcr_k1; + case 18: + val = vecbanks; break; default: diff --git a/riscv/insns/mtpcr.h b/riscv/insns/mtpcr.h index 59f864f..f06fcf3 100644 --- a/riscv/insns/mtpcr.h +++ b/riscv/insns/mtpcr.h @@ -15,31 +15,33 @@ switch(insn.rtype.rs2) count = RS1; break; case 5: - cause &= ~(1 << (TIMER_IRQ+CAUSE_IP_SHIFT)); + interrupts_pending &= ~(1 << TIMER_IRQ); compare = RS1; break; - case 7: - sim.send_ipi(RS1); + mmu.set_ptbr(RS1); break; + case 8: + sim.send_ipi(RS1); + break; case 9: - mmu.set_ptbr(RS1); + interrupts_pending &= ~(1 << IPI_IRQ); break; - case 11: - vecbanks = RS1 & 0xff; - vecbanks_count = __builtin_popcountll(vecbanks); + case 12: + pcr_k0 = RS1; + break; + case 13: + pcr_k1 = RS1; break; case 16: sim.set_tohost(RS1); break; - case 24: - pcr_k0 = RS1; - break; - case 25: - pcr_k1 = RS1; + case 18: + vecbanks = RS1 & 0xff; + vecbanks_count = __builtin_popcountll(vecbanks); break; } 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; } diff --git a/riscv/processor.h b/riscv/processor.h index 3bc1177..a675141 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -30,7 +30,6 @@ private: reg_t XPR[NXPR]; freg_t FPR[NFPR]; reg_t pc; - uint32_t fsr; // counters reg_t cycle; @@ -38,12 +37,14 @@ private: // privileged control registers reg_t epc; reg_t badvaddr; - reg_t cause; reg_t evec; reg_t pcr_k0; reg_t pcr_k1; + uint32_t cause; + uint32_t interrupts_pending; uint32_t id; uint32_t sr; // only modify the status register using set_sr() + uint32_t fsr; uint32_t count; uint32_t compare; diff --git a/riscv/sim.cc b/riscv/sim.cc index 9020da4..f1c1b3b 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -77,6 +77,11 @@ void sim_t::run(bool debug) { htif->wait_for_start(); + // word 0 of memory contains the memory capacity in MB + mmu->store_uint32(0, memsz >> 20); + // word 1 of memory contains the core count + mmu->store_uint32(4, num_cores()); + // start core 0 send_ipi(0); diff --git a/riscv/trap.h b/riscv/trap.h index ad5491a..8e43c2c 100644 --- a/riscv/trap.h +++ b/riscv/trap.h @@ -7,7 +7,7 @@ DECLARE_TRAP(illegal_instruction), \ DECLARE_TRAP(privileged_instruction), \ DECLARE_TRAP(fp_disabled), \ - DECLARE_TRAP(interrupt), \ + DECLARE_TRAP(reserved0), \ DECLARE_TRAP(syscall), \ DECLARE_TRAP(breakpoint), \ DECLARE_TRAP(load_address_misaligned), \ @@ -18,16 +18,14 @@ DECLARE_TRAP(vector_bank), \ DECLARE_TRAP(vector_illegal_instruction), \ DECLARE_TRAP(reserved1), \ - DECLARE_TRAP(reserved2), \ - DECLARE_TRAP(reserved3), \ - DECLARE_TRAP(int0), \ - DECLARE_TRAP(int1), \ - DECLARE_TRAP(int2), \ - DECLARE_TRAP(int3), \ - DECLARE_TRAP(int4), \ - DECLARE_TRAP(int5), \ - DECLARE_TRAP(int6), \ - DECLARE_TRAP(int7), \ + DECLARE_TRAP(irq0), \ + DECLARE_TRAP(irq1), \ + DECLARE_TRAP(irq2), \ + DECLARE_TRAP(irq3), \ + DECLARE_TRAP(irq4), \ + DECLARE_TRAP(irq5), \ + DECLARE_TRAP(irq6), \ + DECLARE_TRAP(irq7), \ #define DECLARE_TRAP(x) trap_##x enum trap_t -- 2.30.2