CHAPTER 05
5. Linux enumeration과 BAR sizing을 함수 경계로 따라간다
pci_host_probe() 이후 PCI core는 Vendor ID를 읽어 pci_dev를 만들고 header/capability/BAR를 조사하며 bridge를 재귀적으로 scan합니다. BAR size probe와 resource assignment는 driver probe보다 앞에서 일어나므로 'driver가 BAR 주소를 정한다'고 쓰면 안 됩니다.
Linux PCI scan의 핵심 함수 흐름
| 순서 | 함수/단계 | 입력 | 출력/소유권 | 실패 증상 |
|---|---|---|---|---|
| 1 | pci_host_probe | host bridge/windows/ops | root bus scan 시작 | root bus 생성 실패 |
| 2 | pci_scan_root_bus_bridge | root bus number/resources | struct pci_bus | window/resource 불일치 |
| 3 | pci_scan_child_bus | bus | 발견한 max bus | bridge 뒤 topology 누락 |
| 4 | pci_scan_slot | device number | function scan | multifunction/ARI 누락 |
| 5 | pci_scan_device | bus/devfn | 임시 pci_dev | Vendor ID 0xffff |
| 6 | pci_setup_device | config header | class/header/resource 정보 | unknown header/class |
| 7 | pci_read_bases | BAR registers | resource size/flags | BAR size/type 오류 |
| 8 | pci_scan_bridge | Type-1 bridge | secondary bus tree | bus number/CFG1 실패 |
| 9 | resource assignment | host/bridge windows | BAR assigned address | no space/collision |
| 10 | pci_bus_add_devices | configured pci_dev | driver core 등록 | driver match/probe 안 됨 |
BAR bit와 sizing 해석
| 항목 | 32-bit Memory BAR | 64-bit Memory BAR | I/O BAR | 주의점 |
|---|---|---|---|---|
| type bit | bit0=0 | bit0=0, type bits=10b | bit0=1 | raw low bits는 address가 아님 |
| prefetchable | bit3 | bit3 | 해당 없음 | CPU cacheable 의미와 다름 |
| address mask | ~0xf | low ~0xf + upper dword | ~0x3 | type bit 제거 후 계산 |
| size probe | all ones write/read | low/high를 한 resource로 | all ones write/read | decode 끄고 원값 복원 |
| size 식 | ~mask + 1 | 64bit mask에 적용 | ~mask + 1 | 0 또는 미구현 BAR 처리 |
| alignment | size와 동일 | size와 동일 | size와 동일 | bridge/host window도 포함해야 함 |
resource window의 포함 관계
| 레벨 | 예 | 반드시 포함해야 하는 것 | 검증 위치 |
|---|---|---|---|
| Host MEM window | CPU PA↔PCI MEM | 모든 downstream non-prefetchable BAR | DT ranges/_CRS, root bus resource |
| Host PREF window | 64-bit prefetchable | prefetchable BAR와 child bridge window | root resource tree |
| Bridge MEM window | bus 1 bridge | 그 bridge 아래 non-pref BAR | Type-1 header 0x20.. |
| Bridge PREF window | bus 1 bridge | 그 아래 prefetchable BAR | Type-1 header 0x24.. |
| Endpoint BAR | 03:00.0 BAR0 | device register aperture | sysfs resource/lspci |
| DWC outbound iATU | CPU aperture→PCI window | host resource가 실제 transaction으로 변환되는 범위 | iATU raw dump |
실제 검증 절차
| 순서 | 실행 | 남길 증거 | 판정 목적 |
|---|---|---|---|
| 1 | `lspci -tv`와 모든 bridge의 Primary/Secondary/Subordinate를 저장합니다. | tree와 bus number가 일치 | CFG1 routing 전제 확인 |
| 2 | 각 BAR의 raw 값, size, flags, assigned bus address와 CPU resource를 한 행에 둡니다. | 64-bit BAR pair와 window 포함 관계 | BAR 종류/주소 혼동 방지 |
| 3 | host/bridge/DWC iATU window를 interval로 그려 겹침과 누락을 검사합니다. | parent가 child 전체를 포함 | 일부 offset만 실패하는 문제 탐지 |
| 4 | driver bind 전 `resource`와 bind 후 request owner를 비교합니다. | PCI core 할당과 driver 소유 전환 | driver가 주소를 할당했다는 오해 제거 |
주의BAR에 all-ones를 쓰는 size probe는 PCI core가 decode와 동시 접근을 제어하는 문맥에서 수행합니다. 실행 중인 device에 devmem으로 그대로 따라 하면 안 됩니다.
공개적으로 다시 확인할 수 있는 자료
공개되지 않은 제조사 레지스터나 제품별 오프셋은 추측하지 않았습니다. 아래의 제조사 자료, 아키텍처 문서, 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 연결
FPGA 엔드포인트: 열거 성공 다음에 확인할 경계
FPGA의 PCIe 하드 IP가 링크와 Configuration 요청을 처리해도 사용자 레지스터나 DMA 작업까지 저절로 완성되는 것은 아닙니다. AMD PG213 v1.3의 PIO 예제는 CPU가 먼저 보내는 MMIO 요청을 사용자 메모리와 연결합니다. 쓰기는 선택한 대상 값을 갱신하고 읽기는 요청에 맞는 Completion with Data를 돌려줍니다. 이 PIO 예제를 자체 DMA 엔진의 검증 결과로 읽지 않습니다.
| 경계 | 확인할 사실 | 아직 증명되지 않은 것 |
|---|---|---|
| Configuration·BAR | ID, BAR 크기·유형과 할당 주소 | 사용자 레지스터 동작, DMA 데이터 정확성 |
| PIO·사용자 로직 | BAR 선택·offset·byte enable과 레지스터/메모리 대응, 읽기 응답 | 호스트 메모리 접근과 장시간 전송 |
| DMA·드라이버 | DMA API가 반환한 주소, 길이, descriptor, 완료와 소유권 전환 | 모든 reset·오류·동시성 상황의 복구 |
PG195 v4.2의 DMA/Bridge Subsystem은 descriptor로 H2C/C2H 전송을 지정하고 상태·오류를 알리는 별도 구성입니다. 레지스터용 AXI4-Lite 접근과 데이터 전송 인터페이스도 구분합니다. 사용한 IP 이름·버전·구성을 먼저 적고, PG213의 스트림 인터페이스나 오래된 TRN 예제의 신호를 다른 DMA IP에 그대로 옮기지 않습니다.
요청 추적 책임도 설정에 따라 다릅니다. PG213의 Non-Posted tag 관리에서 내부 관리 모드는 할당된 tag를 사용자 로직에 전달합니다. 외부 관리 모드는 사용자 로직이 진행 중인 요청과 충돌하지 않는 tag와 자원 한도를 관리해야 합니다. 내부 모드라도 사용자 작업과 돌아온 응답을 연결할 정보는 보존해야 합니다.
Root Port 모델과 PIO 예제로 요청·응답부터 검증한 뒤, 실제 장치에서는 제조사가 안전한 시험 대상으로 정의한 레지스터·버퍼만 사용합니다. 읽으면 지워지는 상태나 제어 레지스터를 임의 패턴 시험에 쓰지 않습니다. 작은 DMA의 주소·방향·길이·완료를 확인하고, reset 시 진행 중인 요청을 드라이버와 로직이 어떻게 종료하는지 별도로 시험합니다. 이 절은 설계 경계를 정리한 것으로 실제 FPGA·드라이버를 실행하지 않았으며, 과거 발표의 처리량이나 응답 시간을 현재 제품의 성능으로 전재하지 않았습니다.
English summary. Enumeration, PIO register behavior and descriptor-driven DMA are separate validation stages. Track address ownership and outstanding requests according to the actual IP configuration. A working BAR or PIO example does not establish DMA correctness or reset recovery.