CHAPTER 03
3. ECAM, CFG0와 CFG1을 BDF 계산부터 추적한다
Configuration access는 CPU load/store처럼 보이지만 DWC가 Type 0 또는 Type 1 Configuration Request TLP로 바꿉니다. root bus는 DBI, 바로 아래 bus는 CFG0, 그 뒤 bus는 CFG1이라는 경계를 지키지 않으면 link가 L0여도 Vendor ID가 0xffff로 보입니다.
ECAM 식
일반적인 ECAM offset은 (bus << 20) | (device << 15) | (function << 12) | register입니다. bus당 1MiB, function당 4KiB입니다.
256MiB alignment
DWC가 8bit bus field 전체를 ECAM으로 노출하는 경우 256 buses × 1MiB이므로 base alignment와 aperture size를 확인합니다. Linux host driver도 ECAM 가능 여부를 검증합니다.
Root bus DBI
Root Port 자체 config는 DBI aperture에서 읽습니다. downstream config iATU를 거치지 않습니다.
CFG0
Root Port의 immediate secondary bus에 있는 endpoint/function을 Type 0 request로 접근합니다.
CFG1
PCIe-to-PCIe bridge 뒤의 bus는 Type 1 request로 bridge가 downstream routing하도록 합니다.
Config Shift mode
DWC ECAM mode에서는 CPU config aperture address의 BDF field를 TLP BDF로 옮기는 shift mode를 사용할 수 있습니다. REGION_CTRL2의 해당 enable과 window 범위를 확인합니다.
BDF와 ECAM offset 계산 예
| 대상 | BDF | 계산 | ECAM offset | DWC 경로 |
|---|---|---|---|---|
| Root Port | 00:00.0 | root DBI | DBI + reg | iATU 없음 |
| 직결 endpoint | 01:00.0 | (1<<20)+(0<<15)+(0<<12) | 0x00100000 + reg | CFG0 |
| 직결 multi-function | 01:00.3 | (1<<20)+(3<<12) | 0x00103000 + reg | CFG0 |
| bus 2 device 5 | 02:05.0 | (2<<20)+(5<<15) | 0x00228000 + reg | CFG1 |
| bus 7 device 31 fn7 | 07:1f.7 | (7<<20)+(31<<15)+(7<<12) | 0x007ff000 + reg | CFG1 |
Configuration Request가 실패할 때 구분
| 관측 | Link | iATU | Analyzer/AER | 우선 원인 |
|---|---|---|---|---|
| root DBI도 0xffffffff | 무관 | 무관 | TLP 없음 | DBI clock/reset/base |
| bus 1만 실패 | L0 | CFG0 확인 | CfgRd0 없음 | CFG0 aperture/shift/BDF |
| bus 1 성공, bus 2+ 실패 | L0 | CFG1 확인 | CfgRd1 없음/UR | bridge bus number/CFG1 |
| CfgRd TLP는 나가나 Cpl 없음 | L0 | 대체로 통과 | Completion Timeout | endpoint/route/bus number |
| CplD는 오나 CPU 0xffff | L0 | completion path | analyzer 정상 | AXI return/error/accessor |
| 특정 function만 실패 | L0 | BDF target | UR 또는 no response | multifunction/ARI/function presence |
ECAM window 검증 항목
| 항목 | Linux/DWC 조건 | 잘못되면 보이는 증상 |
|---|---|---|
| base alignment | bus bits 수에 맞는 정렬 | ECAM mode 비활성 또는 BDF alias |
| window size | bus-range를 모두 포함 | 높은 bus만 접근 실패 |
| bus-range | firmware resource와 실제 topology | subordinate bus scan 중단 |
| CFG0 1MiB | immediate bus 32×8×4KiB | bus 1 BDF 일부 alias |
| CFG1 remainder | 2번 이후 bus 공간 | bridge 뒤만 0xffff |
| region index | 다른 MEM/IO region과 충돌 없음 | config 후 BAR window가 사라짐 |
| shift mode | CPU aperture BDF field 사용 | target BDF가 00:00.0 등에 고정 |
실제 검증 절차
| 순서 | 실행 | 남길 증거 | 판정 목적 |
|---|---|---|---|
| 1 | 접근할 BDF와 register로 ECAM offset을 손으로 한 번 계산합니다. | driver가 사용한 VA/PA와 동일 | BDF bit 배치 오류 배제 |
| 2 | root bus, bus 1, bus 2의 Vendor ID read를 각각 trace합니다. | DBI/CFG0/CFG1 세 경로 분리 | 실패 경계 정확히 지정 |
| 3 | 각 access 직전 iATU region type/base/limit/target/ctrl2를 저장합니다. | BDF와 type이 access에 맞게 변경 | stale region/reprogram race 확인 |
| 4 | protocol analyzer가 있으면 request type, BDF, tag와 completion status를 기록합니다. | software BDF와 TLP header 일치 | controller 앞/뒤 경계 확정 |
주의0xffff는 '장치 없음'을 표현할 때 흔히 보이는 값일 뿐입니다. Completion Timeout, UR, AXI error가 Linux config accessor에서 같은 값으로 정리될 수 있으므로 AER와 TLP evidence를 함께 봅니다.
공개적으로 다시 확인할 수 있는 자료
공개되지 않은 vendor register나 integration별 offset을 추측해서 채우지 않았습니다. 아래 제조사 자료, architecture 문서와 Linux v6.18.37 원본에서 다시 확인할 수 있는 범위만 사용했습니다.
Linux v6.18.37 DWC common source
iATU programming, version/capability와 eDMA detection
Linux v6.18.37 DWC host source
ECAM/CFG access, Root Port setup, MSI irqdomain와 host lifecycle
Linux v6.18.37 PCI probe
Vendor ID read, pci_dev 생성, BAR sizing와 bridge scan
Linux v6.18.37 PCI resource assignment
bridge window와 endpoint BAR resource 배치
Linux DWC Devicetree binding
reg/ranges, iATU window 수, lane/speed와 MSI/IOMMU 연결