From c34f5413a3eaa560fdccb9be31576e3895d6c83e Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Mon, 25 Mar 2019 10:30:13 +0100 Subject: [PATCH] Add MMU MPRIV for easier machinemode emulation #60 --- src/main/scala/vexriscv/Pipeline.scala | 8 ++++---- src/main/scala/vexriscv/VexRiscv.scala | 3 ++- src/main/scala/vexriscv/plugin/CsrPlugin.scala | 2 ++ src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala | 2 +- src/main/scala/vexriscv/plugin/MmuPlugin.scala | 9 ++++++--- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/main/scala/vexriscv/Pipeline.scala b/src/main/scala/vexriscv/Pipeline.scala index 91c5c1f..6cbf1c7 100644 --- a/src/main/scala/vexriscv/Pipeline.scala +++ b/src/main/scala/vexriscv/Pipeline.scala @@ -7,14 +7,14 @@ import spinal.lib._ import scala.collection.mutable import scala.collection.mutable.ArrayBuffer -trait PipelineConfig[T] +trait PipelineThing[T] trait Pipeline { type T <: Pipeline val plugins = ArrayBuffer[Plugin[T]]() var stages = ArrayBuffer[Stage]() var unremovableStages = mutable.Set[Stage]() - val configs = mutable.HashMap[PipelineConfig[_], Any]() + val configs = mutable.HashMap[PipelineThing[_], Any]() // val services = ArrayBuffer[Any]() def indexOf(stage : Stage) = stages.indexOf(stage) @@ -37,8 +37,8 @@ trait Pipeline { filtered.head.asInstanceOf[T] } - def update[T](that : PipelineConfig[T], value : T) : Unit = configs(that) = value - def apply[T](that : PipelineConfig[T]) : T = configs(that).asInstanceOf[T] + def update[T](that : PipelineThing[T], value : T) : Unit = configs(that) = value + def apply[T](that : PipelineThing[T]) : T = configs(that).asInstanceOf[T] def build(): Unit ={ plugins.foreach(_.pipeline = this.asInstanceOf[T]) diff --git a/src/main/scala/vexriscv/VexRiscv.scala b/src/main/scala/vexriscv/VexRiscv.scala index 9665a31..aead240 100644 --- a/src/main/scala/vexriscv/VexRiscv.scala +++ b/src/main/scala/vexriscv/VexRiscv.scala @@ -42,6 +42,7 @@ case class VexRiscvConfig(){ object REGFILE_WRITE_VALID extends Stageable(Bool) object REGFILE_WRITE_DATA extends Stageable(Bits(32 bits)) + object MPP extends PipelineThing[UInt] object SRC1 extends Stageable(Bits(32 bits)) object SRC2 extends Stageable(Bits(32 bits)) @@ -79,7 +80,7 @@ case class VexRiscvConfig(){ -object RVC_GEN extends PipelineConfig[Boolean] +object RVC_GEN extends PipelineThing[Boolean] class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{ type T = VexRiscv import config._ diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 35866b4..eeb7eb1 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -499,6 +499,8 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception //User CSR ucycleAccess(CSR.UCYCLE, mcycle(31 downto 0)) ucycleAccess(CSR.UCYCLEH, mcycle(63 downto 32)) + + pipeline.update(MPP, mstatus.MPP) } val supervisorCsr = ifGen(supervisorGen) { diff --git a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala index 3e84789..3dc7ad3 100644 --- a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala @@ -271,7 +271,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, } if(memoryTranslatorPortConfig != null) { - mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(MemoryTranslatorPort.PRIORITY_INSTRUCTION, memoryTranslatorPortConfig) + mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(MemoryTranslatorPort.PRIORITY_DATA, memoryTranslatorPortConfig) redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(pipeline.memory) } } diff --git a/src/main/scala/vexriscv/plugin/MmuPlugin.scala b/src/main/scala/vexriscv/plugin/MmuPlugin.scala index ae51514..682ab74 100644 --- a/src/main/scala/vexriscv/plugin/MmuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/MmuPlugin.scala @@ -87,14 +87,14 @@ class MmuPlugin(virtualRange : UInt => Bool, val csr = pipeline plug new Area{ val status = new Area{ - val sum, mxr = RegInit(False) + val sum, mxr, mprv = RegInit(False) } val satp = new Area { val mode = RegInit(False) val ppn = Reg(UInt(20 bits)) } - for(offset <- List(CSR.MSTATUS, CSR.SSTATUS)) csrService.rw(offset, 19 -> status.mxr, 18 -> status.sum) + for(offset <- List(CSR.MSTATUS, CSR.SSTATUS)) csrService.rw(offset, 19 -> status.mxr, 18 -> status.sum, 17 -> status.mprv) csrService.rw(CSR.SATP, 31 -> satp.mode, 0 -> satp.ppn) //TODO write only ? } @@ -108,7 +108,10 @@ class MmuPlugin(virtualRange : UInt => Bool, val privilegeService = pipeline.serviceElse(classOf[PrivilegeService], PrivilegeServiceDefault()) val entryToReplace = Counter(port.args.portTlbSize) val requireMmuLockup = virtualRange(port.bus.cmd.virtualAddress) && !port.bus.cmd.bypassTranslation && csr.satp.mode - if(!allowMachineModeMmu) requireMmuLockup clearWhen(privilegeService.isMachine()) + if(!allowMachineModeMmu) { + requireMmuLockup clearWhen(!csr.status.mprv && privilegeService.isMachine()) + if(port.priority == MmuPort.PRIORITY_DATA) requireMmuLockup clearWhen(csr.status.mprv && pipeline(config.MPP) === 3) + } when(requireMmuLockup) { port.bus.rsp.physicalAddress := cacheLine.physicalAddress(1) @@ (cacheLine.superPage ? port.bus.cmd.virtualAddress(21 downto 12) | cacheLine.physicalAddress(0)) @@ port.bus.cmd.virtualAddress(11 downto 0)