AXI Traffic Filter
The AXI traffic filter (axi_filter_wrap) is the common address and
attribute filter used on the inbound and outbound AXI paths of both SEP
and SMC. This section describes the decode algorithm, which is identical
in every instance; the subsystem chapters describe where each instance
sits in their fabric and how firmware is expected to program it.
A filter holds a configurable number of independent entries. Each entry
is one filter_ctrl register triple — FILTER_CONFIG, START_ADDR,
END_ADDR — and every entry is evaluated against every transaction.
1. Instances
Table 1 compares the filter dimensions, unmatched-traffic behavior, and bypass controls.
| Instance | Entries | Address | Data bus | Unmatched traffic | Bypass |
|---|---|---|---|---|---|
SEP inbound |
16 |
56-bit |
64-bit |
Blocked |
While SEP-scope debug is enabled |
SEP outbound |
32 |
56-bit |
64-bit |
Blocked |
None |
SMC inbound |
16 |
56-bit |
64-bit |
Blocked |
None |
SMC outbound |
16 |
56-bit |
64-bit |
Permitted |
None |
NS and source ID matching are enabled on all four instances. Group ID
matching is disabled at build time on all four, so the group_id field
has no effect.
2. Match, Then Permit
Decode is two distinct steps, and the difference between them governs what happens when entries overlap.
First, every entry is evaluated in parallel to produce a match. An entry matches only when all of the following hold:
-
entry_enabledis 1. A disabled entry never matches. -
The transaction address falls inside the entry’s address range, after the granule widening described below.
-
prot[1]equalsallow_ns. This is an equality test, not a permission grant: an entry withallow_ns = 0matches secure transactions only, and an entry withallow_ns = 1matches non-secure transactions only. -
The transaction’s source ID equals
src_id, orsrc_idis 0, which is a wildcard matching any source ID. -
allow_burstis 1, or the transaction is a single beat (AxLEN= 0).
Second, the lowest-numbered matching entry wins, and only that entry’s
permission bit is consulted: read_allowed for AR, write_allowed for
AW. If the bit is clear, the transaction is blocked. If no entry matches
at all, the outcome is the instance’s unmatched-traffic policy from the
Table 1.
The two steps therefore fail differently:
-
A transaction that fails a match condition on an entry falls through to the remaining entries, and a higher-numbered entry can still admit it. A non-secure transaction, a burst, or a foreign source ID is not denied by an entry that rejects it; it simply does not select that entry.
-
A transaction that matches the lowest-numbered entry but finds its permission bit clear is blocked outright. Higher-numbered entries are never examined, even if one of them would have permitted the access.
Entry index is thus a strict priority and the first match ends the search, so a specific policy takes effect only at a lower index than any broader policy that overlaps it.
Writes and reads are decoded independently: the AW channel and the AR
channel each run the full decode against their own address, burst
length, prot[1] and source ID, so a write and a read to the same
address may select different entries.
3. Address Range Granule
Address comparison ignores the low address bits, so a filter range
always covers a whole number of granules. allow_burst selects the
granule:
-
allow_burst = 1: the granule is 4 KB and address bits [11:0] are ignored. -
allow_burst = 0: the granule is the data bus width — 8 bytes on every instance in the Table 1 — and address bits [2:0] are ignored.
START_ADDR consequently widens down to the base of its granule and
END_ADDR widens up to the top of its granule, so a range is never
narrower than one granule. Programming START_ADDR equal to END_ADDR,
or any range shorter than the granule, still admits the whole granule,
and a range that straddles a granule boundary admits both granules.
Table 2 illustrates the address ranges admitted when burst filtering widens a programmed interval.
allow_burst |
START_ADDR |
END_ADDR |
Addresses admitted |
|---|---|---|---|
1 |
|
|
|
1 |
|
|
|
1 |
|
|
|
0 |
|
|
|
Hardware writes the widened values back into START_ADDR and END_ADDR
when both land in the same granule, so reading back the first example
above returns 0x1000 and 0x1FFF. When the programmed range spans more
than one granule the write-back does not fire and read-back returns the
programmed values unchanged, even though address matching still widens
them, so read-back is not the effective range.
Widening only ever enlarges a range, so a range programmed tighter than the granule opens more address space than the programmed numbers suggest. The Programmer’s Guide gives the filter programming rules.
4. Blocked Transactions
A blocked transaction is not dropped. It is steered to an AXI error
subordinate that terminates it with a DECERR response on BRESP or
RRESP, so the initiator always receives a response.
5. Locking a Filter Entry
Setting FILTER_CONFIG.locked freezes a filter entry. The bit is
write-once (woset): once set it cannot be cleared. While it is set,
every write to that entry’s FILTER_CONFIG, START_ADDR and END_ADDR
registers is steered to the same AXI error subordinate as a blocked
transaction and terminates with a DECERR response; reads still return
the locked configuration. This holds for the SMC and SEP filter
instances alike.