В обычном PCI (про экспресс пока не в курсе) BAR регистры бриджа программируются так,
чтобы они покрывали адресные пространства всех устройств на другой стороне бриджа.
Для иллюстрации, если устройства X,Y,Z на вторичной шине живут по адресам 0x80000000, 0x80100000 и 0x80200000 и каждое требует 1М адресного пространства, то бридж должен быть сконфигурурован так, чтобы отвечал не запросы до адресам всех устройств на вторичной шине. В данном случае 0x80000000..0x802fffff.
Код
[host]
|
-----------------
|
[B]
|
-----------------
| | |
[X] [Y] [Z]
Это все можно представить так, что для всех устройств по одну сторону бриджа бридж выглядит как одно устройства. Если кто-нибудь к нему обращается, то бридж начинает соответствующую транзакцию на другой стороне. Соответственно, чтобы с одной стороны запросы могли добраться до всех устройств на другой стороне, бридж должен отвечать на запросы с адресами любого из устройств на вторичной шине.
Эта процедура применяется ко всем типам адресов - I/O, prefetchable и non-prefetchable memory.
Если интересны детали, можете заглянуть в исходники NetBSD - там все довольно наглядно.
http://cvsweb.netbsd.org/bsdweb.cgi/src/sy...x-cvsweb-markup