1
0

WIP on priv-1.10

This commit is contained in:
Andrew Waterman
2017-02-27 14:27:19 -08:00
parent 43dea38ee9
commit db0a02b78e
8 changed files with 101 additions and 111 deletions

View File

@ -40,8 +40,7 @@ class DatapathPTWIO(implicit p: Parameters) extends CoreBundle()(p) {
}
class PTE(implicit p: Parameters) extends CoreBundle()(p) {
val reserved_for_hardware = Bits(width = 16)
val ppn = UInt(width = 38)
val ppn = UInt(width = 54)
val reserved_for_software = Bits(width = 2)
val d = Bool()
val a = Bool()
@ -53,19 +52,13 @@ class PTE(implicit p: Parameters) extends CoreBundle()(p) {
val v = Bool()
def table(dummy: Int = 0) = v && !r && !w && !x
def leaf(dummy: Int = 0) = v && (r || (x && !w))
def leaf(dummy: Int = 0) = v && (r || (x && !w)) && a
def ur(dummy: Int = 0) = sr() && u
def uw(dummy: Int = 0) = sw() && u
def ux(dummy: Int = 0) = sx() && u
def sr(dummy: Int = 0) = leaf() && r
def sw(dummy: Int = 0) = leaf() && w
def sw(dummy: Int = 0) = leaf() && w && d
def sx(dummy: Int = 0) = leaf() && x
def access_ok(req: PTWReq) = {
val perm_ok = Mux(req.fetch, x, Mux(req.store, w, r || (x && req.mxr)))
val priv_ok = Mux(u, !req.pum, req.prv(0))
leaf() && priv_ok && perm_ok
}
}
class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
@ -77,10 +70,11 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
require(usingAtomics, "PTW requires atomic memory operations")
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 s_ready :: s_req :: s_wait1 :: s_wait2 :: Nil = Enum(UInt(), 4)
val state = Reg(init=s_ready)
val count = Reg(UInt(width = log2Up(pgLevels)))
val s1_kill = Reg(next = Bool(false))
val resp_valid = Reg(next = Bool(false))
val r_req = Reg(new PTWReq)
val r_req_dest = Reg(Bits())
@ -128,23 +122,18 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
(hit && count < pgLevels-1, Mux1H(hits, data))
}
val pte_wdata = Wire(init=new PTE().fromBits(0))
pte_wdata.a := true
pte_wdata.d := r_req.store
io.mem.req.valid := state.isOneOf(s_req, s_set_dirty)
io.mem.req.valid := state === s_req
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 := M_XRD
io.mem.req.bits.typ := log2Ceil(xLen/8)
io.mem.req.bits.addr := pte_addr
io.mem.s1_data := pte_wdata.asUInt
io.mem.s1_kill := s1_kill
io.mem.invalidate_lr := Bool(false)
val resp_ppns = (0 until pgLevels-1).map(i => Cat(pte_addr >> (pgIdxBits + pgLevelBits*(pgLevels-i-1)), r_req.addr(pgLevelBits*(pgLevels-i-1)-1,0))) :+ (pte_addr >> pgIdxBits)
for (i <- 0 until io.requestor.size) {
io.requestor(i).resp.valid := state === s_done && (r_req_dest === i)
io.requestor(i).resp.valid := resp_valid && (r_req_dest === i)
io.requestor(i).resp.bits.pte := r_pte
io.requestor(i).resp.bits.pte.ppn := resp_ppns(count)
io.requestor(i).ptbr := io.dpath.ptbr
@ -174,7 +163,8 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
state := s_wait2
when (io.mem.xcpt.pf.ld) {
r_pte.v := false
state := s_done
state := s_ready
resp_valid := true
}
}
is (s_wait2) {
@ -182,41 +172,16 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
state := s_req
}
when (io.mem.resp.valid) {
state := s_done
when (pte.access_ok(r_req) && (!pte.a || (r_req.store && !pte.d))) {
state := s_set_dirty
}.otherwise {
r_pte := pte
}
r_pte := pte
when (pte.table() && count < pgLevels-1) {
state := s_req
count := count + 1
}.otherwise {
state := s_ready
resp_valid := true
}
}
}
is (s_set_dirty) {
when (io.mem.req.ready) {
state := s_wait1_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) {
state := s_set_dirty
}
when (io.mem.resp.valid) {
state := s_req
}
}
is (s_done) {
state := s_ready
}
}
}