Add MMU MPRIV for easier machinemode emulation #60

This commit is contained in:
Dolu1990 2019-03-25 10:30:13 +01:00
parent 9d55283b3b
commit c34f5413a3
5 changed files with 15 additions and 9 deletions

View File

@ -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])

View File

@ -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._

View File

@ -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) {

View File

@ -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)
}
}

View File

@ -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)