Construct device tree ROM in MMIO region
Rebuild riscv-tools for this to work!
This commit is contained in:
parent
49d93da87e
commit
e25a020e60
@ -1 +1 @@
|
|||||||
Subproject commit 84a47e0b4ef322daf0ade05510bf4d30d9d9a0fa
|
Subproject commit 3fba5b66223eb92413baa555cd2792b31fe135e3
|
@ -18,13 +18,41 @@ class DefaultConfig extends Config (
|
|||||||
type PF = PartialFunction[Any,Any]
|
type PF = PartialFunction[Any,Any]
|
||||||
def findBy(sname:Any):Any = here[PF](site[Any](sname))(pname)
|
def findBy(sname:Any):Any = here[PF](site[Any](sname))(pname)
|
||||||
def genCsrAddrMap: AddrMap = {
|
def genCsrAddrMap: AddrMap = {
|
||||||
|
val deviceTree = AddrMapEntry("devicetree", None, MemSize(1 << 15, AddrMapConsts.R))
|
||||||
val csrSize = (1 << 12) * (site(XLen) / 8)
|
val csrSize = (1 << 12) * (site(XLen) / 8)
|
||||||
val csrs = (0 until site(NTiles)).map{ i =>
|
val csrs = (0 until site(NTiles)).map{ i =>
|
||||||
AddrMapEntry(s"csr$i", None, MemSize(csrSize, AddrMapConsts.RW))
|
AddrMapEntry(s"csr$i", None, MemSize(csrSize, AddrMapConsts.RW))
|
||||||
}
|
}
|
||||||
val scrSize = site(HtifKey).nSCR * (site(XLen) / 8)
|
val scrSize = site(HtifKey).nSCR * (site(XLen) / 8)
|
||||||
val scr = AddrMapEntry("scr", None, MemSize(scrSize, AddrMapConsts.RW))
|
val scr = AddrMapEntry("scr", None, MemSize(scrSize, AddrMapConsts.RW))
|
||||||
new AddrMap(csrs :+ scr)
|
new AddrMap(deviceTree +: csrs :+ scr)
|
||||||
|
}
|
||||||
|
def makeDeviceTree() = {
|
||||||
|
val addrMap = new AddrHashMap(site(GlobalAddrMap))
|
||||||
|
val dt = new DeviceTreeGenerator
|
||||||
|
dt.beginNode("")
|
||||||
|
dt.addProp("#address-cells", 2)
|
||||||
|
dt.addProp("#size-cells", 2)
|
||||||
|
dt.addProp("model", "Rocket-Chip")
|
||||||
|
dt.beginNode("memory@0")
|
||||||
|
dt.addProp("device_type", "memory")
|
||||||
|
dt.addReg(0, site(MMIOBase).toLong)
|
||||||
|
dt.endNode()
|
||||||
|
dt.beginNode("cpus")
|
||||||
|
dt.addProp("#address-cells", 2)
|
||||||
|
dt.addProp("#size-cells", 2)
|
||||||
|
for (i <- 0 until site(NTiles)) {
|
||||||
|
val csrs = addrMap(s"conf:csr$i")
|
||||||
|
dt.beginNode(s"cpu@${csrs.start.toLong.toHexString}")
|
||||||
|
dt.addProp("device_type", "cpu")
|
||||||
|
dt.addProp("compatible", "riscv")
|
||||||
|
dt.addProp("isa", s"rv${site(XLen)}")
|
||||||
|
dt.addReg(csrs.start.toLong)
|
||||||
|
dt.endNode()
|
||||||
|
}
|
||||||
|
dt.endNode()
|
||||||
|
dt.endNode()
|
||||||
|
dt.toArray()
|
||||||
}
|
}
|
||||||
pname match {
|
pname match {
|
||||||
case HtifKey => HtifParameters(
|
case HtifKey => HtifParameters(
|
||||||
@ -165,6 +193,7 @@ class DefaultConfig extends Config (
|
|||||||
case UseBackupMemoryPort => true
|
case UseBackupMemoryPort => true
|
||||||
case MMIOBase => Dump("MEM_SIZE", BigInt(1 << 30)) // 1 GB
|
case MMIOBase => Dump("MEM_SIZE", BigInt(1 << 30)) // 1 GB
|
||||||
case ExternalIOStart => 2 * site(MMIOBase)
|
case ExternalIOStart => 2 * site(MMIOBase)
|
||||||
|
case DeviceTree => makeDeviceTree()
|
||||||
case GlobalAddrMap => AddrMap(
|
case GlobalAddrMap => AddrMap(
|
||||||
AddrMapEntry("mem", None, MemChannels(site(MMIOBase), site(NMemoryChannels), AddrMapConsts.RWX)),
|
AddrMapEntry("mem", None, MemChannels(site(MMIOBase), site(NMemoryChannels), AddrMapConsts.RWX)),
|
||||||
AddrMapEntry("conf", None, MemSubmap(site(ExternalIOStart) - site(MMIOBase), genCsrAddrMap)),
|
AddrMapEntry("conf", None, MemSubmap(site(ExternalIOStart) - site(MMIOBase), genCsrAddrMap)),
|
||||||
|
80
src/main/scala/DeviceTree.scala
Normal file
80
src/main/scala/DeviceTree.scala
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package rocketchip
|
||||||
|
|
||||||
|
case object DeviceTree extends cde.Field[Array[Byte]]
|
||||||
|
|
||||||
|
private class StringTable {
|
||||||
|
private val strings = collection.mutable.HashMap[String, Int]()
|
||||||
|
private val data = collection.mutable.ArrayBuffer[Byte]()
|
||||||
|
|
||||||
|
def add(x: String) = {
|
||||||
|
if (!strings.contains(x)) {
|
||||||
|
strings(x) = data.length
|
||||||
|
data ++= x.getBytes
|
||||||
|
data += 0
|
||||||
|
}
|
||||||
|
strings(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
def toArray = data.toArray
|
||||||
|
}
|
||||||
|
|
||||||
|
class DeviceTreeGenerator {
|
||||||
|
def beginNode(name: String): Unit = {
|
||||||
|
append(pack(1))
|
||||||
|
append(pack(name))
|
||||||
|
}
|
||||||
|
def endNode(): Unit = append(pack(2))
|
||||||
|
def addProp(name: String, data: Int): Unit = addProp(name, pack(data), 4)
|
||||||
|
def addProp(name: String, data: String): Unit =
|
||||||
|
addProp(name, pack(data), data.getBytes.length+1)
|
||||||
|
def addReg(values: Long*): Unit = {
|
||||||
|
val seq = values.toSeq
|
||||||
|
val buf = java.nio.ByteBuffer.allocate(seq.length*8)
|
||||||
|
seq foreach buf.putLong
|
||||||
|
addProp("reg", buf.array, buf.array.length)
|
||||||
|
}
|
||||||
|
def toArray(): Array[Byte] = {
|
||||||
|
append(pack(9))
|
||||||
|
val structArray = os.toByteArray
|
||||||
|
val stringArray = strings.toArray
|
||||||
|
|
||||||
|
val headerSize = 40
|
||||||
|
val rsvMap = Array.fill[Byte](16)(0)
|
||||||
|
val rsvMapOffset = headerSize
|
||||||
|
val structOffset = headerSize + rsvMap.length
|
||||||
|
val stringOffset = structOffset + structArray.length
|
||||||
|
val totalSize = stringOffset + stringArray.length
|
||||||
|
|
||||||
|
os.reset()
|
||||||
|
append(pack(0xd00dfeed)) // magic
|
||||||
|
append(pack(totalSize))
|
||||||
|
append(pack(structOffset))
|
||||||
|
append(pack(stringOffset))
|
||||||
|
append(pack(rsvMapOffset))
|
||||||
|
append(pack(17)) // version
|
||||||
|
append(pack(16)) // compatible version
|
||||||
|
append(pack(0)) // boot cpuid
|
||||||
|
append(pack(stringArray.length))
|
||||||
|
append(pack(structArray.length))
|
||||||
|
append(rsvMap)
|
||||||
|
append(structArray)
|
||||||
|
append(stringArray)
|
||||||
|
|
||||||
|
val res = os.toByteArray
|
||||||
|
os.reset
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
private val os = new java.io.ByteArrayOutputStream
|
||||||
|
private val strings = new StringTable
|
||||||
|
private def pack(x: String) = x.getBytes.padTo((x.getBytes.length+4)/4*4, 0.toByte)
|
||||||
|
private def pack(x: Int) = java.nio.ByteBuffer.allocate(4).putInt(x).array
|
||||||
|
private def append(x: Array[Byte]) = os.write(x, 0, x.length)
|
||||||
|
private def addProp(name: String, data: Array[Byte], length: Int) = {
|
||||||
|
require(data.length % 4 == 0)
|
||||||
|
append(pack(3))
|
||||||
|
append(pack(length))
|
||||||
|
append(pack(strings.add(name)))
|
||||||
|
append(data)
|
||||||
|
}
|
||||||
|
}
|
@ -165,6 +165,9 @@ class Uncore(implicit val p: Parameters) extends Module
|
|||||||
scrFile.io.smi <> scrArb.io.out
|
scrFile.io.smi <> scrArb.io.out
|
||||||
// scrFile.io.scr <> (... your SCR connections ...)
|
// scrFile.io.scr <> (... your SCR connections ...)
|
||||||
|
|
||||||
|
val deviceTree = Module(new NastiROM(p(DeviceTree).toSeq))
|
||||||
|
deviceTree.io <> outmemsys.io.deviceTree
|
||||||
|
|
||||||
// Wire the htif to the memory port(s) and host interface
|
// Wire the htif to the memory port(s) and host interface
|
||||||
io.host.debug_stats_csr := htif.io.host.debug_stats_csr
|
io.host.debug_stats_csr := htif.io.host.debug_stats_csr
|
||||||
io.mem <> outmemsys.io.mem
|
io.mem <> outmemsys.io.mem
|
||||||
@ -194,6 +197,7 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe
|
|||||||
val csr = Vec(new SMIIO(xLen, csrAddrBits), nTiles)
|
val csr = Vec(new SMIIO(xLen, csrAddrBits), nTiles)
|
||||||
val scr = new SMIIO(xLen, scrAddrBits)
|
val scr = new SMIIO(xLen, scrAddrBits)
|
||||||
val mmio = new NastiIO
|
val mmio = new NastiIO
|
||||||
|
val deviceTree = new NastiIO
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a simple L1toL2 NoC between the tiles+htif and the banks of outer memory
|
// Create a simple L1toL2 NoC between the tiles+htif and the banks of outer memory
|
||||||
@ -266,6 +270,7 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe
|
|||||||
io.scr <> conv.io.smi
|
io.scr <> conv.io.smi
|
||||||
|
|
||||||
io.mmio <> interconnect.io.slaves(addrHashMap("io").port)
|
io.mmio <> interconnect.io.slaves(addrHashMap("io").port)
|
||||||
|
io.deviceTree <> interconnect.io.slaves(addrHashMap("conf:devicetree").port)
|
||||||
|
|
||||||
val mem_channels = interconnect.io.slaves.take(nMemChannels)
|
val mem_channels = interconnect.io.slaves.take(nMemChannels)
|
||||||
|
|
||||||
|
@ -165,6 +165,9 @@ object TestGenerator extends App with FileSystemUtilities {
|
|||||||
val v = createOutputFile(configClassName + ".knb")
|
val v = createOutputFile(configClassName + ".knb")
|
||||||
v.write(world.getKnobs)
|
v.write(world.getKnobs)
|
||||||
v.close
|
v.close
|
||||||
|
val d = new java.io.FileOutputStream(Driver.targetDir + configClassName + ".dtb")
|
||||||
|
d.write(paramsFromConfig(DeviceTree))
|
||||||
|
d.close
|
||||||
val w = createOutputFile(configClassName + ".cst")
|
val w = createOutputFile(configClassName + ".cst")
|
||||||
w.write(world.getConstraints)
|
w.write(world.getConstraints)
|
||||||
w.close
|
w.close
|
||||||
|
2
uncore
2
uncore
@ -1 +1 @@
|
|||||||
Subproject commit 4380fe85a367da1aabd845fa105fa7d2d198a119
|
Subproject commit 677249148f87cc2735ce88c0892ca02ebd767a94
|
Loading…
Reference in New Issue
Block a user