tilelink2: use byte-aligned addressing
This makes it possible to fully validate user input in a monitor. We will override the lower bits with constant 0s in the TL connect.
This commit is contained in:
		@@ -11,16 +11,13 @@ class TLEdgeOut(
 | 
			
		||||
{
 | 
			
		||||
  // Transfers
 | 
			
		||||
  def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = {
 | 
			
		||||
    // !!! Monitor: lgSize >= beatBytes
 | 
			
		||||
    // !!! Monitor: check address alignment
 | 
			
		||||
    // !!! Monitor: check param values
 | 
			
		||||
    val legal = manager.supportsAcquire(toAddress, lgSize)
 | 
			
		||||
    val a = new TLBundleA(bundle)
 | 
			
		||||
    a.opcode  := TLMessages.Acquire
 | 
			
		||||
    a.param   := growPermissions
 | 
			
		||||
    a.size    := lgSize
 | 
			
		||||
    a.source  := fromSource
 | 
			
		||||
    a.address := toAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    a.address := toAddress
 | 
			
		||||
    a.wmask   := SInt(-1).asUInt
 | 
			
		||||
    a.data    := UInt(0)
 | 
			
		||||
    (legal, a)
 | 
			
		||||
@@ -33,7 +30,7 @@ class TLEdgeOut(
 | 
			
		||||
    c.param   := shrinkPermissions
 | 
			
		||||
    c.size    := lgSize
 | 
			
		||||
    c.source  := fromSource
 | 
			
		||||
    c.address := toAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    c.address := toAddress
 | 
			
		||||
    c.data    := UInt(0)
 | 
			
		||||
    c.error   := Bool(false)
 | 
			
		||||
    (legal, c)
 | 
			
		||||
@@ -46,7 +43,7 @@ class TLEdgeOut(
 | 
			
		||||
    c.param   := shrinkPermissions
 | 
			
		||||
    c.size    := lgSize
 | 
			
		||||
    c.source  := fromSource
 | 
			
		||||
    c.address := toAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    c.address := toAddress
 | 
			
		||||
    c.data    := data
 | 
			
		||||
    c.error   := Bool(false)
 | 
			
		||||
    (legal, c)
 | 
			
		||||
@@ -58,7 +55,7 @@ class TLEdgeOut(
 | 
			
		||||
    c.param   := reportPermissions
 | 
			
		||||
    c.size    := lgSize
 | 
			
		||||
    c.source  := UInt(0)
 | 
			
		||||
    c.address := toAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    c.address := toAddress
 | 
			
		||||
    c.data    := UInt(0)
 | 
			
		||||
    c.error   := Bool(false)
 | 
			
		||||
    c
 | 
			
		||||
@@ -70,7 +67,7 @@ class TLEdgeOut(
 | 
			
		||||
    c.param   := reportPermissions
 | 
			
		||||
    c.size    := lgSize
 | 
			
		||||
    c.source  := UInt(0)
 | 
			
		||||
    c.address := toAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    c.address := toAddress
 | 
			
		||||
    c.data    := data
 | 
			
		||||
    c.error   := Bool(false)
 | 
			
		||||
    c
 | 
			
		||||
@@ -90,7 +87,7 @@ class TLEdgeOut(
 | 
			
		||||
    a.param   := UInt(0)
 | 
			
		||||
    a.size    := lgSize
 | 
			
		||||
    a.source  := fromSource
 | 
			
		||||
    a.address := toAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    a.address := toAddress
 | 
			
		||||
    a.wmask   := fullMask(toAddress, lgSize)
 | 
			
		||||
    a.data    := UInt(0)
 | 
			
		||||
    (legal, a)
 | 
			
		||||
@@ -103,21 +100,20 @@ class TLEdgeOut(
 | 
			
		||||
    a.param   := UInt(0)
 | 
			
		||||
    a.size    := lgSize
 | 
			
		||||
    a.source  := fromSource
 | 
			
		||||
    a.address := toAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    a.address := toAddress
 | 
			
		||||
    a.wmask   := fullMask(toAddress, lgSize)
 | 
			
		||||
    a.data    := data
 | 
			
		||||
    (legal, a)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  def Put(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt, wmask: UInt) = {
 | 
			
		||||
    // !!! Monitor: check that wmask is contained in lgSize
 | 
			
		||||
    val legal = manager.supportsPutPartial(toAddress, lgSize)
 | 
			
		||||
    val a = new TLBundleA(bundle)
 | 
			
		||||
    a.opcode  := TLMessages.PutPartialData
 | 
			
		||||
    a.param   := UInt(0)
 | 
			
		||||
    a.size    := lgSize
 | 
			
		||||
    a.source  := fromSource
 | 
			
		||||
    a.address := toAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    a.address := toAddress
 | 
			
		||||
    a.wmask   := wmask
 | 
			
		||||
    a.data    := data
 | 
			
		||||
    (legal, a)
 | 
			
		||||
@@ -130,7 +126,7 @@ class TLEdgeOut(
 | 
			
		||||
    a.param   := atomic
 | 
			
		||||
    a.size    := lgSize
 | 
			
		||||
    a.source  := fromSource
 | 
			
		||||
    a.address := toAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    a.address := toAddress
 | 
			
		||||
    a.wmask   := fullMask(toAddress, lgSize)
 | 
			
		||||
    a.data    := data
 | 
			
		||||
    (legal, a)
 | 
			
		||||
@@ -143,7 +139,7 @@ class TLEdgeOut(
 | 
			
		||||
    a.param   := atomic
 | 
			
		||||
    a.size    := lgSize
 | 
			
		||||
    a.source  := fromSource
 | 
			
		||||
    a.address := toAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    a.address := toAddress
 | 
			
		||||
    a.wmask   := fullMask(toAddress, lgSize)
 | 
			
		||||
    a.data    := data
 | 
			
		||||
    (legal, a)
 | 
			
		||||
@@ -156,7 +152,7 @@ class TLEdgeOut(
 | 
			
		||||
    a.param   := param
 | 
			
		||||
    a.size    := lgSize
 | 
			
		||||
    a.source  := fromSource
 | 
			
		||||
    a.address := toAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    a.address := toAddress
 | 
			
		||||
    a.wmask   := fullMask(toAddress, lgSize)
 | 
			
		||||
    a.data    := UInt(0)
 | 
			
		||||
    (legal, a)
 | 
			
		||||
@@ -168,7 +164,7 @@ class TLEdgeOut(
 | 
			
		||||
    c.param   := UInt(0)
 | 
			
		||||
    c.size    := lgSize
 | 
			
		||||
    c.source  := UInt(0)
 | 
			
		||||
    c.address := toAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    c.address := toAddress
 | 
			
		||||
    c.data    := UInt(0)
 | 
			
		||||
    c.error   := error
 | 
			
		||||
    c
 | 
			
		||||
@@ -180,7 +176,7 @@ class TLEdgeOut(
 | 
			
		||||
    c.param   := UInt(0)
 | 
			
		||||
    c.size    := lgSize
 | 
			
		||||
    c.source  := UInt(0)
 | 
			
		||||
    c.address := toAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    c.address := toAddress
 | 
			
		||||
    c.data    := data
 | 
			
		||||
    c.error   := Bool(false)
 | 
			
		||||
    c
 | 
			
		||||
@@ -200,7 +196,7 @@ class TLEdgeIn(
 | 
			
		||||
    b.param   := capPermissions
 | 
			
		||||
    b.size    := lgSize
 | 
			
		||||
    b.source  := toSource
 | 
			
		||||
    b.address := fromAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    b.address := fromAddress
 | 
			
		||||
    b.wmask   := fullMask(fromAddress, lgSize)
 | 
			
		||||
    b.data    := UInt(0)
 | 
			
		||||
    (legal, b)
 | 
			
		||||
@@ -250,7 +246,7 @@ class TLEdgeIn(
 | 
			
		||||
    b.param   := UInt(0)
 | 
			
		||||
    b.size    := lgSize
 | 
			
		||||
    b.source  := toSource
 | 
			
		||||
    b.address := fromAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    b.address := fromAddress
 | 
			
		||||
    b.wmask   := fullMask(fromAddress, lgSize)
 | 
			
		||||
    b.data    := UInt(0)
 | 
			
		||||
    (legal, b)
 | 
			
		||||
@@ -263,7 +259,7 @@ class TLEdgeIn(
 | 
			
		||||
    b.param   := UInt(0)
 | 
			
		||||
    b.size    := lgSize
 | 
			
		||||
    b.source  := toSource
 | 
			
		||||
    b.address := fromAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    b.address := fromAddress
 | 
			
		||||
    b.wmask   := fullMask(fromAddress, lgSize)
 | 
			
		||||
    b.data    := data
 | 
			
		||||
    (legal, b)
 | 
			
		||||
@@ -276,7 +272,7 @@ class TLEdgeIn(
 | 
			
		||||
    b.param   := UInt(0)
 | 
			
		||||
    b.size    := lgSize
 | 
			
		||||
    b.source  := toSource
 | 
			
		||||
    b.address := fromAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    b.address := fromAddress
 | 
			
		||||
    b.wmask   := wmask
 | 
			
		||||
    b.data    := data
 | 
			
		||||
    (legal, b)
 | 
			
		||||
@@ -289,7 +285,7 @@ class TLEdgeIn(
 | 
			
		||||
    b.param   := atomic
 | 
			
		||||
    b.size    := lgSize
 | 
			
		||||
    b.source  := toSource
 | 
			
		||||
    b.address := fromAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    b.address := fromAddress
 | 
			
		||||
    b.wmask   := fullMask(fromAddress, lgSize)
 | 
			
		||||
    b.data    := data
 | 
			
		||||
    (legal, b)
 | 
			
		||||
@@ -302,7 +298,7 @@ class TLEdgeIn(
 | 
			
		||||
    b.param   := atomic
 | 
			
		||||
    b.size    := lgSize
 | 
			
		||||
    b.source  := toSource
 | 
			
		||||
    b.address := fromAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    b.address := fromAddress
 | 
			
		||||
    b.wmask   := fullMask(fromAddress, lgSize)
 | 
			
		||||
    b.data    := data
 | 
			
		||||
    (legal, b)
 | 
			
		||||
@@ -315,13 +311,12 @@ class TLEdgeIn(
 | 
			
		||||
    b.param   := param
 | 
			
		||||
    b.size    := lgSize
 | 
			
		||||
    b.source  := toSource
 | 
			
		||||
    b.address := fromAddress >> log2Up(manager.beatBytes)
 | 
			
		||||
    b.address := fromAddress
 | 
			
		||||
    b.wmask   := fullMask(fromAddress, lgSize)
 | 
			
		||||
    b.data    := UInt(0)
 | 
			
		||||
    (legal, b)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  def AccessAck(toSource: UInt, lgSize: UInt, error: Bool = Bool(false)) = {
 | 
			
		||||
    val d = new TLBundleD(bundle)
 | 
			
		||||
    d.opcode := TLMessages.AccessAck
 | 
			
		||||
 
 | 
			
		||||
@@ -272,16 +272,39 @@ case class TLEdgeParameters(
 | 
			
		||||
  val maxTransfer = max(client.maxTransfer, manager.maxTransfer)
 | 
			
		||||
  val maxLgSize = log2Up(maxTransfer)
 | 
			
		||||
 | 
			
		||||
  // Sanity check the link...
 | 
			
		||||
  require (maxTransfer >= manager.beatBytes)
 | 
			
		||||
 | 
			
		||||
  val bundle = TLBundleParameters(
 | 
			
		||||
    addressBits = log2Up(manager.maxAddress + 1) - log2Up(manager.beatBytes),
 | 
			
		||||
    addressBits = log2Up(manager.maxAddress + 1),
 | 
			
		||||
    dataBits    = manager.beatBytes * 8,
 | 
			
		||||
    sourceBits  = log2Up(client.endSourceId),
 | 
			
		||||
    sinkBits    = log2Up(manager.endSinkId),
 | 
			
		||||
    sizeBits    = log2Up(maxLgSize+1))
 | 
			
		||||
 | 
			
		||||
  def addressMask(lgSize: UInt) = Vec.tabulate(maxLgSize) { UInt(_) < lgSize } .toBits.asUInt
 | 
			
		||||
  def isAligned(address: UInt, lgSize: UInt) = (address & addressMask(lgSize)) === UInt(0)
 | 
			
		||||
  def isAligned(address: UInt, lgSize: UInt) =
 | 
			
		||||
    if (maxLgSize == 0) Bool(true) else {
 | 
			
		||||
      val mask = Vec.tabulate(maxLgSize) { UInt(_) < lgSize }
 | 
			
		||||
      address & mask.toBits.asUInt === UInt(0)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// !!! wrong:
 | 
			
		||||
  def fullMask(address: UInt, lgSize: UInt) = UInt(0)
 | 
			
		||||
  // This gets used everywhere, so make the smallest circuit possible ...
 | 
			
		||||
  def fullMask(address: UInt, lgSize: UInt) = {
 | 
			
		||||
    val lgBytes = log2Ceil(manager.beatBytes)
 | 
			
		||||
    def helper(i: Int): Seq[(Bool, Bool)] = {
 | 
			
		||||
      if (i == 0) {
 | 
			
		||||
        Seq((lgSize >= UInt(lgBytes), Bool(true)))
 | 
			
		||||
      } else {
 | 
			
		||||
        val sub = helper(i-1)
 | 
			
		||||
        val size = lgSize === UInt(lgBytes - i)
 | 
			
		||||
        Seq.tabulate (1 << i) { j =>
 | 
			
		||||
          val (sub_acc, sub_eq) = sub(j/2)
 | 
			
		||||
          val eq = sub_eq && address(lgBytes - i) === Bool(j % 2 == 1)
 | 
			
		||||
          val acc = sub_acc || (size && eq)
 | 
			
		||||
          (acc, eq)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    Vec(helper(lgBytes).map(_._1)).toBits.asUInt
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user