Skip to content

Commit

Permalink
Priv 1.12: PTW page fault instead of access exception if PTE reserved…
Browse files Browse the repository at this point in the history
… bit set

PTE.reserved_for_future

TLBEntryData.pf ptw_pf_array
  • Loading branch information
ingallsj committed Dec 27, 2021
1 parent 185cac8 commit 8a7824e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
26 changes: 17 additions & 9 deletions src/main/scala/rocket/PTW.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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()
Expand All @@ -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
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)))))))
Expand All @@ -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) {
Expand All @@ -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())
}
}
}
Expand All @@ -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")
Expand Down
19 changes: 11 additions & 8 deletions src/main/scala/rocket/TLB.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 8a7824e

Please sign in to comment.