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:
parent
45e152e97e
commit
8cff45f254
@ -11,16 +11,13 @@ class TLEdgeOut(
|
|||||||
{
|
{
|
||||||
// Transfers
|
// Transfers
|
||||||
def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = {
|
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 legal = manager.supportsAcquire(toAddress, lgSize)
|
||||||
val a = new TLBundleA(bundle)
|
val a = new TLBundleA(bundle)
|
||||||
a.opcode := TLMessages.Acquire
|
a.opcode := TLMessages.Acquire
|
||||||
a.param := growPermissions
|
a.param := growPermissions
|
||||||
a.size := lgSize
|
a.size := lgSize
|
||||||
a.source := fromSource
|
a.source := fromSource
|
||||||
a.address := toAddress >> log2Up(manager.beatBytes)
|
a.address := toAddress
|
||||||
a.wmask := SInt(-1).asUInt
|
a.wmask := SInt(-1).asUInt
|
||||||
a.data := UInt(0)
|
a.data := UInt(0)
|
||||||
(legal, a)
|
(legal, a)
|
||||||
@ -33,7 +30,7 @@ class TLEdgeOut(
|
|||||||
c.param := shrinkPermissions
|
c.param := shrinkPermissions
|
||||||
c.size := lgSize
|
c.size := lgSize
|
||||||
c.source := fromSource
|
c.source := fromSource
|
||||||
c.address := toAddress >> log2Up(manager.beatBytes)
|
c.address := toAddress
|
||||||
c.data := UInt(0)
|
c.data := UInt(0)
|
||||||
c.error := Bool(false)
|
c.error := Bool(false)
|
||||||
(legal, c)
|
(legal, c)
|
||||||
@ -46,7 +43,7 @@ class TLEdgeOut(
|
|||||||
c.param := shrinkPermissions
|
c.param := shrinkPermissions
|
||||||
c.size := lgSize
|
c.size := lgSize
|
||||||
c.source := fromSource
|
c.source := fromSource
|
||||||
c.address := toAddress >> log2Up(manager.beatBytes)
|
c.address := toAddress
|
||||||
c.data := data
|
c.data := data
|
||||||
c.error := Bool(false)
|
c.error := Bool(false)
|
||||||
(legal, c)
|
(legal, c)
|
||||||
@ -58,7 +55,7 @@ class TLEdgeOut(
|
|||||||
c.param := reportPermissions
|
c.param := reportPermissions
|
||||||
c.size := lgSize
|
c.size := lgSize
|
||||||
c.source := UInt(0)
|
c.source := UInt(0)
|
||||||
c.address := toAddress >> log2Up(manager.beatBytes)
|
c.address := toAddress
|
||||||
c.data := UInt(0)
|
c.data := UInt(0)
|
||||||
c.error := Bool(false)
|
c.error := Bool(false)
|
||||||
c
|
c
|
||||||
@ -70,7 +67,7 @@ class TLEdgeOut(
|
|||||||
c.param := reportPermissions
|
c.param := reportPermissions
|
||||||
c.size := lgSize
|
c.size := lgSize
|
||||||
c.source := UInt(0)
|
c.source := UInt(0)
|
||||||
c.address := toAddress >> log2Up(manager.beatBytes)
|
c.address := toAddress
|
||||||
c.data := data
|
c.data := data
|
||||||
c.error := Bool(false)
|
c.error := Bool(false)
|
||||||
c
|
c
|
||||||
@ -90,7 +87,7 @@ class TLEdgeOut(
|
|||||||
a.param := UInt(0)
|
a.param := UInt(0)
|
||||||
a.size := lgSize
|
a.size := lgSize
|
||||||
a.source := fromSource
|
a.source := fromSource
|
||||||
a.address := toAddress >> log2Up(manager.beatBytes)
|
a.address := toAddress
|
||||||
a.wmask := fullMask(toAddress, lgSize)
|
a.wmask := fullMask(toAddress, lgSize)
|
||||||
a.data := UInt(0)
|
a.data := UInt(0)
|
||||||
(legal, a)
|
(legal, a)
|
||||||
@ -103,21 +100,20 @@ class TLEdgeOut(
|
|||||||
a.param := UInt(0)
|
a.param := UInt(0)
|
||||||
a.size := lgSize
|
a.size := lgSize
|
||||||
a.source := fromSource
|
a.source := fromSource
|
||||||
a.address := toAddress >> log2Up(manager.beatBytes)
|
a.address := toAddress
|
||||||
a.wmask := fullMask(toAddress, lgSize)
|
a.wmask := fullMask(toAddress, lgSize)
|
||||||
a.data := data
|
a.data := data
|
||||||
(legal, a)
|
(legal, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
def Put(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt, wmask: UInt) = {
|
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 legal = manager.supportsPutPartial(toAddress, lgSize)
|
||||||
val a = new TLBundleA(bundle)
|
val a = new TLBundleA(bundle)
|
||||||
a.opcode := TLMessages.PutPartialData
|
a.opcode := TLMessages.PutPartialData
|
||||||
a.param := UInt(0)
|
a.param := UInt(0)
|
||||||
a.size := lgSize
|
a.size := lgSize
|
||||||
a.source := fromSource
|
a.source := fromSource
|
||||||
a.address := toAddress >> log2Up(manager.beatBytes)
|
a.address := toAddress
|
||||||
a.wmask := wmask
|
a.wmask := wmask
|
||||||
a.data := data
|
a.data := data
|
||||||
(legal, a)
|
(legal, a)
|
||||||
@ -130,7 +126,7 @@ class TLEdgeOut(
|
|||||||
a.param := atomic
|
a.param := atomic
|
||||||
a.size := lgSize
|
a.size := lgSize
|
||||||
a.source := fromSource
|
a.source := fromSource
|
||||||
a.address := toAddress >> log2Up(manager.beatBytes)
|
a.address := toAddress
|
||||||
a.wmask := fullMask(toAddress, lgSize)
|
a.wmask := fullMask(toAddress, lgSize)
|
||||||
a.data := data
|
a.data := data
|
||||||
(legal, a)
|
(legal, a)
|
||||||
@ -143,7 +139,7 @@ class TLEdgeOut(
|
|||||||
a.param := atomic
|
a.param := atomic
|
||||||
a.size := lgSize
|
a.size := lgSize
|
||||||
a.source := fromSource
|
a.source := fromSource
|
||||||
a.address := toAddress >> log2Up(manager.beatBytes)
|
a.address := toAddress
|
||||||
a.wmask := fullMask(toAddress, lgSize)
|
a.wmask := fullMask(toAddress, lgSize)
|
||||||
a.data := data
|
a.data := data
|
||||||
(legal, a)
|
(legal, a)
|
||||||
@ -156,7 +152,7 @@ class TLEdgeOut(
|
|||||||
a.param := param
|
a.param := param
|
||||||
a.size := lgSize
|
a.size := lgSize
|
||||||
a.source := fromSource
|
a.source := fromSource
|
||||||
a.address := toAddress >> log2Up(manager.beatBytes)
|
a.address := toAddress
|
||||||
a.wmask := fullMask(toAddress, lgSize)
|
a.wmask := fullMask(toAddress, lgSize)
|
||||||
a.data := UInt(0)
|
a.data := UInt(0)
|
||||||
(legal, a)
|
(legal, a)
|
||||||
@ -168,7 +164,7 @@ class TLEdgeOut(
|
|||||||
c.param := UInt(0)
|
c.param := UInt(0)
|
||||||
c.size := lgSize
|
c.size := lgSize
|
||||||
c.source := UInt(0)
|
c.source := UInt(0)
|
||||||
c.address := toAddress >> log2Up(manager.beatBytes)
|
c.address := toAddress
|
||||||
c.data := UInt(0)
|
c.data := UInt(0)
|
||||||
c.error := error
|
c.error := error
|
||||||
c
|
c
|
||||||
@ -180,7 +176,7 @@ class TLEdgeOut(
|
|||||||
c.param := UInt(0)
|
c.param := UInt(0)
|
||||||
c.size := lgSize
|
c.size := lgSize
|
||||||
c.source := UInt(0)
|
c.source := UInt(0)
|
||||||
c.address := toAddress >> log2Up(manager.beatBytes)
|
c.address := toAddress
|
||||||
c.data := data
|
c.data := data
|
||||||
c.error := Bool(false)
|
c.error := Bool(false)
|
||||||
c
|
c
|
||||||
@ -200,7 +196,7 @@ class TLEdgeIn(
|
|||||||
b.param := capPermissions
|
b.param := capPermissions
|
||||||
b.size := lgSize
|
b.size := lgSize
|
||||||
b.source := toSource
|
b.source := toSource
|
||||||
b.address := fromAddress >> log2Up(manager.beatBytes)
|
b.address := fromAddress
|
||||||
b.wmask := fullMask(fromAddress, lgSize)
|
b.wmask := fullMask(fromAddress, lgSize)
|
||||||
b.data := UInt(0)
|
b.data := UInt(0)
|
||||||
(legal, b)
|
(legal, b)
|
||||||
@ -250,7 +246,7 @@ class TLEdgeIn(
|
|||||||
b.param := UInt(0)
|
b.param := UInt(0)
|
||||||
b.size := lgSize
|
b.size := lgSize
|
||||||
b.source := toSource
|
b.source := toSource
|
||||||
b.address := fromAddress >> log2Up(manager.beatBytes)
|
b.address := fromAddress
|
||||||
b.wmask := fullMask(fromAddress, lgSize)
|
b.wmask := fullMask(fromAddress, lgSize)
|
||||||
b.data := UInt(0)
|
b.data := UInt(0)
|
||||||
(legal, b)
|
(legal, b)
|
||||||
@ -263,7 +259,7 @@ class TLEdgeIn(
|
|||||||
b.param := UInt(0)
|
b.param := UInt(0)
|
||||||
b.size := lgSize
|
b.size := lgSize
|
||||||
b.source := toSource
|
b.source := toSource
|
||||||
b.address := fromAddress >> log2Up(manager.beatBytes)
|
b.address := fromAddress
|
||||||
b.wmask := fullMask(fromAddress, lgSize)
|
b.wmask := fullMask(fromAddress, lgSize)
|
||||||
b.data := data
|
b.data := data
|
||||||
(legal, b)
|
(legal, b)
|
||||||
@ -276,7 +272,7 @@ class TLEdgeIn(
|
|||||||
b.param := UInt(0)
|
b.param := UInt(0)
|
||||||
b.size := lgSize
|
b.size := lgSize
|
||||||
b.source := toSource
|
b.source := toSource
|
||||||
b.address := fromAddress >> log2Up(manager.beatBytes)
|
b.address := fromAddress
|
||||||
b.wmask := wmask
|
b.wmask := wmask
|
||||||
b.data := data
|
b.data := data
|
||||||
(legal, b)
|
(legal, b)
|
||||||
@ -289,7 +285,7 @@ class TLEdgeIn(
|
|||||||
b.param := atomic
|
b.param := atomic
|
||||||
b.size := lgSize
|
b.size := lgSize
|
||||||
b.source := toSource
|
b.source := toSource
|
||||||
b.address := fromAddress >> log2Up(manager.beatBytes)
|
b.address := fromAddress
|
||||||
b.wmask := fullMask(fromAddress, lgSize)
|
b.wmask := fullMask(fromAddress, lgSize)
|
||||||
b.data := data
|
b.data := data
|
||||||
(legal, b)
|
(legal, b)
|
||||||
@ -302,7 +298,7 @@ class TLEdgeIn(
|
|||||||
b.param := atomic
|
b.param := atomic
|
||||||
b.size := lgSize
|
b.size := lgSize
|
||||||
b.source := toSource
|
b.source := toSource
|
||||||
b.address := fromAddress >> log2Up(manager.beatBytes)
|
b.address := fromAddress
|
||||||
b.wmask := fullMask(fromAddress, lgSize)
|
b.wmask := fullMask(fromAddress, lgSize)
|
||||||
b.data := data
|
b.data := data
|
||||||
(legal, b)
|
(legal, b)
|
||||||
@ -315,13 +311,12 @@ class TLEdgeIn(
|
|||||||
b.param := param
|
b.param := param
|
||||||
b.size := lgSize
|
b.size := lgSize
|
||||||
b.source := toSource
|
b.source := toSource
|
||||||
b.address := fromAddress >> log2Up(manager.beatBytes)
|
b.address := fromAddress
|
||||||
b.wmask := fullMask(fromAddress, lgSize)
|
b.wmask := fullMask(fromAddress, lgSize)
|
||||||
b.data := UInt(0)
|
b.data := UInt(0)
|
||||||
(legal, b)
|
(legal, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def AccessAck(toSource: UInt, lgSize: UInt, error: Bool = Bool(false)) = {
|
def AccessAck(toSource: UInt, lgSize: UInt, error: Bool = Bool(false)) = {
|
||||||
val d = new TLBundleD(bundle)
|
val d = new TLBundleD(bundle)
|
||||||
d.opcode := TLMessages.AccessAck
|
d.opcode := TLMessages.AccessAck
|
||||||
|
@ -272,16 +272,39 @@ case class TLEdgeParameters(
|
|||||||
val maxTransfer = max(client.maxTransfer, manager.maxTransfer)
|
val maxTransfer = max(client.maxTransfer, manager.maxTransfer)
|
||||||
val maxLgSize = log2Up(maxTransfer)
|
val maxLgSize = log2Up(maxTransfer)
|
||||||
|
|
||||||
|
// Sanity check the link...
|
||||||
|
require (maxTransfer >= manager.beatBytes)
|
||||||
|
|
||||||
val bundle = TLBundleParameters(
|
val bundle = TLBundleParameters(
|
||||||
addressBits = log2Up(manager.maxAddress + 1) - log2Up(manager.beatBytes),
|
addressBits = log2Up(manager.maxAddress + 1),
|
||||||
dataBits = manager.beatBytes * 8,
|
dataBits = manager.beatBytes * 8,
|
||||||
sourceBits = log2Up(client.endSourceId),
|
sourceBits = log2Up(client.endSourceId),
|
||||||
sinkBits = log2Up(manager.endSinkId),
|
sinkBits = log2Up(manager.endSinkId),
|
||||||
sizeBits = log2Up(maxLgSize+1))
|
sizeBits = log2Up(maxLgSize+1))
|
||||||
|
|
||||||
def addressMask(lgSize: UInt) = Vec.tabulate(maxLgSize) { UInt(_) < lgSize } .toBits.asUInt
|
def isAligned(address: UInt, lgSize: UInt) =
|
||||||
def isAligned(address: UInt, lgSize: UInt) = (address & addressMask(lgSize)) === UInt(0)
|
if (maxLgSize == 0) Bool(true) else {
|
||||||
|
val mask = Vec.tabulate(maxLgSize) { UInt(_) < lgSize }
|
||||||
// !!! wrong:
|
address & mask.toBits.asUInt === UInt(0)
|
||||||
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user