1
0

[rocket] Respect physical memory protection during page table walks

This commit is contained in:
Andrew Waterman 2016-08-02 14:51:11 -07:00
parent 5d4f6383f2
commit 76f33d88a6

View File

@ -73,7 +73,7 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
require(usingAtomics, "PTW requires atomic memory operations") require(usingAtomics, "PTW requires atomic memory operations")
val s_ready :: s_req :: s_wait :: s_set_dirty :: s_wait_dirty :: s_done :: Nil = Enum(UInt(), 6) val s_ready :: s_req :: s_wait1 :: s_wait2 :: s_set_dirty :: s_wait1_dirty :: s_wait2_dirty :: s_done :: Nil = Enum(UInt(), 8)
val state = Reg(init=s_ready) val state = Reg(init=s_ready)
val count = Reg(UInt(width = log2Up(pgLevels))) val count = Reg(UInt(width = log2Up(pgLevels)))
val s1_kill = Reg(next = Bool(false)) val s1_kill = Reg(next = Bool(false))
@ -96,7 +96,7 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
when ((tmp.ppn >> ppnBits) =/= 0) { res.v := false } when ((tmp.ppn >> ppnBits) =/= 0) { res.v := false }
res res
} }
val pte_addr = Cat(r_pte.ppn, vpn_idx) << log2Up(xLen/8) val pte_addr = Cat(r_pte.ppn, vpn_idx) << log2Ceil(xLen/8)
when (arb.io.out.fire()) { when (arb.io.out.fire()) {
r_req := arb.io.out.bits r_req := arb.io.out.bits
@ -132,7 +132,7 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
io.mem.req.valid := state === s_req || state === s_set_dirty io.mem.req.valid := state === s_req || state === s_set_dirty
io.mem.req.bits.phys := Bool(true) io.mem.req.bits.phys := Bool(true)
io.mem.req.bits.cmd := Mux(state === s_set_dirty, M_XA_OR, M_XRD) io.mem.req.bits.cmd := Mux(state === s_set_dirty, M_XA_OR, M_XRD)
io.mem.req.bits.typ := MT_D io.mem.req.bits.typ := log2Ceil(xLen/8)
io.mem.req.bits.addr := pte_addr io.mem.req.bits.addr := pte_addr
io.mem.s1_data := pte_wdata.asUInt io.mem.s1_data := pte_wdata.asUInt
io.mem.s1_kill := s1_kill io.mem.s1_kill := s1_kill
@ -163,10 +163,17 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
count := count + 1 count := count + 1
r_pte.ppn := pte_cache_data r_pte.ppn := pte_cache_data
}.elsewhen (io.mem.req.ready) { }.elsewhen (io.mem.req.ready) {
state := s_wait state := s_wait1
} }
} }
is (s_wait) { is (s_wait1) {
state := s_wait2
when (io.mem.xcpt.pf.ld) {
r_pte.v := false
state := s_done
}
}
is (s_wait2) {
when (io.mem.s2_nack) { when (io.mem.s2_nack) {
state := s_req state := s_req
} }
@ -185,10 +192,17 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
} }
is (s_set_dirty) { is (s_set_dirty) {
when (io.mem.req.ready) { when (io.mem.req.ready) {
state := s_wait_dirty state := s_wait1_dirty
} }
} }
is (s_wait_dirty) { is (s_wait1_dirty) {
state := s_wait2_dirty
when (io.mem.xcpt.pf.st) {
r_pte.v := false
state := s_done
}
}
is (s_wait2_dirty) {
when (io.mem.s2_nack) { when (io.mem.s2_nack) {
state := s_set_dirty state := s_set_dirty
} }