[PCIe] Enumeration 완전 정리 | Configuration Space, BAR, Bus 번호 할당, Capability

2026. 6. 17. 22:23기초지식

반응형

PCIe Enumeration 개요

PCIe Enumeration은 시스템 부팅 시 BIOS/UEFI 또는 OS가 PCIe 토폴로지를 탐색하고, 각 디바이스에 Bus 번호를 부여하며, 메모리/IO 리소스를 할당하는 과정이다. PCI Configuration Space를 통해 이루어진다.

  • Depth-First Search(DFS) 방식으로 토폴로지 탐색
  • Bus 0부터 시작해서 Bridge 발견 시 새로운 Bus 번호 할당
  • BAR(Base Address Register)를 통해 디바이스 메모리 공간 매핑
  • Capability Pointer를 통해 지원 기능 탐색

PCI Configuration Space 구조

PCIe는 전통적인 PCI의 256바이트 Configuration Space를 4096바이트(4KB)로 확장한다. 앞 256바이트는 PCI 호환 영역, 나머지 3840바이트는 PCIe Extended Configuration Space이다.


PCI-Compatible Configuration Space (0x000 - 0x0FF):
  Offset 0x00: Vendor ID (16b) / Device ID (16b)
  Offset 0x04: Command (16b) / Status (16b)
  Offset 0x08: Revision ID (8b) / Class Code (24b)
  Offset 0x0C: Cache Line Size / Latency Timer / Header Type / BIST
  Offset 0x10 ~ 0x24: BAR 0~5 (Type 0) / BAR 0~1 + Bridge Registers (Type 1)
  Offset 0x28: Cardbus CIS Pointer (Type 0) / Secondary Latency Timer (Type 1)
  Offset 0x2C: Subsystem Vendor ID / Subsystem ID
  Offset 0x30: Expansion ROM Base Address
  Offset 0x34: Capabilities Pointer
  Offset 0x3C: Interrupt Line / Interrupt Pin / Min_Gnt / Max_Lat

PCIe Extended Configuration Space (0x100 - 0xFFF):
  0x100~: Extended Capabilities (AER, SR-IOV, LTR, etc.)

Header Type - Type 0 vs Type 1

Header Type 필드(offset 0x0E)로 디바이스 종류를 구분한다.

Type 0 Header - Endpoint Device

  • Header Type[6:0] = 0x00
  • BAR 0~5 최대 6개 사용 가능 (offset 0x10 ~ 0x24)
  • Subsystem Vendor ID / Subsystem ID 존재
  • 일반 디바이스(NIC, GPU, SSD 등)에 사용

Type 1 Header - Bridge Device

  • Header Type[6:0] = 0x01
  • BAR 0~1만 사용 (Bridge 자체 리소스)
  • Primary Bus Number / Secondary Bus Number / Subordinate Bus Number 존재
  • Memory Base / Memory Limit / Prefetchable Memory Base / Limit 존재
  • PCIe Switch의 Upstream/Downstream Port, Root Port에 사용

Multi-Function Device

  • Header Type[7] = 1이면 Multi-Function Device
  • 하나의 물리 디바이스가 Function 0~7까지 최대 8개 Function 지원
  • Function 0은 반드시 존재해야 함 (Enumeration 진입점)
  • 각 Function은 독립적인 Configuration Space를 가짐

BAR (Base Address Register)

BAR는 디바이스가 필요로 하는 메모리 또는 IO 주소 공간의 크기와 타입을 선언하고, OS가 실제 주소를 할당해주는 매커니즘이다.

BAR 타입 구분


BAR[0]: Memory Space Indicator
  0 = Memory Space BAR
  1 = I/O Space BAR

Memory Space BAR[2:1]: Type
  00 = 32-bit address space
  10 = 64-bit address space (BAR 두 개를 pair로 사용)
  01 = reserved

Memory Space BAR[3]: Prefetchable
  0 = Non-Prefetchable (Side Effect 있을 수 있음)
  1 = Prefetchable (캐싱, Burst Read 허용)

BAR 크기 탐색 방법


[BAR 크기 확인 절차]
1. 원래 BAR 값 저장 (saved_value = BAR)
2. BAR에 0xFFFFFFFF 쓰기
3. BAR 읽기 (size_mask = BAR)
4. 원래 BAR 값 복원
5. size_mask에서 타입 비트 마스킹 후 NOT 연산 + 1 = 크기

예: size_mask = 0xFFFF0000 (하위 16비트가 0)
  -> 크기 = ~(0xFFFF0000 & 0xFFFFFFF0) + 1
         = 0x0000FFFF + 1
         = 0x10000 = 64KB

64-bit BAR의 경우:
  - BAR[n]에 하위 32비트 기록
  - BAR[n+1]에 상위 32비트 기록
  - 두 BAR를 합쳐 64-bit 주소 공간 표현

BAR 주소 할당 규칙

  • BAR 크기에 맞게 Alignment 필수 - 64KB BAR는 64KB 경계에 할당
  • Prefetchable BAR는 가능한 Prefetchable Window에 배치
  • 64-bit BAR는 MMIO High 영역(4GB 이상)에 배치 가능
  • OS는 Resource Manager가 conflict 없이 할당 관리

Bus 번호 할당 - Depth-First Search

Enumeration은 DFS 방식으로 진행된다. Root Bus = 0부터 시작하여 Bridge를 발견할 때마다 새로운 Bus 번호를 부여한다.


[Enumeration 절차 예시]
초기 상태:
  Bus 0: Root Complex (Host Bridge)

Step 1: Bus 0 스캔
  - Device 0, Function 0: Root Port (Type 1 Header 발견)
  -> Secondary Bus = 1, Subordinate Bus = 임시 최대값(0xFF) 할당

Step 2: Bus 1 스캔 (DFS로 진입)
  - Device 0, Function 0: PCIe Switch Upstream Port (Type 1 Header 발견)
  -> Secondary Bus = 2, Subordinate Bus = 0xFF

Step 3: Bus 2 스캔
  - Device 2, Function 0: Switch Downstream Port A (Type 1 Header)
  -> Secondary Bus = 3, Subordinate Bus = 0xFF
  - Device 3, Function 0: Switch Downstream Port B (Type 1 Header)
  -> Secondary Bus = (4, later), Subordinate Bus = 0xFF

Step 4: Bus 3 스캔
  - Device 0: NVMe SSD (Type 0 Header = Endpoint)
  -> Bus 3의 마지막 디바이스 확정
  -> Downstream Port A의 Subordinate Bus = 3으로 갱신

Step 5: Bus 4 할당 후 스캔
  - Device 0: GPU (Type 0 Header = Endpoint)
  -> Downstream Port B의 Subordinate Bus = 4로 갱신

최종 결과:
  Root Port: Primary=0, Secondary=1, Subordinate=4
  SW Upstream: Primary=1, Secondary=2, Subordinate=4
  SW Downstream A: Primary=2, Secondary=3, Subordinate=3
  SW Downstream B: Primary=2, Secondary=4, Subordinate=4

Subordinate Bus Number의 역할

  • Bridge가 Routing 결정 시 사용 - Secondary <= TLP 목적지 Bus <= Subordinate이면 해당 Bridge 아래로 전달
  • Hot-plug 지원 시 미래 확장을 위해 Subordinate를 여유 있게 할당하기도 함

Capability Structure

PCIe 디바이스가 지원하는 선택적 기능을 Linked List 구조로 나열한 것이다. Capabilities Pointer(offset 0x34)에서 시작한다.

Capability 구조


각 Capability Entry:
  Byte 0: Capability ID
  Byte 1: Next Capability Pointer (0x00 = 마지막)
  Byte 2~: Capability-specific Registers

주요 Capability ID:
  0x01: Power Management Interface (PMI)
  0x04: Slot Identification
  0x05: MSI (Message Signaled Interrupt)
  0x10: PCI Express Capability (필수)
  0x11: MSI-X
  0x12: SATA HBA
  0x13: Advanced Features

PCI Express Capability (0x10) - 핵심 구조


Offset +0x00: Capability ID = 0x10
Offset +0x02: PCI Express Capabilities Register
  [3:0] Capability Version
  [7:4] Device/Port Type
        0000 = PCIe Endpoint
        0001 = Legacy PCIe Endpoint
        0100 = Root Port
        0101 = Upstream Port
        0110 = Downstream Port
        0111 = PCIe-to-PCI Bridge
        1001 = Root Complex Integrated Endpoint
Offset +0x04: Device Capabilities Register
Offset +0x08: Device Control Register
Offset +0x0A: Device Status Register
Offset +0x0C: Link Capabilities Register
  [3:0] Max Link Speed (1=2.5GT/s, 2=5GT/s, 3=8GT/s, 4=16GT/s, 5=32GT/s)
  [9:4] Max Link Width (x1=1, x2=2, x4=4, x8=8, x16=16)
Offset +0x10: Link Control Register
  [0]   ASPM L0s Enable
  [1]   ASPM L1 Enable
  [5:4] RCB (Read Completion Boundary)
  [6]   Link Disable
  [7]   Retrain Link
Offset +0x12: Link Status Register
  [3:0] Current Link Speed
  [9:4] Negotiated Link Width
  [13]  Link Training
  [15]  Link Bandwidth Management Status

Extended Capability Structure

PCIe 전용 확장 기능은 0x100 오프셋부터 시작하는 Extended Capability Space에 정의된다. 동일한 Linked List 구조이지만 포맷이 다르다.


각 Extended Capability Entry:
  [15:0]  Extended Capability ID
  [19:16] Capability Version
  [31:20] Next Extended Capability Offset (0x000 = 마지막)

주요 Extended Capability ID:
  0x0001: Advanced Error Reporting (AER)
  0x0002: Virtual Channel (VC)
  0x0003: Device Serial Number
  0x0004: Power Budgeting
  0x000E: ARI (Alternative Routing-ID Interpretation)
  0x0010: SR-IOV (Single Root I/O Virtualization)
  0x0018: LTR (Latency Tolerance Reporting)
  0x001E: L1 PM Substates
  0x0023: Data Link Feature
  0x0025: Physical Layer 16.0 GT/s
  0x0026: Lane Margining at the Receiver

ARI (Alternative Routing-ID Interpretation)

  • 기존 PCIe: Slot당 최대 8 Function (3-bit Function Number)
  • ARI 활성화 시: Bus당 최대 256 Function (8-bit Function Number)
  • SR-IOV의 Virtual Function 지원을 위해 필요
  • Downstream Port와 Endpoint 모두 ARI 지원 시 활성화 가능

Command Register와 Status Register

Configuration Space offset 0x04의 Command/Status 레지스터는 디바이스의 기본 동작 제어에 사용된다.

Command Register (offset 0x04)


[0]  I/O Space Enable       - IO BAR 접근 허용
[1]  Memory Space Enable    - Memory BAR 접근 허용 (필수)
[2]  Bus Master Enable      - DMA 요청 허용 (PCIe에서 Posted/Non-Posted 생성 허용)
[6]  Parity Error Response  - Parity Error 시 Parity Error bit 세팅
[8]  SERR# Enable           - Fatal Error 시 SERR# 신호 발생
[10] Interrupt Disable      - INTx 인터럽트 비활성화 (MSI 사용 시 설정)

Status Register (offset 0x06)


[3]  Interrupt Status       - INTx 인터럽트 펜딩 상태
[4]  Capabilities List      - 1이면 Capabilities Pointer 유효
[19] Signaled Target Abort  - Completer에서 Abort 발생
[20] Received Target Abort  - Requester 측에서 Abort 수신
[24] Master Data Parity Error
[27] Detected Parity Error

ECAM - Enhanced Configuration Access Mechanism

PCIe의 4KB Configuration Space에 접근하기 위한 메모리 매핑 방식이다. BIOS/UEFI가 MCFG(Memory Mapped Configuration) ACPI 테이블에 ECAM 기반 주소를 등록한다.


ECAM 주소 계산:
  Base Address + (Bus << 20) | (Device << 15) | (Function << 12) | Offset

예: Base = 0xE0000000, Bus=1, Dev=2, Func=0, Offset=0x10
  -> 0xE0000000 + (1 << 20) + (2 << 15) + (0 << 12) + 0x10
  -> 0xE0000000 + 0x100000 + 0x10000 + 0x10
  -> 0xE0110010

전통적인 CF8/CFC I/O Port 방식은 256바이트까지만 접근 가능
ECAM은 4096바이트 전체 접근 가능 (PCIe Extended Space 포함)

MSI / MSI-X

PCIe 디바이스의 인터럽트 메커니즘이다. 전통적인 INTx(레거시 인터럽트 핀 방식)를 대체한다.

MSI (Message Signaled Interrupt)

  • Memory Write TLP를 통해 인터럽트 신호 전달 - 물리 핀 불필요
  • 1~32개의 인터럽트 벡터 지원
  • MSI Capability(0x05)의 Message Address/Data 레지스터에 OS가 값 설정
  • 디바이스는 Message Address로 Memory Write TLP 전송 시 인터럽트 발생

MSI-X (MSI eXtended)

  • 최대 2048개 벡터 지원 (MSI의 32개 대비 대폭 확장)
  • MSI-X Table과 PBA(Pending Bit Array)를 BAR가 가리키는 메모리에 배치
  • 벡터별로 독립적인 Address/Data 설정 가능 - NUMA/CPU Affinity 최적화
  • 고성능 NVMe, 10GbE+ NIC 등에서 필수적으로 사용

SR-IOV (Single Root I/O Virtualization)

하나의 물리 PCIe 디바이스(Physical Function, PF)를 다수의 가상 Function(Virtual Function, VF)으로 분리하는 기술이다. 가상화 환경에서 디바이스를 VM에 직접 할당하는 데 사용한다.

  • PF: 전체 디바이스 제어 담당 - SR-IOV Extended Capability 포함
  • VF: 경량화된 Function - 데이터 경로(BAR)만 가짐, Configuration Space 최소화
  • VF는 Enumeration 시 별도 BDF(Bus:Device:Function)로 노출됨
  • ARI 활성화 필요 - VF 수가 많을 경우 256 Function 범위 필요
  • IOMMU와 결합하여 각 VM의 DMA를 격리

다음 글

기초지식 카테고리 글 더보기