From 960c147148ea1165ed8b710b5357261eb8301599 Mon Sep 17 00:00:00 2001 From: John Ingalls Date: Tue, 23 Apr 2024 11:13:25 -0700 Subject: [PATCH] Hypervisor: drive mtinst/htinst --- src/main/scala/rocket/CSR.scala | 17 +++++++++++++++-- src/main/scala/rocket/Frontend.scala | 4 ++++ src/main/scala/rocket/RocketCore.scala | 9 +++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 67812022773..27bcce9af72 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -286,6 +286,7 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle val pc = Input(UInt(vaddrBitsExtended.W)) val tval = Input(UInt(vaddrBitsExtended.W)) val htval = Input(UInt(((maxSVAddrBits + 1) min xLen).W)) + val mhtinst_read_pseudo = Input(Bool()) val gva = Input(Bool()) val time = Output(UInt(xLen.W)) val fcsr_rm = Output(Bits(FPConstants.RM_SZ.W)) @@ -578,6 +579,12 @@ class CSRFile( val reg_vxsat = usingVector.option(Reg(Bool())) val reg_vxrm = usingVector.option(Reg(UInt(io.vector.get.vxrm.getWidth.W))) + val reg_mtinst_read_pseudo = Reg(Bool()) + val reg_htinst_read_pseudo = Reg(Bool()) + // XLEN=32: 0x00002000 + // XLEN=64: 0x00003000 + val Seq(read_mtinst, read_htinst) = Seq(reg_mtinst_read_pseudo, reg_htinst_read_pseudo).map(r => Cat(r, (xLen == 32).option(0.U).getOrElse(r), 0.U(12.W))) + val reg_mcountinhibit = RegInit(0.U((CSR.firstHPM + nPerfCounters).W)) io.inhibit_cycle := reg_mcountinhibit(0) val reg_instret = WideCounter(64, io.retire, inhibit = reg_mcountinhibit(2)) @@ -797,7 +804,7 @@ class CSRFile( val reg_rocc = roccCSRs.zip(io.roccCSRs).map(t => generateCustomCSR(t._1, t._2)) if (usingHypervisor) { - read_mapping += CSRs.mtinst -> 0.U + read_mapping += CSRs.mtinst -> read_mtinst read_mapping += CSRs.mtval2 -> reg_mtval2 val read_hstatus = io.hstatus.asUInt.extract(xLen-1,0) @@ -813,7 +820,7 @@ class CSRFile( read_mapping += CSRs.hgeie -> 0.U read_mapping += CSRs.hgeip -> 0.U read_mapping += CSRs.htval -> reg_htval - read_mapping += CSRs.htinst -> 0.U + read_mapping += CSRs.htinst -> read_htinst read_mapping += CSRs.henvcfg -> reg_henvcfg.asUInt if (xLen == 32) read_mapping += CSRs.henvcfgh -> (reg_henvcfg.asUInt >> 32) @@ -1060,6 +1067,7 @@ class CSRFile( reg_scause := cause reg_stval := tval reg_htval := io.htval + reg_htinst_read_pseudo := io.mhtinst_read_pseudo reg_mstatus.spie := reg_mstatus.sie reg_mstatus.spp := reg_mstatus.prv reg_mstatus.sie := false.B @@ -1072,6 +1080,7 @@ class CSRFile( reg_mcause := cause reg_mtval := tval reg_mtval2 := io.htval + reg_mtinst_read_pseudo := io.mhtinst_read_pseudo reg_mstatus.mpie := reg_mstatus.mie reg_mstatus.mpp := trimPrivilege(reg_mstatus.prv) reg_mstatus.mie := false.B @@ -1397,6 +1406,10 @@ class CSRFile( when (decoded_addr(CSRs.htval)) { reg_htval := wdata } when (decoded_addr(CSRs.mtval2)) { reg_mtval2 := wdata } + val write_mhtinst_read_pseudo = wdata(13) && (xLen == 32).option(true.B).getOrElse(wdata(12)) + when(decoded_addr(CSRs.mtinst)) { reg_mtinst_read_pseudo := write_mhtinst_read_pseudo } + when(decoded_addr(CSRs.htinst)) { reg_htinst_read_pseudo := write_mhtinst_read_pseudo } + when (decoded_addr(CSRs.vsstatus)) { val new_vsstatus = wdata.asTypeOf(new MStatus()) reg_vsstatus.sie := new_vsstatus.sie diff --git a/src/main/scala/rocket/Frontend.scala b/src/main/scala/rocket/Frontend.scala index f6c0ad52b68..27c2b0c8af3 100644 --- a/src/main/scala/rocket/Frontend.scala +++ b/src/main/scala/rocket/Frontend.scala @@ -52,6 +52,7 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) { val sfence = Valid(new SFenceReq) val resp = Flipped(Decoupled(new FrontendResp)) val gpa = Flipped(Valid(UInt(vaddrBitsExtended.W))) + val gpa_is_pte = Input(Bool()) val btb_update = Valid(new BTBUpdate) val bht_update = Valid(new BHTUpdate) val ras_update = Valid(new RASUpdate) @@ -348,9 +349,11 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) // supply guest physical address to commit stage val gpa_valid = Reg(Bool()) val gpa = Reg(UInt(vaddrBitsExtended.W)) + val gpa_is_pte = Reg(Bool()) when (fq.io.enq.fire && s2_tlb_resp.gf.inst) { when (!gpa_valid) { gpa := s2_tlb_resp.gpa + gpa_is_pte := s2_tlb_resp.gpa_is_pte } gpa_valid := true.B } @@ -359,6 +362,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) } io.cpu.gpa.valid := gpa_valid io.cpu.gpa.bits := gpa + io.cpu.gpa_is_pte := gpa_is_pte // performance events io.cpu.perf.acquire := icache.io.perf.acquire diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index 65f8c73234a..20052b375f6 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -712,7 +712,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val tval_valid = wb_xcpt && (tval_any_addr || tval_inst) csr.io.gva := wb_xcpt && (tval_any_addr && csr.io.status.v || tval_dmem_addr && wb_reg_hls_or_dv) csr.io.tval := Mux(tval_valid, encodeVirtualAddress(wb_reg_wdata, wb_reg_wdata), 0.U) - csr.io.htval := { + val (htval, mhtinst_read_pseudo) = { val htval_valid_imem = wb_reg_xcpt && wb_reg_cause === Causes.fetch_guest_page_fault.U val htval_imem = Mux(htval_valid_imem, io.imem.gpa.bits, 0.U) assert(!htval_valid_imem || io.imem.gpa.valid) @@ -720,8 +720,13 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val htval_valid_dmem = wb_xcpt && tval_dmem_addr && io.dmem.s2_xcpt.gf.asUInt.orR && !io.dmem.s2_xcpt.pf.asUInt.orR val htval_dmem = Mux(htval_valid_dmem, io.dmem.s2_gpa, 0.U) - (htval_dmem | htval_imem) >> hypervisorExtraAddrBits + val htval = (htval_dmem | htval_imem) >> hypervisorExtraAddrBits + // read pseudoinstruction if a guest-page fault is caused by an implicit memory access for VS-stage address translation + val mhtinst_read_pseudo = (io.imem.gpa_is_pte && htval_valid_imem) || (io.dmem.s2_gpa_is_pte && htval_valid_dmem) + (htval, mhtinst_read_pseudo) } + csr.io.htval := htval + csr.io.mhtinst_read_pseudo := mhtinst_read_pseudo io.ptw.ptbr := csr.io.ptbr io.ptw.hgatp := csr.io.hgatp io.ptw.vsatp := csr.io.vsatp