(공사 중)NVMe Base Spec. Rev. 1.4c

2. System Bus (PIC Express) Registers

PCI 버스에는 여러가지 장치가 물리는데 그 장치를 사용하려면, 각 장치가 어떤 것이고(identification), 어떻게 장치와 통신해야 하는지(protocol)를 알아야 한다. PCI 버스에서는 장치를 인식하고, 그 장치의 기본적인 정보를 얻어오기 위해 configuration space를 사용한다. 각 장치에 대해 할당된 configuration space를 통해 파악하게 되며 Device ID,Vendor ID,Status,Class code 등의 정보들이 해당 주소 공간에 저장되어 있다.

imgPCI configuration space header

디바이스의 PCI configuration space 정보를 읽으면 디바이스와 통신을 하기 위한 기본적인 정보를 알 수 있다. PCI slot에 연결된 장치치에 대한 configuration space는 집적으로 읽을수 없다. 즉, OS가 부팅하면서 PCI에 연결된 모든 디바이스를 검색 해야 한다. 이때, PCI디바이스는 물리적으로 모든 디바이스에 bus, device, function 이라는 번호가 부여된다. 이 번호는 PCI slot에 따라 부여되는 것이기 때문에, 모든 bus, 모든 device, 모든 function을 스캔 해 보면, 컴퓨터에 달린 모든 디바이스 정보를 알 수 있다. 이 과정을 enumeration이라 한다

imgPCI enumeration 과정

계속 공부를 진행하며 bus, device, function의 차이에 대해 궁금해졌다. 우리가 사용하는 PC에서 PCI slot에 장치를 연결한다면 해당 장치는 모두 다른 bus번호로 연결되는 것인지 등 어떤 디바이스들이 같은 bus를 공유하는지에 대해 궁금했다.

img

PCI address

Configuration Address Space

  • ‘Configuration Address Space’ has been defined to support PCI hardware configuration
  • ‘Configuration Address Space’ provides access to 256 bytes of special configuration registers per PCI device.
  • PCI Express introduces ‘Extended Configuration Space‘ which extends the Configuration Space to 4096 bytes per Function
  • ‘Configuration Read’ command and ‘Configuration Write’ command are used to transfer data between each ‘Configuration Address Space’ of PCI devices

Memory Address Space

  • ‘Memory address space’ is used for burst transactions
  • Two different address formats are used: 32-bit address format and 64-bit address format
  • ‘Memory Read’ command and ‘Memory Write’ command are used to transfer data in ‘Memory Address Space’

I/O Address Space

  • ‘I/O address space’ is for compatibility with the x86 architecture’s I/O port address space. Future revisions of PCI Express specification may deprecate the use of ‘I/O Address Space’
  • ‘I/O Read’ command and ‘I/O Write’ command are used to transfer data in ‘I/O Address Space’.

Configuration Address Space

  • PCI devices have a set of registers referred to as ‘Configuration Space‘
  • This configuration space is used for auto configuration of inserted PCI cards
  • Configuration Space registers are mapped to memory locations
  • PCI framework S/W should access the configuration space.

NVMe Spec 2장에서는 어떻게 PCI header, PCI capabilities, PCIe extended capabilites가 NVMe controller에 대해 구성되어 있는지를 살펴 본다.

imgPCIe registers

PCIe register에 대한 큰 틀에서의 구성이다. SSD 내에 존재하는 controller의 PCIe와 관련된 IP의 register들에 대한 설정이다. PCI header는 0x00 ~ 0x3F까지 범위이며, 뒤의 register들은 펌웨어에서 메모리 어느 부분에 베이스 주소를 가지고 갈 것인지에 따라 다르게 설정될수 있다.

가장 먼저 PCI header에 대해 살펴 볼 것이다.

PCI Header

PCI header는 디바이스의 타입에 따라 Type 0, Type 1 두 종류로 나뉘며 Type에 따라 header의 bit가 다르게 사용된다. 하지만, 여기에서는 RC 혹은 Bridge를 사용한 디바이스가 아닌 RC에 다이렉트로 연결된 End device를 가정으로 설명한다.

  • Type 0 header: PCI Express 디바이스
  • Type 1 header: Switch 및 Root Complex 가상 PCI Bridges

imgType 0 header

imgPCI header 설명

그리고 PCI header에 대해 spec을 그냥 읽는 것 보다는 하나의 디바이스를 예제로 보는 것이 좋기 때문에 아래처럼 실행하자.

$ lspci -x

img$ lspci –help 결과

PCI slot에 연결된 디바이스들에 대해 정보를 알기 위해선 리눅스에서 lspci 명령을 통해 알수 있다. Configuration address 중 PCI header 부분에 대해서만 알고 싶다면 -x 옵션을 전체 4KB에 대한 영역 전부 알고 싶다면 -xxx 옵션을 주면 된다. 아래는 Virutual box에서 가상으로 생성한 NVMe device의 결과이다.

img$ lspci -x 결과

img

  • ID - identifiers
    • ID 값에 대한 비트 필드를 나타낸다.
    • vendor ID와 devie ID 두개의 필드를 가진다.
    • vendor ID: 80ee
    • devcie ID: 4e56
    • 삼성 디바이스의 경우 144d의 vendor ID를 가지게 된다.
    • vendor ID list를 보고 싶으면 여기를 들어가면 볼 수 있다.

img

  • CMD - command
    • 2B의 값을 가진다.
    • 값: 0x0007
    • Enable
      • I/O space enable
      • Memory space enable
      • bus master enable
    • device로 하여금 I/O space와 memory space 영역에 접근을 가능하도록 한다.
    • bus master로 동작하기 때문에 위의 영역을 통해 데이터 전송을 할 수 있다. (어떤 데이터를 주고 받는 것일까?)

img

  • STS - device status
    • 2B의 값을 가진다.
    • 값: 0x0010
    • Enable
      • capabilites list
    • capabilities list가 존재 함을 나타낸다.

img

  • RID - revision ID
    • 1B의 값을 가진다.
    • 값: 0x00
    • controller의 수정 버전을 나타내는 것 같다. (확실치 않음, 내가 본 5대의 SSD는 모두 0의 값을 가짐)

img

  • CC - class code
    • 3B의 값을 가진다.
    • 값: 0X010802
    • Programming interface : 0x02, 즉 I/O controller가 있음을 나타낸다.
    • sub class code : 0x08
    • base class code: 0x01
    • PCI의 class 분류를 볼려면 여기를 누르면 된다.
    • 대 분류, 중분류라고 생각 하면 될거 같다. mass storage 중에서도 플로피 디스크, IDE 등 다양한 storage들이 존재하는데 그 중에서 sub class code가 0x08이므로 non-volatile memory를 나타낸다.

img

  • CLS - cache line size
    • 1B의 값을 가진다.
    • 현재 여기에서는 0의 값을 가져 cache 가 없는 것으로 확인 되지만, 실제 SSD중 일부 제품의 경우 해당 크기가 정해져있는 것으로 확인 되었다.

img

  • MLT - master latency timer
    • 1B의 값을 가진다.
    • 값: 0X40

img

  • HTYPE - header type
    • 1B의 값을 가진다.
    • 여기에서는 두개의 필드 모두 0의 값을 가진다. 하지만, NVM subsyetem에서 multi function을 지원하는 경우 해당 7번 bit는 set된다.

img

  • BIST - build in self test
    • 1B의 값을 가진다.
    • 모두 0의 값을 가진다. BIST를 지원하지 않는다.

img

  • MLBAR - memory register base address
    • 4B의 값을 가진다.
    • 값: 0xf0808000

img

  • MUBAR - memory register base address
    • MLBAR의 base address와 합쳐서 최대 64bit의 base address 주소 공간을 가질 수 있다.

img

  • BAR2 - index/data pair register base address
    • 4B의 값을 가진다.
    • 값: 0x0000d271

img

  • CCPTR - cardbus cis pointer
    • 지원 안함