CHAPTER 02
2. dw_pcie_setup_rc()가 DBI에 쓰는 값을 순서대로 해석한다
Root Port setup은 class code 하나를 쓰는 함수가 아닙니다. DBI read-only override를 열고 공통 link 설정, MSI, RC BAR, bus number, Command, equalization preset, iATU를 programming한 뒤 class와 speed change를 설정하고 override를 닫습니다.
dw_pcie_setup_rc()의 실제 순서
| 순서 | 코드 동작 | register/field | 의도 | 검증값 |
|---|---|---|---|---|
| 1 | DBI RO write enable | 0x8bc bit 0 | RO field 초기화 허용 | 함수 끝에서 반드시 clear |
| 2 | dw_pcie_setup | lane/speed/link capability | 공통 DWC 설정 | DT lane/speed와 DBI 일치 |
| 3 | dw_pcie_msi_init | MSI addr/mask/enable | 내부 MSI block 초기화 | 외부 MSI domain일 때 경로 확인 |
| 4 | RC BAR0/1 임시 설정 | BAR0=0x4, BAR1=0 | 64-bit BAR 형식 초기화 | 뒤에서 BAR0=0으로 정리 |
| 5 | Interrupt Pin 설정 | PCI_INTERRUPT_LINE dword | INTA pin 정보 | legacy IRQ 사용 여부와 분리 |
| 6 | bus number 초기값 | Primary=0 Secondary=1 Subordinate=255 | 초기 downstream scan 허용 | scan 후 bridge bus number와 비교 |
| 7 | Command enable | IO/MEM/MASTER/SERR | Root Port decode와 master 허용 | endpoint Command와 혼동 금지 |
| 8 | unsupported L1SS 숨김 | capability 조정 | 미지원 power state 노출 방지 | 실제 PHY/clock capability 대조 |
| 9 | equalization preset | Link EQ control registers | 지원 rate/lane preset programming | Gen3/4/5/6 target별 값 |
| 10 | iATU setup | CFG/MEM/IO windows | CPU↔PCI translation | child_ops가 generic DWC일 때만 |
| 11 | RC BAR0 clear | BAR0=0 | Root Port BAR 정리 | resource scan 전에 값 확인 |
| 12 | class code | PCI_CLASS_DEVICE=PCI bridge | PCI core에 Root Port type 제시 | 0604 class |
| 13 | speed change | 0x80c bit 17 | target speed retrain 요청 | Recovery와 current speed |
| 14 | DBI RO write disable | 0x8bc bit 0 clear | runtime 보호 복구 | 성공/오류 경로 모두 확인 |
DBI write override를 점검할 이유
| 상황 | 위험 | 관찰 증상 | 수정 원칙 |
|---|---|---|---|
| override를 열지 않음 | RO field write 무시 | class/bus/link capability가 reset value | 초기화 범위에서만 enable |
| 너무 일찍 닫음 | 뒤쪽 preset/class write 무시 | Gen speed 또는 class만 틀림 | 마지막 RO write 뒤 close |
| 닫지 않음 | runtime에서 보호 field 변경 가능 | 우발 write가 topology를 깨뜨림 | 함수 exit 전에 반드시 disable |
| 오류 경로에서 return | override가 열린 채 남음 | 다음 probe 결과가 비결정적 | goto cleanup 또는 finally 성격 경로 |
| DBI와 DBI2 혼동 | 다른 shadow/BAR bank write | readback은 되지만 실제 header 불변 | accessor와 aperture 확인 |
실제 검증 절차
| 순서 | 실행 | 남길 증거 | 판정 목적 |
|---|---|---|---|
| 1 | setup 전후 DBI Type-1 header와 PCIe Capability를 dump합니다. | 의도한 field만 변경 | reset value와 programming diff 확보 |
| 2 | 0x8bc bit 0을 함수 진입/탈출에서 trace합니다. | 탈출 뒤 0 | RO protection lifetime 검증 |
| 3 | Primary/Secondary/Subordinate와 Linux가 만든 root bus 번호를 비교합니다. | scan 시점에 routing 가능한 범위 | CFG1 실패를 bus-number 문제와 연결 |
| 4 | Link Capability/Control/Status와 Port Logic target을 한 표로 저장합니다. | capability≥target≥current 관계 | 속도 policy와 협상 결과 분리 |
주의Root Port Command의 BUS_MASTER enable은 endpoint driver가 DMA를 시작했다는 뜻이 아닙니다. endpoint의 PCI_COMMAND_MASTER와 queue programming은 별도 수명입니다.
공개적으로 다시 확인할 수 있는 자료
공개되지 않은 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 연결