diff --git a/src/main/scala/vexriscv/Services.scala b/src/main/scala/vexriscv/Services.scala index 4b0aeca..47a16d1 100644 --- a/src/main/scala/vexriscv/Services.scala +++ b/src/main/scala/vexriscv/Services.scala @@ -71,6 +71,7 @@ case class MemoryTranslatorCmd() extends Bundle{ case class MemoryTranslatorRsp() extends Bundle{ val physicalAddress = UInt(32 bits) val isIoAccess = Bool + val isPaging = Bool val allowRead, allowWrite, allowExecute = Bool val exception = Bool val refilling = Bool diff --git a/src/main/scala/vexriscv/ip/DataCache.scala b/src/main/scala/vexriscv/ip/DataCache.scala index 7cbe4ba..1c60690 100644 --- a/src/main/scala/vexriscv/ip/DataCache.scala +++ b/src/main/scala/vexriscv/ip/DataCache.scala @@ -551,9 +551,20 @@ class DataCache(p : DataCacheConfig) extends Component{ val memCmdSent = RegInit(False) setWhen (io.mem.cmd.ready) clearWhen (!io.cpu.writeBack.isStuck) - io.cpu.redo := False + val badPermissions = (!mmuRsp.allowWrite && request.wr) || (!mmuRsp.allowRead && (!request.wr || isAmo)) + val loadStoreFault = io.cpu.writeBack.isValid && (mmuRsp.exception || badPermissions) + io.cpu.writeBack.accessError := False - io.cpu.writeBack.mmuException := io.cpu.writeBack.isValid && (if(catchIllegal) mmuRsp.exception || (!mmuRsp.allowWrite && request.wr) || (!mmuRsp.allowRead && (!request.wr || isAmo)) else False) + when(mmuRsp.isIoAccess) { + io.cpu.writeBack.data := io.mem.rsp.data + if (catchAccessError) io.cpu.writeBack.accessError := io.mem.rsp.valid && io.mem.rsp.error + } otherwise { + io.cpu.writeBack.data := dataMux + if (catchAccessError) io.cpu.writeBack.accessError := (waysHits & B(tagsReadRsp.map(_.error))) =/= 0 || (loadStoreFault && !mmuRsp.isPaging) + } + + io.cpu.redo := False + io.cpu.writeBack.mmuException := loadStoreFault && (if(catchIllegal) mmuRsp.isPaging else False) io.cpu.writeBack.unalignedAccess := io.cpu.writeBack.isValid && (if(catchUnaligned) ((request.size === 2 && mmuRsp.physicalAddress(1 downto 0) =/= 0) || (request.size === 1 && mmuRsp.physicalAddress(0 downto 0) =/= 0)) else False) io.cpu.writeBack.isWrite := request.wr @@ -626,14 +637,6 @@ class DataCache(p : DataCacheConfig) extends Component{ } } - when(mmuRsp.isIoAccess){ - io.cpu.writeBack.data := io.mem.rsp.data - if(catchAccessError) io.cpu.writeBack.accessError := io.mem.rsp.valid && io.mem.rsp.error - } otherwise { - io.cpu.writeBack.data := dataMux - if(catchAccessError) io.cpu.writeBack.accessError := (waysHits & B(tagsReadRsp.map(_.error))) =/= 0 - } - //remove side effects on exceptions when(mmuRsp.refilling || io.cpu.writeBack.accessError || io.cpu.writeBack.mmuException || io.cpu.writeBack.unalignedAccess){ io.mem.cmd.valid := False diff --git a/src/main/scala/vexriscv/ip/InstructionCache.scala b/src/main/scala/vexriscv/ip/InstructionCache.scala index 4df0f79..380e6b3 100644 --- a/src/main/scala/vexriscv/ip/InstructionCache.scala +++ b/src/main/scala/vexriscv/ip/InstructionCache.scala @@ -438,9 +438,9 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{ val mmuRsp = io.cpu.fetch.mmuBus.rsp io.cpu.fetch.cacheMiss := !hit.valid - io.cpu.fetch.error := hit.error + io.cpu.fetch.error := hit.error || (!mmuRsp.isPaging && (mmuRsp.exception || !mmuRsp.allowExecute)) io.cpu.fetch.mmuRefilling := mmuRsp.refilling - io.cpu.fetch.mmuException := !mmuRsp.refilling && (mmuRsp.exception || !mmuRsp.allowExecute) + io.cpu.fetch.mmuException := !mmuRsp.refilling && mmuRsp.isPaging && (mmuRsp.exception || !mmuRsp.allowExecute) }) } @@ -468,9 +468,9 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{ } io.cpu.decode.cacheMiss := !hit.valid - io.cpu.decode.error := hit.error + io.cpu.decode.error := hit.error || (!mmuRsp.isPaging && (mmuRsp.exception || !mmuRsp.allowExecute)) io.cpu.decode.mmuRefilling := mmuRsp.refilling - io.cpu.decode.mmuException := !mmuRsp.refilling && (mmuRsp.exception || !mmuRsp.allowExecute) + io.cpu.decode.mmuException := !mmuRsp.refilling && mmuRsp.isPaging && (mmuRsp.exception || !mmuRsp.allowExecute) io.cpu.decode.physicalAddress := mmuRsp.physicalAddress }) } diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index fd45dd8..1dedd79 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -273,15 +273,14 @@ class DBusCachedPlugin(val config : DataCacheConfig, exceptionBus.valid := True exceptionBus.code := (input(MEMORY_WR) ? U(7) | U(5)).resized } - - if (catchUnaligned) when(cache.io.cpu.writeBack.unalignedAccess) { - exceptionBus.valid := True - exceptionBus.code := (input(MEMORY_WR) ? U(6) | U(4)).resized - } if(catchIllegal) when (cache.io.cpu.writeBack.mmuException) { exceptionBus.valid := True exceptionBus.code := (input(MEMORY_WR) ? U(15) | U(13)).resized } + if (catchUnaligned) when(cache.io.cpu.writeBack.unalignedAccess) { + exceptionBus.valid := True + exceptionBus.code := (input(MEMORY_WR) ? U(6) | U(4)).resized + } when(cache.io.cpu.redo) { redoBranch.valid := True diff --git a/src/main/scala/vexriscv/plugin/MmuPlugin.scala b/src/main/scala/vexriscv/plugin/MmuPlugin.scala index 9dedde5..6d7f6a8 100644 --- a/src/main/scala/vexriscv/plugin/MmuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/MmuPlugin.scala @@ -127,6 +127,7 @@ class MmuPlugin(ioRange : UInt => Bool, port.bus.rsp.allowExecute := cacheLine.allowExecute port.bus.rsp.exception := cacheHit && (cacheLine.exception || cacheLine.allowUser && privilegeService.isSupervisor() && !csr.status.sum || !cacheLine.allowUser && privilegeService.isUser()) port.bus.rsp.refilling := !cacheHit + port.bus.rsp.isPaging := True } otherwise { port.bus.rsp.physicalAddress := port.bus.cmd.virtualAddress port.bus.rsp.allowRead := True @@ -134,6 +135,7 @@ class MmuPlugin(ioRange : UInt => Bool, port.bus.rsp.allowExecute := True port.bus.rsp.exception := False port.bus.rsp.refilling := False + port.bus.rsp.isPaging := False } port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress) diff --git a/src/main/scala/vexriscv/plugin/PmpPlugin.scala b/src/main/scala/vexriscv/plugin/PmpPlugin.scala index f232ee4..88be675 100644 --- a/src/main/scala/vexriscv/plugin/PmpPlugin.scala +++ b/src/main/scala/vexriscv/plugin/PmpPlugin.scala @@ -205,6 +205,7 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] } port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress) + port.bus.rsp.isPaging := False port.bus.rsp.exception := False port.bus.rsp.refilling := False port.bus.busy := False diff --git a/src/main/scala/vexriscv/plugin/StaticMemoryTranslatorPlugin.scala b/src/main/scala/vexriscv/plugin/StaticMemoryTranslatorPlugin.scala index 351ebc5..7a31d18 100644 --- a/src/main/scala/vexriscv/plugin/StaticMemoryTranslatorPlugin.scala +++ b/src/main/scala/vexriscv/plugin/StaticMemoryTranslatorPlugin.scala @@ -32,6 +32,7 @@ class StaticMemoryTranslatorPlugin(ioRange : UInt => Bool) extends Plugin[VexRis port.bus.rsp.allowWrite := True port.bus.rsp.allowExecute := True port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress) + port.bus.rsp.isPaging := False port.bus.rsp.exception := False port.bus.rsp.refilling := False port.bus.busy := False