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
import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer
trait PipelineConfig[T] trait PipelineThing[T]
trait Pipeline { trait Pipeline {
type T <: Pipeline type T <: Pipeline
val plugins = ArrayBuffer[Plugin[T]]() val plugins = ArrayBuffer[Plugin[T]]()
var stages = ArrayBuffer[Stage]() var stages = ArrayBuffer[Stage]()
var unremovableStages = mutable.Set[Stage]() var unremovableStages = mutable.Set[Stage]()
val configs = mutable.HashMap[PipelineConfig[_], Any]() val configs = mutable.HashMap[PipelineThing[_], Any]()
// val services = ArrayBuffer[Any]() // val services = ArrayBuffer[Any]()
def indexOf(stage : Stage) = stages.indexOf(stage) def indexOf(stage : Stage) = stages.indexOf(stage)
@ -37,8 +37,8 @@ trait Pipeline {
filtered.head.asInstanceOf[T] filtered.head.asInstanceOf[T]
} }
def update[T](that : PipelineConfig[T], value : T) : Unit = configs(that) = value def update[T](that : PipelineThing[T], value : T) : Unit = configs(that) = value
def apply[T](that : PipelineConfig[T]) : T = configs(that).asInstanceOf[T] def apply[T](that : PipelineThing[T]) : T = configs(that).asInstanceOf[T]
def build(): Unit ={ def build(): Unit ={
plugins.foreach(_.pipeline = this.asInstanceOf[T]) 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_VALID extends Stageable(Bool)
object REGFILE_WRITE_DATA extends Stageable(Bits(32 bits)) object REGFILE_WRITE_DATA extends Stageable(Bits(32 bits))
object MPP extends PipelineThing[UInt]
object SRC1 extends Stageable(Bits(32 bits)) object SRC1 extends Stageable(Bits(32 bits))
object SRC2 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{ class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{
type T = VexRiscv type T = VexRiscv
import config._ import config._

View File

@ -499,6 +499,8 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception
//User CSR //User CSR
ucycleAccess(CSR.UCYCLE, mcycle(31 downto 0)) ucycleAccess(CSR.UCYCLE, mcycle(31 downto 0))
ucycleAccess(CSR.UCYCLEH, mcycle(63 downto 32)) ucycleAccess(CSR.UCYCLEH, mcycle(63 downto 32))
pipeline.update(MPP, mstatus.MPP)
} }
val supervisorCsr = ifGen(supervisorGen) { val supervisorCsr = ifGen(supervisorGen) {

View File

@ -271,7 +271,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
} }
if(memoryTranslatorPortConfig != null) { 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) 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 csr = pipeline plug new Area{
val status = new Area{ val status = new Area{
val sum, mxr = RegInit(False) val sum, mxr, mprv = RegInit(False)
} }
val satp = new Area { val satp = new Area {
val mode = RegInit(False) val mode = RegInit(False)
val ppn = Reg(UInt(20 bits)) 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 ? 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 privilegeService = pipeline.serviceElse(classOf[PrivilegeService], PrivilegeServiceDefault())
val entryToReplace = Counter(port.args.portTlbSize) val entryToReplace = Counter(port.args.portTlbSize)
val requireMmuLockup = virtualRange(port.bus.cmd.virtualAddress) && !port.bus.cmd.bypassTranslation && csr.satp.mode 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) { 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) 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)