Skip to content

Commit

Permalink
Merge pull request #2422 from chipsalliance/supervisor-sans-mmu
Browse files Browse the repository at this point in the history
Separate concept of supervisor mode from presence of MMU
  • Loading branch information
aswaterman authored Apr 20, 2020
2 parents 37fc327 + edc804f commit 4689a06
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class RocketLogicalTreeNode(
def getOMInterruptTargets(): Seq[OMInterruptTarget] = {
Seq(OMInterruptTarget(
hartId = tile.rocketParams.hartId,
modes = OMModes.getModes(tile.rocketParams.core.useVM)
modes = OMModes.getModes(tile.rocketParams.core.hasSupervisorMode)
))
}

Expand Down
6 changes: 4 additions & 2 deletions src/main/scala/diplomaticobjectmodel/model/OMISA.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ case object U extends OMExtensionType
case object S extends OMExtensionType

trait OMAddressTranslationMode extends OMEnum
case object Bare extends OMAddressTranslationMode
case object Sv32 extends OMAddressTranslationMode
case object Sv39 extends OMAddressTranslationMode
case object Sv48 extends OMAddressTranslationMode
Expand Down Expand Up @@ -81,6 +82,7 @@ object OMISA {
}

val addressTranslationModes = xLen match {
case _ if !coreParams.useVM => Bare
case 32 => Sv32
case 64 => Sv39
case _ => throw new IllegalArgumentException(s"ERROR: Invalid Xlen: $xLen")
Expand All @@ -95,8 +97,8 @@ object OMISA {
f = coreParams.fpu.map(x => isaExtSpec(F, "2.0")),
d = coreParams.fpu.filter(_.fLen > 32).map(x => isaExtSpec(D, "2.0")),
c = coreParams.useCompressed.option(isaExtSpec(C, " 2.0")),
u = (coreParams.useVM || coreParams.useUser).option(isaExtSpec(U, "1.10")),
s = coreParams.useVM.option(isaExtSpec(S, "1.10")),
u = (coreParams.hasSupervisorMode || coreParams.useUser).option(isaExtSpec(U, "1.10")),
s = coreParams.hasSupervisorMode.option(isaExtSpec(S, "1.10")),
addressTranslationModes = Seq(addressTranslationModes),
customExtensions = customExtensions
)
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/diplomaticobjectmodel/model/OMPLIC.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ case object OMSupervisorMode extends OMPrivilegeMode
case object OMUserMode extends OMPrivilegeMode

object OMModes {
def getModes(useVM: Boolean): Seq[OMPrivilegeMode] = {
useVM match {
def getModes(hasSupervisorMode: Boolean): Seq[OMPrivilegeMode] = {
hasSupervisorMode match {
case false => Seq(OMMachineMode)
case true => Seq(OMMachineMode, OMSupervisorMode)
}
Expand Down
84 changes: 48 additions & 36 deletions src/main/scala/rocket/CSR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -309,15 +309,15 @@ class CSRFile(
val (supported_interrupts, delegable_interrupts) = {
val sup = Wire(new MIP)
sup.usip := false
sup.ssip := Bool(usingVM)
sup.ssip := Bool(usingSupervisor)
sup.hsip := false
sup.msip := true
sup.utip := false
sup.stip := Bool(usingVM)
sup.stip := Bool(usingSupervisor)
sup.htip := false
sup.mtip := true
sup.ueip := false
sup.seip := Bool(usingVM)
sup.seip := Bool(usingSupervisor)
sup.heip := false
sup.meip := true
sup.rocc := usingRoCC
Expand Down Expand Up @@ -357,11 +357,11 @@ class CSRFile(
val reg_mie = Reg(UInt(width = xLen))
val (reg_mideleg, read_mideleg) = {
val reg = Reg(UInt(xLen.W))
(reg, Mux(usingVM, reg & delegable_interrupts, 0.U))
(reg, Mux(usingSupervisor, reg & delegable_interrupts, 0.U))
}
val (reg_medeleg, read_medeleg) = {
val reg = Reg(UInt(xLen.W))
(reg, Mux(usingVM, reg & delegable_exceptions, 0.U))
(reg, Mux(usingSupervisor, reg & delegable_exceptions, 0.U))
}
val reg_mip = Reg(new MIP)
val reg_mepc = Reg(UInt(width = vaddrBitsExtended))
Expand All @@ -381,7 +381,7 @@ class CSRFile(
}
val (reg_scounteren, read_scounteren) = {
val reg = Reg(UInt(32.W))
(reg, Mux(usingVM, reg & delegable_counters, 0.U))
(reg, Mux(usingSupervisor, reg & delegable_counters, 0.U))
}

val reg_sepc = Reg(UInt(width = vaddrBitsExtended))
Expand Down Expand Up @@ -438,7 +438,7 @@ class CSRFile(
val isaString = (if (coreParams.useRVE) "E" else "I") +
isaMaskString +
"X" + // Custom extensions always present (e.g. CEASE instruction)
(if (usingVM) "S" else "") +
(if (usingSupervisor) "S" else "") +
(if (usingUser) "U" else "")
val isaMax = (BigInt(log2Ceil(xLen) - 4) << (xLen-2)) | isaStringToMask(isaString)
val reg_misa = Reg(init=UInt(isaMax))
Expand Down Expand Up @@ -517,7 +517,7 @@ class CSRFile(
}
}

if (usingVM) {
if (usingSupervisor) {
val read_sie = reg_mie & read_mideleg
val read_sip = read_mip & read_mideleg
val read_sstatus = Wire(init = 0.U.asTypeOf(new MStatus))
Expand Down Expand Up @@ -581,7 +581,7 @@ class CSRFile(
WFI-> List(N,N,N,N,Y,N)) ++
usingDebug.option( DRET-> List(N,N,Y,N,N,N)) ++
coreParams.haveCFlush.option(CFLUSH_D_L1-> List(N,N,N,N,N,N)) ++
usingVM.option( SRET-> List(N,N,Y,N,N,N)) ++
usingSupervisor.option( SRET-> List(N,N,Y,N,N,N)) ++
usingVM.option( SFENCE_VMA-> List(N,N,N,N,N,Y))

val insn_call :: insn_break :: insn_ret :: insn_cease :: insn_wfi :: insn_sfence :: Nil =
Expand All @@ -594,12 +594,12 @@ class CSRFile(
val _ :: is_break :: is_ret :: _ :: is_wfi :: is_sfence :: Nil =
DecodeLogic(io_dec.csr << 20, decode_table(0)._2.map(x=>X), decode_table).map(_.asBool)

val allow_wfi = Bool(!usingVM) || reg_mstatus.prv > PRV.S || !reg_mstatus.tw
val allow_wfi = Bool(!usingSupervisor) || reg_mstatus.prv > PRV.S || !reg_mstatus.tw
val allow_sfence_vma = Bool(!usingVM) || reg_mstatus.prv > PRV.S || !reg_mstatus.tvm
val allow_sret = Bool(!usingVM) || reg_mstatus.prv > PRV.S || !reg_mstatus.tsr
val allow_sret = Bool(!usingSupervisor) || reg_mstatus.prv > PRV.S || !reg_mstatus.tsr
val counter_addr = io_dec.csr(log2Ceil(read_mcounteren.getWidth)-1, 0)
val allow_counter = (reg_mstatus.prv > PRV.S || read_mcounteren(counter_addr)) &&
(!usingVM || reg_mstatus.prv >= PRV.S || read_scounteren(counter_addr))
(!usingSupervisor || reg_mstatus.prv >= PRV.S || read_scounteren(counter_addr))
io_dec.fp_illegal := io.status.fs === 0 || !reg_misa('f'-'a')
io_dec.vector_illegal := io.status.vs === 0 || !reg_misa('v'-'a')
io_dec.fp_csr := decodeFast(fp_csrs.keys.toList)
Expand Down Expand Up @@ -629,7 +629,7 @@ class CSRFile(
val causeIsDebugBreak = !cause(xLen-1) && insn_break && Cat(reg_dcsr.ebreakm, reg_dcsr.ebreakh, reg_dcsr.ebreaks, reg_dcsr.ebreaku)(reg_mstatus.prv)
val trapToDebug = Bool(usingDebug) && (reg_singleStepped || causeIsDebugInt || causeIsDebugTrigger || causeIsDebugBreak || reg_debug)
val debugTVec = Mux(reg_debug, Mux(insn_break, UInt(0x800), UInt(0x808)), UInt(0x800))
val delegate = Bool(usingVM) && reg_mstatus.prv <= PRV.S && Mux(cause(xLen-1), read_mideleg(cause_lsbs), read_medeleg(cause_lsbs))
val delegate = Bool(usingSupervisor) && reg_mstatus.prv <= PRV.S && Mux(cause(xLen-1), read_mideleg(cause_lsbs), read_medeleg(cause_lsbs))
def mtvecBaseAlign = 2
def mtvecInterruptAlign = {
require(reg_mip.getWidth <= xLen)
Expand All @@ -652,7 +652,7 @@ class CSRFile(
io.status.debug := reg_debug
io.status.isa := reg_misa
io.status.uxl := (if (usingUser) log2Ceil(xLen) - 4 else 0)
io.status.sxl := (if (usingVM) log2Ceil(xLen) - 4 else 0)
io.status.sxl := (if (usingSupervisor) log2Ceil(xLen) - 4 else 0)
io.status.dprv := Reg(next = Mux(reg_mstatus.mprv && !reg_debug, reg_mstatus.mpp, reg_mstatus.prv))
if (xLen == 32)
io.status.sd_rv32 := io.status.sd
Expand Down Expand Up @@ -712,7 +712,8 @@ class CSRFile(
val supported_exceptions: BigInt = 0x8fe |
(if (usingCompressed && !coreParams.misaWritable) 0 else 1) |
(if (usingUser) 0x100 else 0) |
(if (usingVM) 0xb200 else 0)
(if (usingSupervisor) 0x200 else 0) |
(if (usingVM) 0xb000 else 0)
if (((supported_exceptions >> i) & 1) != 0) {
val en = exception && cause === i
val delegable = (delegable_exceptions & (BigInt(1) << i).U) =/= 0
Expand All @@ -722,7 +723,7 @@ class CSRFile(
}

when (insn_ret) {
when (Bool(usingVM) && !io.rw.addr(9)) {
when (Bool(usingSupervisor) && !io.rw.addr(9)) {
reg_mstatus.sie := reg_mstatus.spie
reg_mstatus.spie := true
reg_mstatus.spp := PRV.U
Expand Down Expand Up @@ -803,19 +804,21 @@ class CSRFile(
if (usingUser) {
reg_mstatus.mprv := new_mstatus.mprv
reg_mstatus.mpp := legalizePrivilege(new_mstatus.mpp)
if (usingVM) {
reg_mstatus.mxr := new_mstatus.mxr
reg_mstatus.sum := new_mstatus.sum
if (usingSupervisor) {
reg_mstatus.spp := new_mstatus.spp
reg_mstatus.spie := new_mstatus.spie
reg_mstatus.sie := new_mstatus.sie
reg_mstatus.tw := new_mstatus.tw
reg_mstatus.tvm := new_mstatus.tvm
reg_mstatus.tsr := new_mstatus.tsr
}
if (usingVM) {
reg_mstatus.mxr := new_mstatus.mxr
reg_mstatus.sum := new_mstatus.sum
reg_mstatus.tvm := new_mstatus.tvm
}
}

if (usingVM || usingFPU || usingVector) reg_mstatus.fs := formFS(new_mstatus.fs)
if (usingSupervisor || usingFPU) reg_mstatus.fs := formFS(new_mstatus.fs)
reg_mstatus.vs := formVS(new_mstatus.vs)
if (usingRoCC) reg_mstatus.xs := Fill(2, new_mstatus.xs.orR)
}
Expand All @@ -834,7 +837,7 @@ class CSRFile(
// io.interrupts.seip. We don't want the value on the PLIC line to
// inadvertently be OR'd into read_mip.seip.
val new_mip = readModifyWriteCSR(io.rw.cmd, reg_mip.asUInt, io.rw.wdata).asTypeOf(new MIP)
if (usingVM) {
if (usingSupervisor) {
reg_mip.ssip := new_mip.ssip
reg_mip.stip := new_mip.stip
reg_mip.seip := new_mip.seip
Expand Down Expand Up @@ -871,36 +874,40 @@ class CSRFile(
val new_dcsr = new DCSR().fromBits(wdata)
reg_dcsr.step := new_dcsr.step
reg_dcsr.ebreakm := new_dcsr.ebreakm
if (usingVM) reg_dcsr.ebreaks := new_dcsr.ebreaks
if (usingSupervisor) reg_dcsr.ebreaks := new_dcsr.ebreaks
if (usingUser) reg_dcsr.ebreaku := new_dcsr.ebreaku
if (usingUser) reg_dcsr.prv := legalizePrivilege(new_dcsr.prv)
}
when (decoded_addr(CSRs.dpc)) { reg_dpc := formEPC(wdata) }
when (decoded_addr(CSRs.dscratch)) { reg_dscratch := wdata }
}
if (usingVM) {
if (usingSupervisor) {
when (decoded_addr(CSRs.sstatus)) {
val new_sstatus = new MStatus().fromBits(wdata)
reg_mstatus.sie := new_sstatus.sie
reg_mstatus.spie := new_sstatus.spie
reg_mstatus.spp := new_sstatus.spp
reg_mstatus.mxr := new_sstatus.mxr
reg_mstatus.sum := new_sstatus.sum
reg_mstatus.fs := formFS(new_sstatus.fs)
reg_mstatus.vs := formVS(new_sstatus.vs)
if (usingVM) {
reg_mstatus.mxr := new_sstatus.mxr
reg_mstatus.sum := new_sstatus.sum
}
if (usingRoCC) reg_mstatus.xs := Fill(2, new_sstatus.xs.orR)
}
when (decoded_addr(CSRs.sip)) {
val new_sip = new MIP().fromBits((read_mip & ~read_mideleg) | (wdata & read_mideleg))
reg_mip.ssip := new_sip.ssip
}
when (decoded_addr(CSRs.satp)) {
val new_satp = new PTBR().fromBits(wdata)
val valid_modes = 0 +: (minPgLevels to pgLevels).map(new_satp.pgLevelsToMode(_))
when (new_satp.mode.isOneOf(valid_modes.map(_.U))) {
reg_satp.mode := new_satp.mode & valid_modes.reduce(_|_)
reg_satp.ppn := new_satp.ppn(ppnBits-1,0)
if (asIdBits > 0) reg_satp.asid := new_satp.asid(asIdBits-1,0)
if (usingVM) {
val new_satp = new PTBR().fromBits(wdata)
val valid_modes = 0 +: (minPgLevels to pgLevels).map(new_satp.pgLevelsToMode(_))
when (new_satp.mode.isOneOf(valid_modes.map(_.U))) {
reg_satp.mode := new_satp.mode & valid_modes.reduce(_|_)
reg_satp.ppn := new_satp.ppn(ppnBits-1,0)
if (asIdBits > 0) reg_satp.asid := new_satp.asid(asIdBits-1,0)
}
}
}
when (decoded_addr(CSRs.sie)) { reg_mie := (reg_mie & ~read_mideleg) | (wdata & read_mideleg) }
Expand Down Expand Up @@ -993,16 +1000,21 @@ class CSRFile(
}

reg_satp.asid := 0
if (!usingVM) {
reg_satp.mode := 0
reg_satp.ppn := 0
}

if (nBreakpoints <= 1) reg_tselect := 0
for (bpc <- reg_bp map {_.control}) {
bpc.ttype := bpc.tType
bpc.maskmax := bpc.maskMax
bpc.reserved := 0
bpc.zero := 0
bpc.h := false
if (!usingVM) bpc.s := false
if (!usingSupervisor) bpc.s := false
if (!usingUser) bpc.u := false
if (!usingVM && !usingUser) bpc.m := true
if (!usingSupervisor && !usingUser) bpc.m := true
when (reset) {
bpc.action := 0.U
bpc.dmode := false
Expand Down Expand Up @@ -1046,12 +1058,12 @@ class CSRFile(
}

def legalizePrivilege(priv: UInt): UInt =
if (usingVM) Mux(priv === PRV.H, PRV.U, priv)
if (usingSupervisor) Mux(priv === PRV.H, PRV.U, priv)
else if (usingUser) Fill(2, priv(0))
else PRV.M

def trimPrivilege(priv: UInt): UInt =
if (usingVM) priv
if (usingSupervisor) priv
else legalizePrivilege(priv)

def writeCounter(lo: Int, ctr: WideCounter, wdata: UInt) = {
Expand Down
7 changes: 6 additions & 1 deletion src/main/scala/rocket/IDecode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,15 @@ class CFlushDecode(supportsFlushLine: Boolean)(implicit val p: Parameters) exten
List(Y,N,N,N,N,N,N,Y,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_FLUSH_ALL,N,N,N,N,N,N,N,CSR.I,N,N,N,N))
}

class SVMDecode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
SFENCE_VMA->List(Y,N,N,N,N,N,Y,Y,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_SFENCE, N,N,N,N,N,N,N,CSR.N,N,N,N,N))
}

class SDecode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
SFENCE_VMA->List(Y,N,N,N,N,N,Y,Y,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_SFENCE, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
SRET-> List(Y,N,N,N,N,N,N,X,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N))
}

Expand Down
4 changes: 3 additions & 1 deletion src/main/scala/rocket/RocketCore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ case class RocketCoreParams(
bootFreqHz: BigInt = 0,
useVM: Boolean = true,
useUser: Boolean = false,
useSupervisor: Boolean = false,
useDebug: Boolean = true,
useAtomics: Boolean = true,
useAtomicsOnlyForIO: Boolean = false,
Expand Down Expand Up @@ -172,7 +173,8 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
(usingRoCC.option(new RoCCDecode)) ++:
(rocketParams.useSCIE.option(new SCIEDecode)) ++:
(if (xLen == 32) new I32Decode else new I64Decode) +:
(usingVM.option(new SDecode)) ++:
(usingVM.option(new SVMDecode)) ++:
(usingSupervisor.option(new SDecode)) ++:
(usingDebug.option(new DebugDecode)) ++:
Seq(new FenceIDecode(tile.dcache.flushOnFenceI)) ++:
coreParams.haveCFlush.option(new CFlushDecode(tile.dcache.canSupportCFlushLine)) ++:
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/subsystem/HasTiles.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ trait HasTiles extends HasCoreMonitorBundles { this: BaseSubsystem =>
plicOpt .map { _.intnode }
.getOrElse { meipNode.get }

// From PLIC: "seip" (only if vm/supervisor mode is enabled)
if (tile.tileParams.core.useVM) {
// From PLIC: "seip" (only if supervisor mode is enabled)
if (tile.tileParams.core.hasSupervisorMode) {
tile.crossIntIn() :=
plicOpt .map { _.intnode }
.getOrElse { NullIntSource() }
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/tile/BaseTile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ trait HasNonDiplomaticTileParameters {
def tileParams: TileParams = p(TileKey)

def usingVM: Boolean = tileParams.core.useVM
def usingUser: Boolean = tileParams.core.useUser || usingVM
def usingUser: Boolean = tileParams.core.useUser || usingSupervisor
def usingSupervisor: Boolean = tileParams.core.hasSupervisorMode
def usingDebug: Boolean = tileParams.core.useDebug
def usingRoCC: Boolean = !p(BuildRoCC).isEmpty
def usingBTB: Boolean = tileParams.btb.isDefined && tileParams.btb.get.nEntries > 0
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/tile/Core.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ trait CoreParams {
val bootFreqHz: BigInt
val useVM: Boolean
val useUser: Boolean
val useSupervisor: Boolean
val useDebug: Boolean
val useAtomics: Boolean
val useAtomicsOnlyForIO: Boolean
Expand Down Expand Up @@ -43,6 +44,7 @@ trait CoreParams {
val mtvecWritable: Boolean
def customCSRs(implicit p: Parameters): CustomCSRs = new CustomCSRs

def hasSupervisorMode: Boolean = useSupervisor || useVM
def instBytes: Int = instBits / 8
def fetchBytes: Int = fetchWidth * instBytes
def lrscCycles: Int
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/tile/Interrupts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class TileInterrupts(implicit p: Parameters) extends CoreBundle()(p) {
val mtip = Bool()
val msip = Bool()
val meip = Bool()
val seip = usingVM.option(Bool())
val seip = usingSupervisor.option(Bool())
val lip = Vec(coreParams.nLocalInterrupts, Bool())
}

Expand Down Expand Up @@ -55,7 +55,7 @@ trait SinksExternalInterrupts { this: BaseTile =>
// debug, msip, mtip, meip, seip, lip offsets in CSRs
def csrIntMap: List[Int] = {
val nlips = tileParams.core.nLocalInterrupts
val seip = if (usingVM) Seq(9) else Nil
val seip = if (usingSupervisor) Seq(9) else Nil
List(65535, 3, 7, 11) ++ seip ++ List.tabulate(nlips)(_ + 16)
}

Expand Down

0 comments on commit 4689a06

Please sign in to comment.