2015-10-06 05:33:55 +02:00
|
|
|
// See LICENSE for license details.
|
|
|
|
|
|
|
|
package junctions
|
|
|
|
|
|
|
|
import Chisel._
|
2015-10-22 03:15:46 +02:00
|
|
|
import cde.{Parameters, Field}
|
2015-10-06 05:33:55 +02:00
|
|
|
import scala.collection.mutable.HashMap
|
|
|
|
|
2015-10-07 03:14:51 +02:00
|
|
|
case object PAddrBits extends Field[Int]
|
|
|
|
case object VAddrBits extends Field[Int]
|
|
|
|
case object PgIdxBits extends Field[Int]
|
|
|
|
case object PgLevels extends Field[Int]
|
|
|
|
case object PgLevelBits extends Field[Int]
|
|
|
|
case object ASIdBits extends Field[Int]
|
|
|
|
case object PPNBits extends Field[Int]
|
|
|
|
case object VPNBits extends Field[Int]
|
|
|
|
|
|
|
|
case object GlobalAddrMap extends Field[AddrMap]
|
|
|
|
case object MMIOBase extends Field[BigInt]
|
|
|
|
|
|
|
|
trait HasAddrMapParameters {
|
|
|
|
implicit val p: Parameters
|
|
|
|
|
|
|
|
val paddrBits = p(PAddrBits)
|
|
|
|
val vaddrBits = p(VAddrBits)
|
|
|
|
val pgIdxBits = p(PgIdxBits)
|
|
|
|
val ppnBits = p(PPNBits)
|
|
|
|
val vpnBits = p(VPNBits)
|
|
|
|
val pgLevels = p(PgLevels)
|
|
|
|
val pgLevelBits = p(PgLevelBits)
|
|
|
|
val asIdBits = p(ASIdBits)
|
|
|
|
|
2016-01-15 01:41:32 +01:00
|
|
|
val addrMap = new AddrHashMap(p(GlobalAddrMap), p(MMIOBase))
|
2015-10-07 03:14:51 +02:00
|
|
|
}
|
|
|
|
|
2015-10-06 05:33:55 +02:00
|
|
|
abstract class MemRegion { def size: BigInt }
|
|
|
|
|
|
|
|
case class MemSize(size: BigInt, prot: Int) extends MemRegion
|
|
|
|
case class MemSubmap(size: BigInt, entries: AddrMap) extends MemRegion
|
|
|
|
|
|
|
|
object AddrMapConsts {
|
2015-12-05 09:26:16 +01:00
|
|
|
val R = 0x1
|
2015-10-06 05:33:55 +02:00
|
|
|
val W = 0x2
|
2015-12-05 09:26:16 +01:00
|
|
|
val X = 0x4
|
2015-10-06 05:33:55 +02:00
|
|
|
val RW = R | W
|
|
|
|
val RX = R | X
|
|
|
|
val RWX = R | W | X
|
|
|
|
}
|
|
|
|
|
|
|
|
class AddrMapProt extends Bundle {
|
|
|
|
val x = Bool()
|
2015-12-05 09:26:16 +01:00
|
|
|
val w = Bool()
|
|
|
|
val r = Bool()
|
2015-10-06 05:33:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
case class AddrMapEntry(name: String, start: Option[BigInt], region: MemRegion)
|
|
|
|
|
|
|
|
case class AddrHashMapEntry(port: Int, start: BigInt, size: BigInt, prot: Int)
|
|
|
|
|
|
|
|
class AddrMap(entries: Seq[AddrMapEntry]) extends scala.collection.IndexedSeq[AddrMapEntry] {
|
|
|
|
|
|
|
|
def apply(index: Int): AddrMapEntry = entries(index)
|
|
|
|
|
|
|
|
def length: Int = entries.size
|
|
|
|
|
|
|
|
def countSlaves: Int = {
|
|
|
|
this map { entry: AddrMapEntry => entry.region match {
|
|
|
|
case MemSize(_, _) => 1
|
|
|
|
case MemSubmap(_, submap) => submap.countSlaves
|
|
|
|
}} reduceLeft(_ + _)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
object AddrMap {
|
|
|
|
def apply(elems: AddrMapEntry*): AddrMap = new AddrMap(elems)
|
|
|
|
}
|
|
|
|
|
2016-01-15 01:41:32 +01:00
|
|
|
class AddrHashMap(addrmap: AddrMap, start: BigInt) {
|
2015-10-06 05:33:55 +02:00
|
|
|
val mapping = new HashMap[String, AddrHashMapEntry]
|
|
|
|
|
2016-01-15 01:41:32 +01:00
|
|
|
private def genPairs(am: AddrMap, start: BigInt): Seq[(String, AddrHashMapEntry)] = {
|
2015-10-06 05:33:55 +02:00
|
|
|
var ind = 0
|
2016-01-15 01:41:32 +01:00
|
|
|
var base = start
|
2015-10-06 05:33:55 +02:00
|
|
|
var pairs = Seq[(String, AddrHashMapEntry)]()
|
|
|
|
am.foreach { case AddrMapEntry(name, startOpt, region) =>
|
|
|
|
region match {
|
|
|
|
case MemSize(size, prot) => {
|
|
|
|
if (!startOpt.isEmpty) base = startOpt.get
|
|
|
|
pairs = (name, AddrHashMapEntry(ind, base, size, prot)) +: pairs
|
|
|
|
base += size
|
|
|
|
ind += 1
|
|
|
|
}
|
|
|
|
case MemSubmap(size, submap) => {
|
|
|
|
if (!startOpt.isEmpty) base = startOpt.get
|
2016-01-15 01:41:32 +01:00
|
|
|
val subpairs = genPairs(submap, base).map {
|
2015-10-06 05:33:55 +02:00
|
|
|
case (subname, AddrHashMapEntry(subind, subbase, subsize, prot)) =>
|
|
|
|
(name + ":" + subname,
|
2016-01-15 01:41:32 +01:00
|
|
|
AddrHashMapEntry(ind + subind, subbase, subsize, prot))
|
2015-10-06 05:33:55 +02:00
|
|
|
}
|
|
|
|
pairs = subpairs ++ pairs
|
|
|
|
ind += subpairs.size
|
|
|
|
base += size
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pairs
|
|
|
|
}
|
|
|
|
|
2016-01-15 01:41:32 +01:00
|
|
|
for ((name, ind) <- genPairs(addrmap, start)) { mapping(name) = ind }
|
2015-10-06 05:33:55 +02:00
|
|
|
|
|
|
|
def nEntries: Int = mapping.size
|
|
|
|
def apply(name: String): AddrHashMapEntry = mapping(name)
|
|
|
|
def get(name: String): Option[AddrHashMapEntry] = mapping.get(name)
|
|
|
|
def sortedEntries(): Seq[(String, BigInt, BigInt, Int)] = {
|
|
|
|
val arr = new Array[(String, BigInt, BigInt, Int)](mapping.size)
|
|
|
|
mapping.foreach { case (name, AddrHashMapEntry(port, base, size, prot)) =>
|
|
|
|
arr(port) = (name, base, size, prot)
|
|
|
|
}
|
|
|
|
arr.toSeq
|
|
|
|
}
|
|
|
|
|
|
|
|
def isValid(addr: UInt): Bool = {
|
2016-01-15 01:41:32 +01:00
|
|
|
addr < UInt(start) || sortedEntries().map {
|
|
|
|
case (_, base, size, _) =>
|
|
|
|
addr >= UInt(base) && addr < UInt(base + size)
|
2015-10-06 05:33:55 +02:00
|
|
|
}.reduceLeft(_ || _)
|
|
|
|
}
|
|
|
|
|
|
|
|
def getProt(addr: UInt): AddrMapProt = {
|
2016-01-15 01:41:32 +01:00
|
|
|
val protBits = Mux(addr < UInt(start),
|
|
|
|
Bits(AddrMapConsts.RWX, 3),
|
|
|
|
Mux1H(sortedEntries().map { case (_, base, size, prot) =>
|
|
|
|
(addr >= UInt(base) && addr < UInt(base + size), Bits(prot, 3))
|
|
|
|
}))
|
|
|
|
new AddrMapProt().fromBits(protBits)
|
2015-10-06 05:33:55 +02:00
|
|
|
}
|
|
|
|
}
|