ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [컴퓨터 구조] PCI 인터럽트
    공학/컴퓨터구조 2023. 8. 8. 20:43

    글의 참고

    - https://people.freebsd.org/~jhb/papers/bsdcan/2007/article/node4.html

    - https://leftasexercise.com/2018/11/05/interrupts-the-heartbeat-of-a-unix-kernel/

    - https://github.com/christianb93/ctOS/blob/master/doc/hardware/InterruptController.md

    - https://en.wikipedia.org/wiki/Industry_Standard_Architecture

    - https://flylib.com/books/en/3.356.1.154/1/


    글의 전제

    - 밑줄로 작성된 글은 강조 표시를 의미한다.

    - 그림 출처는 항시 그림 아래에 표시했다.


    글의 내용

    : PC-AT 시절에 주로 사용되던 버스는 ISA 버스였다. ISA는 16비트 대역폭을 지원하며, 이에 맞게 버스와 인터럽트 컨트롤러들이 설계되었다. PC-AT 시절 I/O 디바이스와 CPU는 어떻게 인터럽트를 주고 받았을까? CPU가 외부 디바이스와 통신 하기 위해서는 반드시 버스를 통해서만 가능하다. 즉, PC-AT 시절에 CPU가 I/O 디바이스로부터 인터럽트를 받기 위해서는 ISA 버스를 통해서만 가능했다. 그런데, CPU에 외부 디바이스들의 하드웨어 인터럽트 라인을 모두 설치하기에는 그 양이 너무 많았다. 그래서 CPU는 인터럽트 몸빵받이를 하나 만들었다. 그게 바로 `인터럽트 컨트롤러`다. 이 친구는 사실 몸빵만 하는 친구가 아니다. 외부 인터럽트 관련 다양한 처리를 맡아서 하는데, 그 내용은 이 글을 참고하자.

     

    : 그런데, 이 글은 PCI 인터럽트 관련 글 아닌가? PCI 버스를 어떻게 ISA 버스와 연결시켰을까? PC-AT의 구조를 한 번 봐야한다.

    : PC-AT는 PC/XT 에 비하면 양반인 편이다. IBM PC/XT 시절에도 ISA 버스를 사용했었다. 즉, ISA 버스는 애초에 PC/XT를 위해서 8비트로 제작이 되었다가 PC/AT 에서도 사용하기 위해 16비트로 확장된 것 이다. 위 그림은 PC/AT 에서도 PCI 버스와 ISA 버스가 공존하는 모습을 보여준다.

     

    : PC-AT 구조를 따르는 x86 구조에는 몇 가지 단점이 존재한다. 첫 번째로, 기존 x86 구조가 8259 인터럽트 컨트롤러와 ISA 버스에 강하게 의존하고 있었다. 즉, 16비트 구조에 너무 강하게 의존하고 있다. 그래서 x86에 32비트 PCI 버스가 등장했을 때, 호환성 문제가 발생했다. 왜냐면, PCI 버스가 32비트이다 보니, ISA 디바이스들과 PCI 디바이스들이 통신하기 위해서는 반드시 `브릿지`가 필요했다. 두 번째로, 인텔 `x86`은 이전 제품들에 대한 호환성을 지키는 구조를 채택하다보니 구조가 굉장히 복잡해졌다. A#20이나 PIC, ISA 같은 고전적인 하드웨어들이 2020년까지도 버젓이 존재했었다. 

     

    : PC-AT 에서 사용되던 ISA 버스같은 경우, 인터럽트가 `active-high & 엣지 트리거`로만 동작을 해야했다. 인터럽트 엣지 트리거 특성은 ISA 인터럽트를 여러 디바이스들이 공유할 수 없게 만드는 구조였다. 그래서 모든 ISA 디바이스들은 PIC 8259에 전용 인터럽트 라인을 달아야만 했다. 그런데, PCI 버스는 인터럽트를 반드시 `assedted low & 레벨 트리거`만 동작하도록 설계되었다. 즉, PCI 인터럽트 라인은 해당 디바이스 드라이버가 다시 핀을 `deasserted` 하기 전까지는 계속 `asserted`로 남아있게 된다.

    Once the INTx# signal is asserted, it remains asserted until the device driver clears the pending request. When the request is cleared, the device deasserts its INTx# signal. PCI defines one interrupt line for a single function device and up to four interrupt lines for a multi-function device or connector. For a single function device, only INTA# may be used while the other three interrupt lines have no meaning.
    ...

    핀 번호 전기적 특성 설명
    INTA# o/d(오픈 드레인) Interrupt A is used to request an interrupt.
    INTB# o/d Interrupt B is used to request an interrupt and only has meaning on a multi-function device.
    INTC# o/d Interrupt C is used to request an interrupt and only has meaning on a multi-function device.
    INTD# o/d Interrupt C is used to request an interrupt and only has meaning on a multi-function device.


    Any function on a multi-function device can be connected to any of the INTx# lines. `The Interrupt Pin register` (refer to Section 6.2.4 for details) defines which INTx# line the function uses to request an interrupt. If a device implements a single INTx# line, it is called INTA#; if it implements two lines, they are called INTA# and INTB#; and so forth. For a multi-function device, all functions may use the same INTx# line or each may have its own (up to a maximum of four functions) or any combination thereof. A single function can never generate an interrupt request on more than one INTx# line.

    The system vendor is free to combine the various INTx# signals from the PCI connector(s) in any way to connect them to the interrupt controller. They may be wire-ORed or electronically switched under program control, or any combination thereof. The system designer must insure that each INTx# signal from each connector is connected to an input on the interrupt controller. This means the device driver may not make any assumptions about interrupt sharing. All PCI device drivers must be able to share an interrupt (chaining) with any other logical device including devices in the same multi-function package.

    - 참고 : PCI_Rev_30.pdf [ 2.2.6. Interrupt Pins (Optional) ]

    : `single functon`은 절대로 2개 이상의 인터럽트를 발생시킬 수 없다. 즉, `single function`은 `INTA#` 라인에만 인터럽트를 발생시킬 수 있다.

     

    : PCI 디바이스 드라이버는 `Interrupt Line register`와 `Interrupt Pin register`를 통해 PCI 디바이스의 인터럽트 라인을 인터럽트 컨트롤러의 몇 번 입력 핀에 라우팅할 것인지와 자신이 사용해야 하는 인터럽트 핀 번호를 알 수 있다. 만약, `Multi-function` 디바이스가 아니라면, 무조건 `INTA#`만 사용하게 되므로, 이 레지스터에는 `1`이 써져있을 것이다.

    The Interrupt Line register is an eight-bit register used to communicate interrupt line routing information. The register is read/write and must be implemented by any device (or device function) that uses an interrupt pin. POST software will write the routing information into this register as it initializes and configures the system.

    The value in this register tells which input of the system interrupt controller(s) the device's interrupt pin is connected to. The device itself does not use this value, rather it is used by device drivers and operating systems. Device drivers and operating systems can use this information to determine priority and vector information. Values in this register are system architecture specific.


    The Interrupt Pin register tells which interrupt pin the device (or device function) uses
    . A value of 1 corresponds to `INTA#`. A value of 2 corresponds to `INTB#`. A value of 3 corresponds to `INTC#`. A value of 4 corresponds to `INTD#`. Devices (or device functions) that do not use an interrupt pin must put a 0 in this register. The values 05h through FFh are reserved. This register is read-only. Refer to Section 2.2.6 for further description of the usage of the `INTx#` pins.

    - 참고 : PCI_Rev_30.pdf

     

    : 그리고 PIC 8259 인터럽트 라인들은 대개 IBM PC 구조에서는 역할이 고정적으로 정해져있었다. 즉, IRQ0은 타이머, IRQ1은 키보드 등등으로 남는 핀은 IRQ[5, 9, 10, 11] 핀밖에 없었다. PCI 인터럽트로 이 라인들을 사용하면 문제가 없을것이라 생각했다. 그러나, ISA 버스에 추가적인 디바이스들이 붙기 시작했다. 예를 들어, 사운드 카드가 종종 IRQ5를 사용했다. 사용할 수 있는 인터럽트 번호가 줄어들 뿐만 아니라, PCI에서 IRQ5에 누가 장착되어 있는지 여부를 판단해야 하는 경우도 발생했다. 이 시점에서 PIR이 등장했다.

     

    : PIR은 `Programmable Interrupt Router`의 약자로 `PCI Link Device`라고 불렸다. PIR은 PIC 인터럽트 시그널을 받아서, PIC에게 라우팅하는 역할을 했다. 아래 그림을 보자. PIR의 라우팅 테이블은 아래와 같다고 하자.

    INPUT OUTPUT
    INT#A O0
    INT#B O1
    INT#C O2
    INT#D O3

    : 그렇면, PIC Slot[1, 2]에서 인터럽트를 발생시키면, 어디서 받게될까? `PCI Slot[1, 2]의  INTA#`는 PIR의 `O0`으로 라우팅되기 때문에 Master PIC 8259의에서 받게된다.

     

    : 주의할 점이 있다. 예를 들어, PIRT이 INT#A를 IRQ 11로 라우팅할 경우, INT#A에 연결된 모든 인터럽트가 IRQ11로 라우팅된다. 즉, PIR은 개별 PCI 인터럽트 하나하나를 세밀하게 특정 IRQ로 라우팅은 불가능하다는 것이다. PIR도 입력핀이 4개밖에 안되므로, 많은 수의 PIC 디바이스들의 인터럽트를 처리하기 위해서는 `그룹핑`해서 처리할 수 밖에 없었다.

     

    : 그런데, `PIR`은 인터넷에서 검색하면 내용자체가 거의 존재하지 않는다. `PIR` 이라는 용어가 뭔가 공식적이지 않게 사용되는 듯 하다. 그래서 `$PRI`, `PCI IRQ Routing Table` 등으로 검색해야 좀 더 많은 내용들을 찾을 수 있다. 그런데, 나도 이 글을 토대로 내용을 작성하고 있지만, 의심이 들기 시작했다. 왜냐면, PIR의 위치도 궁금하지만, PIC는 CPU에게 인터럽트를 전송한다는 구조가 비효율적이기 때문이다. 왜냐면, PIC가 ISA 버스를 기반으로 설계가 되었기 때문에 속도가 굉장히 느리다. 즉, `PCI 디바이스 -> PIR -> PIC -> CPU` 구조로 IRQ가 전달된다는 것인데, 이게 쉽게 납득이 가지 않는 구조다. 이건 저 당시에 `Intel South-Bridge` 구조를 확인해볼 필요가 있다.

    : 위 그림은 `PIIX4`를 South-Bridge로 사용한 PC 마더 보드의 구조이다. 기본적으로 3개의 버스가 사용된 것을 확인할 수 있다. PIC와 IO APIC는 어디에 위치해 있을까? PIIX4 스펙을 보면, PIC(82C59)는 `82371AB`에 속해있지만, `IO APIC`는 외부로 빠져있는 듯 하다. 그런데, PIIX4가 `external IO APIC`를 지원한다고 되어있는 것을 보면, IO APIC 또한 `PIIX4`에 연결되어 있을것이다.

    `PIIX4` provides an ISA-Compatible interrupt controller that incorporates the functionality of `two 82C59 interrupt controllers`. The two interrupt controllers are cascaded so that 14 external and two internal interrupts are possible. In addition, PIIX4 supports a serial interrupt scheme. PIIX4 provides full support for the use of an `external IO APIC`.

    - 참고 : 82430FX PCISET DATA SHEET 82437FX TRITON SYSTEM CONTROLLER (TSC)

    : `PIIX4` 구조를 보면, `PIC or IO APIC -> PIR -> CPU` 혹은 `PCI -> PIR -> CPU` 구조로 처리가 될 것 같다. 그리고, PIR은 PIC 버스에 붙어있을 확률이 매우 높아진다. 그렇면, 왜 이 글은 `PCI 디바이스 -> PIR -> PIC -> CPU` 구조로 설명을 했을까? 사실, 이 글이 맞다. 내가 구조를 놓친 부분이 있다.

     

    : APIC가 도입된 초기 시점에는 `APIC Bus`가 별도로 존재했다. 사우드-브릿지에 존재하는 `IO APIC`를 지원하기 위해서 APIC Bus는 CPU와 사우스-브리지를 직접연결하는 구조를 채택했다. 이런 구조라면, `PCI 디바이스 -> PIR -> PIC -> CPU`가 성립이 된다. 위에서 PIC는 IO APIC로 봐도 무방하다. 왜냐면, IO APIC는 PIC를 완전히 지원하기 때문이다. 그리고 PIIX3 에서 IO APIC와 APIC Bus 가 처음 등장했을 때는, Local APIC는 없었다. 그러면, 이제 그림을 수정해보자.

    : PIR은 ISA 버스에 들어가 있을 확률이 크다. 왜냐면, PIIX 혹 PIIX3 구조에서는 CPU에게 인터럽트를 전달하기 하려면, 반드시 사우스 브릿지안에 APIC Bus를 통해서만 전달이 가능하기 때문이다.

     

    그런데, 위의 구조가 맞을까? 위 그림은 마치 `PIR`과 `CPU`가 ISA 버스에 있는 것으로 보이는데, 맞는 그림일까? 대개 CPU는 고속 버스인 PCI 쪽에 붙어있다. 그리고 PIR은 2개의 브릿지 역할을 할 것이다. 즉, PCI와 ISA 버스 2개 모두에 걸쳐있을 것이다.

    '공학 > 컴퓨터구조' 카테고리의 다른 글

    [컴퓨터 구조] ISA 버스  (0) 2023.08.09
    [컴퓨터 구조] PCI  (1) 2023.08.09
    [컴퓨터구조][ARM] ARMv7 부트 코드  (0) 2023.08.07
    [컴퓨터 구조] 디스크 주소 지정  (0) 2023.08.07
    [컴퓨터 구조] Data Alignment  (0) 2023.08.07
Designed by Tistory.