uncore: add DTS meta-data for devices
This commit is contained in:
parent
0b950b5938
commit
9a5e2e038b
@ -849,7 +849,7 @@ trait DebugModule extends Module with HasDebugModuleParameters with HasRegMap {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class TLDebugModule(address: BigInt = 0)(implicit p: Parameters)
|
class TLDebugModule(address: BigInt = 0)(implicit p: Parameters)
|
||||||
extends TLRegisterRouter(address, beatBytes=p(XLen)/8, executable=true)(
|
extends TLRegisterRouter(address, "debug", Nil, beatBytes=p(XLen)/8, executable=true)(
|
||||||
new TLRegBundle((), _ ) with DebugModuleBundle)(
|
new TLRegBundle((), _ ) with DebugModuleBundle)(
|
||||||
new TLRegModule((), _, _) with DebugModule)
|
new TLRegModule((), _, _) with DebugModule)
|
||||||
|
|
||||||
|
@ -58,19 +58,34 @@ class TLPLIC(supervisor: Boolean, maxPriorities: Int, address: BigInt = 0xC00000
|
|||||||
val contextsPerHart = if (supervisor) 2 else 1
|
val contextsPerHart = if (supervisor) 2 else 1
|
||||||
require (maxPriorities >= 0)
|
require (maxPriorities >= 0)
|
||||||
|
|
||||||
|
// plic0 => max devices 1023
|
||||||
|
val device = new SimpleDevice("interrupt-controller", Seq("riscv,plic0")) {
|
||||||
|
override val alwaysExtended = true
|
||||||
|
override def describe(resources: ResourceBindings): Description = {
|
||||||
|
val Description(name, mapping) = super.describe(resources)
|
||||||
|
val extra = Map(
|
||||||
|
"interrupt-controller" -> Nil,
|
||||||
|
"riscv,ndev" -> Seq(ResourceInt(nDevices)),
|
||||||
|
"#interrupt-cells" -> Seq(ResourceInt(1)),
|
||||||
|
"#address-cells" -> Seq(ResourceInt(0)))
|
||||||
|
Description(name, mapping ++ extra)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val node = TLRegisterNode(
|
val node = TLRegisterNode(
|
||||||
address = AddressSet(address, PLICConsts.size-1),
|
address = AddressSet(address, PLICConsts.size-1),
|
||||||
|
device = device,
|
||||||
beatBytes = p(XLen)/8,
|
beatBytes = p(XLen)/8,
|
||||||
undefZero = false)
|
undefZero = false)
|
||||||
|
|
||||||
val intnode = IntNexusNode(
|
val intnode = IntNexusNode(
|
||||||
numSourcePorts = 0 to 1024,
|
numSourcePorts = 0 to 1024,
|
||||||
numSinkPorts = 0 to 1024,
|
numSinkPorts = 0 to 1024,
|
||||||
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(contextsPerHart))) },
|
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(contextsPerHart, Seq(Resource(device, "int"))))) },
|
||||||
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) })
|
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) })
|
||||||
|
|
||||||
/* Negotiated sizes */
|
/* Negotiated sizes */
|
||||||
def nDevices = intnode.edgesIn.map(_.source.num).sum
|
def nDevices: Int = intnode.edgesIn.map(_.source.num).sum
|
||||||
def nPriorities = min(maxPriorities, nDevices)
|
def nPriorities = min(maxPriorities, nDevices)
|
||||||
def nHarts = intnode.edgesOut.map(_.source.num).sum
|
def nHarts = intnode.edgesOut.map(_.source.num).sum
|
||||||
|
|
||||||
@ -106,6 +121,19 @@ class TLPLIC(supervisor: Boolean, maxPriorities: Int, address: BigInt = 0xC00000
|
|||||||
s" };\n")).mkString
|
s" };\n")).mkString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assign all the devices unique ranges
|
||||||
|
lazy val sources = intnode.edgesIn.map(_.source)
|
||||||
|
lazy val flatSources = (sources zip sources.map(_.num).scanLeft(0)(_+_).init).map {
|
||||||
|
case (s, o) => s.sources.map(z => z.copy(range = z.range.offset(o)))
|
||||||
|
}.flatten
|
||||||
|
|
||||||
|
ResourceBinding {
|
||||||
|
flatSources.foreach { s => s.resources.foreach { r =>
|
||||||
|
// +1 because interrupt 0 is reserved
|
||||||
|
(s.range.start until s.range.end).foreach { i => r.bind(device, ResourceInt(i+1)) }
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val tl_in = node.bundleIn
|
val tl_in = node.bundleIn
|
||||||
@ -113,11 +141,6 @@ class TLPLIC(supervisor: Boolean, maxPriorities: Int, address: BigInt = 0xC00000
|
|||||||
val harts = intnode.bundleOut
|
val harts = intnode.bundleOut
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign all the devices unique ranges
|
|
||||||
val sources = intnode.edgesIn.map(_.source)
|
|
||||||
val flatSources = (sources zip sources.map(_.num).scanLeft(0)(_+_).init).map {
|
|
||||||
case (s, o) => s.sources.map(z => z.copy(range = z.range.offset(o)))
|
|
||||||
}.flatten
|
|
||||||
// Compact the interrupt vector the same way
|
// Compact the interrupt vector the same way
|
||||||
val interrupts = (intnode.edgesIn zip io.devices).map { case (e, i) => i.take(e.source.num) }.flatten
|
val interrupts = (intnode.edgesIn zip io.devices).map { case (e, i) => i.take(e.source.num) }.flatten
|
||||||
// This flattens the harts into an MSMSMSMSMS... or MMMMM.... sequence
|
// This flattens the harts into an MSMSMSMSMS... or MMMMM.... sequence
|
||||||
|
@ -83,8 +83,9 @@ trait CoreplexLocalInterrupterModule extends Module with HasRegMap with MixCorep
|
|||||||
|
|
||||||
/** Power, Reset, Clock, Interrupt */
|
/** Power, Reset, Clock, Interrupt */
|
||||||
// Magic TL2 Incantation to create a TL2 Slave
|
// Magic TL2 Incantation to create a TL2 Slave
|
||||||
|
// prci0 => at most 4095 devices
|
||||||
class CoreplexLocalInterrupter(address: BigInt = 0x02000000)(implicit p: Parameters)
|
class CoreplexLocalInterrupter(address: BigInt = 0x02000000)(implicit p: Parameters)
|
||||||
extends TLRegisterRouter(address, size = ClintConsts.size, beatBytes = p(XLen)/8, undefZero = true)(
|
extends TLRegisterRouter(address, "clint", Seq("riscv,clint0"), size = ClintConsts.size, beatBytes = p(XLen)/8, undefZero = true)(
|
||||||
new TLRegBundle((), _) with CoreplexLocalInterrupterBundle)(
|
new TLRegBundle((), _) with CoreplexLocalInterrupterBundle)(
|
||||||
new TLRegModule((), _, _) with CoreplexLocalInterrupterModule)
|
new TLRegModule((), _, _) with CoreplexLocalInterrupterModule)
|
||||||
{
|
{
|
||||||
|
@ -14,8 +14,11 @@ import config._
|
|||||||
|
|
||||||
class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
|
class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
|
val device = new SimpleDevice("rom", Nil)
|
||||||
|
|
||||||
val node = TLManagerNode(beatBytes, TLManagerParameters(
|
val node = TLManagerNode(beatBytes, TLManagerParameters(
|
||||||
address = List(AddressSet(base, size-1)),
|
address = List(AddressSet(base, size-1)),
|
||||||
|
resources = device.reg,
|
||||||
regionType = RegionType.UNCACHED,
|
regionType = RegionType.UNCACHED,
|
||||||
executable = executable,
|
executable = executable,
|
||||||
supportsGet = TransferSizes(1, beatBytes),
|
supportsGet = TransferSizes(1, beatBytes),
|
||||||
|
@ -34,6 +34,7 @@ trait ExampleModule extends HasRegMap
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a concrete TL2 version of the abstract Example slave
|
// Create a concrete TL2 version of the abstract Example slave
|
||||||
class TLExample(params: ExampleParams)(implicit p: Parameters) extends TLRegisterRouter(params.address, 4)(
|
class TLExample(params: ExampleParams)(implicit p: Parameters)
|
||||||
|
extends TLRegisterRouter(params.address, "somedev", Seq("ucbbar,random-interface"), 4)(
|
||||||
new TLRegBundle(params, _) with ExampleBundle)(
|
new TLRegBundle(params, _) with ExampleBundle)(
|
||||||
new TLRegModule(params, _, _) with ExampleModule)
|
new TLRegModule(params, _, _) with ExampleModule)
|
||||||
|
@ -8,10 +8,18 @@ import diplomacy._
|
|||||||
import regmapper._
|
import regmapper._
|
||||||
import scala.math.{min,max}
|
import scala.math.{min,max}
|
||||||
|
|
||||||
class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
|
class TLRegisterNode(
|
||||||
|
address: AddressSet,
|
||||||
|
device: Device,
|
||||||
|
deviceKey: String = "reg",
|
||||||
|
concurrency: Int = 0,
|
||||||
|
beatBytes: Int = 4,
|
||||||
|
undefZero: Boolean = true,
|
||||||
|
executable: Boolean = false)
|
||||||
extends TLManagerNode(Seq(TLManagerPortParameters(
|
extends TLManagerNode(Seq(TLManagerPortParameters(
|
||||||
Seq(TLManagerParameters(
|
Seq(TLManagerParameters(
|
||||||
address = Seq(address),
|
address = Seq(address),
|
||||||
|
resources = Seq(Resource(device, deviceKey)),
|
||||||
executable = executable,
|
executable = executable,
|
||||||
supportsGet = TransferSizes(1, beatBytes),
|
supportsGet = TransferSizes(1, beatBytes),
|
||||||
supportsPutPartial = TransferSizes(1, beatBytes),
|
supportsPutPartial = TransferSizes(1, beatBytes),
|
||||||
@ -72,18 +80,26 @@ class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int =
|
|||||||
|
|
||||||
object TLRegisterNode
|
object TLRegisterNode
|
||||||
{
|
{
|
||||||
def apply(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) =
|
def apply(
|
||||||
new TLRegisterNode(address, concurrency, beatBytes, undefZero, executable)
|
address: AddressSet,
|
||||||
|
device: Device,
|
||||||
|
deviceKey: String = "reg",
|
||||||
|
concurrency: Int = 0,
|
||||||
|
beatBytes: Int = 4,
|
||||||
|
undefZero: Boolean = true,
|
||||||
|
executable: Boolean = false) =
|
||||||
|
new TLRegisterNode(address, device, deviceKey, concurrency, beatBytes, undefZero, executable)
|
||||||
}
|
}
|
||||||
|
|
||||||
// These convenience methods below combine to make it possible to create a TL2
|
// These convenience methods below combine to make it possible to create a TL2
|
||||||
// register mapped device from a totally abstract register mapped device.
|
// register mapped device from a totally abstract register mapped device.
|
||||||
// See GPIO.scala in this directory for an example
|
// See GPIO.scala in this directory for an example
|
||||||
|
|
||||||
abstract class TLRegisterRouterBase(val address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean, executable: Boolean)(implicit p: Parameters) extends LazyModule
|
abstract class TLRegisterRouterBase(devname: String, devcompat: Seq[String], val address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean, executable: Boolean)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val node = TLRegisterNode(address, concurrency, beatBytes, undefZero, executable)
|
val device = new SimpleDevice(devname, devcompat)
|
||||||
val intnode = IntSourceNode(interrupts)
|
val node = TLRegisterNode(address, device, "reg", concurrency, beatBytes, undefZero, executable)
|
||||||
|
val intnode = IntSourceNode(interrupts, Seq(Resource(device, "int")))
|
||||||
}
|
}
|
||||||
|
|
||||||
case class TLRegBundleArg(interrupts: util.HeterogeneousBag[Vec[Bool]], in: util.HeterogeneousBag[TLBundle])(implicit val p: Parameters)
|
case class TLRegBundleArg(interrupts: util.HeterogeneousBag[Vec[Bool]], in: util.HeterogeneousBag[TLBundle])(implicit val p: Parameters)
|
||||||
@ -106,11 +122,19 @@ class TLRegModule[P, B <: TLRegBundleBase](val params: P, bundleBuilder: => B, r
|
|||||||
def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
|
def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLRegisterRouter[B <: TLRegBundleBase, M <: LazyModuleImp]
|
class TLRegisterRouter[B <: TLRegBundleBase, M <: LazyModuleImp](
|
||||||
(val base: BigInt, val interrupts: Int = 0, val size: BigInt = 4096, val concurrency: Int = 0, val beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
|
val base: BigInt,
|
||||||
|
val devname: String,
|
||||||
|
val devcompat: Seq[String],
|
||||||
|
val interrupts: Int = 0,
|
||||||
|
val size: BigInt = 4096,
|
||||||
|
val concurrency: Int = 0,
|
||||||
|
val beatBytes: Int = 4,
|
||||||
|
val undefZero: Boolean = true,
|
||||||
|
val executable: Boolean = false)
|
||||||
(bundleBuilder: TLRegBundleArg => B)
|
(bundleBuilder: TLRegBundleArg => B)
|
||||||
(moduleBuilder: (=> B, TLRegisterRouterBase) => M)(implicit p: Parameters)
|
(moduleBuilder: (=> B, TLRegisterRouterBase) => M)(implicit p: Parameters)
|
||||||
extends TLRegisterRouterBase(AddressSet(base, size-1), interrupts, concurrency, beatBytes, undefZero, executable)
|
extends TLRegisterRouterBase(devname, devcompat, AddressSet(base, size-1), interrupts, concurrency, beatBytes, undefZero, executable)
|
||||||
{
|
{
|
||||||
require (isPow2(size))
|
require (isPow2(size))
|
||||||
// require (size >= 4096) ... not absolutely required, but highly recommended
|
// require (size >= 4096) ... not absolutely required, but highly recommended
|
||||||
|
@ -214,7 +214,7 @@ trait RRTest0Module extends HasRegMap
|
|||||||
regmap(RRTest0Map.map:_*)
|
regmap(RRTest0Map.map:_*)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RRTest0(address: BigInt)(implicit p: Parameters) extends TLRegisterRouter(address, 0, 32, 0, 4)(
|
class RRTest0(address: BigInt)(implicit p: Parameters) extends TLRegisterRouter(address, "test0", Nil, 0, 32, 0, 4)(
|
||||||
new TLRegBundle((), _) with RRTest0Bundle)(
|
new TLRegBundle((), _) with RRTest0Bundle)(
|
||||||
new TLRegModule((), _, _) with RRTest0Module)
|
new TLRegModule((), _, _) with RRTest0Module)
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ trait RRTest1Module extends Module with HasRegMap
|
|||||||
regmap(map:_*)
|
regmap(map:_*)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RRTest1(address: BigInt)(implicit p: Parameters) extends TLRegisterRouter(address, 0, 32, 6, 4)(
|
class RRTest1(address: BigInt)(implicit p: Parameters) extends TLRegisterRouter(address, "test1", Nil, 0, 32, 6, 4)(
|
||||||
new TLRegBundle((), _) with RRTest1Bundle)(
|
new TLRegBundle((), _) with RRTest1Bundle)(
|
||||||
new TLRegModule((), _, _) with RRTest1Module)
|
new TLRegModule((), _, _) with RRTest1Module)
|
||||||
|
|
||||||
|
@ -9,9 +9,12 @@ import util._
|
|||||||
|
|
||||||
class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
|
class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
|
val device = new MemoryDevice
|
||||||
|
|
||||||
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
||||||
Seq(TLManagerParameters(
|
Seq(TLManagerParameters(
|
||||||
address = List(address),
|
address = List(address),
|
||||||
|
resources = device.reg,
|
||||||
regionType = RegionType.UNCACHED,
|
regionType = RegionType.UNCACHED,
|
||||||
executable = executable,
|
executable = executable,
|
||||||
supportsGet = TransferSizes(1, beatBytes),
|
supportsGet = TransferSizes(1, beatBytes),
|
||||||
|
@ -8,9 +8,12 @@ import diplomacy._
|
|||||||
|
|
||||||
class TLZero(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
|
class TLZero(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
|
val device = new SimpleDevice("rom", Seq("ucbbar,cacheable-zero"))
|
||||||
|
|
||||||
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
||||||
Seq(TLManagerParameters(
|
Seq(TLManagerParameters(
|
||||||
address = List(address),
|
address = List(address),
|
||||||
|
resources = device.reg,
|
||||||
regionType = RegionType.UNCACHED,
|
regionType = RegionType.UNCACHED,
|
||||||
executable = executable,
|
executable = executable,
|
||||||
supportsGet = TransferSizes(1, beatBytes),
|
supportsGet = TransferSizes(1, beatBytes),
|
||||||
|
Loading…
Reference in New Issue
Block a user