Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pointer masking): support Ssnpm & Smnpm & Smmpm #3921

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/main/scala/xiangshan/Bundle.scala
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,13 @@ class TlbCsrBundle(implicit p: Parameters) extends XSBundle {
}
val mPBMTE = Bool()
val hPBMTE = Bool()
val pmm = new Bundle {
val mseccfg = UInt(2.W)
val menvcfg = UInt(2.W)
val henvcfg = UInt(2.W)
val hstatus = UInt(2.W)
val senvcfg = UInt(2.W)
}

override def toPrintable: Printable = {
p"Satp mode:0x${Hexadecimal(satp.mode)} asid:0x${Hexadecimal(satp.asid)} ppn:0x${Hexadecimal(satp.ppn)} " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ object CSRBundles {
val PBMTE = RO( 62) .withReset(0.U) // Svpbmt Enable
val ADUE = RO( 61) .withReset(0.U) // Svadu extension Enable
val DTE = RO( 59) .withReset(0.U) // Ssdbltrp extension Enable
val PMM = RO(33, 32) .withReset(0.U) // Smnpm extension
val PMM = EnvPMM(33, 32, wNoEffect).withReset(EnvPMM.Disable) // Smnpm extension
val CBZE = RW( 7) .withReset(1.U) // Zicboz extension
val CBCFE = RW( 6) .withReset(1.U) // Zicbom extension
val CBIE = EnvCBIE( 5, 4, wNoEffect).withReset(EnvCBIE.Inval) // Zicbom extension
Expand Down
8 changes: 8 additions & 0 deletions src/main/scala/xiangshan/backend/fu/NewCSR/CSRDefines.scala
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,14 @@ object CSRDefines {
override def isLegal(enumeration: CSREnumType): Bool = enumeration.isOneOf(Off, Flush, Inval)
}

object EnvPMM extends CSREnum with WARLApply {
val Disable = Value("b00".U)
val PMLEN7 = Value("b10".U)
val PMLEN16 = Value("b11".U)

override def isLegal(enumeration: CSREnumType): Bool = enumeration.isOneOf(Disable, PMLEN7, PMLEN16)
}

object ReflectHelper {
val mirror: ru.Mirror = ru.runtimeMirror(getClass.getClassLoader)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ class HstatusBundle extends CSRBundle {
val VTW = RW(21).withReset(0.U)
val VTSR = RW(22).withReset(0.U)
val VSXL = XLENField(33, 32).withReset(XLENField.XLEN64)
val HUPMM = EnvPMM(49, 48, wNoEffect).withReset(EnvPMM.Disable) // Ssnpm extension

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ trait MachineLevel { self: NewCSR =>
.setAddr(CSRs.mtval2)

val mseccfg = Module(new CSRModule("Mseccfg", new CSRBundle {
val PMM = EnvPMM(33, 32, wNoEffect).withReset(EnvPMM.Disable) // Smmpm extension
val MLPE = RO(10) // Landing pand, Zicfilp extension
val SSEED = RO( 9) // Zkr extension
val USEED = RO( 8) // Zkr extension
Expand Down
12 changes: 12 additions & 0 deletions src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,13 @@ class NewCSR(implicit val p: Parameters) extends Module
val dvirt = Bool()
val mPBMTE = Bool()
val hPBMTE = Bool()
val pmm = new Bundle {
val mseccfg = UInt(2.W)
val menvcfg = UInt(2.W)
val henvcfg = UInt(2.W)
val hstatus = UInt(2.W)
val senvcfg = UInt(2.W)
}
})

val toDecode = new CSRToDecode
Expand Down Expand Up @@ -1281,6 +1288,11 @@ class NewCSR(implicit val p: Parameters) extends Module
)
io.tlb.mPBMTE := RegNext(menvcfg.regOut.PBMTE.asBool)
io.tlb.hPBMTE := RegNext(henvcfg.regOut.PBMTE.asBool)
io.tlb.pmm.mseccfg := RegNext(mseccfg.regOut.PMM.asUInt)
io.tlb.pmm.menvcfg := RegNext(menvcfg.regOut.PMM.asUInt)
io.tlb.pmm.henvcfg := RegNext(henvcfg.regOut.PMM.asUInt)
io.tlb.pmm.hstatus := RegNext(hstatus.regOut.HUPMM.asUInt)
io.tlb.pmm.senvcfg := RegNext(senvcfg.regOut.PMM.asUInt)

io.toDecode.illegalInst.sfenceVMA := isModeHS && mstatus.regOut.TVM || isModeHU
io.toDecode.virtualInst.sfenceVMA := isModeVS && hstatus.regOut.VTVM || isModeVU
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@ class CSR(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg)
tlb.mPBMTE := csrMod.io.tlb.mPBMTE
tlb.hPBMTE := csrMod.io.tlb.hPBMTE

// pointer masking extension
tlb.pmm := csrMod.io.tlb.pmm

/** Since some CSR read instructions are allowed to be pipelined, ready/valid signals should be modified */
io.in.ready := csrMod.io.in.ready // Todo: Async read imsic may block CSR
io.out.valid := csrModOutValid
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/xiangshan/cache/mmu/MMUBundle.scala
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ class TlbExceptionBundle(implicit p: Parameters) extends TlbBundle {
class TlbResp(nDups: Int = 1)(implicit p: Parameters) extends TlbBundle {
val paddr = Vec(nDups, Output(UInt(PAddrBits.W)))
val gpaddr = Vec(nDups, Output(UInt(XLEN.W)))
val fullva = Output(UInt(XLEN.W)) // For pointer masking
val pbmt = Vec(nDups, Output(UInt(ptePbmtLen.W)))
val miss = Output(Bool())
val fastMiss = Output(Bool())
Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/xiangshan/cache/mmu/MMUConst.scala
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ trait HasTlbConst extends HasXSParameter {
def Sv39x4 = "h8".U
def Sv48x4 = "h9".U

def PMLEN7 = "b10".U
def PMLEN16 = "b11".U
def MaxMaskedWidth = 16

def get_pn(addr: UInt) = {
require(addr.getWidth > offLen)
addr(addr.getWidth-1, offLen)
Expand Down
79 changes: 68 additions & 11 deletions src/main/scala/xiangshan/cache/mmu/TLB.scala
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,22 @@ class TLB(Width: Int, nRespDups: Int = 1, Block: Seq[Boolean], q: TLBParameters)
val mmu_flush_pipe = DelayN(sfence.valid && sfence.bits.flushPipe, q.fenceDelay) // for svinval, won't flush pipe
val flush_pipe = io.flushPipe
val redirect = io.redirect
val EffectiveVa = Wire(Vec(Width, UInt(XLEN.W)))
val req_in = req
val req_out = req.map(a => RegEnable(a.bits, a.fire))
val req_out = Reg(Vec(Width, new TlbReq))
for (i <- 0 until Width) {
when (req(i).fire) {
req_out(i) := req(i).bits
req_out(i).fullva := EffectiveVa(i)
}
}
val req_out_v = (0 until Width).map(i => ValidHold(req_in(i).fire && !req_in(i).bits.kill, resp(i).fire, flush_pipe(i)))

val isHyperInst = (0 until Width).map(i => req_out_v(i) && req_out(i).hyperinst)

// ATTENTION: csr and flush from backend are delayed. csr should not be later than flush.
// because, csr will influence tlb behavior.
val ifecth = if (q.fetchi) true.B else false.B
val ifetch = if (q.fetchi) true.B else false.B
val mode_tmp = if (q.useDmode) csr.priv.dmode else csr.priv.imode
val mode = (0 until Width).map(i => Mux(isHyperInst(i), csr.priv.spvp, mode_tmp))
val virt_in = csr.priv.virt
Expand Down Expand Up @@ -128,17 +135,67 @@ class TLB(Width: Int, nRespDups: Int = 1, Block: Seq[Boolean], q: TLBParameters)
val prepf = WireInit(VecInit(Seq.fill(Width)(false.B)))
val pregpf = WireInit(VecInit(Seq.fill(Width)(false.B)))
val preaf = WireInit(VecInit(Seq.fill(Width)(false.B)))
val premode = (0 until Width).map(i => Mux(req_in(i).bits.hyperinst, csr.priv.spvp, mode_tmp))
for (i <- 0 until Width) {
resp(i).bits.fullva := RegEnable(EffectiveVa(i), req(i).valid)
}
val prevmEnable = (0 until Width).map(i => !(virt_in || req_in(i).bits.hyperinst) && (
if (EnbaleTlbDebug) (Sv39Enable || Sv48Enable)
else (Sv39Enable || Sv48Enable) && (mode(i) < ModeM))
else (Sv39Enable || Sv48Enable) && (premode(i) < ModeM))
)
val pres2xlateEnable = (0 until Width).map(i => (virt_in || req_in(i).bits.hyperinst) && (Sv39x4Enable || Sv48x4Enable) && (mode(i) < ModeM))
val pres2xlateEnable = (0 until Width).map(i => (virt_in || req_in(i).bits.hyperinst) && (Sv39x4Enable || Sv48x4Enable) && (premode(i) < ModeM))

(0 until Width).foreach { i =>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debug info will be removed soon

dontTouch(prepf(i))
dontTouch(pregpf(i))
dontTouch(preaf(i))
dontTouch(premode(i))
dontTouch(EffectiveVa(i))
dontTouch(prevmEnable(i))
dontTouch(pres2xlateEnable(i))
}

(0 until Width).foreach{i =>
val pf48 = SignExt(req(i).bits.fullva(47, 0), XLEN) =/= req(i).bits.fullva
val pf39 = SignExt(req(i).bits.fullva(38, 0), XLEN) =/= req(i).bits.fullva
val gpf48 = req(i).bits.fullva(XLEN - 1, 48 + 2) =/= 0.U
val gpf39 = req(i).bits.fullva(XLEN - 1, 39 + 2) =/= 0.U
val af = req(i).bits.fullva(XLEN - 1, PAddrBits) =/= 0.U

val pmm = WireInit(0.U(2.W))

when (ifetch || req(i).bits.hlvx) {
pmm := 0.U
} .elsewhen (premode(i) === ModeM) {
pmm := csr.pmm.mseccfg
} .elsewhen (!(virt_in || req_in(i).bits.hyperinst) && premode(i) === ModeS) {
pmm := csr.pmm.menvcfg
} .elsewhen ((virt_in || req_in(i).bits.hyperinst) && premode(i) === ModeS) {
pmm := csr.pmm.henvcfg
} .elsewhen (req_in(i).bits.hyperinst && csr.priv.imode === ModeU) {
pmm := csr.pmm.hstatus
} .elsewhen (premode(i) === ModeU) {
pmm := csr.pmm.senvcfg
}

when (prevmEnable(i) || (pres2xlateEnable(i) && vsatp.mode =/= 0.U)) {
when (pmm === PMLEN7) {
EffectiveVa(i) := SignExt(req_in(i).bits.fullva(56, 0), XLEN)
} .elsewhen (pmm === PMLEN16) {
EffectiveVa(i) := SignExt(req_in(i).bits.fullva(47, 0), XLEN)
} .otherwise {
EffectiveVa(i) := req_in(i).bits.fullva
}
} .otherwise {
when (pmm === PMLEN7) {
EffectiveVa(i) := ZeroExt(req_in(i).bits.fullva(56, 0), XLEN)
} .elsewhen (pmm === PMLEN16) {
EffectiveVa(i) := ZeroExt(req_in(i).bits.fullva(47, 0), XLEN)
} .otherwise {
EffectiveVa(i) := req_in(i).bits.fullva
}
}

val pf48 = SignExt(EffectiveVa(i)(47, 0), XLEN) =/= EffectiveVa(i)
val pf39 = SignExt(EffectiveVa(i)(38, 0), XLEN) =/= EffectiveVa(i)
val gpf48 = EffectiveVa(i)(XLEN - 1, 48 + 2) =/= 0.U
val gpf39 = EffectiveVa(i)(XLEN - 1, 39 + 2) =/= 0.U
val af = EffectiveVa(i)(XLEN - 1, PAddrBits) =/= 0.U
when (req(i).valid && req(i).bits.checkfullva) {
when (prevmEnable(i) || pres2xlateEnable(i)) {
when (req_in_s2xlate(i) === onlyStage2) {
Expand Down Expand Up @@ -345,7 +402,7 @@ class TLB(Width: Int, nRespDups: Int = 1, Block: Seq[Boolean], q: TLBParameters)
val ldUpdate = !perm.a && isLd // update A/D through exception
val stUpdate = (!perm.a || !perm.d) && isSt // update A/D through exception
val instrUpdate = !perm.a && isInst // update A/D through exception
val modeCheck = !(mode(idx) === ModeU && !perm.u || mode(idx) === ModeS && perm.u && (!sum(idx) || ifecth))
val modeCheck = !(mode(idx) === ModeU && !perm.u || mode(idx) === ModeS && perm.u && (!sum(idx) || ifetch))
val ldPermFail = !(modeCheck && Mux(hlvx, perm.x, perm.r || mxr(idx) && perm.x))
val stPermFail = !(modeCheck && perm.w)
val instrPermFail = !(modeCheck && perm.x)
Expand Down Expand Up @@ -391,7 +448,7 @@ class TLB(Width: Int, nRespDups: Int = 1, Block: Seq[Boolean], q: TLBParameters)
resp(idx).bits.excp(nDups).vaNeedExt := false.B
// overwrite miss & gpaddr when exception related to high address truncation happens
resp(idx).bits.miss := false.B
resp(idx).bits.gpaddr(nDups) := RegNext(req(idx).bits.fullva)
resp(idx).bits.gpaddr(nDups) := req_out(idx).fullva
} .otherwise {
// isForVSnonLeafPTE is used only when gpf happens and it caused by a G-stage translation which supports VS-stage translation
// it will be sent to CSR in order to modify the m/htinst.
Expand Down
7 changes: 4 additions & 3 deletions src/main/scala/xiangshan/mem/pipeline/AtomicsUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class AtomicsUnit(implicit p: Parameters) extends XSModule
// paddr after translation
val paddr = Reg(UInt())
val gpaddr = Reg(UInt())
val vaddr = in.src(0)
val vaddr = Reg(UInt())
val is_mmio = Reg(Bool())
val isForVSnonLeafPTE = Reg(Bool())

Expand All @@ -89,7 +89,7 @@ class AtomicsUnit(implicit p: Parameters) extends XSModule
val fuop_reg = Reg(UInt(8.W))

io.exceptionInfo.valid := atom_override_xtval
io.exceptionInfo.bits.vaddr := in.src(0)
io.exceptionInfo.bits.vaddr := vaddr
io.exceptionInfo.bits.gpaddr := gpaddr
io.exceptionInfo.bits.isForVSnonLeafPTE := isForVSnonLeafPTE

Expand Down Expand Up @@ -217,6 +217,7 @@ class AtomicsUnit(implicit p: Parameters) extends XSModule
when (io.dtlb.resp.fire && have_sent_first_tlb_req){
paddr := io.dtlb.resp.bits.paddr(0)
gpaddr := io.dtlb.resp.bits.gpaddr(0)
vaddr := io.dtlb.resp.bits.fullva
isForVSnonLeafPTE := io.dtlb.resp.bits.isForVSnonLeafPTE
// exception handling
val addrAligned = LookupTree(in.uop.fuOpType(1,0), List(
Expand Down Expand Up @@ -313,7 +314,7 @@ class AtomicsUnit(implicit p: Parameters) extends XSModule
pipe_req.probe_need_data := false.B
pipe_req.source := AMO_SOURCE.U
pipe_req.addr := get_block_addr(paddr)
pipe_req.vaddr := get_block_addr(in.src(0)) // vaddr
pipe_req.vaddr := get_block_addr(vaddr) // vaddr
pipe_req.word_idx := get_word(paddr)
pipe_req.amo_data := genWdata(in.src(1), in.uop.fuOpType(1,0))
pipe_req.amo_mask := genWmask(paddr, in.uop.fuOpType(1,0))
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/xiangshan/mem/pipeline/LoadUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,7 @@ class LoadUnit(implicit p: Parameters) extends XSModule

s1_out := s1_in
s1_out.vaddr := s1_vaddr
s1_out.fullva := io.tlb.resp.bits.fullva
s1_out.vaNeedExt := io.tlb.resp.bits.excp(0).vaNeedExt
s1_out.isHyper := io.tlb.resp.bits.excp(0).isHyper
s1_out.paddr := s1_paddr_dup_lsu
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/xiangshan/mem/pipeline/StoreUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ class StoreUnit(implicit p: Parameters) extends XSModule
val s1_isHyper = io.tlb.resp.bits.excp(0).isHyper
val s1_paddr = io.tlb.resp.bits.paddr(0)
val s1_gpaddr = io.tlb.resp.bits.gpaddr(0)
val s1_fullva = io.tlb.resp.bits.fullva
val s1_isForVSnonLeafPTE = io.tlb.resp.bits.isForVSnonLeafPTE
val s1_tlb_miss = io.tlb.resp.bits.miss
val s1_mmio = s1_mmio_cbo
Expand Down Expand Up @@ -316,6 +317,7 @@ class StoreUnit(implicit p: Parameters) extends XSModule
s1_out := s1_in
s1_out.paddr := s1_paddr
s1_out.gpaddr := s1_gpaddr
s1_out.fullva := s1_fullva
s1_out.vaNeedExt := s1_vaNeedExt
s1_out.isHyper := s1_isHyper
s1_out.miss := false.B
Expand Down
Loading