diff --git a/src/main/scala/rocket/PTW.scala b/src/main/scala/rocket/PTW.scala index a97f1b102f2..b1816106db9 100644 --- a/src/main/scala/rocket/PTW.scala +++ b/src/main/scala/rocket/PTW.scala @@ -27,6 +27,7 @@ class PTWReq(implicit p: Parameters) extends CoreBundle()(p) { class PTWResp(implicit p: Parameters) extends CoreBundle()(p) { val ae_ptw = Bool() val ae_final = Bool() + val pf = Bool() val gf = Bool() val hr = Bool() val hw = Bool() @@ -75,7 +76,8 @@ class DatapathPTWIO(implicit p: Parameters) extends CoreBundle()(p) } class PTE(implicit p: Parameters) extends CoreBundle()(p) { - val ppn = UInt(width = 54) + val reserved_for_future = UInt(width = 10) + val ppn = UInt(width = 44) val reserved_for_software = Bits(width = 2) val d = Bool() val a = Bool() @@ -86,7 +88,7 @@ class PTE(implicit p: Parameters) extends CoreBundle()(p) { val r = Bool() val v = Bool() - def table(dummy: Int = 0) = v && !r && !w && !x && !d && !a && !u + def table(dummy: Int = 0) = v && !r && !w && !x && !d && !a && !u && reserved_for_future === 0 def leaf(dummy: Int = 0) = v && (r || (x && !w)) && a def ur(dummy: Int = 0) = sr() && u def uw(dummy: Int = 0) = sw() && u @@ -144,6 +146,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( val count = Reg(UInt(width = log2Ceil(pgLevels))) val resp_ae_ptw = Reg(Bool()) val resp_ae_final = Reg(Bool()) + val resp_pf = Reg(Bool()) val resp_gf = Reg(Bool()) val resp_hr = Reg(Bool()) val resp_hw = Reg(Bool()) @@ -385,6 +388,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( io.requestor(i).resp.valid := resp_valid(i) io.requestor(i).resp.bits.ae_ptw := resp_ae_ptw io.requestor(i).resp.bits.ae_final := resp_ae_final + io.requestor(i).resp.bits.pf := resp_pf io.requestor(i).resp.bits.gf := resp_gf io.requestor(i).resp.bits.hr := resp_hr io.requestor(i).resp.bits.hw := resp_hw @@ -428,6 +432,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( aux_pte.ppn := Mux(arb.io.out.bits.bits.vstage1, io.dpath.vsatp.ppn, arb.io.out.bits.bits.addr) resp_ae_ptw := false resp_ae_final := false + resp_pf := false resp_gf := false resp_hr := true resp_hw := true @@ -492,7 +497,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( Mux(l2_hit && !l2_error, l2_pte, Mux(state === s_req && !stage2_pte_cache_hit && pte_cache_hit, makePTE(pte_cache_data, l2_pte), Mux(do_switch, makeHypervisorRootPTE(r_hgatp, pte.ppn, r_pte), - Mux(mem_resp_valid, Mux(!traverse && (r_req.vstage1 && stage2), merged_pte, pte), + Mux(mem_resp_valid, Mux(!traverse && r_req.vstage1 && stage2, merged_pte, pte), Mux(state === s_fragment_superpage && !homogeneous, makePTE(makeFragmentedSuperpagePPN(r_pte.ppn)(count), r_pte), Mux(arb.io.out.fire(), Mux(arb.io.out.bits.bits.stage2, makeHypervisorRootPTE(io.dpath.hgatp, io.dpath.vsatp.ppn, r_pte), makePTE(satp.ppn, r_pte)), r_pte))))))) @@ -512,7 +517,8 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( }.otherwise { val gf = stage2 && !stage2_final && !pte.ur() val ae = pte.v && invalid_paddr - val success = pte.v && !ae && !gf + val pf = pte.v && pte.reserved_for_future =/= 0 + val success = pte.v && !ae && !pf && !gf when (do_both_stages && !stage2_final && success) { when (stage2) { @@ -536,10 +542,11 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( } resp_ae_final := ae - resp_gf := gf - resp_hr := !stage2 || !gf && pte.ur() - resp_hw := !stage2 || !gf && pte.uw() - resp_hx := !stage2 || !gf && pte.ux() + resp_pf := pf && !stage2 + resp_gf := gf || (pf && stage2) + resp_hr := !stage2 || (!pf && !gf && pte.ur()) + resp_hw := !stage2 || (!pf && !gf && pte.uw()) + resp_hx := !stage2 || (!pf && !gf && pte.ux()) } } } @@ -560,8 +567,9 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( for (i <- 0 until pgLevels) { val leaf = mem_resp_valid && !traverse && count === i - ccover(leaf && pte.v && !invalid_paddr, s"L$i", s"successful page-table access, level $i") + ccover(leaf && pte.v && !invalid_paddr && pte.reserved_for_future === 0, s"L$i", s"successful page-table access, level $i") ccover(leaf && pte.v && invalid_paddr, s"L${i}_BAD_PPN_MSB", s"PPN too large, level $i") + ccover(leaf && pte.v && pte.reserved_for_future =/= 0, s"L${i}_BAD_RSV_MSB", s"reserved MSBs set, level $i") ccover(leaf && !mem_resp_data(0), s"L${i}_INVALID_PTE", s"page not present, level $i") if (i != pgLevels-1) ccover(leaf && !pte.v && mem_resp_data(0), s"L${i}_BAD_PPN_LSB", s"PPN LSBs not zero, level $i") diff --git a/src/main/scala/rocket/TLB.scala b/src/main/scala/rocket/TLB.scala index f7d51023628..86d67aa35a8 100644 --- a/src/main/scala/rocket/TLB.scala +++ b/src/main/scala/rocket/TLB.scala @@ -70,6 +70,7 @@ class TLBEntryData(implicit p: Parameters) extends CoreBundle()(p) { val g = Bool() val ae_ptw = Bool() val ae_final = Bool() + val pf = Bool() val gf = Bool() val sw = Bool() val sx = Bool() @@ -267,6 +268,7 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T newEntry.g := pte.g && pte.v newEntry.ae_ptw := io.ptw.resp.bits.ae_ptw newEntry.ae_final := io.ptw.resp.bits.ae_final + newEntry.pf := io.ptw.resp.bits.pf newEntry.gf := io.ptw.resp.bits.gf newEntry.hr := io.ptw.resp.bits.hr newEntry.hw := io.ptw.resp.bits.hw @@ -313,6 +315,7 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T val nPhysicalEntries = 1 + special_entry.size val ptw_ae_array = Cat(false.B, entries.map(_.ae_ptw).asUInt) val final_ae_array = Cat(false.B, entries.map(_.ae_final).asUInt) + val ptw_pf_array = Cat(false.B, entries.map(_.pf).asUInt) val ptw_gf_array = Cat(false.B, entries.map(_.gf).asUInt) val sum = Mux(priv_v, io.ptw.gstatus.sum, io.ptw.status.sum) val priv_rw_ok = Mux(!priv_s || sum, entries.map(_.u).asUInt, 0.U) | Mux(priv_s, ~entries.map(_.u).asUInt, 0.U) @@ -384,14 +387,14 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T Mux(cmd_amo_logical, ~paa_array, 0.U) | Mux(cmd_amo_arithmetic, ~pal_array, 0.U) | Mux(cmd_lrsc, ~0.U(pal_array.getWidth.W), 0.U) - val ma_ld_array = Mux(misaligned && cmd_read, ~eff_array & ~(ptw_ae_array | final_ae_array | ptw_gf_array), 0.U) - val ma_st_array = Mux(misaligned && cmd_write, ~eff_array & ~(ptw_ae_array | final_ae_array | ptw_gf_array), 0.U) - val pf_ld_array = Mux(cmd_read, ~(Mux(cmd_readx, x_array, r_array) | (ptw_ae_array | ptw_gf_array)), 0.U) - val pf_st_array = Mux(cmd_write_perms, ~(w_array | (ptw_ae_array | ptw_gf_array)), 0.U) - val pf_inst_array = ~(x_array | (ptw_ae_array | ptw_gf_array)) - val gf_ld_array = Mux(priv_v && cmd_read, ~(Mux(cmd_readx, hx_array, hr_array) | ptw_ae_array), 0.U) - val gf_st_array = Mux(priv_v && cmd_write_perms, ~(hw_array | ptw_ae_array), 0.U) - val gf_inst_array = Mux(priv_v, ~(hx_array | ptw_ae_array), 0.U) + val ma_ld_array = Mux(misaligned && cmd_read, ~eff_array & ~(ptw_ae_array | final_ae_array | ptw_pf_array | ptw_gf_array), 0.U) + val ma_st_array = Mux(misaligned && cmd_write, ~eff_array & ~(ptw_ae_array | final_ae_array | ptw_pf_array | ptw_gf_array), 0.U) + val pf_ld_array = Mux(cmd_read_perms, (~Mux(cmd_readx, x_array, r_array & ~ptw_ae_array) | ptw_pf_array) & ~ptw_gf_array, 0.U) + val pf_st_array = Mux(cmd_write_perms, ((~w_array & ~ptw_ae_array) | ptw_pf_array) & ~ptw_gf_array, 0.U) + val pf_inst_array = ((~x_array & ~ptw_ae_array) | ptw_pf_array) & ~ptw_gf_array + val gf_ld_array = Mux(priv_v && cmd_read_perms, ~Mux(cmd_readx, hx_array, hr_array) & ~ptw_ae_array, 0.U) + val gf_st_array = Mux(priv_v && cmd_write_perms, ~hw_array & ~ptw_ae_array, 0.U) + val gf_inst_array = Mux(priv_v, ~hx_array & ~ptw_ae_array, 0.U) val gpa_hits = { val need_gpa_mask = if (instruction) gf_inst_array else gf_ld_array | gf_st_array