1e5cc84f2SXuan Hupackage xiangshan.backend.fu.NewCSR 2e5cc84f2SXuan Hu 3e5cc84f2SXuan Huimport chisel3._ 4e5cc84f2SXuan Huimport chisel3.util._ 5e5cc84f2SXuan Huimport chisel3.util.experimental.decode.TruthTable 690cbdd93SsinceforYyimport freechips.rocketchip.rocket.CSRs 74d2be3d2SsinceforYyimport xiangshan.backend.fu.NewCSR.CSRBundles.{Counteren, PrivState} 84d2be3d2SsinceforYyimport xiangshan.backend.fu.NewCSR.CSRDefines._ 9*7768a97dSTang Haojinimport org.chipsalliance.cde.config.Parameters 10*7768a97dSTang Haojinimport system.HasSoCParameter 11e5cc84f2SXuan Hu 12*7768a97dSTang Haojinclass CSRPermitModule(implicit p: Parameters) extends Module { 13e5cc84f2SXuan Hu val io = IO(new CSRPermitIO) 14e5cc84f2SXuan Hu 1537748a0bSNewPaulWalker val xRetPermitMod = Module(new XRetPermitModule) 1637748a0bSNewPaulWalker val mLevelPermitMod = Module(new MLevelPermitModule) 1737748a0bSNewPaulWalker val sLevelPermitMod = Module(new SLevelPermitModule) 1837748a0bSNewPaulWalker val privilegePermitMod = Module(new PrivilegePermitModule) 1937748a0bSNewPaulWalker val virtualLevelPermitMod = Module(new VirtualLevelPermitModule) 2037748a0bSNewPaulWalker val indirectCSRPermitMod = Module(new IndirectCSRPermitModule) 2137748a0bSNewPaulWalker 2237748a0bSNewPaulWalker xRetPermitMod.io.in.privState := io.in.privState 2337748a0bSNewPaulWalker xRetPermitMod.io.in.debugMode := io.in.debugMode 2437748a0bSNewPaulWalker xRetPermitMod.io.in.xRet := io.in.xRet 2537748a0bSNewPaulWalker xRetPermitMod.io.in.status := io.in.status 2637748a0bSNewPaulWalker 2737748a0bSNewPaulWalker mLevelPermitMod.io.in.csrAccess := io.in.csrAccess 2837748a0bSNewPaulWalker mLevelPermitMod.io.in.privState := io.in.privState 2937748a0bSNewPaulWalker mLevelPermitMod.io.in.status := io.in.status 3037748a0bSNewPaulWalker mLevelPermitMod.io.in.xcounteren := io.in.xcounteren 3137748a0bSNewPaulWalker mLevelPermitMod.io.in.xenvcfg := io.in.xenvcfg 3237748a0bSNewPaulWalker mLevelPermitMod.io.in.xstateen := io.in.xstateen 3337748a0bSNewPaulWalker mLevelPermitMod.io.in.aia := io.in.aia 3437748a0bSNewPaulWalker 3537748a0bSNewPaulWalker sLevelPermitMod.io.in.csrAccess := io.in.csrAccess 3637748a0bSNewPaulWalker sLevelPermitMod.io.in.privState := io.in.privState 3737748a0bSNewPaulWalker sLevelPermitMod.io.in.xcounteren := io.in.xcounteren 3837748a0bSNewPaulWalker sLevelPermitMod.io.in.xstateen := io.in.xstateen 3937748a0bSNewPaulWalker 4037748a0bSNewPaulWalker privilegePermitMod.io.in.csrAccess := io.in.csrAccess 4137748a0bSNewPaulWalker privilegePermitMod.io.in.privState := io.in.privState 4237748a0bSNewPaulWalker privilegePermitMod.io.in.debugMode := io.in.debugMode 4337748a0bSNewPaulWalker 4437748a0bSNewPaulWalker virtualLevelPermitMod.io.in.csrAccess := io.in.csrAccess 4537748a0bSNewPaulWalker virtualLevelPermitMod.io.in.privState := io.in.privState 4637748a0bSNewPaulWalker virtualLevelPermitMod.io.in.status := io.in.status 4737748a0bSNewPaulWalker virtualLevelPermitMod.io.in.xcounteren := io.in.xcounteren 4837748a0bSNewPaulWalker virtualLevelPermitMod.io.in.xenvcfg := io.in.xenvcfg 4937748a0bSNewPaulWalker virtualLevelPermitMod.io.in.xstateen := io.in.xstateen 5037748a0bSNewPaulWalker virtualLevelPermitMod.io.in.aia := io.in.aia 5137748a0bSNewPaulWalker 5237748a0bSNewPaulWalker indirectCSRPermitMod.io.in.csrAccess := io.in.csrAccess 5337748a0bSNewPaulWalker indirectCSRPermitMod.io.in.privState := io.in.privState 5437748a0bSNewPaulWalker indirectCSRPermitMod.io.in.aia := io.in.aia 5537748a0bSNewPaulWalker 5637748a0bSNewPaulWalker private val (ren, wen) = ( 5752abe1cbSXuan Hu io.in.csrAccess.ren, 5852abe1cbSXuan Hu io.in.csrAccess.wen, 59e5cc84f2SXuan Hu ) 60e5cc84f2SXuan Hu 61f1b77b5eSXuan Hu private val csrAccess = WireInit(ren || wen) 6252abe1cbSXuan Hu 6337748a0bSNewPaulWalker val mPermit_EX_II = mLevelPermitMod.io.out.mLevelPermit_EX_II 6437748a0bSNewPaulWalker 6537748a0bSNewPaulWalker val sPermit_EX_II = sLevelPermitMod.io.out.sLevelPermit_EX_II 6637748a0bSNewPaulWalker 6737748a0bSNewPaulWalker val pPermit_EX_II = privilegePermitMod.io.out.privilege_EX_II 6837748a0bSNewPaulWalker val pPermit_EX_VI = privilegePermitMod.io.out.privilege_EX_VI 6937748a0bSNewPaulWalker 70e733b25bSlinzhida val vPermit_EX_II = virtualLevelPermitMod.io.out.virtualLevelPermit_EX_II 7137748a0bSNewPaulWalker val vPermit_EX_VI = virtualLevelPermitMod.io.out.virtualLevelPermit_EX_VI 7237748a0bSNewPaulWalker 7337748a0bSNewPaulWalker val indirectPermit_EX_II = indirectCSRPermitMod.io.out.indirectCSR_EX_II 7437748a0bSNewPaulWalker val indirectPermit_EX_VI = indirectCSRPermitMod.io.out.indirectCSR_EX_VI 7537748a0bSNewPaulWalker 76e733b25bSlinzhida val directPermit_illegal = mPermit_EX_II || sPermit_EX_II || pPermit_EX_II || pPermit_EX_VI || vPermit_EX_II || vPermit_EX_VI 7737748a0bSNewPaulWalker 7837748a0bSNewPaulWalker val csrAccess_EX_II = csrAccess && ( 79e733b25bSlinzhida (mPermit_EX_II || sPermit_EX_II || pPermit_EX_II || vPermit_EX_II) || 8037748a0bSNewPaulWalker (!directPermit_illegal && indirectPermit_EX_II) 8137748a0bSNewPaulWalker ) 8237748a0bSNewPaulWalker val csrAccess_EX_VI = csrAccess && ( 8337748a0bSNewPaulWalker (pPermit_EX_VI || vPermit_EX_VI) || 8437748a0bSNewPaulWalker (!directPermit_illegal && indirectPermit_EX_VI) 8537748a0bSNewPaulWalker ) 8637748a0bSNewPaulWalker 8737748a0bSNewPaulWalker val Xret_EX_II = xRetPermitMod.io.out.Xret_EX_II 8837748a0bSNewPaulWalker val Xret_EX_VI = xRetPermitMod.io.out.Xret_EX_VI 8937748a0bSNewPaulWalker 9037748a0bSNewPaulWalker io.out.EX_II := csrAccess_EX_II || Xret_EX_II 9137748a0bSNewPaulWalker io.out.EX_VI := !io.out.EX_II && (csrAccess_EX_VI || Xret_EX_VI) 9237748a0bSNewPaulWalker 9337748a0bSNewPaulWalker io.out.hasLegalWen := wen && !(io.out.EX_II || io.out.EX_VI) 9437748a0bSNewPaulWalker io.out.hasLegalMNret := xRetPermitMod.io.out.hasLegalMNret 9537748a0bSNewPaulWalker io.out.hasLegalMret := xRetPermitMod.io.out.hasLegalMret 9637748a0bSNewPaulWalker io.out.hasLegalSret := xRetPermitMod.io.out.hasLegalSret 9737748a0bSNewPaulWalker io.out.hasLegalDret := xRetPermitMod.io.out.hasLegalDret 9837748a0bSNewPaulWalker 9937748a0bSNewPaulWalker io.out.hasLegalWriteFcsr := mLevelPermitMod.io.out.hasLegalWriteFcsr 10037748a0bSNewPaulWalker io.out.hasLegalWriteVcsr := mLevelPermitMod.io.out.hasLegalWriteVcsr 10137748a0bSNewPaulWalker} 10237748a0bSNewPaulWalker 10337748a0bSNewPaulWalkerclass XRetPermitModule extends Module { 10437748a0bSNewPaulWalker val io = IO(new Bundle() { 10537748a0bSNewPaulWalker val in = Input(new Bundle { 10637748a0bSNewPaulWalker val privState = new PrivState 10737748a0bSNewPaulWalker val debugMode = Bool() 10837748a0bSNewPaulWalker val xRet = new xRetIO 10937748a0bSNewPaulWalker val status = new statusIO 11037748a0bSNewPaulWalker }) 11137748a0bSNewPaulWalker val out = Output(new Bundle { 11237748a0bSNewPaulWalker val Xret_EX_II = Bool() 11337748a0bSNewPaulWalker val Xret_EX_VI = Bool() 11437748a0bSNewPaulWalker val hasLegalMNret = Bool() 11537748a0bSNewPaulWalker val hasLegalMret = Bool() 11637748a0bSNewPaulWalker val hasLegalSret = Bool() 11737748a0bSNewPaulWalker val hasLegalDret = Bool() 11837748a0bSNewPaulWalker }) 11937748a0bSNewPaulWalker }) 12037748a0bSNewPaulWalker 12137748a0bSNewPaulWalker private val (privState, debugMode) = ( 12237748a0bSNewPaulWalker io.in.privState, 12337748a0bSNewPaulWalker io.in.debugMode, 12437748a0bSNewPaulWalker ) 12537748a0bSNewPaulWalker 126c2a2229dSlewislzh private val (mnret, mret, sret, dret) = ( 12737748a0bSNewPaulWalker io.in.xRet.mnret, 12837748a0bSNewPaulWalker io.in.xRet.mret, 12937748a0bSNewPaulWalker io.in.xRet.sret, 13037748a0bSNewPaulWalker io.in.xRet.dret, 13101cdded8SXuan Hu ) 13201cdded8SXuan Hu 13301cdded8SXuan Hu private val (tsr, vtsr) = ( 13401cdded8SXuan Hu io.in.status.tsr, 13501cdded8SXuan Hu io.in.status.vtsr, 13601cdded8SXuan Hu ) 13701cdded8SXuan Hu 13837748a0bSNewPaulWalker private val mnret_EX_II = mnret && !privState.isModeM 13937748a0bSNewPaulWalker private val mnretIllegal = mnret_EX_II 14037748a0bSNewPaulWalker 14137748a0bSNewPaulWalker private val mret_EX_II = mret && !privState.isModeM 14237748a0bSNewPaulWalker private val mretIllegal = mret_EX_II 14337748a0bSNewPaulWalker 14437748a0bSNewPaulWalker private val sret_EX_II = sret && (privState.isModeHU || privState.isModeHS && tsr) 14537748a0bSNewPaulWalker private val sret_EX_VI = sret && (privState.isModeVU || privState.isModeVS && vtsr) 14637748a0bSNewPaulWalker private val sretIllegal = sret_EX_II || sret_EX_VI 14737748a0bSNewPaulWalker 14837748a0bSNewPaulWalker private val dret_EX_II = dret && !debugMode 14937748a0bSNewPaulWalker private val dretIllegal = dret_EX_II 15037748a0bSNewPaulWalker 15137748a0bSNewPaulWalker io.out.Xret_EX_II := mnret_EX_II || mret_EX_II || sret_EX_II || dret_EX_II 15237748a0bSNewPaulWalker io.out.Xret_EX_VI := sret_EX_VI 15337748a0bSNewPaulWalker io.out.hasLegalMNret := mnret && !mnretIllegal 15437748a0bSNewPaulWalker io.out.hasLegalMret := mret && !mretIllegal 15537748a0bSNewPaulWalker io.out.hasLegalSret := sret && !sretIllegal 15637748a0bSNewPaulWalker io.out.hasLegalDret := dret && !dretIllegal 15737748a0bSNewPaulWalker} 15837748a0bSNewPaulWalker 15937748a0bSNewPaulWalkerclass MLevelPermitModule extends Module { 16037748a0bSNewPaulWalker val io = IO(new Bundle() { 16137748a0bSNewPaulWalker val in = Input(new Bundle { 16237748a0bSNewPaulWalker val csrAccess = new csrAccessIO 16337748a0bSNewPaulWalker val privState = new PrivState 16437748a0bSNewPaulWalker val status = new statusIO 16537748a0bSNewPaulWalker val xcounteren = new xcounterenIO 16637748a0bSNewPaulWalker val xenvcfg = new xenvcfgIO 16737748a0bSNewPaulWalker val xstateen = new xstateenIO 16837748a0bSNewPaulWalker val aia = new aiaIO 16937748a0bSNewPaulWalker }) 17037748a0bSNewPaulWalker val out = Output(new Bundle { 17137748a0bSNewPaulWalker val mLevelPermit_EX_II = Bool() 17237748a0bSNewPaulWalker val hasLegalWriteFcsr = Bool() 17337748a0bSNewPaulWalker val hasLegalWriteVcsr = Bool() 17437748a0bSNewPaulWalker }) 17537748a0bSNewPaulWalker }) 17637748a0bSNewPaulWalker 17737748a0bSNewPaulWalker private val (wen, addr, privState) = ( 17837748a0bSNewPaulWalker io.in.csrAccess.wen, 17937748a0bSNewPaulWalker io.in.csrAccess.addr, 18037748a0bSNewPaulWalker io.in.privState, 18190cbdd93SsinceforYy ) 18290cbdd93SsinceforYy 18337748a0bSNewPaulWalker private val tvm = io.in.status.tvm 184fd0cd118SsinceforYy 18537748a0bSNewPaulWalker private val mcounteren = io.in.xcounteren.mcounteren 18665ddf865SXuan Hu 18737748a0bSNewPaulWalker private val mstateen0 = io.in.xstateen.mstateen0 18826033c52Schengguanghui 18937748a0bSNewPaulWalker private val mcounterenTM = mcounteren(1) 1901e8ffa38SsinceforYy 19137748a0bSNewPaulWalker private val menvcfg = io.in.xenvcfg.menvcfg 1921e8ffa38SsinceforYy 19337748a0bSNewPaulWalker private val menvcfgSTCE = menvcfg(63) 1941e8ffa38SsinceforYy 19588857889SXuan Hu private val (sFSIsOff, sVSIsOff, sOrVsFSIsOff, sOrVsVSIsOff) = ( 19688857889SXuan Hu io.in.status.mstatusFSOff, 19788857889SXuan Hu io.in.status.mstatusVSOff, 19888857889SXuan Hu io.in.status.mstatusFSOff || io.in.status.vsstatusFSOff, 19988857889SXuan Hu io.in.status.mstatusVSOff || io.in.status.vsstatusVSOff, 2004d2be3d2SsinceforYy ) 2014d2be3d2SsinceforYy 20237748a0bSNewPaulWalker private val mvienSEIE = io.in.aia.mvienSEIE 2037a0a09b9SsinceforYy 20452abe1cbSXuan Hu private val csrIsRO = addr(11, 10) === "b11".U 20565ddf865SXuan Hu private val csrIsHPM = addr >= CSRs.cycle.U && addr <= CSRs.hpmcounter31.U 20688857889SXuan Hu private val csrIsFp = Seq(CSRs.fflags, CSRs.frm, CSRs.fcsr).map(_.U === addr).reduce(_ || _) 2078c5acf73SsinceforYy private val csrIsVec = Seq(CSRs.vstart, CSRs.vxsat, CSRs.vxrm, CSRs.vcsr, CSRs.vtype).map(_.U === addr).reduce(_ || _) 20888857889SXuan Hu private val csrIsWritableVec = Seq(CSRs.vstart, CSRs.vxsat, CSRs.vxrm, CSRs.vcsr).map(_.U === addr).reduce(_ || _) 20965ddf865SXuan Hu private val counterAddr = addr(4, 0) // 32 counters 210e5cc84f2SXuan Hu 21137748a0bSNewPaulWalker private val rwIllegal = csrIsRO && wen 21237748a0bSNewPaulWalker 21337748a0bSNewPaulWalker private val fsEffectiveOff = sFSIsOff && !privState.isVirtual || sOrVsFSIsOff && privState.isVirtual 21437748a0bSNewPaulWalker private val vsEffectiveOff = sVSIsOff && !privState.isVirtual || sOrVsVSIsOff && privState.isVirtual 21537748a0bSNewPaulWalker 21637748a0bSNewPaulWalker private val fpOff_EX_II = csrIsFp && fsEffectiveOff 21737748a0bSNewPaulWalker private val vecOff_EX_II = csrIsVec && vsEffectiveOff 21837748a0bSNewPaulWalker 21937748a0bSNewPaulWalker private val fpVec_EX_II = fpOff_EX_II || vecOff_EX_II 22037748a0bSNewPaulWalker 22137748a0bSNewPaulWalker private val rwStimecmp_EX_II = !privState.isModeM && (!mcounterenTM || !menvcfgSTCE) && (addr === CSRs.vstimecmp.U || addr === CSRs.stimecmp.U) 22237748a0bSNewPaulWalker 22337748a0bSNewPaulWalker private val accessHPM_EX_II = csrIsHPM && !privState.isModeM && !mcounteren(counterAddr) 22437748a0bSNewPaulWalker 22537748a0bSNewPaulWalker private val rwSatp_EX_II = privState.isModeHS && tvm && (addr === CSRs.satp.U || addr === CSRs.hgatp.U) 22637748a0bSNewPaulWalker 22737748a0bSNewPaulWalker private val rwStopei_EX_II = privState.isModeHS && mvienSEIE && (addr === CSRs.stopei.U) 22837748a0bSNewPaulWalker 22937748a0bSNewPaulWalker /** 23037748a0bSNewPaulWalker * Sm/Ssstateen0 begin 23137748a0bSNewPaulWalker */ 23237748a0bSNewPaulWalker // SE0 bit 63 23337748a0bSNewPaulWalker private val csrIsHstateen0 = addr === CSRs.hstateen0.U 23437748a0bSNewPaulWalker private val csrIsSstateen0 = addr === CSRs.sstateen0.U 23537748a0bSNewPaulWalker private val csrIsStateen0 = csrIsHstateen0 || csrIsSstateen0 23637748a0bSNewPaulWalker private val accessStateen0_EX_II = csrIsStateen0 && !privState.isModeM && !mstateen0.SE0.asBool 23737748a0bSNewPaulWalker 23837748a0bSNewPaulWalker // ENVCFG bit 62 23937748a0bSNewPaulWalker private val csrIsHenvcfg = addr === CSRs.henvcfg.U 24037748a0bSNewPaulWalker private val csrIsSenvcfg = addr === CSRs.senvcfg.U 24137748a0bSNewPaulWalker private val csrIsEnvcfg = csrIsHenvcfg || csrIsSenvcfg 24237748a0bSNewPaulWalker private val accessEnvcfg_EX_II = csrIsEnvcfg && !privState.isModeM && !mstateen0.ENVCFG.asBool 24337748a0bSNewPaulWalker 24437748a0bSNewPaulWalker // CSRIND bit 60 indirect reg (Sscsrind extensions), this is not implemented 24537748a0bSNewPaulWalker // csr addr S: [0x150, 0x157] VS: [0x250, 0x257] 24637748a0bSNewPaulWalker private val csrIsSi = addr.head(9) === CSRs.siselect.U.head(9) 24737748a0bSNewPaulWalker private val csrIsVSi = addr.head(9) === CSRs.vsiselect.U.head(9) 24837748a0bSNewPaulWalker private val csrIsIND = csrIsSi || csrIsVSi 24937748a0bSNewPaulWalker private val accessIND_EX_II = csrIsIND && !privState.isModeM && !mstateen0.CSRIND.asBool 25037748a0bSNewPaulWalker 25137748a0bSNewPaulWalker // AIA bit 59 25237748a0bSNewPaulWalker private val ssAiaHaddr = Seq(CSRs.hvien.U, CSRs.hvictl.U, CSRs.hviprio1.U, CSRs.hviprio2.U) 25337748a0bSNewPaulWalker private val ssAiaVSaddr = addr === CSRs.vstopi.U 25437748a0bSNewPaulWalker private val ssAiaSaddr = addr === CSRs.stopi.U 25537748a0bSNewPaulWalker private val csrIsAIA = ssAiaHaddr.map(_ === addr).reduce(_ || _) || ssAiaVSaddr || ssAiaSaddr 25637748a0bSNewPaulWalker private val accessAIA_EX_II = csrIsAIA && !privState.isModeM && !mstateen0.AIA.asBool 25737748a0bSNewPaulWalker 25837748a0bSNewPaulWalker // IMSIC bit 58 (Ssaia extension) 25937748a0bSNewPaulWalker private val csrIsStopei = addr === CSRs.stopei.U 26037748a0bSNewPaulWalker private val csrIsVStopei = addr === CSRs.vstopei.U 26137748a0bSNewPaulWalker private val csrIsTpoie = csrIsStopei || csrIsVStopei 26237748a0bSNewPaulWalker private val accessTopie_EX_II = csrIsTpoie && !privState.isModeM && !mstateen0.IMSIC.asBool 26337748a0bSNewPaulWalker 26437748a0bSNewPaulWalker // CONTEXT bit 57 context reg (Sdtrig extensions), this is not implemented 26537748a0bSNewPaulWalker private val csrIsHcontext = addr === CSRs.hcontext.U 26637748a0bSNewPaulWalker private val csrIsScontext = addr === CSRs.scontext.U 26737748a0bSNewPaulWalker private val csrIsContext = csrIsHcontext || csrIsScontext 26837748a0bSNewPaulWalker private val accessContext_EX_II = csrIsContext && !privState.isModeM && !mstateen0.CONTEXT.asBool 26937748a0bSNewPaulWalker 27037748a0bSNewPaulWalker // P1P13 bit 56, Read-only 0 27137748a0bSNewPaulWalker 27237748a0bSNewPaulWalker // Custom bit 0 27337748a0bSNewPaulWalker // csr addr HVS: [0x6c0, 0x6ff], [0xac0, 0xaff], [0xec0, 0xeff] 27437748a0bSNewPaulWalker private val csrIsHVSCustom = (addr(11, 10) =/= "b00".U) && (addr(9, 8) === "b10".U) && (addr(7, 6) === "b11".U) 27537748a0bSNewPaulWalker // [0x5c0, 0x5ff], [0x9c0, 0x9ff], [0xdc0, 0xdff] 27637748a0bSNewPaulWalker private val csrIsSCustom = (addr(11, 10) =/= "b00".U) && (addr(9, 8) === "b01".U) && (addr(7, 6) === "b11".U) 27737748a0bSNewPaulWalker // [0x800, 0x8ff], [0xcc0, 0xcff] 27837748a0bSNewPaulWalker private val csrIsUCustom = (addr(11, 8) === "b1000".U) || (addr(11, 6) === "b110011".U) 27937748a0bSNewPaulWalker private val allCustom = csrIsHVSCustom || csrIsSCustom || csrIsUCustom 28037748a0bSNewPaulWalker private val accessCustom_EX_II = allCustom && !privState.isModeM && !mstateen0.C.asBool 28137748a0bSNewPaulWalker 28237748a0bSNewPaulWalker val xstateControlAccess_EX_II = accessStateen0_EX_II || accessEnvcfg_EX_II || accessIND_EX_II || accessAIA_EX_II || 28337748a0bSNewPaulWalker accessTopie_EX_II || accessContext_EX_II || accessCustom_EX_II 28437748a0bSNewPaulWalker /** 28537748a0bSNewPaulWalker * Sm/Ssstateen end 28637748a0bSNewPaulWalker */ 28737748a0bSNewPaulWalker 28837748a0bSNewPaulWalker io.out.mLevelPermit_EX_II := rwIllegal || fpVec_EX_II || rwStimecmp_EX_II || 28937748a0bSNewPaulWalker accessHPM_EX_II || rwSatp_EX_II || rwStopei_EX_II || xstateControlAccess_EX_II 29037748a0bSNewPaulWalker io.out.hasLegalWriteFcsr := wen && csrIsFp && !fsEffectiveOff 29137748a0bSNewPaulWalker io.out.hasLegalWriteVcsr := wen && csrIsWritableVec && !vsEffectiveOff 29237748a0bSNewPaulWalker} 29337748a0bSNewPaulWalker 29437748a0bSNewPaulWalkerclass SLevelPermitModule extends Module { 29537748a0bSNewPaulWalker val io = IO(new Bundle() { 29637748a0bSNewPaulWalker val in = Input(new Bundle { 29737748a0bSNewPaulWalker val csrAccess = new csrAccessIO 29837748a0bSNewPaulWalker val privState = new PrivState 29937748a0bSNewPaulWalker val xcounteren = new xcounterenIO 30037748a0bSNewPaulWalker val xstateen = new xstateenIO 30137748a0bSNewPaulWalker }) 30237748a0bSNewPaulWalker val out = Output(new Bundle { 30337748a0bSNewPaulWalker val sLevelPermit_EX_II = Bool() 30437748a0bSNewPaulWalker }) 30537748a0bSNewPaulWalker }) 30637748a0bSNewPaulWalker 30737748a0bSNewPaulWalker private val (addr, privState) = ( 30837748a0bSNewPaulWalker io.in.csrAccess.addr, 30937748a0bSNewPaulWalker io.in.privState, 31037748a0bSNewPaulWalker ) 31137748a0bSNewPaulWalker 31237748a0bSNewPaulWalker private val scounteren = io.in.xcounteren.scounteren 31337748a0bSNewPaulWalker 31437748a0bSNewPaulWalker private val sstateen0 = io.in.xstateen.sstateen0 31537748a0bSNewPaulWalker 31637748a0bSNewPaulWalker private val csrIsHPM = addr >= CSRs.cycle.U && addr <= CSRs.hpmcounter31.U 31737748a0bSNewPaulWalker private val counterAddr = addr(4, 0) // 32 counters 31837748a0bSNewPaulWalker 31937748a0bSNewPaulWalker private val accessHPM_EX_II = csrIsHPM && privState.isModeHU && !scounteren(counterAddr) 32037748a0bSNewPaulWalker 32137748a0bSNewPaulWalker private val csrIsUCustom = (addr(11, 8) === "b1000".U) || (addr(11, 6) === "b110011".U) 32237748a0bSNewPaulWalker private val accessCustom_EX_II = csrIsUCustom && privState.isModeHU && !sstateen0.C.asBool 32337748a0bSNewPaulWalker 32437748a0bSNewPaulWalker io.out.sLevelPermit_EX_II := accessHPM_EX_II || accessCustom_EX_II 32537748a0bSNewPaulWalker} 32637748a0bSNewPaulWalker 32737748a0bSNewPaulWalkerclass PrivilegePermitModule extends Module { 32837748a0bSNewPaulWalker val io = IO(new Bundle() { 32937748a0bSNewPaulWalker val in = Input(new Bundle { 33037748a0bSNewPaulWalker val csrAccess = new csrAccessIO 33137748a0bSNewPaulWalker val privState = new PrivState 33237748a0bSNewPaulWalker val debugMode = Bool() 33337748a0bSNewPaulWalker }) 33437748a0bSNewPaulWalker val out = Output(new Bundle { 33537748a0bSNewPaulWalker val privilege_EX_II = Bool() 33637748a0bSNewPaulWalker val privilege_EX_VI = Bool() 33737748a0bSNewPaulWalker }) 33837748a0bSNewPaulWalker }) 33937748a0bSNewPaulWalker 34037748a0bSNewPaulWalker private val (addr, privState, debugMode) = ( 34137748a0bSNewPaulWalker io.in.csrAccess.addr, 34237748a0bSNewPaulWalker io.in.privState, 34337748a0bSNewPaulWalker io.in.debugMode 34437748a0bSNewPaulWalker ) 34537748a0bSNewPaulWalker 346e5cc84f2SXuan Hu private val accessTable = TruthTable(Seq( 347e5cc84f2SXuan Hu // V PRVM ADDR 34846044b17SsinceforYy BitPat("b0__00___00") -> BitPat.Y(), // HU access U 34946044b17SsinceforYy BitPat("b1__00___00") -> BitPat.Y(), // VU access U 35046044b17SsinceforYy BitPat("b0__01___00") -> BitPat.Y(), // HS access U 35146044b17SsinceforYy BitPat("b0__01___01") -> BitPat.Y(), // HS access S 352940c345dSXuan Hu BitPat("b0__01___10") -> BitPat.Y(), // HS access H 353e5cc84f2SXuan Hu BitPat("b1__01___00") -> BitPat.Y(), // VS access U 354e5cc84f2SXuan Hu BitPat("b1__01___01") -> BitPat.Y(), // VS access S 35546044b17SsinceforYy BitPat("b0__11___00") -> BitPat.Y(), // M access HU 35646044b17SsinceforYy BitPat("b0__11___01") -> BitPat.Y(), // M access HS 357b3788359SXuan Hu BitPat("b0__11___10") -> BitPat.Y(), // M access H 35846044b17SsinceforYy BitPat("b0__11___11") -> BitPat.Y(), // M access M 359e5cc84f2SXuan Hu ), BitPat.N()) 360e5cc84f2SXuan Hu 3618084aa02Schengguanghui private val regularPrivilegeLegal = chisel3.util.experimental.decode.decoder( 362e5cc84f2SXuan Hu privState.V.asUInt ## privState.PRVM.asUInt ## addr(9, 8), 363e5cc84f2SXuan Hu accessTable 364e5cc84f2SXuan Hu ).asBool 365e5cc84f2SXuan Hu 36637748a0bSNewPaulWalker private val csrIsM = addr(9, 8) === "b11".U 3671734111cSchengguanghui private val isDebugReg = addr(11, 4) === "h7b".U 3681734111cSchengguanghui private val privilegeLegal = Mux(isDebugReg, debugMode, regularPrivilegeLegal || debugMode) 3698084aa02Schengguanghui 37037748a0bSNewPaulWalker io.out.privilege_EX_II := !privilegeLegal && (!privState.isVirtual || csrIsM) 37137748a0bSNewPaulWalker io.out.privilege_EX_VI := !privilegeLegal && privState.isVirtual && !csrIsM 37237748a0bSNewPaulWalker} 373e5cc84f2SXuan Hu 374*7768a97dSTang Haojinclass VirtualLevelPermitModule(implicit val p: Parameters) extends Module with HasSoCParameter { 37537748a0bSNewPaulWalker val io = IO(new Bundle() { 37637748a0bSNewPaulWalker val in = Input(new Bundle { 37737748a0bSNewPaulWalker val csrAccess = new csrAccessIO 37837748a0bSNewPaulWalker val privState = new PrivState 37937748a0bSNewPaulWalker val status = new statusIO 38037748a0bSNewPaulWalker val xcounteren = new xcounterenIO 38137748a0bSNewPaulWalker val xenvcfg = new xenvcfgIO 38237748a0bSNewPaulWalker val xstateen = new xstateenIO 38337748a0bSNewPaulWalker val aia = new aiaIO 38437748a0bSNewPaulWalker }) 38537748a0bSNewPaulWalker val out = Output(new Bundle { 386e733b25bSlinzhida val virtualLevelPermit_EX_II = Bool() 38737748a0bSNewPaulWalker val virtualLevelPermit_EX_VI = Bool() 38837748a0bSNewPaulWalker }) 38937748a0bSNewPaulWalker }) 390c2a2229dSlewislzh 39137748a0bSNewPaulWalker private val (wen, addr, privState) = ( 39237748a0bSNewPaulWalker io.in.csrAccess.wen, 39337748a0bSNewPaulWalker io.in.csrAccess.addr, 39437748a0bSNewPaulWalker io.in.privState, 39565ddf865SXuan Hu ) 39637748a0bSNewPaulWalker 397e733b25bSlinzhida private val (vtvm, vgein) = ( 398e733b25bSlinzhida io.in.status.vtvm, 399e733b25bSlinzhida io.in.status.vgein, 400e733b25bSlinzhida ) 40137748a0bSNewPaulWalker 40237748a0bSNewPaulWalker private val (hcounteren, scounteren) = ( 40337748a0bSNewPaulWalker io.in.xcounteren.hcounteren, 40437748a0bSNewPaulWalker io.in.xcounteren.scounteren, 40537748a0bSNewPaulWalker ) 40637748a0bSNewPaulWalker 40737748a0bSNewPaulWalker private val hcounterenTM = hcounteren(1) 40837748a0bSNewPaulWalker 40937748a0bSNewPaulWalker private val henvcfg = io.in.xenvcfg.henvcfg 41037748a0bSNewPaulWalker 41137748a0bSNewPaulWalker private val henvcfgSTCE = henvcfg(63) 41237748a0bSNewPaulWalker 41337748a0bSNewPaulWalker private val (hstateen0, sstateen0) = ( 41437748a0bSNewPaulWalker io.in.xstateen.hstateen0, 41537748a0bSNewPaulWalker io.in.xstateen.sstateen0, 41637748a0bSNewPaulWalker ) 41737748a0bSNewPaulWalker 41837748a0bSNewPaulWalker private val hvictlVTI = io.in.aia.hvictlVTI 41937748a0bSNewPaulWalker 42037748a0bSNewPaulWalker private val csrIsHPM = addr >= CSRs.cycle.U && addr <= CSRs.hpmcounter31.U 42137748a0bSNewPaulWalker private val counterAddr = addr(4, 0) // 32 counters 42237748a0bSNewPaulWalker 42337748a0bSNewPaulWalker private val rwSatp_EX_VI = privState.isModeVS && vtvm && (addr === CSRs.satp.U) 42437748a0bSNewPaulWalker 425*7768a97dSTang Haojin private val rwVStopei_EX_II = (privState.isModeM || privState.isModeHS) && (addr === CSRs.vstopei.U) && (vgein === 0.U || vgein > soc.IMSICParams.geilen.U) 426*7768a97dSTang Haojin private val rwStopei_EX_VI = privState.isModeVS && (addr === CSRs.stopei.U) && (vgein === 0.U || vgein > soc.IMSICParams.geilen.U) 427e733b25bSlinzhida 42837748a0bSNewPaulWalker private val rwSip_Sie_EX_VI = privState.isModeVS && hvictlVTI && (addr === CSRs.sip.U || addr === CSRs.sie.U) 42937748a0bSNewPaulWalker 43037748a0bSNewPaulWalker private val rwStimecmp_EX_VI = privState.isModeVS && (addr === CSRs.stimecmp.U) && 43137748a0bSNewPaulWalker (!hcounterenTM || !henvcfgSTCE || wen && hvictlVTI) 43237748a0bSNewPaulWalker 43337748a0bSNewPaulWalker private val accessHPM_EX_VI = csrIsHPM && ( 43465ddf865SXuan Hu privState.isModeVS && !hcounteren(counterAddr) || 43565ddf865SXuan Hu privState.isModeVU && (!hcounteren(counterAddr) || !scounteren(counterAddr)) 43665ddf865SXuan Hu ) 43765ddf865SXuan Hu 43826033c52Schengguanghui /** 43926033c52Schengguanghui * Sm/Ssstateen0 begin 44026033c52Schengguanghui */ 44126033c52Schengguanghui // SE0 bit 63 44237748a0bSNewPaulWalker private val csrIsSstateen0 = addr === CSRs.sstateen0.U 44337748a0bSNewPaulWalker private val accessStateen0_EX_VI = csrIsSstateen0 && privState.isVirtual && !hstateen0.SE0.asBool 44426033c52Schengguanghui 44526033c52Schengguanghui // ENVCFG bit 62 44637748a0bSNewPaulWalker private val csrIsSenvcfg = addr === CSRs.senvcfg.U 44737748a0bSNewPaulWalker private val accessEnvcfg_EX_VI = csrIsSenvcfg && privState.isVirtual && !hstateen0.ENVCFG.asBool 44826033c52Schengguanghui 44926033c52Schengguanghui // CSRIND bit 60 indirect reg (Sscsrind extensions), this is not implemented 45037748a0bSNewPaulWalker // csr addr S: [0x150, 0x157] 45126033c52Schengguanghui private val csrIsSi = addr.head(9) === CSRs.siselect.U.head(9) 45237748a0bSNewPaulWalker private val accessIND_EX_VI = csrIsSi && privState.isVirtual && !hstateen0.CSRIND.asBool 45326033c52Schengguanghui 45426033c52Schengguanghui // AIA bit 59 455ad15bdb2SNewPaulWalker private val ssAiaSaddr = addr === CSRs.stopi.U 456ad15bdb2SNewPaulWalker private val accessAIA_EX_VI = ssAiaSaddr && privState.isVirtual && !hstateen0.AIA.asBool 45726033c52Schengguanghui 45826033c52Schengguanghui // IMSIC bit 58 (Ssaia extension) 45926033c52Schengguanghui private val csrIsStopei = addr === CSRs.stopei.U 46037748a0bSNewPaulWalker private val accessTopie_EX_VI = csrIsStopei && privState.isVirtual && !hstateen0.IMSIC.asBool 46126033c52Schengguanghui 46226033c52Schengguanghui // CONTEXT bit 57 context reg (Sdtrig extensions), this is not implemented 46337748a0bSNewPaulWalker private val csrIsScontext = addr === CSRs.scontext.U 46437748a0bSNewPaulWalker private val accessContext_EX_VI = csrIsScontext && privState.isVirtual && !hstateen0.CONTEXT.asBool 46526033c52Schengguanghui 46626033c52Schengguanghui // P1P13 bit 56, Read-only 0 46726033c52Schengguanghui 46826033c52Schengguanghui // Custom bit 0 46926033c52Schengguanghui // [0x5c0, 0x5ff], [0x9c0, 0x9ff], [0xdc0, 0xdff] 47026033c52Schengguanghui private val csrIsSCustom = (addr(11, 10) =/= "b00".U) && (addr(9, 8) === "b01".U) && (addr(7, 6) === "b11".U) 47126033c52Schengguanghui // [0x800, 0x8ff], [0xcc0, 0xcff] 472ad15bdb2SNewPaulWalker private val csrIsUCustom = (addr(11, 8) === "b1000".U) || (addr(11, 6) === "b110011".U) 47337748a0bSNewPaulWalker private val accessCustom_EX_VI = (csrIsSCustom || csrIsUCustom) && privState.isVirtual && !hstateen0.C.asBool || 47426033c52Schengguanghui csrIsUCustom && privState.isModeVU && hstateen0.C.asBool && !sstateen0.C.asBool 47526033c52Schengguanghui 47637748a0bSNewPaulWalker private val xstateControlAccess_EX_VI = accessStateen0_EX_VI || accessEnvcfg_EX_VI || accessIND_EX_VI || accessAIA_EX_VI || 47737748a0bSNewPaulWalker accessTopie_EX_VI || accessContext_EX_VI || accessCustom_EX_VI 47826033c52Schengguanghui 479e733b25bSlinzhida io.out.virtualLevelPermit_EX_II := rwVStopei_EX_II 480e733b25bSlinzhida io.out.virtualLevelPermit_EX_VI := rwSatp_EX_VI || rwStopei_EX_VI || rwSip_Sie_EX_VI || rwStimecmp_EX_VI || accessHPM_EX_VI || xstateControlAccess_EX_VI 481e5cc84f2SXuan Hu} 482e5cc84f2SXuan Hu 48337748a0bSNewPaulWalkerclass IndirectCSRPermitModule extends Module { 48437748a0bSNewPaulWalker val io = IO(new Bundle() { 485007f6122SXuan Hu val in = Input(new Bundle { 48637748a0bSNewPaulWalker val csrAccess = new csrAccessIO 48737748a0bSNewPaulWalker val privState = new PrivState 48837748a0bSNewPaulWalker val aia = new aiaIO 48937748a0bSNewPaulWalker }) 49037748a0bSNewPaulWalker val out = Output(new Bundle { 49137748a0bSNewPaulWalker val indirectCSR_EX_II = Bool() 49237748a0bSNewPaulWalker val indirectCSR_EX_VI = Bool() 49337748a0bSNewPaulWalker }) 49437748a0bSNewPaulWalker }) 49537748a0bSNewPaulWalker 49637748a0bSNewPaulWalker private val (addr, privState) = ( 49737748a0bSNewPaulWalker io.in.csrAccess.addr, 49837748a0bSNewPaulWalker io.in.privState, 49937748a0bSNewPaulWalker ) 50037748a0bSNewPaulWalker 50137748a0bSNewPaulWalker private val (miselectIsIllegal, siselectIsIllegal, vsiselectIsIllegal) = ( 50237748a0bSNewPaulWalker io.in.aia.miselectIsIllegal, 50337748a0bSNewPaulWalker io.in.aia.siselectIsIllegal, 50437748a0bSNewPaulWalker io.in.aia.vsiselectIsIllegal, 50537748a0bSNewPaulWalker ) 50637748a0bSNewPaulWalker 50737748a0bSNewPaulWalker private val (siselect, vsiselect) = ( 50837748a0bSNewPaulWalker io.in.aia.siselect, 50937748a0bSNewPaulWalker io.in.aia.vsiselect, 51037748a0bSNewPaulWalker ) 51137748a0bSNewPaulWalker 51237748a0bSNewPaulWalker private val mvienSEIE = io.in.aia.mvienSEIE 51337748a0bSNewPaulWalker 51437748a0bSNewPaulWalker private val rwMireg_EX_II = miselectIsIllegal && addr === CSRs.mireg.U 51537748a0bSNewPaulWalker 51637748a0bSNewPaulWalker private val rwSireg_EX_II = ( 51737748a0bSNewPaulWalker (privState.isModeHS && mvienSEIE && siselect >= 0x70.U && siselect <= 0xFF.U) || 51837748a0bSNewPaulWalker ((privState.isModeM || privState.isModeHS) && siselectIsIllegal) || 51937748a0bSNewPaulWalker (privState.isModeVS && (vsiselect < 0x30.U || (vsiselect >= 0x40.U && vsiselect < 0x70.U) || vsiselect > 0xFF.U)) 52037748a0bSNewPaulWalker ) && addr === CSRs.sireg.U 52137748a0bSNewPaulWalker 52237748a0bSNewPaulWalker private val rwSireg_EX_VI = privState.isModeVS && (vsiselect >= 0x30.U && vsiselect <= 0x3F.U) && addr === CSRs.sireg.U 52337748a0bSNewPaulWalker 52437748a0bSNewPaulWalker private val rwVSireg_EX_II = vsiselectIsIllegal && addr === CSRs.vsireg.U 52537748a0bSNewPaulWalker 52637748a0bSNewPaulWalker io.out.indirectCSR_EX_II := rwMireg_EX_II || rwSireg_EX_II || rwVSireg_EX_II 52737748a0bSNewPaulWalker io.out.indirectCSR_EX_VI := rwSireg_EX_VI 52837748a0bSNewPaulWalker} 52937748a0bSNewPaulWalker 53037748a0bSNewPaulWalkerclass csrAccessIO extends Bundle { 53152abe1cbSXuan Hu val ren = Bool() 532e5cc84f2SXuan Hu val wen = Bool() 533e5cc84f2SXuan Hu val addr = UInt(12.W) 53452abe1cbSXuan Hu} 53537748a0bSNewPaulWalker 53637748a0bSNewPaulWalkerclass xRetIO extends Bundle { 537c2a2229dSlewislzh val mnret = Bool() 53801cdded8SXuan Hu val mret = Bool() 53901cdded8SXuan Hu val sret = Bool() 540be37cd3aSsinceforYy val dret = Bool() 54137748a0bSNewPaulWalker} 54237748a0bSNewPaulWalker 54337748a0bSNewPaulWalkerclass statusIO extends Bundle { 54401cdded8SXuan Hu // Trap SRET 54501cdded8SXuan Hu val tsr = Bool() 54601cdded8SXuan Hu // Virtual Trap SRET 54701cdded8SXuan Hu val vtsr = Bool() 54890cbdd93SsinceforYy // Trap Virtual Memory 54990cbdd93SsinceforYy val tvm = Bool() 55090cbdd93SsinceforYy // Virtual Trap Virtual Memory 55190cbdd93SsinceforYy val vtvm = Bool() 552e733b25bSlinzhida val vgein = UInt(6.W) 55337748a0bSNewPaulWalker val mstatusFSOff = Bool() 55437748a0bSNewPaulWalker val vsstatusFSOff = Bool() 55537748a0bSNewPaulWalker val mstatusVSOff = Bool() 55637748a0bSNewPaulWalker val vsstatusVSOff = Bool() 55737748a0bSNewPaulWalker} 55837748a0bSNewPaulWalker 55937748a0bSNewPaulWalkerclass xcounterenIO extends Bundle { 56065ddf865SXuan Hu // Machine level counter enable, access PMC from the level less than M will trap EX_II 56165ddf865SXuan Hu val mcounteren = UInt(32.W) 56265ddf865SXuan Hu // Hypervisor level counter enable. 56365ddf865SXuan Hu // Accessing PMC from VS/VU level will trap EX_VI, if m[x]=1 && h[x]=0 56465ddf865SXuan Hu val hcounteren = UInt(32.W) 56565ddf865SXuan Hu // Supervisor level counter enable. 56665ddf865SXuan Hu // Accessing PMC from **HU level** will trap EX_II, if s[x]=0 56765ddf865SXuan Hu // Accessing PMC from **VU level** will trap EX_VI, if m[x]=1 && h[x]=1 && s[x]=0 56865ddf865SXuan Hu val scounteren = UInt(32.W) 56937748a0bSNewPaulWalker} 57037748a0bSNewPaulWalker 57137748a0bSNewPaulWalkerclass xenvcfgIO extends Bundle { 5721e8ffa38SsinceforYy // Machine environment configuration register. 5731e8ffa38SsinceforYy // Accessing stimecmp or vstimecmp from **Non-M level** will trap EX_II, if menvcfg.STCE=0 5741e8ffa38SsinceforYy val menvcfg = UInt(64.W) 5751e8ffa38SsinceforYy // Hypervisor environment configuration register. 5761e8ffa38SsinceforYy // Accessing vstimecmp from ** V level** will trap EX_VI, if menvcfg.STCE=1 && henvcfg.STCE=0 5771e8ffa38SsinceforYy val henvcfg = UInt(64.W) 57837748a0bSNewPaulWalker} 57988857889SXuan Hu 58037748a0bSNewPaulWalkerclass xstateenIO extends Bundle { 58126033c52Schengguanghui // Sm/Ssstateen: to control state access 58226033c52Schengguanghui val mstateen0 = new MstateenBundle0 58326033c52Schengguanghui val hstateen0 = new HstateenBundle0 58426033c52Schengguanghui val sstateen0 = new SstateenBundle0 58501cdded8SXuan Hu} 58637748a0bSNewPaulWalker 58737748a0bSNewPaulWalkerclass aiaIO extends Bundle { 5887a0a09b9SsinceforYy val miselectIsIllegal = Bool() 5897a0a09b9SsinceforYy val siselectIsIllegal = Bool() 5907a0a09b9SsinceforYy val vsiselectIsIllegal = Bool() 5917a0a09b9SsinceforYy val siselect = UInt(64.W) 5927a0a09b9SsinceforYy val vsiselect = UInt(64.W) 5937a0a09b9SsinceforYy val mvienSEIE = Bool() 5947a0a09b9SsinceforYy val hvictlVTI = Bool() 5957a0a09b9SsinceforYy} 59637748a0bSNewPaulWalker 59737748a0bSNewPaulWalkerclass CSRPermitIO extends Bundle { 59837748a0bSNewPaulWalker val in = Input(new Bundle { 59937748a0bSNewPaulWalker val csrAccess = new csrAccessIO 60037748a0bSNewPaulWalker val privState = new PrivState 60137748a0bSNewPaulWalker val debugMode = Bool() 60237748a0bSNewPaulWalker val xRet = new xRetIO 60337748a0bSNewPaulWalker val status = new statusIO 60437748a0bSNewPaulWalker val xcounteren = new xcounterenIO 60537748a0bSNewPaulWalker val xenvcfg = new xenvcfgIO 60637748a0bSNewPaulWalker val xstateen = new xstateenIO 60737748a0bSNewPaulWalker val aia = new aiaIO 608007f6122SXuan Hu }) 609e5cc84f2SXuan Hu 610007f6122SXuan Hu val out = Output(new Bundle { 61152abe1cbSXuan Hu val hasLegalWen = Bool() 612c2a2229dSlewislzh val hasLegalMNret = Bool() 61352abe1cbSXuan Hu val hasLegalMret = Bool() 61452abe1cbSXuan Hu val hasLegalSret = Bool() 615be37cd3aSsinceforYy val hasLegalDret = Bool() 61688857889SXuan Hu val hasLegalWriteFcsr = Bool() 61788857889SXuan Hu val hasLegalWriteVcsr = Bool() 618f1b77b5eSXuan Hu val EX_II = Bool() 619f1b77b5eSXuan Hu val EX_VI = Bool() 620007f6122SXuan Hu }) 621e5cc84f2SXuan Hu} 622