일반적인 linux에서의 인터럽트에 대한 질문을 했었는데
ARM에 한정된 ARM 종속적인 인터럽트에 대해 새로운 질문을 드리기 위해 새로 게시글을 열었습니다.
(1) 인터럽트 핸들러가 실행 중이면 동일한 인터럽트는 비활성화되어 재진입이 금지되잖아요?
모든 프로세서에서 비활성화되는 건가요? local 프로세서에서만 비활성화되는 건가요?
그리고 어느 레벨에서 비활성화되는지 궁금합니다.
인터럽트 컨트롤러 드라이브에서 동일한 인터럽트를 비활성화시키는 코드를 봤는데
(해당 코드만 봤을 때는 local 프로세서에서만 비활성화되는 것 같긴 했습니다.)
그 코드 때문에 컨트롤러 레벨에서 비활성화되는 것인가요?
(2) ARM에서는 irq 간에는 중첩을 허용하지 않는다고 하는데
fiq 간에도 중첩이 허용되지 않겠죠?
ARM에서는 NMI (Non-Maskable Interrupt)가 지원되지 않는 것 같은데 맞죠?
그러면 fiq를 다른 아키텍처의 NMI와 같은 용도로 사용하나요?
ARM에서는 NMI를 어떻게 구현하나요?
혹시 NMI를 위해 fiq로 구현해놓는다면
irq가 실행중일때는 non-masking 되어 즉시 실행되겠지만
다른 fiq가 실행중일때는 pending이 되어
완전한 NMI로의 구현이 안되겠네요?
다른 방법으로 ARM에서 지원하는 NMI를 구현할 수 있나요?
댓글 5
-
문c(문영일)
2019.04.08 23:17
-
무명
2019.04.15 20:34
답변 정말 감사드립니다.
추가로 몇가지 더 질문드리고 싶습니다.
답변 말씀을 인용하여 "대부분의 x86 NMI들은 ARM에서는 irq로 처리합니다."라면구현한 NMI 목적의 irq가 다른 irq에 의해 masking이 될텐데 어떻게 NMI로 처리할 수 있을까요?
이게 제일 궁금합니다.
그리고 fiq를 구현하려면 HW적인 support가 필요한가요?
fiq 핀이 따로 있나요?
아니면 HW적인 support 없이도 기존의 irq로 등록된 handler를 fiq로 등록하여 fiq로 사용할 수도 있나요?
-
문c(문영일)
2019.04.16 08:45
x86의 NMI는 non-maskable interrupt입니다.
하지만 arm에서의 fiq는 fast interrupt이고, maskable interrupt 입니다.arm에서 인터럽트가 인입되면 mask 되는 구간은 최소화 시키고, bottom-half로
대부분의 처리를 이양합니다. 그런 후 다시 mask를 해제합니다.
mask 되는 동안 인터럽트 컨트롤러는 pending된 인터럽트 중
높은 우선 순위를 가진 인터럽트를 먼저 처리합니다.이렇게 하여 처리하면 중첩을 허용하지 않더라도 왠만한 인터럽트는 모두 해결합니다.
fiq를 구현하는데 별도의 hw적인 처리는 필요없습니다. 인터럽트 라우팅을 담당하는 레지스터를
설정하면 fiq 시그널로 넘어갑니다. arm에서의 인터럽트 컨트롤러는 시스템마다 다양하므로
각 시스템이 사용하는 인터럽트 컨트롤러의 레지스터 관련 정보를 파악하셔야 합니다.이렇게 진입한 fiq에 해당하는 루틴은 공백 상태이므로 나머지 구현은 사용자에게 맞깁니다.
irq로 등록된 핸들러를 호출하려면 거기에 해당하는 호출 루틴을 만드셔야 합니다.
main 커널에는 아무것도 없는 상태입니다.감사합니다.
-
무명
2019.04.22 15:04
혹시 말씀하신 fiq로 인터럽트 라우팅을 담당하는 레지스터는 어떤 레지스터인가요?
-
문c(문영일)
2019.04.23 08:41
안녕하세요?
인터럽트 컨트롤러마다 레지스터가 다 다르므로 사용하시고 계시는 제품의 매뉴얼을 살펴보셔야 알 수 있습니다.
만일 ARM사의 GIC라고 가정하면 GICD_IGROUPR (Interrupt Group Registers) 을 사용합니다.
참고: http://jake.dothome.co.kr/ic/ | 문c 블로그
감사합니다.
.
안녕하세요? 문c 블로그(jake.dothome.co.kr)의 문영일입니다.
(1) 인터럽트의 enable/disable은 각각의 core에서 제어합니다.
참고로 타이머같이 core 마다 연결된 PPI가 있고, 그렇지 않고 공유하는 SPI도 있습니다.
$ cat /proc/interrupts 를 통해 어떤 cpu에 인터럽트들이 연결되어 있나 확인할 수 있습니다.
인터럽트를 비활성화하는 것은 여러 단계에 있습니다.
가장 쉽게는 local cpu에 진입하는 인터럽트를 막는 방법,
두 번째는 각 인터럽트 컨트롤러의 단계별로 라우팅을 막는 방법,
세 번째는 디바이스에서 인터럽트가 발생되지 않도록 제한하는 방법 등이 있습니다.
첫 번째 방법은 커널 코드에서 많이 볼 수 있습니다.
두 번째 방법은 일반적인 상황에서는 사용하지 않습니다. 특수한 장비의 경우는 특정 기능을
사용하기 위해 튜닝하여 사용할 가능성은 있습니다. 물론 펌웨어 레벨은 얼마든지 가능합니다.
참고로 ARM32의 경우 인터럽트 컨트롤러만 수십여가지입니다.
ARM64의 경우 대부분 ARM사의 GIC를 사용합니다.
세 번째 방법은 관련 디바이스 루틴에서 사용하므로, 각각의 디바이스에 따라 구현 루틴이
다릅니다.
(2) "ARM의 경우 irq 간에는 중첩을 허용하지 않고, fiq는 구현되어 있지 않습니다."
- 위의 말은 ARM 메인 라인 코드에 한정합니다. 실제 SoC 밴더마다 특수한 하드웨어 환경이
적용되는 경우에는 해당 인터럽트의 우선 처리를 위해 여러 가지 방법을 사용할 수도
있습니다.
개론책과 커널 코드의 일부 주석에 나온것 처럼 x86의 NMI를 많은 분들이 ARM의 fiq에
1:1로 대응한다고 이해하고 있습니다. 그러나 실제 ARM에서는 irq 및 fiq 모두에 해당합니다.
대부분의 x86 NMI들을 ARM에서는 irq로 처리합니다.
ARM에서 fiq를 사용하는 경우는 임베디드 시스템에서 아주 빠른 latency를 보장해야 하는
특수한 디바이스인 경우에 한해 해당 SoC사가 별도로 구현하여 사용합니다.
ARM에서 irq나 fiq를 중첩하려면 별도의 인터럽트 전용 스택을 구현해서 처리해야 하므로
난이도가 올라가긴합니다. 그래도 그러한 처리가 필요하면 구현해서 해야합니다.
(현재 ARM 메인라인에서는 fiq 루틴에서 아무것도 하지 않고, ARM64의 경우 에러 처리를
수행합니다)
감사합니다.