diff --git a/src/main/scala/vexriscv/demo/GenFull.scala b/src/main/scala/vexriscv/demo/GenFull.scala index 97ae71a..dfa7b1e 100644 --- a/src/main/scala/vexriscv/demo/GenFull.scala +++ b/src/main/scala/vexriscv/demo/GenFull.scala @@ -49,8 +49,7 @@ object GenFull extends App{ ), new MmuPlugin( virtualRange = _(31 downto 28) === 0xC, - ioRange = _(31 downto 28) === 0xF, - allowUserIo = false + ioRange = _(31 downto 28) === 0xF ), new DecoderSimplePlugin( catchIllegalInstruction = true diff --git a/src/main/scala/vexriscv/demo/Linux.scala b/src/main/scala/vexriscv/demo/Linux.scala index 4bfeb95..a1bd0f7 100644 --- a/src/main/scala/vexriscv/demo/Linux.scala +++ b/src/main/scala/vexriscv/demo/Linux.scala @@ -90,12 +90,11 @@ https://github.com/riscv/riscv-qemu/wiki#build-and-install //TODO test dcache flush //TODO have to check, look like supervisor can't get interrupt if the machine mod didn't delegated it, have to check exactly +//TODO IBus cached and uncached, do not allow supervisor if it's a user page ? io.cpu.fetch.mmuException object LinuxGen { def configFull(litex : Boolean, withMmu : Boolean) = { val config = VexRiscvConfig( plugins = List( - new DummyFencePlugin(), //TODO should be removed for design with caches - //Uncomment the whole IBusSimplePlugin and comment IBusCachedPlugin if you want uncached iBus config // new IBusSimplePlugin( // resetVector = 0x80000000l, @@ -179,7 +178,7 @@ object LinuxGen { ), new RegFilePlugin( regFileReadyKind = plugin.SYNC, - zeroBoot = true //TODO + zeroBoot = true ), new IntAluPlugin, new SrcPlugin( @@ -240,10 +239,7 @@ object LinuxGen { ) ) if(withMmu) config.plugins += new MmuPlugin( - virtualRange = a => True, - // virtualRange = x => x(31 downto 24) =/= 0x81, - ioRange = (x => if(litex) x(31 downto 28) === 0xB || x(31 downto 28) === 0xE || x(31 downto 28) === 0xF else x(31 downto 28) === 0xF), - allowUserIo = true //TODO ?? + ioRange = (x => if(litex) x(31 downto 28) === 0xB || x(31 downto 28) === 0xE || x(31 downto 28) === 0xF else x(31 downto 28) === 0xF) ) else { config.plugins += new StaticMemoryTranslatorPlugin( ioRange = _(31 downto 28) === 0xF diff --git a/src/main/scala/vexriscv/ip/DataCache.scala b/src/main/scala/vexriscv/ip/DataCache.scala index 66f6999..8c50d40 100644 --- a/src/main/scala/vexriscv/ip/DataCache.scala +++ b/src/main/scala/vexriscv/ip/DataCache.scala @@ -8,7 +8,6 @@ import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig} import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig} import spinal.lib.bus.simple._ -//TODO flush case class DataCacheConfig(cacheSize : Int, bytePerLine : Int, diff --git a/src/main/scala/vexriscv/ip/InstructionCache.scala b/src/main/scala/vexriscv/ip/InstructionCache.scala index c36dcdb..08683c4 100644 --- a/src/main/scala/vexriscv/ip/InstructionCache.scala +++ b/src/main/scala/vexriscv/ip/InstructionCache.scala @@ -411,7 +411,7 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{ io.cpu.fetch.cacheMiss := !hit.valid io.cpu.fetch.error := hit.error io.cpu.fetch.mmuRefilling := mmuRsp.refilling - io.cpu.fetch.mmuException := !mmuRsp.refilling && (mmuRsp.exception || !mmuRsp.allowExecute || (!mmuRsp.allowUser && io.cpu.fetch.isUser)) //TODO Do not allow supervisor if it's a user page ? + io.cpu.fetch.mmuException := !mmuRsp.refilling && (mmuRsp.exception || !mmuRsp.allowExecute || (!mmuRsp.allowUser && io.cpu.fetch.isUser)) }) } @@ -441,7 +441,7 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{ io.cpu.decode.cacheMiss := !hit.valid io.cpu.decode.error := hit.error io.cpu.decode.mmuRefilling := mmuRsp.refilling - io.cpu.decode.mmuException := !mmuRsp.refilling && (mmuRsp.exception || !mmuRsp.allowExecute || (!mmuRsp.allowUser && io.cpu.decode.isUser)) //TODO Do not allow supervisor if it's a user page ? + io.cpu.decode.mmuException := !mmuRsp.refilling && (mmuRsp.exception || !mmuRsp.allowExecute || (!mmuRsp.allowUser && io.cpu.decode.isUser)) io.cpu.decode.physicalAddress := mmuRsp.physicalAddress }) } diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 59410f7..3b45cca 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -813,7 +813,7 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception import lastStage._ //Manage MRET / SRET instructions - when(arbitration.isValid && input(ENV_CTRL) === EnvCtrlEnum.XRET) { //TODO do not allow user mode already implemented somewhere else ? + when(arbitration.isValid && input(ENV_CTRL) === EnvCtrlEnum.XRET) { fetcher.haltIt() jumpInterface.valid := True beforeLastStage.arbitration.flushAll := True @@ -885,7 +885,6 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception //Manage MRET / SRET instructions when(arbitration.isValid && input(ENV_CTRL) === EnvCtrlEnum.XRET) { - //TODO check MPP value too when(input(INSTRUCTION)(29 downto 28).asUInt > privilege) { illegalInstruction := True } diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index fcf807b..530ba8a 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -113,6 +113,8 @@ class DBusCachedPlugin(config : DataCacheConfig, MEMORY_MANAGMENT -> True )) + decoderService.add(FENCE, Nil) + mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(MemoryTranslatorPort.PRIORITY_DATA ,memoryTranslatorPortConfig) redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(pipeline.writeBack) @@ -284,6 +286,7 @@ class DBusCachedPlugin(config : DataCacheConfig, mmuBus.cmd.bypassTranslation setWhen(memory.input(IS_DBUS_SHARING)) cache.io.cpu.memory.isValid setWhen(memory.input(IS_DBUS_SHARING)) + cache.io.cpu.memory.mmuBus.rsp.allowUser setWhen(memory.input(IS_DBUS_SHARING)) cache.io.cpu.writeBack.isValid setWhen(writeBack.input(IS_DBUS_SHARING)) dBusAccess.rsp.valid := writeBack.input(IS_DBUS_SHARING) && !cache.io.cpu.writeBack.isWrite && (cache.io.cpu.redo || !cache.io.cpu.writeBack.haltIt) dBusAccess.rsp.data := cache.io.cpu.writeBack.data diff --git a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala index 54b7f19..a1ad3dd 100644 --- a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala @@ -292,6 +292,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, ) } + decoderService.add(FENCE, Nil) rspStage = if(stages.last == execute) execute else (if(emitCmdInMemoryStage) writeBack else memory) if(catchSomething) { diff --git a/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala index 1ecde55..07babf9 100644 --- a/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala @@ -78,8 +78,6 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l, super.setup(pipeline) - //def MANAGEMENT = M"-----------------100-----0001111" - val decoderService = pipeline.service(classOf[DecoderService]) decoderService.addDefault(FLUSH_ALL, False) decoderService.add(FENCE_I, List( diff --git a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala index 269f76a..af77a89 100644 --- a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala @@ -7,6 +7,7 @@ import spinal.lib.bus.amba4.axi._ import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig} import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig} import spinal.lib.bus.simple._ +import vexriscv.Riscv.{FENCE, FENCE_I} case class IBusSimpleCmd() extends Bundle{ @@ -192,6 +193,9 @@ class IBusSimplePlugin(resetVector : BigInt, super.setup(pipeline) iBus = master(IBusSimpleBus(false)).setName("iBus") + val decoderService = pipeline.service(classOf[DecoderService]) + decoderService.add(FENCE_I, Nil) + if(catchSomething) { decodeExceptionPort = pipeline.service(classOf[ExceptionService]).newExceptionPort(pipeline.decode,1) } diff --git a/src/main/scala/vexriscv/plugin/MmuPlugin.scala b/src/main/scala/vexriscv/plugin/MmuPlugin.scala index dfcced5..5d14978 100644 --- a/src/main/scala/vexriscv/plugin/MmuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/MmuPlugin.scala @@ -38,17 +38,16 @@ case class MmuPort(bus : MemoryTranslatorBus, priority : Int, args : MmuPortConf case class MmuPortConfig(portTlbSize : Int) -class MmuPlugin(virtualRange : UInt => Bool, - ioRange : UInt => Bool, - allowUserIo : Boolean, - allowMachineModeMmu : Boolean = false) extends Plugin[VexRiscv] with MemoryTranslator { +class MmuPlugin(ioRange : UInt => Bool, + virtualRange : UInt => Bool = address => True, +// allowUserIo : Boolean = false, + enableMmuInMachineMode : Boolean = false) extends Plugin[VexRiscv] with MemoryTranslator { var dBusAccess : DBusAccess = null val portsInfo = ArrayBuffer[MmuPort]() override def newTranslationPort(priority : Int,args : Any): MemoryTranslatorBus = { -// val exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(stage) - val port = MmuPort(MemoryTranslatorBus(),priority,args.asInstanceOf[MmuPortConfig], portsInfo.length /*,exceptionBus*/) + val port = MmuPort(MemoryTranslatorBus(),priority,args.asInstanceOf[MmuPortConfig], portsInfo.length) portsInfo += port port.bus } @@ -96,7 +95,7 @@ class MmuPlugin(virtualRange : UInt => Bool, } 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 ? + csrService.rw(CSR.SATP, 31 -> satp.mode, 0 -> satp.ppn) } val core = pipeline plug new Area { @@ -109,7 +108,7 @@ 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) { + if(!enableMmuInMachineMode) { requireMmuLockup clearWhen(!csr.status.mprv && privilegeService.isMachine()) when(privilegeService.isMachine()) { if (port.priority == MmuPort.PRIORITY_DATA) { @@ -133,7 +132,7 @@ class MmuPlugin(virtualRange : UInt => Bool, port.bus.rsp.allowRead := True port.bus.rsp.allowWrite := True port.bus.rsp.allowExecute := True - port.bus.rsp.allowUser := Bool(allowUserIo) + port.bus.rsp.allowUser := True port.bus.rsp.exception := False port.bus.rsp.refilling := False }