add comments to diplomacy resource. (#913)
This commit is contained in:
parent
9040d921b5
commit
81b9ac42a3
@ -6,11 +6,33 @@ import Chisel.log2Ceil
|
|||||||
import scala.collection.immutable.{ListMap,SortedMap}
|
import scala.collection.immutable.{ListMap,SortedMap}
|
||||||
|
|
||||||
sealed trait ResourceValue
|
sealed trait ResourceValue
|
||||||
|
|
||||||
|
/** Permission of an address space.
|
||||||
|
* @param r readable.
|
||||||
|
* @param w writable.
|
||||||
|
* @param x executable.
|
||||||
|
* @param c cacheable.
|
||||||
|
*/
|
||||||
case class ResourcePermissions(r: Boolean, w: Boolean, x: Boolean, c: Boolean) // Not part of DTS
|
case class ResourcePermissions(r: Boolean, w: Boolean, x: Boolean, c: Boolean) // Not part of DTS
|
||||||
|
|
||||||
|
/** An address space description.
|
||||||
|
* @param address the address space.
|
||||||
|
* @param permissions the permission attributes of this space. See [[freechips.rocketchip.diplomacy.ResourcePermissions]].
|
||||||
|
*/
|
||||||
final case class ResourceAddress(address: Seq[AddressSet], permissions: ResourcePermissions) extends ResourceValue
|
final case class ResourceAddress(address: Seq[AddressSet], permissions: ResourcePermissions) extends ResourceValue
|
||||||
|
|
||||||
|
/** A mapped address space (eg: when map a device to a bus).
|
||||||
|
* @param address the address space.
|
||||||
|
* @param offset the address offset of the mapped device (eg: base address of the bus).
|
||||||
|
* @param permissions the permission attributes of this space. See [[freechips.rocketchip.diplomacy.ResourcePermissions]].
|
||||||
|
*/
|
||||||
final case class ResourceMapping(address: Seq[AddressSet], offset: BigInt, permissions: ResourcePermissions) extends ResourceValue
|
final case class ResourceMapping(address: Seq[AddressSet], offset: BigInt, permissions: ResourcePermissions) extends ResourceValue
|
||||||
final case class ResourceInt(value: BigInt) extends ResourceValue
|
final case class ResourceInt(value: BigInt) extends ResourceValue
|
||||||
final case class ResourceString(value: String) extends ResourceValue
|
final case class ResourceString(value: String) extends ResourceValue
|
||||||
|
|
||||||
|
/** A reference pointing to another device in DTS (eg: interrupt to interrupt controller).
|
||||||
|
* @param value the label (String) of the device.
|
||||||
|
*/
|
||||||
final case class ResourceReference(value: String) extends ResourceValue
|
final case class ResourceReference(value: String) extends ResourceValue
|
||||||
final case class ResourceMap(value: Map[String, Seq[ResourceValue]], labels: Seq[String] = Nil) extends ResourceValue
|
final case class ResourceMap(value: Map[String, Seq[ResourceValue]], labels: Seq[String] = Nil) extends ResourceValue
|
||||||
|
|
||||||
@ -21,12 +43,17 @@ case class ResourceBindings(map: Map[String, Seq[Binding]])
|
|||||||
def apply(key: String): Seq[Binding] = map.getOrElse(key, Nil)
|
def apply(key: String): Seq[Binding] = map.getOrElse(key, Nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A serializable description of a device.
|
||||||
|
* @param name the resolved name of this device. See [[freechips.rocketchip.diplomacy.DeviceRegName]].
|
||||||
|
* @param mapping the property map of this device.
|
||||||
|
*/
|
||||||
case class Description(name: String, mapping: Map[String, Seq[ResourceValue]])
|
case class Description(name: String, mapping: Map[String, Seq[ResourceValue]])
|
||||||
|
|
||||||
abstract class Device
|
abstract class Device
|
||||||
{
|
{
|
||||||
def describe(resources: ResourceBindings): Description
|
def describe(resources: ResourceBindings): Description
|
||||||
|
|
||||||
|
/** make sure all derived devices have an unique label */
|
||||||
val label = "L" + Device.index.toString
|
val label = "L" + Device.index.toString
|
||||||
Device.index = Device.index + 1
|
Device.index = Device.index + 1
|
||||||
}
|
}
|
||||||
@ -36,9 +63,12 @@ object Device
|
|||||||
private var index: Int = 0
|
private var index: Int = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A trait for devices that generate interrupts. */
|
||||||
trait DeviceInterrupts
|
trait DeviceInterrupts
|
||||||
{
|
{
|
||||||
this: Device =>
|
this: Device =>
|
||||||
|
|
||||||
|
/** Whether to always use the expanded interrupt description in DTS: "interrupts-extended" */
|
||||||
val alwaysExtended = false
|
val alwaysExtended = false
|
||||||
def describeInterrupts(resources: ResourceBindings): Map[String, Seq[ResourceValue]] = {
|
def describeInterrupts(resources: ResourceBindings): Map[String, Seq[ResourceValue]] = {
|
||||||
val int = resources("int")
|
val int = resources("int")
|
||||||
@ -64,6 +94,7 @@ trait DeviceInterrupts
|
|||||||
def int = Seq(Resource(this, "int"))
|
def int = Seq(Resource(this, "int"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A trait for resolving the name of a device. */
|
||||||
trait DeviceRegName
|
trait DeviceRegName
|
||||||
{
|
{
|
||||||
this: Device =>
|
this: Device =>
|
||||||
@ -94,14 +125,18 @@ trait DeviceRegName
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A simple device descriptor for devices that may support interrupts and address spaces.
|
||||||
|
* @param devname the base device named used in device name generation.
|
||||||
|
* @param devcompat a list of compatible devices. See device tree property "compatible".
|
||||||
|
*/
|
||||||
class SimpleDevice(devname: String, devcompat: Seq[String]) extends Device with DeviceInterrupts with DeviceRegName
|
class SimpleDevice(devname: String, devcompat: Seq[String]) extends Device with DeviceInterrupts with DeviceRegName
|
||||||
{
|
{
|
||||||
def describe(resources: ResourceBindings): Description = {
|
def describe(resources: ResourceBindings): Description = {
|
||||||
val name = describeName(devname, resources)
|
val name = describeName(devname, resources) // the generated device name in device tree
|
||||||
val int = describeInterrupts(resources)
|
val int = describeInterrupts(resources) // interrupt description
|
||||||
|
|
||||||
def optDef(x: String, seq: Seq[ResourceValue]) = if (seq.isEmpty) None else Some(x -> seq)
|
def optDef(x: String, seq: Seq[ResourceValue]) = if (seq.isEmpty) None else Some(x -> seq)
|
||||||
val compat = optDef("compatible", devcompat.map(ResourceString(_)))
|
val compat = optDef("compatible", devcompat.map(ResourceString(_))) // describe the list of compatiable devices
|
||||||
|
|
||||||
val reg = resources.map.filterKeys(regFilter)
|
val reg = resources.map.filterKeys(regFilter)
|
||||||
val (named, bulk) = reg.partition { case (k, v) => regName(k).isDefined }
|
val (named, bulk) = reg.partition { case (k, v) => regName(k).isDefined }
|
||||||
@ -114,13 +149,18 @@ class SimpleDevice(devname: String, devcompat: Seq[String]) extends Device with
|
|||||||
require (false, s"DTS device $name has $k = $seq, must be a single ResourceAddress!")
|
require (false, s"DTS device $name has $k = $seq, must be a single ResourceAddress!")
|
||||||
}
|
}
|
||||||
|
|
||||||
val names = optDef("reg-names", named.map(x => ResourceString(regName(x._1).get)).toList)
|
val names = optDef("reg-names", named.map(x => ResourceString(regName(x._1).get)).toList) // names of the named address space
|
||||||
val regs = optDef("reg", (named ++ bulk).flatMap(_._2.map(_.value)).toList)
|
val regs = optDef("reg", (named ++ bulk).flatMap(_._2.map(_.value)).toList) // address ranges of all spaces (named and bulk)
|
||||||
|
|
||||||
Description(name, ListMap() ++ compat ++ int ++ names ++ regs)
|
Description(name, ListMap() ++ compat ++ int ++ names ++ regs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A simple bus
|
||||||
|
* @param devname the base device named used in device name generation.
|
||||||
|
* @param devcompat a list of compatible devices. See device tree property "compatible".
|
||||||
|
* @param offset the base address of this bus.
|
||||||
|
*/
|
||||||
class SimpleBus(devname: String, devcompat: Seq[String], offset: BigInt = 0) extends SimpleDevice(devname, devcompat ++ Seq("simple-bus"))
|
class SimpleBus(devname: String, devcompat: Seq[String], offset: BigInt = 0) extends SimpleDevice(devname, devcompat ++ Seq("simple-bus"))
|
||||||
{
|
{
|
||||||
override def describe(resources: ResourceBindings): Description = {
|
override def describe(resources: ResourceBindings): Description = {
|
||||||
@ -147,6 +187,7 @@ class SimpleBus(devname: String, devcompat: Seq[String], offset: BigInt = 0) ext
|
|||||||
def ranges = Seq(Resource(this, "ranges"))
|
def ranges = Seq(Resource(this, "ranges"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A generic memory block. */
|
||||||
class MemoryDevice extends Device with DeviceRegName
|
class MemoryDevice extends Device with DeviceRegName
|
||||||
{
|
{
|
||||||
override val prefix = ""
|
override val prefix = ""
|
||||||
@ -169,12 +210,13 @@ case class Resource(owner: Device, key: String)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The resource binding scope for a LazyModule that generates a device tree (currently Coreplex only). */
|
||||||
trait BindingScope
|
trait BindingScope
|
||||||
{
|
{
|
||||||
this: LazyModule =>
|
this: LazyModule =>
|
||||||
|
|
||||||
private val parentScope = BindingScope.find(parent)
|
private val parentScope = BindingScope.find(parent)
|
||||||
protected[diplomacy] var resourceBindingFns: Seq[() => Unit] = Nil
|
protected[diplomacy] var resourceBindingFns: Seq[() => Unit] = Nil // callback functions to resolve resource binding during elaboration
|
||||||
protected[diplomacy] var resourceBindings: Seq[(Resource, Option[Device], ResourceValue)] = Nil
|
protected[diplomacy] var resourceBindings: Seq[(Resource, Option[Device], ResourceValue)] = Nil
|
||||||
|
|
||||||
private case class ExpandedValue(path: Seq[String], labels: Seq[String], value: Seq[ResourceValue])
|
private case class ExpandedValue(path: Seq[String], labels: Seq[String], value: Seq[ResourceValue])
|
||||||
@ -208,6 +250,7 @@ trait BindingScope
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Generate the device tree. */
|
||||||
def bindingTree: ResourceMap = {
|
def bindingTree: ResourceMap = {
|
||||||
eval
|
eval
|
||||||
val map: Map[Device, ResourceBindings] =
|
val map: Map[Device, ResourceBindings] =
|
||||||
@ -232,6 +275,9 @@ object BindingScope
|
|||||||
|
|
||||||
object ResourceBinding
|
object ResourceBinding
|
||||||
{
|
{
|
||||||
|
/** Add a resource callback function to the callback list BindingScope.resourceBindingFns.
|
||||||
|
* @param block the callback function to be added.
|
||||||
|
*/
|
||||||
def apply(block: => Unit) {
|
def apply(block: => Unit) {
|
||||||
val scope = BindingScope.find()
|
val scope = BindingScope.find()
|
||||||
require (scope.isDefined, "ResourceBinding must be called from within a BindingScope")
|
require (scope.isDefined, "ResourceBinding must be called from within a BindingScope")
|
||||||
|
Loading…
Reference in New Issue
Block a user