1
0
Fork 0
rocket-chip/src/main/scala/tile/Interrupts.scala

78 lines
2.3 KiB
Scala

// See LICENSE.SiFive for license details.
package freechips.rocketchip.tile
import Chisel._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.interrupts._
import freechips.rocketchip.util._
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())
val lip = Vec(coreParams.nLocalInterrupts, Bool())
}
// Use diplomatic interrupts to external interrupts from the subsystem into the tile
trait HasExternalInterrupts { this: BaseTile =>
val intInwardNode = intXbar.intnode
protected val intSinkNode = IntSinkNode(IntSinkPortSimple())
intSinkNode := intXbar.intnode
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)))
intSinkNode.edges.in.flatMap(_.source.sources).map { case s =>
for (i <- s.range.start until s.range.end) {
csrIntMap.lift(i).foreach { j =>
s.resources.foreach { r =>
r.bind(intcDevice, ResourceInt(j))
}
}
}
}
}
// 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 subsystem.HasRocketTiles
// debug, msip, mtip, meip, seip, lip offsets in CSRs
def csrIntMap: List[Int] = {
val nlips = tileParams.core.nLocalInterrupts
val seip = if (usingVM) Seq(9) else Nil
List(65535, 3, 7, 11) ++ seip ++ List.tabulate(nlips)(_ + 16)
}
// go from flat diplomatic Interrupts to bundled TileInterrupts
def decodeCoreInterrupts(core: TileInterrupts) {
val async_ips = Seq(core.debug)
val periph_ips = Seq(
core.msip,
core.mtip,
core.meip)
val seip = if (core.seip.isDefined) Seq(core.seip.get) else Nil
val core_ips = core.lip
val (interrupts, _) = intSinkNode.in(0)
(async_ips ++ periph_ips ++ seip ++ core_ips).zip(interrupts).foreach { case(c, i) => c := i }
}
}