2017-02-09 22:59:09 +01:00
|
|
|
// See LICENSE.SiFive for license details.
|
|
|
|
|
2017-07-07 19:48:16 +02:00
|
|
|
package freechips.rocketchip.tile
|
2017-02-09 22:59:09 +01:00
|
|
|
|
|
|
|
import Chisel._
|
2017-07-07 19:48:16 +02:00
|
|
|
|
|
|
|
import freechips.rocketchip.config.Parameters
|
2017-12-21 02:18:38 +01:00
|
|
|
import freechips.rocketchip.diplomacy._
|
2017-12-14 04:00:29 +01:00
|
|
|
import freechips.rocketchip.interrupts._
|
2017-07-07 19:48:16 +02:00
|
|
|
import freechips.rocketchip.util._
|
2017-02-09 22:59:09 +01:00
|
|
|
|
|
|
|
class TileInterrupts(implicit p: Parameters) extends CoreBundle()(p) {
|
|
|
|
val debug = Bool()
|
|
|
|
val mtip = Bool()
|
|
|
|
val msip = Bool()
|
|
|
|
val meip = Bool()
|
|
|
|
val seip = usingVM.option(Bool())
|
2017-03-30 04:14:04 +02:00
|
|
|
val lip = Vec(coreParams.nLocalInterrupts, Bool())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use diplomatic interrupts to external interrupts from the coreplex into the tile
|
2017-12-28 23:00:13 +01:00
|
|
|
trait HasExternalInterrupts { this: BaseTile =>
|
2017-03-30 04:14:04 +02:00
|
|
|
|
2017-12-28 23:00:13 +01:00
|
|
|
val intInwardNode = intXbar.intnode
|
2018-01-09 04:38:10 +01:00
|
|
|
protected val intSinkNode = IntSinkNode(IntSinkPortSimple())
|
2017-12-28 23:00:13 +01:00
|
|
|
intSinkNode := intXbar.intnode
|
2017-12-21 02:18:38 +01:00
|
|
|
|
|
|
|
val intcDevice = new Device {
|
|
|
|
def describe(resources: ResourceBindings): Description = {
|
|
|
|
Description(s"cpus/cpu@$hartId/interrupt-controller", Map(
|
|
|
|
"compatible" -> "riscv,cpu-intc".asProperty,
|
|
|
|
"interrupt-controller" -> Nil,
|
|
|
|
"#interrupt-cells" -> 1.asProperty))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ResourceBinding {
|
|
|
|
Resource(intcDevice, "reg").bind(ResourceInt(BigInt(hartId)))
|
|
|
|
|
2017-12-28 23:00:13 +01:00
|
|
|
intSinkNode.edges.in.flatMap(_.source.sources).map { case s =>
|
2017-12-21 02:18:38 +01:00
|
|
|
for (i <- s.range.start until s.range.end) {
|
|
|
|
csrIntMap.lift(i).foreach { j =>
|
|
|
|
s.resources.foreach { r =>
|
|
|
|
r.bind(intcDevice, ResourceInt(j))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-03-30 04:14:04 +02:00
|
|
|
|
|
|
|
// TODO: the order of the following two functions must match, and
|
|
|
|
// also match the order which things are connected to the
|
|
|
|
// per-tile crossbar in coreplex.HasRocketTiles
|
|
|
|
|
|
|
|
// debug, msip, mtip, meip, seip, lip offsets in CSRs
|
|
|
|
def csrIntMap: List[Int] = {
|
|
|
|
val nlips = tileParams.core.nLocalInterrupts
|
2017-04-25 00:58:33 +02:00
|
|
|
val seip = if (usingVM) Seq(9) else Nil
|
|
|
|
List(65535, 3, 7, 11) ++ seip ++ List.tabulate(nlips)(_ + 16)
|
2017-03-30 04:14:04 +02:00
|
|
|
}
|
2017-12-21 02:18:38 +01:00
|
|
|
|
2017-03-30 04:14:04 +02:00
|
|
|
// go from flat diplomatic Interrupts to bundled TileInterrupts
|
|
|
|
def decodeCoreInterrupts(core: TileInterrupts) {
|
2017-04-28 23:49:24 +02:00
|
|
|
val async_ips = Seq(core.debug)
|
|
|
|
val periph_ips = Seq(
|
2017-03-30 04:14:04 +02:00
|
|
|
core.msip,
|
|
|
|
core.mtip,
|
2017-05-03 04:24:19 +02:00
|
|
|
core.meip)
|
|
|
|
|
|
|
|
val seip = if (core.seip.isDefined) Seq(core.seip.get) else Nil
|
2017-04-28 23:49:24 +02:00
|
|
|
|
|
|
|
val core_ips = core.lip
|
|
|
|
|
2017-12-28 23:00:13 +01:00
|
|
|
val (interrupts, _) = intSinkNode.in(0)
|
2017-09-15 23:44:07 +02:00
|
|
|
(async_ips ++ periph_ips ++ seip ++ core_ips).zip(interrupts).foreach { case(c, i) => c := i }
|
2017-03-30 04:14:04 +02:00
|
|
|
}
|
2017-02-09 22:59:09 +01:00
|
|
|
}
|