From cd4d296a0c65eb923b309b4c96522f206739ad2a Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Thu, 14 May 2020 17:22:32 +0100 Subject: [PATCH] Initial attempt to allow reads/writes to xtvec, xepc via xtcc, xepcc --- src_Core/RISCY_OOO/procs/lib/Decode.bsv | 60 +++++++++++++++++----- src_Core/RISCY_OOO/procs/lib/Exec.bsv | 34 ++++++++---- src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv | 10 +++- 3 files changed, 81 insertions(+), 23 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index 5c9c923..92c9d07 100755 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -858,19 +858,55 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.imm = Invalid; end else begin // fnCSRRWI, fnCSRRW, fnCSRRSI, fnCSRRS, fnCSRRCI, fnCSRRC - // TODO change to SCR if r/w to x{epc,tvec}? - dInst.iType = Csr; - dInst.execFunc = (case (funct3) - fnCSRRWI, fnCSRRW: tagged Alu Csrw; - fnCSRRSI, fnCSRRS: tagged Alu Csrs; - fnCSRRCI, fnCSRRC: tagged Alu Csrc; - endcase); + if (truncate(immI) == pack(CSRmtvec) || truncate(immI) == pack(CSRmepc) || truncate(immI) == pack(CSRstvec) || truncate(immI) == pack(CSRsepc)) begin + Bool shouldWrite = (funct3 == fnCSRRWI || funct3 == fnCSRRW) || rs1 != 0; + dInst.iType = shouldWrite ? Scr : Cap; + regs.dst = Valid(tagged Gpr rd); + regs.src1 = (funct3[2] == 0 ? Valid(tagged Gpr rs1) : Invalid); + dInst.imm = (funct3[2] == 0 ? Invalid : Valid(zeroExtend(rs1))); + regs.src2 = Invalid; - regs.dst = Valid(tagged Gpr rd); - regs.src1 = Invalid; // going to be CSR Reg - regs.src2 = (funct3[2] == 0 ? Valid(tagged Gpr rs1) : Invalid); - dInst.imm = (funct3[2] == 0 ? Invalid : Valid(zeroExtend(rs1))); - dInst.csr = Valid(unpackCSR(truncate(immI))); + CSRAccessFunc accessFunc = (case (funct3) + fnCSRRWI, fnCSRRW: Write; + fnCSRRSI, fnCSRRS: Set; + fnCSRRCI, fnCSRRC: Clear; + endcase); + + let scrType = ?; + case (truncate(immI)) + pack(CSRmepc): begin + scrType = EPC (accessFunc); + dInst.scr = Valid (SCR_MEPCC); + end + pack(CSRmtvec): begin + scrType = TVEC (accessFunc); + dInst.scr = Valid (SCR_MTCC); + end + pack(CSRsepc): begin + scrType = EPC (accessFunc); + dInst.scr = Valid (SCR_SEPCC); + end + pack(CSRstvec): begin + scrType = TVEC (accessFunc); + dInst.scr = Valid (SCR_STCC); + end + endcase + + dInst.capFunc = CapModify (SpecialRW (scrType)); + end else begin + dInst.iType = Csr; + dInst.execFunc = (case (funct3) + fnCSRRWI, fnCSRRW: tagged Alu Csrw; + fnCSRRSI, fnCSRRS: tagged Alu Csrs; + fnCSRRCI, fnCSRRC: tagged Alu Csrc; + endcase); + + regs.dst = Valid(tagged Gpr rd); + regs.src1 = Invalid; // going to be CSR Reg + regs.src2 = (funct3[2] == 0 ? Valid(tagged Gpr rs1) : Invalid); + dInst.imm = (funct3[2] == 0 ? Invalid : Valid(zeroExtend(rs1))); + dInst.csr = Valid(unpackCSR(truncate(immI))); + end end end diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index 2703054..dea225d 100755 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -168,12 +168,20 @@ function CapPipe setBoundsALU(CapPipe cap, Data len, SetBoundsFunc boundsOp); endfunction (* noinline *) -function CapPipe specialRWALU(CapPipe cap, SpecialRWFunc scrType); +function CapPipe specialRWALU(CapPipe cap, CapPipe oldCap, SpecialRWFunc scrType); + function csrOp (oldOffset, val, f) = + case (f) + Write: val; + Set: (oldOffset | val); + Clear: (oldOffset & ~val); + endcase; let offset = getOffset(cap); CapPipe res = (case (scrType) matches - TCC: update_scr_via_csr(cap, offset & ~64'h2); // Mask out bit 1 - EPCC: update_scr_via_csr(cap, offset & ~64'h1); // Mask out bit 0 TODO factor out update_scr_via_csr - Normal: cap; + tagged TVEC .csrf: update_scr_via_csr(oldCap, csrOp(offset, getAddr(cap), csrf) & ~64'h2); + tagged EPC .csrf: update_scr_via_csr(oldCap, csrOp(offset, getAddr(cap), csrf) & ~64'h1); + tagged TCC: update_scr_via_csr(cap, offset & ~64'h2); // Mask out bit 1 + tagged EPCC: update_scr_via_csr(cap, offset & ~64'h1); // Mask out bit 0 TODO factor out update_scr_via_csr + tagged Normal: cap; endcase); return res; endfunction @@ -186,7 +194,13 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); tagged SetBounds .boundsOp : setBoundsALU(a, getAddr(b), boundsOp); tagged SpecialRW .scrType : - b; + case (scrType) matches + tagged TCC: b; + tagged EPCC: b; + tagged Normal: b; + tagged TVEC ._: nullWithAddr(getOffset(b)); + tagged EPC ._: nullWithAddr(getOffset(b)); + endcase tagged SetAddr .addrSource : if (addrSource == Src2Type && (getKind(b) == UNSEALED)) return nullWithAddr(-1); // TODO correct behaviour around reserved types else return setAddr(a, (addrSource == Src2Type) ? zeroExtend(getKind(b).SEALED_WITH_TYPE) : getAddr(b) ).value; @@ -317,8 +331,8 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C Bool newPcc = dInst.iType == CJALR || dInst.iType == CCall; ControlFlow cf = ControlFlow{pc: pcc, nextPc: nullCap, taken: False, newPcc: newPcc, mispredict: False}; - CapPipe aluVal2 = rVal2; - if (getDInstImm(dInst) matches tagged Valid .imm) aluVal2 = nullWithAddr(imm); //isValid(dInst.imm) ? fromMaybe(?, dInst.imm) : rVal2; + Maybe#(CapPipe) capImm = isValid(getDInstImm(dInst)) ? Valid (nullWithAddr(getDInstImm(dInst).Valid)) : Invalid; + let aluVal2 = fromMaybe(rVal2, capImm); // Get the alu function. By default, it adds. This is used by memory instructions AluFunc alu_f = dInst.execFunc matches tagged Alu .alu_f ? alu_f : Add; Data alu_result = alu(getAddr(rVal1), getAddr(aluVal2), alu_f); @@ -350,8 +364,8 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C CCall : cap_alu_result; CJALR : link_pcc; Jr : nullWithAddr(getOffset(link_pcc)); - Auipc : nullWithAddr(getOffset(pcc) + fromMaybe(?, getDInstImm(dInst))); - Auipcc : incOffset(pcc, fromMaybe(?, getDInstImm(dInst))).value; // could be computed with alu + Auipc : nullWithAddr(getOffset(pcc) + getDInstImm(dInst).Valid); + Auipcc : incOffset(pcc, getDInstImm(dInst).Valid).value; // could be computed with alu Csr : rVal1; Scr : rVal2; Cap : cap_alu_result; @@ -363,7 +377,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C default : cf.nextPc; //TODO should this be nullified? endcase); - CapPipe scr_data = specialRWALU(rVal1, dInst.capFunc.CapModify.SpecialRW); + CapPipe scr_data = specialRWALU(fromMaybe(rVal1, capImm), aluVal2, dInst.capFunc.CapModify.SpecialRW); return ExecResult{data: data, csrData: csr_data, scrData: scr_data, addr: addr, controlFlow: cf, capException: capException, boundsCheck: boundsCheck}; endfunction diff --git a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv index 38ba061..58aaeff 100755 --- a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv @@ -252,7 +252,15 @@ typedef enum { } SetBoundsFunc deriving(Bits, Eq, FShow); typedef enum { - TCC, EPCC, Normal + Write, Set, Clear +} CSRAccessFunc deriving(Bits, Eq, FShow); + +typedef union tagged { + CSRAccessFunc TVEC; + CSRAccessFunc EPC; + void TCC; + void EPCC; + void Normal; } SpecialRWFunc deriving(Bits, Eq, FShow); typedef enum {