Skip to content

Commit b159d6e

Browse files
lewislzhAnzooooo
authored andcommitted
feat(Ss/Smdbltrp) : Support RISC-V Ss/Smdbltrp Extension (#3789)
* NEMU commit: 066cb1f1c61feb21153399c26ca393dfb3a560d7 * NEMU configs: * riscv64-xs-ref_defconfig * riscv64-dual-xs-ref_defconfig Including: * fix(format): adjust code format and add one config (OpenXiangShan/NEMU#603) * fix(vfredusum): set xstatus.fs and xstatus.vs dirty (OpenXiangShan/NEMU#605) * fix(vf): do not set dirtyFs for some instructions (OpenXiangShan/NEMU#606) * feat(trigger): add trigger support for rva. * configs(xs): open Sm/sdbltrp extension and add MDT_INIT config (OpenXiangShan/NEMU#604) --- * spike commit: c0b18d3913d8ceac83743a053a7dbd2fb8716c83 * spike config: CPU=XIANGSHAN Including: * fix(rva, trigger): For rva instr, raise BP from trigger prior to misaligned. * fix(Makefile): Increase maxdepth for finding .h files. * fix(tdata1): CPU_XIANGSHAN do not implement hit bit in tdata1. * fix(icount): place the read before the return of the detect_icount_match.
1 parent bb66b2a commit b159d6e

16 files changed

+197
-45
lines changed

src/main/scala/xiangshan/backend/fu/NewCSR/CSRBundles.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ object CSRBundles {
4747
val STCE = RO( 63) .withReset(0.U) // Sstc Enable
4848
val PBMTE = RO( 62) .withReset(0.U) // Svpbmt Enable
4949
val ADUE = RO( 61) .withReset(0.U) // Svadu extension Enable
50+
val DTE = RO( 59) .withReset(0.U) // Ssdbltrp extension Enable
5051
val PMM = RO(33, 32) .withReset(0.U) // Smnpm extension
5152
val CBZE = RW( 7) .withReset(1.U) // Zicboz extension
5253
val CBCFE = RW( 6) .withReset(1.U) // Zicbom extension

src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/CSREvent.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class TrapEntryEventInput(implicit val p: Parameters) extends Bundle with HasXSP
125125
val isFetchMalAddr = Input(Bool())
126126
val isFetchBkpt = Input(Bool())
127127
val trapIsForVSnonLeafPTE = Input(Bool())
128+
val hasDTExcp = Input(Bool())
128129

129130
// always current privilege
130131
val iMode = Input(new PrivState())
@@ -136,6 +137,9 @@ class TrapEntryEventInput(implicit val p: Parameters) extends Bundle with HasXSP
136137
val hstatus = Input(new HstatusBundle)
137138
val sstatus = Input(new SstatusBundle)
138139
val vsstatus = Input(new SstatusBundle)
140+
// envcfg
141+
val menvcfg = Input(new MEnvCfg)
142+
val henvcfg = Input(new HEnvCfg)
139143

140144
val pcFromXtvec = Input(UInt(XLEN.W))
141145

src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/MNretEvent.scala

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import xiangshan.AddrTransType
1515

1616
class MNretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
1717
val mnstatus = ValidIO((new MnstatusBundle).addInEvent(_.MNPP, _.MNPV, _.NMIE))
18-
val mstatus = ValidIO((new MstatusBundle).addInEvent(_.MPRV))
18+
val mstatus = ValidIO((new MstatusBundle).addInEvent(_.MPRV, _.MDT, _.SDT))
19+
val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SDT))
1920
val targetPc = ValidIO(new TargetPCBundle)
2021
}
2122

@@ -26,6 +27,7 @@ class MNretEventInput extends Bundle {
2627
val satp = Input(new SatpBundle)
2728
val vsatp = Input(new SatpBundle)
2829
val hgatp = Input(new HgatpBundle)
30+
val vsstatus = Input(new SstatusBundle)
2931
}
3032

3133
class MNretEventModule(implicit p: Parameters) extends Module with CSREventBase {
@@ -49,18 +51,29 @@ class MNretEventModule(implicit p: Parameters) extends Module with CSREventBase
4951
sv48x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4
5052
)
5153

54+
val outPrivState = Wire(new PrivState)
55+
outPrivState.PRVM := in.mnstatus.MNPP
56+
outPrivState.V := Mux(in.mnstatus.MNPP === PrivMode.M, VirtMode.Off.asUInt, in.mnstatus.MNPV.asUInt)
57+
58+
val mnretToM = outPrivState.isModeM
59+
val mnretToS = outPrivState.isModeHS
60+
val mnretToVU = outPrivState.isModeVU
61+
5262
out := DontCare
5363

5464
out.privState.valid := valid
5565
out.mnstatus .valid := valid
5666
out.targetPc .valid := valid
5767

58-
out.privState.bits.PRVM := in.mnstatus.MNPP
59-
out.privState.bits.V := Mux(in.mnstatus.MNPP === PrivMode.M, VirtMode.Off.asUInt, in.mnstatus.MNPV.asUInt)
68+
out.privState.bits := outPrivState
6069
out.mnstatus.bits.MNPP := PrivMode.U
6170
out.mnstatus.bits.MNPV := VirtMode.Off.asUInt
6271
out.mnstatus.bits.NMIE := 1.U
6372
out.mstatus.bits.MPRV := Mux(in.mnstatus.MNPP =/= PrivMode.M, 0.U, in.mstatus.MPRV.asUInt)
73+
// clear MDT when mnret to below M
74+
out.mstatus.bits.MDT := Mux(mnretToM, in.mstatus.MDT.asBool, 0.U)
75+
out.mstatus.bits.SDT := Mux(mnretToM || mnretToS, in.mstatus.SDT.asBool, 0.U)
76+
out.vsstatus.bits.SDT := Mux(mnretToVU, 0.U, in.vsstatus.SDT.asBool)
6477
out.targetPc.bits.pc := in.mnepc.asUInt
6578
out.targetPc.bits.raiseIPF := instrAddrTransType.checkPageFault(in.mnepc.asUInt)
6679
out.targetPc.bits.raiseIAF := instrAddrTransType.checkAccessFault(in.mnepc.asUInt)

src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/MretEvent.scala

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ import xiangshan.AddrTransType
1414

1515

1616
class MretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
17-
val mstatus = ValidIO((new MstatusBundle).addInEvent(_.MPP, _.MPV, _.MIE, _.MPIE, _.MPRV))
17+
val mstatus = ValidIO((new MstatusBundle).addInEvent(_.MPP, _.MPV, _.MIE, _.MPIE, _.MPRV, _.MDT, _.SDT))
18+
val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SDT))
1819
val targetPc = ValidIO(new TargetPCBundle)
1920
}
2021

2122
class MretEventInput extends Bundle {
2223
val mstatus = Input(new MstatusBundle)
24+
val vsstatus = Input(new SstatusBundle)
2325
val mepc = Input(new Epc())
2426
val satp = Input(new SatpBundle)
2527
val vsatp = Input(new SatpBundle)
@@ -46,20 +48,33 @@ class MretEventModule(implicit p: Parameters) extends Module with CSREventBase {
4648
sv39x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv39x4,
4749
sv48x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4
4850
)
51+
val outPrivState = Wire(new PrivState)
52+
outPrivState.PRVM := in.mstatus.MPP
53+
outPrivState.V := Mux(in.mstatus.MPP === PrivMode.M, VirtMode.Off.asUInt, in.mstatus.MPV.asUInt)
54+
55+
val mretToM = outPrivState.isModeM
56+
val mretToS = outPrivState.isModeHS
57+
val mretToVu = outPrivState.isModeVU
4958

5059
out := DontCare
5160

5261
out.privState.valid := valid
5362
out.mstatus .valid := valid
5463
out.targetPc .valid := valid
5564

56-
out.privState.bits.PRVM := in.mstatus.MPP
57-
out.privState.bits.V := Mux(in.mstatus.MPP === PrivMode.M, VirtMode.Off.asUInt, in.mstatus.MPV.asUInt)
65+
out.privState.bits := outPrivState
5866
out.mstatus.bits.MPP := PrivMode.U
5967
out.mstatus.bits.MPV := VirtMode.Off.asUInt
6068
out.mstatus.bits.MIE := in.mstatus.MPIE
6169
out.mstatus.bits.MPIE := 1.U
6270
out.mstatus.bits.MPRV := Mux(in.mstatus.MPP =/= PrivMode.M, 0.U, in.mstatus.MPRV.asUInt)
71+
// clear MDT when return mret always execute in M mode
72+
out.mstatus.bits.MDT := 0.U
73+
// clear sstatus.SDT when return mode below M and HS
74+
out.mstatus.bits.SDT := Mux(mretToM || mretToS, in.mstatus.SDT.asBool, 0.U)
75+
// clear vsstatus.SDT when return to VU
76+
out.vsstatus.bits.SDT := Mux(mretToVu, 0.U, in.vsstatus.SDT.asBool)
77+
6378
out.targetPc.bits.pc := in.mepc.asUInt
6479
out.targetPc.bits.raiseIPF := instrAddrTransType.checkPageFault(in.mepc.asUInt)
6580
out.targetPc.bits.raiseIAF := instrAddrTransType.checkAccessFault(in.mepc.asUInt)

src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/SretEvent.scala

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ import xiangshan.AddrTransType
1515

1616
class SretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
1717
// Todo: write sstatus instead of mstatus
18-
val mstatus = ValidIO((new MstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP, _.MPRV))
18+
val mstatus = ValidIO((new MstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP, _.MPRV, _.MDT, _.SDT))
1919
val hstatus = ValidIO((new HstatusBundle).addInEvent(_.SPV))
20-
val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP))
20+
val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP, _.SDT))
2121
val targetPc = ValidIO(new TargetPCBundle)
2222
}
2323

2424
class SretEventInput extends Bundle {
2525
val privState = Input(new PrivState)
26-
val sstatus = Input(new SstatusBundle)
26+
val mstatus = Input(new MstatusBundle)
2727
val hstatus = Input(new HstatusBundle)
2828
val vsstatus = Input(new SstatusBundle)
2929
val sepc = Input(new Epc())
@@ -53,45 +53,62 @@ class SretEventModule(implicit p: Parameters) extends Module with CSREventBase {
5353
sv48x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4
5454
)
5555

56-
private val sretInHSorM = in.privState.isModeM || in.privState.isModeHS
56+
private val sretInM = in.privState.isModeM
57+
private val sretInHS = in.privState.isModeHS
58+
private val sretInHSorM = sretInM || sretInHS
5759
private val sretInVS = in.privState.isModeVS
5860

5961
private val xepc = Mux1H(Seq(
6062
sretInHSorM -> in.sepc,
6163
sretInVS -> in.vsepc,
6264
)).asUInt
6365

64-
out := DontCare
65-
66-
out.privState.valid := valid
67-
out.targetPc .valid := valid
6866

69-
out.privState.bits.PRVM := Mux1H(Seq(
67+
private val outPrivState = Wire(new PrivState)
68+
outPrivState.PRVM := Mux1H(Seq(
7069
// SPP is not PrivMode enum type, so asUInt
71-
sretInHSorM -> in.sstatus.SPP.asUInt,
70+
sretInHSorM -> in.mstatus.SPP.asUInt,
7271
sretInVS -> in.vsstatus.SPP.asUInt,
7372
))
74-
out.privState.bits.V := Mux1H(Seq(
73+
outPrivState.V := Mux1H(Seq(
7574
sretInHSorM -> in.hstatus.SPV,
7675
sretInVS -> in.privState.V, // keep
7776
))
7877

78+
private val sretToVU = outPrivState.isModeVU
79+
private val sretToVS = outPrivState.isModeVS
80+
private val sretToU = outPrivState.isModeHU
81+
82+
out := DontCare
83+
84+
out.privState.valid := valid
85+
out.targetPc .valid := valid
86+
87+
out.privState.bits := outPrivState
88+
7989
// hstatus
8090
out.hstatus.valid := valid && sretInHSorM
8191
out.hstatus.bits.SPV := VirtMode.Off
8292

8393
// sstatus
8494
out.mstatus.valid := valid && sretInHSorM
8595
out.mstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width
86-
out.mstatus.bits.SIE := in.sstatus.SPIE
96+
out.mstatus.bits.SIE := in.mstatus.SPIE
8797
out.mstatus.bits.SPIE := 1.U
8898
out.mstatus.bits.MPRV := 0.U // sret will always leave M mode
99+
out.mstatus.bits.MDT := Mux(sretInM, 0.U, in.mstatus.MDT.asBool) // when execute return in M mode, set MDT 0
100+
out.mstatus.bits.SDT := MuxCase(in.mstatus.SDT.asBool, Seq(
101+
sretInHS -> 0.U, // sret will alway leave M mode
102+
(sretInM && (sretToU || sretToVS || sretToVU)) -> 0.U
103+
))
104+
89105

90106
// vsstatus
91107
out.vsstatus.valid := valid && sretInVS
92108
out.vsstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width
93109
out.vsstatus.bits.SIE := in.vsstatus.SPIE
94110
out.vsstatus.bits.SPIE := 1.U
111+
out.vsstatus.bits.SDT := Mux(sretToVU || sretInVS, 0.U, in.vsstatus.SDT.asBool) // clear SDT when return to VU or sret in vs
95112

96113
out.targetPc.bits.pc := xepc
97114
out.targetPc.bits.raiseIPF := instrAddrTransType.checkPageFault(xepc)

src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/TrapEntryHSEvent.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import xiangshan.AddrTransType
1515
class TrapEntryHSEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
1616

1717
// Todo: use sstatus instead of mstatus
18-
val mstatus = ValidIO((new MstatusBundle ).addInEvent(_.SPP, _.SPIE, _.SIE))
18+
val mstatus = ValidIO((new MstatusBundle ).addInEvent(_.SPP, _.SPIE, _.SIE, _.SDT))
1919
val hstatus = ValidIO((new HstatusBundle ).addInEvent(_.SPV, _.SPVP, _.GVA))
2020
val sepc = ValidIO((new Epc ).addInEvent(_.epc))
2121
val scause = ValidIO((new CauseBundle ).addInEvent(_.Interrupt, _.ExceptionCode))
@@ -124,6 +124,7 @@ class TrapEntryHSEventModule(implicit val p: Parameters) extends Module with CSR
124124
out.mstatus.bits.SPP := current.privState.PRVM.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width
125125
out.mstatus.bits.SPIE := current.sstatus.SIE
126126
out.mstatus.bits.SIE := 0.U
127+
out.mstatus.bits.SDT := in.menvcfg.DTE.asBool // when DTE open set SDT to 1, else SDT is readonly 0
127128
// hstatus
128129
out.hstatus.bits.SPV := current.privState.V
129130
// SPVP is not PrivMode enum type, so asUInt and shrink the width

src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/TrapEntryMEvent.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import xiangshan.AddrTransType
1313

1414
class TrapEntryMEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
1515

16-
val mstatus = ValidIO((new MstatusBundle ).addInEvent(_.MPV, _.MPP, _.GVA, _.MPIE, _.MIE))
16+
val mstatus = ValidIO((new MstatusBundle ).addInEvent(_.MPV, _.MPP, _.GVA, _.MPIE, _.MIE, _.MDT))
1717
val mepc = ValidIO((new Epc ).addInEvent(_.epc))
1818
val mcause = ValidIO((new CauseBundle ).addInEvent(_.Interrupt, _.ExceptionCode))
1919
val mtval = ValidIO((new OneFieldBundle).addInEvent(_.ALL))
@@ -32,6 +32,7 @@ class TrapEntryMEventModule(implicit val p: Parameters) extends Module with CSRE
3232
private val satp = current.satp
3333
private val vsatp = current.vsatp
3434
private val hgatp = current.hgatp
35+
private val isDTExcp = current.hasDTExcp
3536

3637
private val highPrioTrapNO = in.causeNO.ExceptionCode.asUInt
3738
private val isException = !in.causeNO.Interrupt.asBool
@@ -96,6 +97,8 @@ class TrapEntryMEventModule(implicit val p: Parameters) extends Module with CSRE
9697
(isLSGuestExcp ) -> trapMemGPA,
9798
))
9899

100+
private val precause = Cat(isInterrupt, highPrioTrapNO)
101+
99102
out := DontCare
100103

101104
out.privState.valid := valid
@@ -113,11 +116,12 @@ class TrapEntryMEventModule(implicit val p: Parameters) extends Module with CSRE
113116
out.mstatus.bits.GVA := tvalFillGVA
114117
out.mstatus.bits.MPIE := current.mstatus.MIE
115118
out.mstatus.bits.MIE := 0.U
119+
out.mstatus.bits.MDT := 1.U
116120
out.mepc.bits.epc := Mux(isFetchMalAddr, in.fetchMalTval(63, 1), trapPC(63, 1))
117121
out.mcause.bits.Interrupt := isInterrupt
118-
out.mcause.bits.ExceptionCode := highPrioTrapNO
122+
out.mcause.bits.ExceptionCode := Mux(isDTExcp, ExceptionNO.EX_DT.U, highPrioTrapNO)
119123
out.mtval.bits.ALL := Mux(isFetchMalAddr, in.fetchMalTval, tval)
120-
out.mtval2.bits.ALL := tval2 >> 2
124+
out.mtval2.bits.ALL := Mux(isDTExcp, precause, tval2 >> 2)
121125
out.mtinst.bits.ALL := Mux(isFetchGuestExcp && in.trapIsForVSnonLeafPTE || isLSGuestExcp && in.memExceptionIsForVSnonLeafPTE, 0x3000.U, 0.U)
122126
out.targetPc.bits.pc := in.pcFromXtvec
123127
out.targetPc.bits.raiseIPF := false.B

src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/TrapEntryVSEvent.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import xiangshan.AddrTransType
1414

1515
class TrapEntryVSEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
1616

17-
val vsstatus = ValidIO((new SstatusBundle ).addInEvent(_.SPP, _.SPIE, _.SIE))
17+
val vsstatus = ValidIO((new SstatusBundle ).addInEvent(_.SPP, _.SPIE, _.SIE, _.SDT))
1818
val vsepc = ValidIO((new Epc ).addInEvent(_.epc))
1919
val vscause = ValidIO((new CauseBundle ).addInEvent(_.Interrupt, _.ExceptionCode))
2020
val vstval = ValidIO((new OneFieldBundle).addInEvent(_.ALL))
@@ -122,6 +122,7 @@ class TrapEntryVSEventModule(implicit val p: Parameters) extends Module with CSR
122122
out.vsstatus.bits.SPP := current.privState.PRVM.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width
123123
out.vsstatus.bits.SPIE := current.vsstatus.SIE
124124
out.vsstatus.bits.SIE := 0.U
125+
out.vsstatus.bits.SDT := in.henvcfg.DTE.asBool // when DTE open set SDT to 1, else SDT is readonly 0
125126
// SPVP is not PrivMode enum type, so asUInt and shrink the width
126127
out.vsepc.bits.epc := Mux(isFetchMalAddr, in.fetchMalTval(63, 1), trapPC(63, 1))
127128
out.vscause.bits.Interrupt := isInterrupt

src/main/scala/xiangshan/backend/fu/NewCSR/HypervisorLevel.scala

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,16 @@ trait HypervisorLevel { self: NewCSR =>
6262
.setAddr(CSRs.hvictl)
6363

6464
val henvcfg = Module(new CSRModule("Henvcfg", new HEnvCfg) with HasHypervisorEnvBundle {
65-
when (!menvcfg.STCE.asBool) {
65+
when(!menvcfg.STCE) {
6666
regOut.STCE := 0.U
6767
}
68-
when (!menvcfg.PBMTE) {
68+
when(!menvcfg.PBMTE) {
6969
regOut.PBMTE := 0.U
7070
}
71-
})
72-
.setAddr(CSRs.henvcfg)
71+
when(!menvcfg.DTE) {
72+
regOut.DTE := 0.U
73+
}
74+
}).setAddr(CSRs.henvcfg)
7375

7476
val htval = Module(new CSRModule("Htval", new XtvalBundle) with TrapEntryHSEventSinkBundle)
7577
.setAddr(CSRs.htval)
@@ -340,6 +342,11 @@ class HEnvCfg extends EnvCfg {
340342
this.STCE.setRW().withReset(1.U)
341343
}
342344
this.PBMTE.setRW().withReset(0.U)
345+
if (CSRConfig.EXT_DBLTRP) {
346+
// software write envcfg to open ssdbltrp if need
347+
// set 0 to pass ci
348+
this.DTE.setRW().withReset(0.U)
349+
}
343350
}
344351

345352
trait HypervisorBundle { self: CSRModule[_] =>

0 commit comments

Comments
 (0)