Commit b2cbb69a authored by Yuxiao Mao's avatar Yuxiao Mao
Browse files

Merge branch 'dev': experimentation config, use 1:1 rop detection, reduce...

Merge branch 'dev': experimentation config, use 1:1 rop detection, reduce area, fix matana link in description
parents 39a6efbf cece7fbe
......@@ -7,13 +7,13 @@ Some of adaptation to 1.5.0 have been proposed to branch `dev-chipyard1.5` but i
## Setup
First, add this repo as a submodule.
First, add this repo as a submodule of Chipyard.
Then apply patches to include MATANA into Chipyard.
```
# add MATANA as a submodule of Chipyard
cd <path/to/Chipyard>
git submodule add https://gitlab.laas.fr/rehad/rehad-chipyard generators/matana
git submodule add https://gitlab.laas.fr/matana/matana-chipyard generators/matana
# Apply patch that connect MATANA to Chipyard + Rocket-Chip + ...
git apply generators/matana/chipyard/chipyard.patch
......
......@@ -103,7 +103,7 @@ index 0000000..df04c91
+../../../../../matana/chipyard/generators/chipyard/src/main/scala/config/MatanaConfigs.scala
\ No newline at end of file
diff --git a/variables.mk b/variables.mk
index 4d49d5f..4808b57 100644
index 4d49d5f..5cfef81 100644
--- a/variables.mk
+++ b/variables.mk
@@ -25,14 +25,26 @@
......@@ -113,7 +113,7 @@ index 4d49d5f..4808b57 100644
-SUB_PROJECT ?= chipyard
+SUB_PROJECT ?= matana
+# for Rehad dev
+# for Matana dev
+ifeq ($(SUB_PROJECT),matana)
+ SBT_PROJECT ?= chipyard
+ MODEL ?= ImplemTop
......
diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala
index c6d86ce5f..99d98c9fc 100644
index c6d86ce5f..b71537cb9 100644
--- a/src/main/scala/rocket/RocketCore.scala
+++ b/src/main/scala/rocket/RocketCore.scala
@@ -846,6 +846,20 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
@@ -846,6 +846,26 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
io.rocc.cmd.bits.rs1 := wb_reg_wdata
io.rocc.cmd.bits.rs2 := wb_reg_rs2
......@@ -15,10 +15,16 @@ index c6d86ce5f..99d98c9fc 100644
+ // dmem access is at ex stage
+ io.matana.dmemaddr_data := encodeVirtualAddress(ex_rs(0), alu.io.adder_out) // copy from io.dmem.req.bits.addr
+ io.matana.dmemaddr_valid := ex_reg_valid && ex_ctrl.mem
+ // dmem physical addr s2_paddr is at wb stage (cf s2_xcpt)
+ io.matana.dmempaddr_data := io.dmem.s2_paddr
+ io.matana.dmempaddr_valid := wb_reg_valid && wb_ctrl.mem
+ // performance counters
+ io.matana.hpc.dcache_miss := io.dmem.perf.acquire
+ io.matana.hpc.dcache_blocked := id_ctrl.mem && dcache_blocked
+ io.matana.hpc.dcache_release := io.dmem.perf.release
+ io.matana.hpc.branch_mispredict := take_pc_mem && mem_direction_misprediction
+ io.matana.hpc.dtlb_miss := io.dmem.perf.tlbMiss
+ io.matana.hpc.l2tlb_miss := io.ptw.perf.l2miss
+
// gate the clock
val unpause = csr.io.time(rocketParams.lgPauseCycles-1, 0) === 0 || io.dmem.perf.release || take_pc
......
......@@ -12,11 +12,17 @@ class MatanaCoreIO extends Bundle {
val pc_valid = Output(Bool())
val dmemaddr_data = Output(UInt(40.W)) // used by DCacheMetadataReq
val dmemaddr_valid = Output(Bool())
val dmempaddr_data = Output(UInt(32.W)) // In config (1MedCore + 64bit), paddrBits = 32
val dmempaddr_valid = Output(Bool())
val hpc = Output(new MatanaCoreHpcIO())
}
class MatanaCoreHpcIO extends Bundle {
val dcache_miss = Bool()
val dcache_blocked = Bool()
val dcache_release = Bool()
val branch_mispredict = Bool()
val dtlb_miss = Bool()
val l2tlb_miss = Bool()
}
......@@ -19,9 +19,9 @@ case class MatanaParams(
dExample: Option[DetectExampleParams] = None, //Some(DetectExampleParams()),
dPatternTimer: Option[DetectPatternTimerParams] = Some(DetectPatternTimerParams()),
dPatternPrime: Option[DetectPatternPrimeParams] = Some(DetectPatternPrimeParams()),
dPatternCacheEvent: Option[DetectPatternCacheEventParams] = Some(DetectPatternCacheEventParams()),
dPatternLibAccess: Option[DetectPatternLibAccessParams] = Some(DetectPatternLibAccessParams()),
dPatternRop: Option[DetectPatternRopParams] = Some(DetectPatternRopParams()),
dPatternCacheEvent: Option[DetectPatternCacheEventParams] = None, //Some(DetectPatternCacheEventParams()),
dPatternLibAccess: Option[DetectPatternLibAccessParams] = None, //Some(DetectPatternLibAccessParams()),
dPatternRop: Option[DetectPatternRopParams] = None, //Some(DetectPatternRopParams()),
counterWidth: Int = 32
) {
require(isPow2(clockDiv))
......@@ -37,6 +37,8 @@ case class MatanaParams(
// TODO: compute the real value of vaddrBitsExtended, useful for CoreIO too (refer to rocket-chip.tile.BaseTile)
private val vaddrBitsExtended : Int = if(XLen == 32) 32 else 40
val addrWidth = vaddrBitsExtended
val paddrWidth : Int = 32
}
case object MatanaKey extends Field[Option[MatanaParams]](None)
......
......@@ -47,15 +47,28 @@ class DetectPatternCacheEventInternal(params: DetectPatternCacheEventParams)(imp
val countPackValidThreshLengthMinus1_5 = 10 // Thresh = 2^(10+1) = 2048 = 0x800
val atk_dcache_miss_dec1 = RegInit(false.B)
atk_dcache_miss_dec1 := count_pack_valid(countPackValidThreshLengthMinus1_1, 0) === 0.U
atk_dcache_miss_dec1 := count_pack_valid(countPackValidThreshLengthMinus1_1, 0) === 0.U && in.isMonitoring
val atk_dcache_miss_dec2 = RegInit(false.B)
atk_dcache_miss_dec2 := count_pack_valid(countPackValidThreshLengthMinus1_2, 0) === 0.U
atk_dcache_miss_dec2 := count_pack_valid(countPackValidThreshLengthMinus1_2, 0) === 0.U && in.isMonitoring
val atk_dcache_miss_dec3 = RegInit(false.B)
atk_dcache_miss_dec3 := count_pack_valid(countPackValidThreshLengthMinus1_3, 0) === 0.U
atk_dcache_miss_dec3 := count_pack_valid(countPackValidThreshLengthMinus1_3, 0) === 0.U && in.isMonitoring
val atk_dcache_miss_dec4 = RegInit(false.B)
atk_dcache_miss_dec4 := count_pack_valid(countPackValidThreshLengthMinus1_4, 0) === 0.U
atk_dcache_miss_dec4 := count_pack_valid(countPackValidThreshLengthMinus1_4, 0) === 0.U && in.isMonitoring
val atk_dcache_miss_dec5 = RegInit(false.B)
atk_dcache_miss_dec5 := count_pack_valid(countPackValidThreshLengthMinus1_5, 0) === 0.U
atk_dcache_miss_dec5 := count_pack_valid(countPackValidThreshLengthMinus1_5, 0) === 0.U && in.isMonitoring
// Other events
val pack_has_dcache_blocked = RegInit(false.B).suggestName("dpdcacheevent_pack_has_dcache_blocked")
pack_has_dcache_blocked := in.vec_hpc.map(_.dcache_blocked).reduce(_||_) && in.isMonitoring
val pack_has_dcache_release = RegInit(false.B).suggestName("dpdcacheevent_pack_has_dcache_release")
pack_has_dcache_release := in.vec_hpc.map(_.dcache_release).reduce(_||_) && in.isMonitoring
val pack_has_branch_mispredict = RegInit(false.B).suggestName("dpdcacheevent_pack_has_branch_mispredict")
pack_has_branch_mispredict := in.vec_hpc.map(_.branch_mispredict).reduce(_||_) && in.isMonitoring
val pack_has_dtlb_miss = RegInit(false.B).suggestName("dpdcacheevent_pack_has_dtlb_miss")
pack_has_dtlb_miss := in.vec_hpc.map(_.dtlb_miss).reduce(_||_) && in.isMonitoring
val pack_has_l2tlb_miss = RegInit(false.B).suggestName("dpdcacheevent_pack_has_l2tlb_miss")
pack_has_l2tlb_miss := in.vec_hpc.map(_.l2tlb_miss).reduce(_||_) && in.isMonitoring
override def regmap(offset: Int) =
......@@ -65,6 +78,11 @@ class DetectPatternCacheEventInternal(params: DetectPatternCacheEventParams)(imp
RegmapUtil.countEventMax(atk_dcache_miss, in.resetCounters, atk_dcache_miss_dec3, offset + 0x20, "AtkDCacheEventMiss3") ++
RegmapUtil.countEventMax(atk_dcache_miss, in.resetCounters, atk_dcache_miss_dec4, offset + 0x28, "AtkDCacheEventMiss4") ++
RegmapUtil.countEventMax(atk_dcache_miss, in.resetCounters, atk_dcache_miss_dec5, offset + 0x30, "AtkDCacheEventMiss5") ++
RegmapUtil.countEvent(pack_has_dcache_blocked, in.resetCounters, offset + 0x80, "PackDCacheBlocked") ++
RegmapUtil.countEvent(pack_has_dcache_release, in.resetCounters, offset + 0x84, "PackDCacheRelease") ++
RegmapUtil.countEvent(pack_has_branch_mispredict, in.resetCounters, offset + 0x88, "PackBranchMispredict") ++
RegmapUtil.countEvent(pack_has_dtlb_miss, in.resetCounters, offset + 0x8C, "PackDTLBMiss") ++
RegmapUtil.countEvent(pack_has_l2tlb_miss, in.resetCounters, offset + 0x90, "PackL2TLBMiss") ++
Nil
}
......
......@@ -16,6 +16,8 @@ class DetectPatternPrimeIn()(implicit val mp: MatanaParams) extends Bundle {
val isMonitoring = Bool()
val dmemaddr_valid = Bool()
val dmemaddr_data = UInt(mp.addrWidth.W)
val dmempaddr_valid = Bool()
val dmempaddr_data = UInt(mp.paddrWidth.W)
val pack_has_valid = Bool()
val pack_has_loadword = Bool()
}
......@@ -108,6 +110,65 @@ class DetectPatternPrimeInternal(params: DetectPatternPrimeParams)(implicit mp:
atk_prime_2 := (count2 === countThresh2.U) && in.isMonitoring && in.dmemaddr_valid
// Attack pattern (physical address)
// Description: Multiples access to DCache, each time in same set with differents tag
// 1) diff tag same set c+2, diff tag diff set c+1, same tag same set c-2, same tag diff set c-1 (thresh 8)
// 2) diff tag same set c+2, diff tag diff set c+1, same tag same set c-4, same tag diff set c-2 (thresh 8)
val dmemptag = Wire(UInt((mp.paddrWidth - params.tagAddrLSB).W))
dmemptag := in.dmempaddr_data(mp.paddrWidth - 1, params.tagAddrLSB)
val dmempset = Wire(UInt((params.tagAddrLSB - params.setAddrLSB).W))
dmempset := in.dmempaddr_data(params.tagAddrLSB - 1, params.setAddrLSB)
val saved_dmemptag = RegInit(VecInit(Seq.fill(params.savedDMemTagNum)(0.U((mp.addrWidth - params.tagAddrLSB).W)))).suggestName("saved_dmemptag")
val saved_dmempset = RegInit(VecInit(Seq.fill(params.savedDMemSetNum)(0.U((params.tagAddrLSB - params.setAddrLSB).W)))).suggestName("saved_dmempset")
val countp1 = RegInit(0.U(log2Ceil(countThresh1 + 1).W)).suggestName("dpprime_countp1")
val countp2 = RegInit(0.U(log2Ceil(countThresh2 + 1).W)).suggestName("dpprime_countp2")
// Update saved_dmem* array in FIFO way
when (in.dmempaddr_valid && in.isMonitoring) {
when (saved_dmemptag.map(_ =/= dmemptag).reduce(_&&_)) { // new tag
when (saved_dmempset.map(_ =/= dmempset).reduce(_&&_)) { // new set
// Update saved_dmempset, newer at 0
saved_dmempset.foldLeft(dmempset) { (data, last) =>
last := data
last
}
countp1 := Mux(countp1 <= countThresh1.U - 1.U, countp1 + 1.U, countThresh1.U)
countp2 := Mux(countp2 <= countThresh2.U - 1.U, countp2 + 1.U, countThresh2.U)
}.otherwise { // old set
countp1 := Mux(countp1 <= countThresh1.U - 2.U, countp1 + 2.U, countThresh1.U)
countp2 := Mux(countp2 <= countThresh2.U - 2.U, countp2 + 2.U, countThresh2.U)
}
// Update saved_dmemptag, newer at 0
saved_dmemptag.foldLeft(dmemptag) { (data, last) =>
last := data
last
}
}.otherwise { // old tag
when (saved_dmempset.map(_ =/= dmemptag).reduce(_&&_)) { // new set
// Update saved_dmempset, newer at 0
saved_dmempset.foldLeft(dmempset) { (data, last) =>
last := data
last
}
countp1 := Mux(countp1 >= 1.U, countp1 - 1.U, 0.U)
countp2 := Mux(countp2 >= 2.U, countp2 - 2.U, 0.U)
}.otherwise { // old set
countp1 := Mux(countp1 >= 2.U, countp1 - 2.U, 0.U)
countp2 := Mux(countp2 >= 4.U, countp2 - 4.U, 0.U)
}
}
}
// only count atk during monitoring, and when an dmempaddr is present (prevent counting during wait)
val atk_prime_phy_1 = RegInit(false.B)
atk_prime_phy_1 := (countp1 === countThresh1.U) && in.isMonitoring && in.dmempaddr_valid
val atk_prime_phy_2 = RegInit(false.B)
atk_prime_phy_2 := (countp2 === countThresh2.U) && in.isMonitoring && in.dmempaddr_valid
// Attack Pattern (instruction-based)
// Description: all valid pack contains an word size load. For -O0 there is store with load, we suppose if store to the same addr, the next load can be conclude in the same slow cycle.
// 1) valid load c+1, valid not load c-2 (thresh 16)
......@@ -134,20 +195,20 @@ class DetectPatternPrimeInternal(params: DetectPatternPrimeParams)(implicit mp:
// 2) = atk_prime_1, but decrement the counter by 1 if count_pack_valid reach thresh 0x400 (1024)
// Count pack valid for decrement counters
val count_pack_valid = RegInit(0.U(mp.counterWidth.W)).suggestName("dpprime_count_pack_valid")
val count_slow_cycle = RegInit(0.U(mp.counterWidth.W)).suggestName("dpprime_count_pack_valid")
when (in.resetCounters) {
count_pack_valid := 0.U
count_slow_cycle := 0.U
}.elsewhen (in.isMonitoring) {
count_pack_valid := count_pack_valid + in.pack_has_valid
count_slow_cycle := count_slow_cycle + 1.U
}
val countPackValidThreshLengthMinus1_1 = 10 // Thresh = 2^(10+1) = 2048 = 0x800
val countPackValidThreshLengthMinus1_2 = 9 // Thresh = 2^(9+1) = 1024 = 0x400
val countSlowCycleThreshLengthMinus1_1 = 10 // Thresh = 2^(10+1) = 2048 = 0x800
val countSlowCycleThreshLengthMinus1_2 = 9 // Thresh = 2^(9+1) = 1024 = 0x400
val atk_prime_mix1_dec = RegInit(false.B)
atk_prime_mix1_dec := count_pack_valid(countPackValidThreshLengthMinus1_1, 0) === 0.U
atk_prime_mix1_dec := count_slow_cycle(countSlowCycleThreshLengthMinus1_1, 0) === 0.U
val atk_prime_mix2_dec = RegInit(false.B)
atk_prime_mix2_dec := count_pack_valid(countPackValidThreshLengthMinus1_2, 0) === 0.U
atk_prime_mix2_dec := count_slow_cycle(countSlowCycleThreshLengthMinus1_2, 0) === 0.U
// Debug Signals
......@@ -157,10 +218,12 @@ class DetectPatternPrimeInternal(params: DetectPatternPrimeParams)(implicit mp:
override def regmap(offset: Int) =
RegmapUtil.countEvent(atk_prime_1, in.resetCounters, offset + 0x0, "AtkPrime1") ++
RegmapUtil.countEvent(atk_prime_2, in.resetCounters, offset + 0x4, "AtkPrime2") ++
RegmapUtil.countEvent(atk_primeinst_1, in.resetCounters, offset + 0x10, "AtkPrimeInst1") ++
RegmapUtil.countEventMax(atk_prime_1, in.resetCounters, atk_prime_mix1_dec, offset + 0x20, "AtkPrimeMix1") ++
RegmapUtil.countEventMax(atk_prime_1, in.resetCounters, atk_prime_mix2_dec, offset + 0x30, "AtkPrimeMix2") ++
// RegmapUtil.countEvent(atk_prime_2, in.resetCounters, offset + 0x4, "AtkPrime2") ++
// RegmapUtil.countEvent(atk_primeinst_1, in.resetCounters, offset + 0x10, "AtkPrimeInst1") ++
// RegmapUtil.countEventMax(atk_prime_1, in.resetCounters, atk_prime_mix1_dec, offset + 0x20, "AtkPrimeMix1") ++
// RegmapUtil.countEventMax(atk_prime_1, in.resetCounters, atk_prime_mix2_dec, offset + 0x30, "AtkPrimeMix2") ++
// RegmapUtil.countEvent(atk_prime_phy_1, in.resetCounters, offset + 0x40, "AtkPrimePhy1") ++
// RegmapUtil.countEvent(atk_prime_phy_2, in.resetCounters, offset + 0x44, "AtkPrimePhy2") ++
Nil
}
......
......@@ -27,50 +27,112 @@ class DetectPatternRopInternal(params: DetectPatternRopParams)(implicit mp: Mata
// Attack Pattern
// Description: Jalr chained short instruction sequence.
// 1) jalr + jalr = c+1, other jalr = c-2 (window size 1+1) (thresh proably 10 as in mispredict1) (window size 2+1 has high false positive rate)
// 2) jalr + jalr = c+1, other jalr = c-2 (window size 1+1, step 1/2)
// 1) jalr + jalr = c+1, other jalr = c-2 (window size N+1) (thresh proably 10 as in mispredict1)
// Note:
// 1) clockDiv will impact the pattern on window size, smaller clockDiv is perhaps more accurate.
// 2) ROP gadget destination is likely not in cache, so jalr will take longer and will probably be visible in different clockDiv pack. But this property may increase false positive as legal chain will now seems to be shorter.
val npackSizeMax = 2
val npack_jalr = RegInit(0.U(npackSizeMax.W)).suggestName("npack_jalr")
when (in.pack_has_valid) {
npack_jalr := Cat(npack_jalr(npackSizeMax - 2, 0), in.pack_has_jalr)
}
val nstepNum = 2 // step 1/2 of slow cycle
require(mp.clockDiv % nstepNum == 0)
require(nstepNum == 2) // Only support value 2 for now, else needs modify the use of dpack_jalr in when
val nstepSize: Int = mp.clockDiv / nstepNum
val dpack_jalr = Wire(Vec(nstepNum, Bool())).suggestName("dpack_jalr")
for (i <- 0 until nstepNum) {
dpack_jalr(i) := in.pack_jalr.zipWithIndex.filter{ case (data, index) =>
((index <= nstepSize*(i+1)-1) && (index >= nstepSize*i))
}.map(_._1).reduce(_||_)
val npackSizeMax = 16
val npackSize1 = 8
val npackSize2 = 9
val npackSize3 = 10
val npackSize4 = 11
val npackSize5 = 12
val npackSize6 = 13
val npackSize7 = 14
val npackSize8 = 15
val npackSize9 = 16
val npack_jalr = RegInit(0.U(npackSizeMax.W)).suggestName("npack_jalr") // if last N valid cycles has jalr
val npack_jalr_orR1 = RegInit(false.B)
val npack_jalr_orR2 = RegInit(false.B)
val npack_jalr_orR3 = RegInit(false.B)
val npack_jalr_orR4 = RegInit(false.B)
val npack_jalr_orR5 = RegInit(false.B)
val npack_jalr_orR6 = RegInit(false.B)
val npack_jalr_orR7 = RegInit(false.B)
val npack_jalr_orR8 = RegInit(false.B)
val npack_jalr_orR9 = RegInit(false.B)
when (in.isMonitoring && in.pack_has_valid) {
npack_jalr := Cat(npack_jalr(npackSizeMax-2, 0), in.pack_has_jalr)
npack_jalr_orR1 := npack_jalr(npackSize1-2, 0).orR || in.pack_has_jalr
npack_jalr_orR2 := npack_jalr(npackSize2-2, 0).orR || in.pack_has_jalr
npack_jalr_orR3 := npack_jalr(npackSize3-2, 0).orR || in.pack_has_jalr
npack_jalr_orR4 := npack_jalr(npackSize4-2, 0).orR || in.pack_has_jalr
npack_jalr_orR5 := npack_jalr(npackSize5-2, 0).orR || in.pack_has_jalr
npack_jalr_orR6 := npack_jalr(npackSize6-2, 0).orR || in.pack_has_jalr
npack_jalr_orR7 := npack_jalr(npackSize7-2, 0).orR || in.pack_has_jalr
npack_jalr_orR8 := npack_jalr(npackSize8-2, 0).orR || in.pack_has_jalr
npack_jalr_orR9 := npack_jalr(npackSize9-2, 0).orR || in.pack_has_jalr
}
val countjalr1 = RegInit(0.U(mp.counterWidth.W)).suggestName("dprop_countjalr1")
val countjalr2 = RegInit(0.U(mp.counterWidth.W)).suggestName("dprop_countjalr2")
val countjalr3 = RegInit(0.U(mp.counterWidth.W)).suggestName("dprop_countjalr3")
val countjalr4 = RegInit(0.U(mp.counterWidth.W)).suggestName("dprop_countjalr4")
val countjalr5 = RegInit(0.U(mp.counterWidth.W)).suggestName("dprop_countjalr5")
val countjalr6 = RegInit(0.U(mp.counterWidth.W)).suggestName("dprop_countjalr6")
val countjalr7 = RegInit(0.U(mp.counterWidth.W)).suggestName("dprop_countjalr7")
val countjalr8 = RegInit(0.U(mp.counterWidth.W)).suggestName("dprop_countjalr8")
val countjalr9 = RegInit(0.U(mp.counterWidth.W)).suggestName("dprop_countjalr9")
when (in.resetCounters) {
countjalr1 := 0.U
countjalr2 := 0.U
countjalr3 := 0.U
countjalr4 := 0.U
countjalr5 := 0.U
countjalr6 := 0.U
countjalr7 := 0.U
countjalr8 := 0.U
countjalr9 := 0.U
}.otherwise {
when (in.isMonitoring && in.pack_has_jalr) { // evaluate counter when jalr (include pack_has_valid)
when (npack_jalr(0)) { // has jalr adjacent
when (npack_jalr_orR1) { // has jalr adjacent
countjalr1 := countjalr1 + 1.U
}.otherwise { // no jalr adjacent
countjalr1 := Mux(countjalr1 >= 2.U, countjalr1 - 2.U, 0.U)
}
when (npack_jalr(0) && dpack_jalr.reduce(_&&_)) { // has jalr in adjacent window and step
countjalr2 := countjalr2 + 2.U
}.elsewhen (npack_jalr(0) || dpack_jalr.reduce(_&&_)) { // has jalr in adjacent window or step
when (npack_jalr_orR2) { // has jalr adjacent
countjalr2 := countjalr2 + 1.U
}.otherwise { // no jalr adjacent
countjalr2 := Mux(countjalr2 >= 2.U, countjalr2 - 2.U, 0.U)
}
when (npack_jalr_orR3) { // has jalr adjacent
countjalr3 := countjalr3 + 1.U
}.otherwise { // no jalr adjacent
countjalr3 := Mux(countjalr3 >= 2.U, countjalr3 - 2.U, 0.U)
}
when (npack_jalr_orR4) { // has jalr adjacent
countjalr4 := countjalr4 + 1.U
}.otherwise { // no jalr adjacent
countjalr4 := Mux(countjalr4 >= 2.U, countjalr4 - 2.U, 0.U)
}
when (npack_jalr_orR5) { // has jalr adjacent
countjalr5 := countjalr5 + 1.U
}.otherwise { // no jalr adjacent
countjalr5 := Mux(countjalr5 >= 2.U, countjalr5 - 2.U, 0.U)
}
when (npack_jalr_orR6) { // has jalr adjacent
countjalr6 := countjalr6 + 1.U
}.otherwise { // no jalr adjacent
countjalr6 := Mux(countjalr6 >= 2.U, countjalr6 - 2.U, 0.U)
}
when (npack_jalr_orR7) { // has jalr adjacent
countjalr7 := countjalr7 + 1.U
}.otherwise { // no jalr adjacent
countjalr7 := Mux(countjalr7 >= 2.U, countjalr7 - 2.U, 0.U)
}
when (npack_jalr_orR8) { // has jalr adjacent
countjalr8 := countjalr8 + 1.U
}.otherwise { // no jalr adjacent
countjalr8 := Mux(countjalr8 >= 2.U, countjalr8 - 2.U, 0.U)
}
when (npack_jalr_orR9) { // has jalr adjacent
countjalr9 := countjalr9 + 1.U
}.otherwise { // no jalr adjacent
countjalr9 := Mux(countjalr9 >= 2.U, countjalr9 - 2.U, 0.U)
}
}
}
......@@ -88,7 +150,14 @@ class DetectPatternRopInternal(params: DetectPatternRopParams)(implicit mp: Mata
override def regmap(offset: Int) =
RegmapUtil.readValueMax(countjalr1, in.resetCounters, mp.counterWidth, offset, "CountRopJalr1") ++
RegmapUtil.readValueMax(countjalr2, in.resetCounters, mp.counterWidth, offset + 0x10, "CountRopJalr2") ++
//RegmapUtil.readValueMax(countjalr2, in.resetCounters, mp.counterWidth, offset + 0x8, "CountRopJalr2") ++
//RegmapUtil.readValueMax(countjalr3, in.resetCounters, mp.counterWidth, offset + 0x10, "CountRopJalr3") ++
//RegmapUtil.readValueMax(countjalr4, in.resetCounters, mp.counterWidth, offset + 0x18, "CountRopJalr4") ++
//RegmapUtil.readValueMax(countjalr5, in.resetCounters, mp.counterWidth, offset + 0x20, "CountRopJalr5") ++
//RegmapUtil.readValueMax(countjalr6, in.resetCounters, mp.counterWidth, offset + 0x28, "CountRopJalr6") ++
RegmapUtil.readValueMax(countjalr7, in.resetCounters, mp.counterWidth, offset + 0x30, "CountRopJalr7") ++
//RegmapUtil.readValueMax(countjalr8, in.resetCounters, mp.counterWidth, offset + 0x38, "CountRopJalr8") ++
//RegmapUtil.readValueMax(countjalr9, in.resetCounters, mp.counterWidth, offset + 0x40, "CountRopJalr9") ++
Nil
}
......
package matana
import chisel3._
import chisel3.util.Cat
import chisel3.util.{Cat, log2Ceil}
import freechips.rocketchip.regmapper.RegField
case class DetectPatternTimerParams(
......@@ -33,23 +33,49 @@ class DetectPatternTimerInternal(params: DetectPatternTimerParams)(implicit mp:
// Registed (valid) pack analysis result for multiple slow cycles
val npackSize: Int = params.npackSizeInFastCycles / mp.clockDiv
val npackSizeMax: Int = npackSize * 16;
val npack_timer = RegInit(0.U(npackSize.W)).suggestName("npack_timer")
val npack_timer_orR = RegInit(false.B)
when (in.pack_has_valid) {
npack_timer := Cat(npack_timer(npackSize-2, 0), in.pack_has_timer)
npack_timer_orR := npack_timer(npackSize-2, 0).orR || in.pack_has_timer
val last_timer_count = RegInit(0.U((log2Ceil(npackSizeMax) + 1).W)).suggestName("last_timer_count")
val last_timer_in_window = RegInit(false.B).suggestName("last_timer_in_window")
when (in.resetCounters) {
last_timer_count := 0.U
last_timer_in_window := false.B
} .elsewhen (in.isMonitoring && in.pack_has_valid) {
when (in.pack_has_timer) {
last_timer_count := 0.U
last_timer_in_window := true.B
}.otherwise {
last_timer_count := last_timer_count + 1.U
last_timer_in_window := Mux(last_timer_in_window && (last_timer_count >= npackSizeMax.U), false.B, last_timer_in_window)
}
}
val atk_timer_timer = Wire(Bool())
atk_timer_timer := npack_timer_orR && in.pack_has_timer && in.isMonitoring
val atk_timer_timer2 = Wire(Bool())
val atk_timer_timer4 = Wire(Bool())
val atk_timer_timer8 = Wire(Bool())
val atk_timer_timer16 = Wire(Bool())
atk_timer_timer := last_timer_in_window && (last_timer_count <= npackSize.U) && in.pack_has_timer && in.isMonitoring
atk_timer_timer2 := last_timer_in_window && (last_timer_count <= (npackSize*2).U) && in.pack_has_timer && in.isMonitoring
atk_timer_timer4 := last_timer_in_window && (last_timer_count <= (npackSize*4).U) && in.pack_has_timer && in.isMonitoring
atk_timer_timer8 := last_timer_in_window && (last_timer_count <= (npackSize*8).U) && in.pack_has_timer && in.isMonitoring
atk_timer_timer16 := last_timer_in_window && (last_timer_count <= (npackSize*16).U) && in.pack_has_timer && in.isMonitoring
val atk_timer_flush = Wire(Bool())
atk_timer_flush := npack_timer_orR && in.pack_has_flush && in.isMonitoring
atk_timer_flush := last_timer_in_window && (last_timer_count <= npackSize.U) && in.pack_has_flush && in.isMonitoring
override def regmap(offset: Int) =
(if (params.withTimerTimer) RegmapUtil.countEventThreshAlarm(atk_timer_timer, in.resetCounters, offset, "AtkTimerTimer") else Nil) ++
(if (params.withTimerFlush) RegmapUtil.countEventThreshAlarm(atk_timer_flush, in.resetCounters, offset + 0x10, "AtkTimerFlush") else Nil)
(if (params.withTimerTimer) {
// RegmapUtil.countEventThreshAlarm(atk_timer_timer, in.resetCounters, offset, "AtkTimerTimer") ++
RegmapUtil.countEvent(atk_timer_timer2, in.resetCounters, offset + 0x10, "AtkTimerTimer2") ++
// RegmapUtil.countEvent(atk_timer_timer4, in.resetCounters, offset + 0x14, "AtkTimerTimer4") ++
// RegmapUtil.countEvent(atk_timer_timer8, in.resetCounters, offset + 0x18, "AtkTimerTimer8") ++
// RegmapUtil.countEvent(atk_timer_timer16, in.resetCounters, offset + 0x20, "AtkTimerTimer16") ++
Nil
} else Nil) ++
(if (params.withTimerFlush) {
RegmapUtil.countEventThreshAlarm(atk_timer_flush, in.resetCounters, offset + 0x80, "AtkTimerFlush")
} else Nil)
}
object DetectPatternTimer {
......
......@@ -36,6 +36,8 @@ class MatanaDetectionPerCoreIO()(implicit val mp: MatanaParams) extends Bundle {
val one_pc_valid = Input(Bool())
val one_dmemaddr_data = Input(UInt(mp.addrWidth.W))
val one_dmemaddr_valid = Input(Bool())
val one_dmempaddr_data = Input(UInt(mp.paddrWidth.W))
val one_dmempaddr_valid = Input(Bool())
// Performance counters
val vec_hpc = Input(Vec(mp.clockDiv, new MatanaCoreHpcIO()))
}
......@@ -133,6 +135,8 @@ class MatanaSlowDetectionImp(outer: MatanaSlowDetection, params: MatanaParams)
detectPatternPrime.in.isMonitoring := isMonitoring
detectPatternPrime.in.dmemaddr_valid := pack0.one_dmemaddr_valid
detectPatternPrime.in.dmemaddr_data := pack0.one_dmemaddr_data
detectPatternPrime.in.dmempaddr_valid := pack0.one_dmempaddr_valid
detectPatternPrime.in.dmempaddr_data := pack0.one_dmempaddr_data
detectPatternPrime.in.pack_has_valid := pack_has_valid
detectPatternPrime.in.pack_has_loadword := pack_has_loadword
......@@ -185,26 +189,23 @@ class MatanaSlowDetectionImp(outer: MatanaSlowDetection, params: MatanaParams)
RegField(mp.pidWidth, monitorPidMin,
RegFieldDesc("monitorPidMin",
"Monitor all process with PID >= monitorPidMin.",
reset=Some(60)))),
0xA0 -> Seq(
RegField.r(mp.addrWidth, lastPC,
RegFieldDesc("lastPC", "Last valid input PC.", reset=Some(0))))
reset=Some(60))))
)
// Combine all regmap
val regmapFinal =
regmap0 ++
// Debug for control signal
RegmapUtil.countEvent(reg_pid_change, resetCounters, 0x20, "PidChange") ++
RegmapUtil.countEvent(reg_pid_change_monitored, resetCounters, 0x24, "PidChangeMonitored") ++
//RegmapUtil.countEvent(reg_pid_change, resetCounters, 0x20, "PidChange") ++
//RegmapUtil.countEvent(reg_pid_change_monitored, resetCounters, 0x24, "PidChangeMonitored") ++
// Internal State
RegmapUtil.countEvent(pack_has_valid, resetCounters, 0x100, "PackValid") ++
RegmapUtil.countEvent(pack_has_timer, resetCounters, 0x104, "PackTimer") ++
RegmapUtil.countEvent(pack_has_flush, resetCounters, 0x108, "PackFlushL1D") ++
RegmapUtil.countEvent(pack0.one_dmemaddr_valid && isMonitoring, resetCounters, 0x10C, "DmemAddrValid") ++
//RegmapUtil.countEvent(pack_has_timer, resetCounters, 0x104, "PackTimer") ++
//RegmapUtil.countEvent(pack_has_flush, resetCounters, 0x108, "PackFlushL1D") ++
//RegmapUtil.countEvent(pack0.one_dmemaddr_valid && isMonitoring, resetCounters, 0x10C, "DmemAddrValid") ++
RegmapUtil.countEvent(isMonitoring, resetCounters, 0x110, "SlowCycle") ++
RegmapUtil.countEvent(pack_has_jalr, resetCounters, 0x114, "PackJalr") ++
RegmapUtil.countEvent(pack_has_jump, resetCounters, 0x118, "PackJump") ++
//RegmapUtil.countEvent(pack_has_jalr, resetCounters, 0x114, "PackJalr") ++
//RegmapUtil.countEvent(pack_has_jump, resetCounters, 0x118, "PackJump") ++
detectPatternTimer.regmap(0x200) ++
detectPatternPrime.regmap(0x300) ++
detectPatternRop.regmap(0x400) ++
......
......@@ -11,7 +11,7 @@ import freechips.rocketchip.util.{Pow2ClockDivider, ShiftRegInit}
// Fix: param (x) to log2(x)
// Fix: Reset is async for the slow domain
class MatanaClockDivider(log2Div: Int)(implicit p: Parameters) extends LazyModule {
require(log2Div > 0)
require(log2Div >= 0)
val node = ClockAdapterNode(
sourceFn = { case src => src.copy(give = src.give.map(x => x.copy(freqMHz = x.freqMHz / 2))) },
......
......@@ -26,10 +26,9 @@ class MatanaTopModule(params: MatanaParams, beatBytes: Int)(implicit p: Paramete
val matana_slow_domain = LazyModule(new ClockSinkDomain(take = None))
matana_slow_domain.clockNode := clockdiv.node
// TileLink and Interrupt crossing to slow clock domain
// Was RationalCrossing(SlowToFast), dont know if it is this element that cause Linux Kernel Freezing
val node = TLInwardCrossingHelper("matanaXbus", matana_slow_domain, matana_slow_detection.node)(AsynchronousCrossing())
val intnode = IntOutwardCrossingHelper("matanaXint", matana_slow_domain, matana_slow_detection.intnode)(AsynchronousCrossing())
// TileLink and Interrupt nodes, (optional) crossing to slow clock domain
val node = if (params.log2ClockDiv == 0) matana_slow_detection.node else TLInwardCrossingHelper("matanaXbus", matana_slow_domain, matana_slow_detection.node)(AsynchronousCrossing())
val intnode = if (params.log2ClockDiv == 0) matana_slow_detection.intnode else IntOutwardCrossingHelper("matanaXint", matana_slow_domain, matana_slow_detection.intnode)(AsynchronousCrossing())
}
@chiselName
......@@ -40,31 +39,53 @@ class MatanaTopModuleImp(outer: MatanaTopModule, params: MatanaParams)
val tiles = Vec(params.nHarts, Flipped(new MatanaCoreIO))
})
val slow = outer.matana_slow_domain.module
val detection = outer.matana_slow_detection.module
// Detection module run only in slow clock domain
detection.clock := slow.<