2009년 12월 19일
PCI 디바이스의 구조와 제어

H5-1. PCI 디바이스의 구조와 제어


여기에서는 PCI 디바이스의 구조와 제어에 관한 정보를 게재합니다.

INtime software의 도입에 의해 PCI 디바이스로의 액세스는 용이하게 됩니다.

INtime을 사용해서 애게스하는 경우의 포인트를 소개합니다.


PCI configuration 레지스터에 대해

PCI 디바이스 제어를 행하기 위한 이해가 깊어지기 위해서, PCI configuration 레지스터를 참조해 주세요. 모든 PCI 디바이스가 정의하는 레지스터에 관한 정보를 게제하고 있습니다.

 

PCI 디바이스 제어의 흐름

PCI 디바이스를 제어하는 경우, 일반적으로 이하와 같은 처리가 필요합니다:

  • 1. 제어하는 PCI 디바이스의 검출
    PCI 디바이스에 액세스 하기 위해서는, 제어하는 디바이스를 검출해, 그 디바이스 정보를 PCI configuration 레지스터로부터 취득할 필요가 있습니다.

  • 2. 인터럽트 레벨(IRQ)의 취득
    PCI 디바이스의 인터럽트를 이용하는 경우, 제어하는 PCI 디바이스를 할당할 수 있는 인터럽트 라인으로부터 인터럽트 레벨을 취득할 필요가 있습니다. 인터럽트를 사용하지 않는 경우, 이 값을 취득할 필요는 없습니다

  • 3. PCI 디바이스 액세스 허가 설정                                                                               

    RTDRM.SYS를 적용할 수 없는 경우, 혹은 디바이스 드라이버가 인스톨 되어 있지 않은 경우, Windows는 해당하는 PCI 디바이스에 대해서 액세스 금지 설정을 합니다. 이러한 상태의 PCI 디바이스를 제어하는 경우, 액세스 금지 설정을 해제할 필요가 있습니다.

  • 4. PCI 디바이스의 I/O공간, 메모리 공간 액세스용 주소의 취득
    제어하는 디바이스의 I/O공간 베이스 주소, 또는/더해서, 메모리 공간 베이스 주소를 취득해, 디바이스의 제어 레지스터에 액세스 합니다. 이 베이스 주소를 취득할 때, 주의하는 점이 있습니다.

  • 5. 메모리 공간을 가상 메모리상에 맵
    제어하는 디바이스에 대해서 메모리액세스 하는 경우, PCI 디바이스가 가지는 메모리 공간을 어플리케이션의 가상 메모리 공간에 매핑 할 필요가 있습니다.

  • 6. 취득한 I/O공간, 메모리 공간 액세스용 주소를 이용한 디바이스 제어

    레지스터에의 액세스에 의해 디바이스를 제어합니다. 레지스터에의 액세스 방법이나 액세스 하는 레지스터등에 대해서는 디바이스를 제공하는 벤더보다 상세한 I/O맵 정보를 입수할 필요가 있습니다.


code00.png

PCI 디바이스 제어의 흐름(코드)

 

코드에 의한 PCI 디바이스 제어 해설

여기에서는 이하의 가상적인 PCI 디바이스를 상정해, PCI 디바이스의 구조와 제어#pciproc로 설명되고 있는 PCI 디바이스 제어의 흐름을 코드 레벨로 해설합니다.
가상적인 PCI 디바이스는 이하와 같은 사양의 것으로 하는:

  • 가상 PCI 디바이스(DUMMY_PCI)

    • 벤더 ID: 0x1234

    • 디바이스 ID: 0x5678

    • I/O베이스 주소에 의한 I/O액세스가능

    • I/O베이스 주소는 dwBaseAddress[0-5]의 0에 격납되고 있는

    • 메모리베이스아드레스에 의한 메모리아크세스가능

    • 메모리베이스아드레스는 dwBaseAddress[0-5]의 2에 격납되고 있는

    • 디바이스가 가지는 메모 리사이즈는 1MB

 

1. 제어하는 PCI 디바이스의 검출

PCI 디바이스를 검출하기 위해서는 PCIDEV 구조체의 정의와 검출하는 디바이스의 벤더 ID, 디바이스 ID가 필요합니다.벤더 ID, 디바이스 ID를 PCIDEV 구조체로 설정해, PciFindDevice() 함수를 콜 하는 것으로써, 검출한 디바이스 정보를 격납한 PCIDEV 구조체 변수를 받을 수 있습니다. DUMMY_PCI의 벤더 ID가 0x1234, 디바이스 ID가 0x5678이기 때문에 각 각을 PCIDEV 구조체 변수인 dev에 격납해, PciFindDevice를 콜 합니다. PciFindDevice는 실패시에 FALSE를 반환합니다 .PCI 디바이스를 검출할 수 없는 이상, 디바이스에의 액세스는 불가능이라는 것이 되기 때문에 본처리를 종료합니다.


 

PCI 디바이스 검출

 

 

2. 인터럽트 레벨(IRQ)의 취득

PCI 디바이스 제어로 인터럽트를 사용하는 경우, 디바이스의 인터럽트 라인으로부터, 인터럽트 레벨을 취득합니다. INtime Version2.23으로부터, APIC 모드를 서포트하는 것으로써, 인터럽트 라인으로서 할당할 수 있는 수치가 종래의 0에서 15(PIC 모드)까지로부터, 크게 변경되어 논리적으로 16로부터 254까지의 수치를 취급하게 되었습니다. 거기에 따라, IRQ 레벨 취득 논리가 변경되었습니다. 이 논리는 종래의 PIC 모드에도 대응하고 있기 때문에, 향후, 이 논리를 사용해 IRQ 레벨을 취득하도록 해 주세요.


code08.png

IRQ 레벨 취득

 

3. PCI 디바이스 액세스 허가 설정

Windows가 디바이스 드라이버의 인스톨 되어 있지 않은 PCI 디바이스의 커멘드 레지스터에 대해 액세스 금지 플래그를 설정할 가능성이 있습니다.금지 플래그를 설정되는 것을 상정해, 커멘드 레지스터의 값을 미리 취득해, 액세스 금지 플래그(I/O액세스·메모리아크세스)를 해제한 값을 재차 설정해 있습니다.


code02.png

I/O액세스·메모리액세스 금지 플래그의 해제

 

4. PCI 디바이스의 I/O공간, 메모리 공간 액세스용 주소의 취득

PCI 디바이스에 액세스 하기 위해서는, PCI configuration 공간의 베이스 어드레스 레지스터(OFFSET:10H)로 설정되어 있는 베이스 주소를 취득할 필요가 있습니다. 이 베이스 어드레스 레지스터는 DWORD[0~5]의 구성이 되고 있습니다만, 실제 어디에 격납되고 있는지, 라고 하는 것은 벤더로부터 제공되는 I/O맵 자료에 근거해 조사할 필요가 있습니다.여기에서는 I/O주소가 0, 메모리아드레스가 2에 격납되고 있기 때문에 각 레지스터보다 각각 취득하고 있습니다.
I/O주소의 취득부에 있고는 0 xFFFC 마스크를 건 값을 베이스 주소로서 취득하고 있습니다. 이것은 베이스 어드레스 레지스터의 특징으로서 레지스터의 0비트의 값은, 해당하는 베이스 어드레스 레지스터가 I/O공간의 것인가, 메모리 공간의 것인지를 판단하기 위한 인디케이터(indicator)로서 이용되고 있어 또 비트 1도 의미를 가진다고 여겨지고 있기 때문입니다. 비트 0에 대해서는 I/O공간의 경우는 비트 1이 설정되어 메모리 공간의 경우는 비트가 설정되지 않습니다. 이 때문에 강제적으로, 비트 0, 비트 1에 대해서 설정되는 플래그를 마스크 해, 올바른 베이스 주소를 취득할 필요가 있습니다. 자세한 것은 PCI configuration 레지스터 를 참조해 주세요.

I/O공간 인디케이터(indicator)의 해제

 

5. 메모리 공간을 가상 메모리상에 맵

액세스 하는 공간이 메모리 공간인 경우, 입출력은 메모리액세스(READ/WRITE)가 됩니다. 메모리 액세스를 실시하기 위해서는 PCI 디바이스의 물리 메모리를 어플리케이션이 가지는 가상 address 공간에 맵 할 필요가 있습니다. INtime에 대해 베이스 주소의 값이 페이지바운다리상(4096바이트 단위 경계)에 없는 경우, 물리 주소를 맵 할 수 없습니다. 거기서, 여기에서는 취득한 베이스 주소가 페이지바운다리상에 올바르게 배치되지 않은 경우, 맵하기 위한 베이스 주소를 포함한 페이지의 바운다리를 베이스로서 맵 합니다. 이렇게 되면, PCI 디바이스의 물리 주소와 실제의 맵 주소간에 차이가 생겨 올바르게 액세스 할 수 없습니다. 거기서 항상 오프셋치를 더한 값을 디바이스에 액세스하기 위한 베이스 주소로서 취득하는 방법을 채용하고 있습니다. 베이스 주소가 바운다리상에 배치되지 않는 경우, 확보하는 메모리의 사이즈도 전후 2 페이지분 증가하고 있습니다. 이것은 맵 하는 사이즈가 페이지 단위(4096바이트)이기 위해, 베이스 주소가 페이지바운다리상에 없는 물리 메모리를 확보하기 위해서는 그 주소를 포함한 불필요한 1 페이지로 끝수가 되는 최종 1 페이지분을 고려한 다음 사이즈를 결정할 필요가 있기 때문에입니다.


code04.png

 

베이스 주소로부터 메모리를 맵

 

6. 취득한 I/O공간, 메모리 공간 액세스용 주소를 이용한 디바이스 제어

INtime로 I/O주소에 대해서 액세스 하기 위해서는 BYTE 액세스(inbyte/outbyte), 워드 액세스(inhword/outhword), DWORD 액세스(inword/outword)가 준비되어 있습니다. 취득한 베이스 주소+오프셋으로 PCI 디바이스가 가지는 레지스터에 대해서 액세스 합니다. 메모리액세스에 관해서는 통상의 메모리와 같이 지정 포인터 조작등에 의해 값을 읽고 쓰기하게 됩니다.

code0a.png

PCI 디바이스에의 액세스

 

by 샤키 | 2009/12/19 15:28 | Linux | 트랙백(1) | 덧글(0)
트랙백 주소 : http://sharkynara.egloos.com/tb/2788379
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from at 2014/03/11 00:39

제목 : http://helenmccrory.org/
line5...more

:         :

:

비공개 덧글



<< 이전 페이지 | 다음 페이지 >>