Prior to this PR, the error device was allowed to be cached by
multiple actors despite never probing any of them. This is a
pretty unusual set of properties that has caused us trouble
several times now in the past.
Let's instead put the Error device into one of two very well
established categories: a straight-up MMIO device or a tracked
memory region.
This removes the mostly obsolete 'numIn/Out' range restrictions on nodes.
It also makes it possible to connect optional crossbars that disappear.
val x = TLXbar()
x := master
slave := x
val y = TLXbar()
x :=* y // only connect y if it gets used
This will create crossbar x, but crossbar y will disappear.
...instead of on the master side of the system bus.
People inheriting from HasTileMasterPort might need to add
`masterNode := tileBus.node` to their Tile child class.
When switching ports, the bypass stalls new messages until all
outstanding messages have received their responses. However, this
stall must NOT stop the remaining beats of a partially sent request.
* CacheCork: an error Grant still says 'toT' even though it is transient
Grants with errors must be handled by a client as though no actual
permissions were obtained, so that two clients do not both end up believing
that they own a block which is only temporarily offline. However, the
Grant MESSAGE should still match the request; ie. if you did Acquire.NtoT,
the response must be Grant.toT, even though the 'error' bit signals that
the Grant actually grants no permissions.
This keeps the implementation of request-response tracking in interstitial
adapters and FSMs simple, consistent with the way multibeat errors must
include all their beats.
* Error: handle permissions properly