Skip to content

Commit

Permalink
feat(MMIOBridge): support Svpbmt on CHI MemAttr (OpenXiangShan#273)
Browse files Browse the repository at this point in the history
### NOTICE
**DO NOT** set **```bufferableNC = true```** when **```needRR = false```**, since the ordering between NC and IO described in SvPBMT was maintained by ```fence iorw, iorw```. And alias with NC and IO must not cause loss of coherency due to SvPBMT, which was NOT guaranteed by CHI specification in which case obtaining different EWA from different agents.
1) For Memory backend, the observability of possible weakly-ordered intermediate states were determined
by the core (the processor pipeline, store buffer, etc.) because there is no ordering guarantee from HN.
2) For Device backend, the observability of possible weakly-ordered intermediate states were determined by the HN (Home Node) on bus with Endpoint Ordering.

### Ordering and MemAttr
> MM = Main Memory, NC = Non-cacheable, IO = Device I/O

- When ```bufferableNC``` configured to **```false```**
  
  | PMA | PBMT | Memory Type |
  |---|---|---|
  | MM | NC | Non-cacheable Non-bufferable
  | MM | IO | Non-cacheable Non-bufferable
  | NC/IO | NC | Device nRnE (no reorder, no early acknowlegment)
  | NC/IO | IO | Device nRnE (no reorder, no early acknowlegment)
- when ```bufferableNC``` configured to **```true```**
  
  | PMA | PBMT | Memory Type |
  |---|---|---|
  | MM | NC | Non-cacheable Bufferable
  | MM | IO | Non-cacheable Bufferable
  | NC/IO | NC | Device nRE  (no reorder, early acknowlegment)
  | NC/IO | IO | Device nRnE (no reorder, no early acknowlegment)
  • Loading branch information
Kumonda221-CrO3 authored Dec 20, 2024
1 parent d7c6d45 commit ba3587e
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 4 deletions.
7 changes: 7 additions & 0 deletions src/main/scala/coupledL2/L2Param.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ case class L1Param
val needResolveAlias = aliasBitsOpt.nonEmpty
}

// Pass PMA and uncached memory attribute from PBMT to MMIOBridge
case object MemBackTypeMM extends ControlKey[Bool]("memBackType_MM")
case class MemBackTypeMMField() extends BundleField[Bool](MemBackTypeMM, Output(Bool()), _ := false.B)

case object MemPageTypeNC extends ControlKey[Bool]("memPageType_NC")
case class MemPageTypeNCField() extends BundleField[Bool](MemPageTypeNC, Output(Bool()), _ := false.B)

// Pass virtual address of upper level cache
case object VaddrKey extends ControlKey[UInt]("vaddr")
case class VaddrField(width: Int) extends BundleField[UInt](VaddrKey, Output(UInt(width.W)), _ := 0.U(width.W))
Expand Down
48 changes: 44 additions & 4 deletions src/main/scala/coupledL2/tl2chi/MMIOBridge.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.tilelink.TLMessages._
import coupledL2.HasCoupledL2Parameters
import coupledL2.{MemBackTypeMM, MemPageTypeNC}

class MMIOBridge()(implicit p: Parameters) extends LazyModule
with HasCoupledL2Parameters
Expand All @@ -49,7 +50,8 @@ class MMIOBridge()(implicit p: Parameters) extends LazyModule
supportsPutFull = TransferSizes(1, 8),
supportsPutPartial = TransferSizes(1, 8)
)),
beatBytes = 8
beatBytes = 8,
requestKeys = Seq(MemBackTypeMM, MemPageTypeNC)
)))

lazy val module = new MMIOBridgeImp(this)
Expand All @@ -59,7 +61,20 @@ class MMIOBridge()(implicit p: Parameters) extends LazyModule
class MMIOBridgeEntry(edge: TLEdgeIn)(implicit p: Parameters) extends TL2CHIL2Module with HasCHIOpcodes {

val needRR = true
val order = WireInit(if (needRR) OrderEncodings.EndpointOrder else OrderEncodings.None)

// *NOTICE: DO NOT set 'bufferableNC = true' when 'needRR = false',
// since the ordering between NC and IO described in SvPBMT was maintained by 'fence iorw, iorw'.
// And alias with NC and IO must not cause loss of coherency due to SvPBMT, which was NOT guaranteed
// by CHI specification in which case obtaining different EWA from different agents.
//
// 1) For Memory backend, the observability of possible weakly-ordered intermediate states were determined
// by the core (the processor pipeline, store buffer, etc.) because there is no ordering guarantee from HN.
//
// 2) For Device backend, the observability of possible weakly-ordered intermediate states were determined
// by the HN (Home Node) on bus with Endpoint Ordering.
val bufferableNC = true

require(!bufferableNC || needRR , "DO NOT set 'bufferableNC = true' when 'needRR = false'")

val io = IO(new Bundle() {
val req = Flipped(DecoupledIO(new TLBundleA(edge.bundle)))
Expand Down Expand Up @@ -95,6 +110,8 @@ class MMIOBridgeEntry(edge: TLEdgeIn)(implicit p: Parameters) extends TL2CHIL2Mo
val corrupt = Reg(Bool())
val traceTag = Reg(Bool())
val isRead = req.opcode === Get
val isBackTypeMM = req.user.lift(MemBackTypeMM).getOrElse(false.B)
val isPageTypeNC = req.user.lift(MemPageTypeNC).getOrElse(false.B)

val wordBits = io.req.bits.data.getWidth // 64
val wordBytes = wordBits / 8
Expand Down Expand Up @@ -197,10 +214,33 @@ class MMIOBridgeEntry(edge: TLEdgeIn)(implicit p: Parameters) extends TL2CHIL2Mo
txreq.bits.size := req.size
txreq.bits.addr := req.address
txreq.bits.allowRetry := allowRetry
txreq.bits.order := order
txreq.bits.pCrdType := Mux(allowRetry, 0.U, pCrdType)
txreq.bits.memAttr := MemAttr(allocate = false.B, cacheable = false.B, device = true.B, ewa = false.B)
txreq.bits.expCompAck := false.B
// *Ordering and MemAttr:
// ---------------------------------------------------------
// [when 'bufferableNC' configured to false]
// PMA = MM , PBMT = NC -> Non-cacheable Non-bufferable
// PMA = MM , PBMT = IO -> Non-cacheable Non-bufferable
// PMA = NC/IO, PBMT = NC -> Device nRnE (no reorder, no early acknowlegment)
// PMA = NC/IO, PBMT = IO -> Device nRnE (no reorder, no early acknowlegment)
// ---------------------------------------------------------
// [when 'bufferableNC' configured to true]
// PMA = MM , PBMT = NC -> Non-cacheable Bufferable
// PMA = MM , PBMT = IO -> Non-cacheable Bufferable
// PMA = NC/IO, PBMT = NC -> Device nRE (no reorder, early acknowlegment)
// PMA = NC/IO, PBMT = IO -> Device nRnE (no reorder, no early acknowlegment)
txreq.bits.order := {
if (needRR)
Mux(!isBackTypeMM, OrderEncodings.EndpointOrder, OrderEncodings.RequestOrder)
else
OrderEncodings.None
}
txreq.bits.memAttr := MemAttr(
allocate = false.B,
cacheable = false.B,
device = !isBackTypeMM,
ewa = if (bufferableNC) (isPageTypeNC || isBackTypeMM) else false.B
)

io.resp.valid := !s_resp && Mux(isRead, w_compdata, w_comp && w_dbidresp && s_ncbwrdata)
io.resp.bits.opcode := Mux(isRead, AccessAckData, AccessAck)
Expand Down

0 comments on commit ba3587e

Please # to comment.