Skip to content

Commit

Permalink
Check priviledge in decode stage
Browse files Browse the repository at this point in the history
  • Loading branch information
Bohan Hu committed Nov 2, 2020
1 parent a51edf9 commit a95d4c5
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
33 changes: 33 additions & 0 deletions src/main/scala/core/csrFile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,15 @@ class ExceptionRedir extends Bundle {
val redir = Bool()
}

class DecodePrivCheck extends Bundle {
val csrAddr = Input(UInt(12.W))
val csrOp = Input(UInt(3.W))
val instRd = Input(UInt(5.W))
val instRs = Input(UInt(5.W))
val instImm = Input(UInt(32.W))
val illegalInst = Output(Bool())
}

class CSRIO extends Bundle {
val commitCSR = new commitCSR
val illegalInst = Output(Bool())
Expand All @@ -316,13 +325,16 @@ class CSRIO extends Bundle {
// To decoder, let decoder handle the interrupt
val intCtrl = Output(new INTCtrl)
val clintIn = Input(new CLINTCSR)

val decodePrivCheck = new DecodePrivCheck
}

class CSRFile extends Module {
val io = IO(new CSRIO)
val M = "b11".U
val S = "b01".U
val U = "b00".U

val accessCSRPriv = io.commitCSR.csrAddr(9, 8)
// IF the instruction is CSRRW / CSRRWI else
val csrRen = io.commitCSR.instValid && ((io.commitCSR.csrOp === CSR_W && io.commitCSR.instRd =/= 0.U) || (io.commitCSR.csrOp =/= CSR_X && io.commitCSR.csrOp =/= CSR_W))
Expand Down Expand Up @@ -667,6 +679,27 @@ class CSRFile extends Module {
io.ifRedir.redir := true.B
io.ifRedir.redirPC := io.commitCSR.instPC + 4.U
}

// Check priv in decode stage
val decodeAccessCSRPriv = io.decodePrivCheck.csrAddr(9, 8)
// IF the instruction is CSRRW / CSRRWI else
val decodeCSRRen = ((io.decodePrivCheck.csrOp === CSR_W && io.decodePrivCheck.instRd =/= 0.U) || (io.decodePrivCheck.csrOp =/= CSR_X && io.decodePrivCheck.csrOp =/= CSR_W))
val decodeCSRWen = !(io.decodePrivCheck.csrOp === CSR_X || io.decodePrivCheck.csrOp === CSR_I ||
((io.decodePrivCheck.csrOp === CSR_S || io.decodePrivCheck.csrOp === CSR_C) && io.decodePrivCheck.instRs === 0.U) ||
((io.decodePrivCheck.csrOp === CSR_SI || io.decodePrivCheck.csrOp === CSR_CI) && io.decodePrivCheck.instImm === 0.U))
val decodeCSRExists = csrMapping.map(kv => io.decodePrivCheck.csrAddr === kv._1).reduce(_ | _).asBool()
val decodeReadOnlyCSR = io.decodePrivCheck.csrAddr(11, 10) === "b11".U
val decodeCSRFalsePriv = decodeAccessCSRPriv > privMode
// Legal stands for CSR exists and the priv is right
val decodeCSRAddrLegal = decodeCSRExists & !decodeCSRFalsePriv
val decodeWriteIllegalCSR = decodeCSRWen & (!decodeCSRAddrLegal |
(mstatus.asTypeOf(new mstatus).TVM && privMode === S && io.decodePrivCheck.csrAddr === CSRAddr.satp) |
decodeReadOnlyCSR)
val decodeReadIllegalCSR = decodeCSRRen & (!decodeCSRAddrLegal |
(mstatus.asTypeOf(new mstatus).TVM && privMode === S && io.decodePrivCheck.csrAddr === CSRAddr.satp))

io.decodePrivCheck.illegalInst := decodeWriteIllegalCSR | decodeReadIllegalCSR

}

object CSRFile extends App {
Expand Down
16 changes: 14 additions & 2 deletions src/main/scala/core/decode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class Decode extends Module {
val decode2Exe = Output(new Decode2Exe)
val instBundleOut = Output(new InstBundle)
val intCtrl = Input(new INTCtrl)
val decodePrivCheck = Flipped(new DecodePrivCheck)
val PLIC_SEI = Input(Bool())
})

Expand Down Expand Up @@ -211,6 +212,13 @@ class Decode extends Module {
io.instBundleOut := io.instBundleIn
io.instBundleOut.instValid := io.decode2Exe.instValid

// CSR Priv Check
io.decodePrivCheck.csrAddr := io.instBundleIn.inst(31, 20)
io.decodePrivCheck.csrOp := csrOp
io.decodePrivCheck.instRs := RS1
io.decodePrivCheck.instRd := Rd
io.decodePrivCheck.instImm := op2

val M = "b11".U
val S = "b01".U
val U = "b00".U
Expand All @@ -221,10 +229,14 @@ class Decode extends Module {

def makeInt(no: Int) = (no.U | 1.U << 63)

when(!io.exceptionInfoIF.valid) {
when(!io.exceptionInfoIF.valid && io.instBundleIn.instValid) {
exceptionInfo.tval := io.instBundleIn.inst
// TODO: Illegal instruction on xRET when x > privMode

// Illegal Inst (CSR false priv)
when(io.decodePrivCheck.illegalInst) {
exceptionInfo.valid := true.B
exceptionInfo.cause := ExceptionNo.illegalInstr.U
}
// ================= Handle ECALL and EBREAK begins ===================
when(io.instBundleIn.inst === "b00000000000000000000000001110011".U) { // ECALL
exceptionInfo.valid := true.B
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/core/top.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class Top extends Module {
decoder.io.regfileIO <> regfile.io.rdPort
decoder.io.exceptionInfoIF <> ifu.io.exceInfoOut
decoder.io.PLIC_SEI := false.B
decoder.io.decodePrivCheck <> csrFile.io.decodePrivCheck

// DECODER <> EXU
exu.io.instBundleIn := decoder.io.instBundleOut
Expand Down

0 comments on commit a95d4c5

Please sign in to comment.