Distinguish between page faults from MMU and access faults from PMP

This commit is contained in:
Samuel Lindemer 2021-01-14 08:34:54 +01:00
parent d2855fcfca
commit 5e6c645461
7 changed files with 26 additions and 19 deletions

View File

@ -71,6 +71,7 @@ case class MemoryTranslatorCmd() extends Bundle{
case class MemoryTranslatorRsp() extends Bundle{ case class MemoryTranslatorRsp() extends Bundle{
val physicalAddress = UInt(32 bits) val physicalAddress = UInt(32 bits)
val isIoAccess = Bool val isIoAccess = Bool
val isPaging = Bool
val allowRead, allowWrite, allowExecute = Bool val allowRead, allowWrite, allowExecute = Bool
val exception = Bool val exception = Bool
val refilling = Bool val refilling = Bool

View File

@ -551,9 +551,20 @@ class DataCache(p : DataCacheConfig) extends Component{
val memCmdSent = RegInit(False) setWhen (io.mem.cmd.ready) clearWhen (!io.cpu.writeBack.isStuck) 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.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.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 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 //remove side effects on exceptions
when(mmuRsp.refilling || io.cpu.writeBack.accessError || io.cpu.writeBack.mmuException || io.cpu.writeBack.unalignedAccess){ when(mmuRsp.refilling || io.cpu.writeBack.accessError || io.cpu.writeBack.mmuException || io.cpu.writeBack.unalignedAccess){
io.mem.cmd.valid := False io.mem.cmd.valid := False

View File

@ -438,9 +438,9 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
val mmuRsp = io.cpu.fetch.mmuBus.rsp val mmuRsp = io.cpu.fetch.mmuBus.rsp
io.cpu.fetch.cacheMiss := !hit.valid 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.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.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.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 io.cpu.decode.physicalAddress := mmuRsp.physicalAddress
}) })
} }

View File

@ -273,15 +273,14 @@ class DBusCachedPlugin(val config : DataCacheConfig,
exceptionBus.valid := True exceptionBus.valid := True
exceptionBus.code := (input(MEMORY_WR) ? U(7) | U(5)).resized 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) { if(catchIllegal) when (cache.io.cpu.writeBack.mmuException) {
exceptionBus.valid := True exceptionBus.valid := True
exceptionBus.code := (input(MEMORY_WR) ? U(15) | U(13)).resized 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) { when(cache.io.cpu.redo) {
redoBranch.valid := True redoBranch.valid := True

View File

@ -127,6 +127,7 @@ class MmuPlugin(ioRange : UInt => Bool,
port.bus.rsp.allowExecute := cacheLine.allowExecute 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.exception := cacheHit && (cacheLine.exception || cacheLine.allowUser && privilegeService.isSupervisor() && !csr.status.sum || !cacheLine.allowUser && privilegeService.isUser())
port.bus.rsp.refilling := !cacheHit port.bus.rsp.refilling := !cacheHit
port.bus.rsp.isPaging := True
} otherwise { } otherwise {
port.bus.rsp.physicalAddress := port.bus.cmd.virtualAddress port.bus.rsp.physicalAddress := port.bus.cmd.virtualAddress
port.bus.rsp.allowRead := True port.bus.rsp.allowRead := True
@ -134,6 +135,7 @@ class MmuPlugin(ioRange : UInt => Bool,
port.bus.rsp.allowExecute := True port.bus.rsp.allowExecute := True
port.bus.rsp.exception := False port.bus.rsp.exception := False
port.bus.rsp.refilling := False port.bus.rsp.refilling := False
port.bus.rsp.isPaging := False
} }
port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress) port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress)

View File

@ -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.isIoAccess := ioRange(port.bus.rsp.physicalAddress)
port.bus.rsp.isPaging := False
port.bus.rsp.exception := False port.bus.rsp.exception := False
port.bus.rsp.refilling := False port.bus.rsp.refilling := False
port.bus.busy := False port.bus.busy := False

View File

@ -32,6 +32,7 @@ class StaticMemoryTranslatorPlugin(ioRange : UInt => Bool) extends Plugin[VexRis
port.bus.rsp.allowWrite := True port.bus.rsp.allowWrite := True
port.bus.rsp.allowExecute := True port.bus.rsp.allowExecute := True
port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress) port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress)
port.bus.rsp.isPaging := False
port.bus.rsp.exception := False port.bus.rsp.exception := False
port.bus.rsp.refilling := False port.bus.rsp.refilling := False
port.bus.busy := False port.bus.busy := False