안녕하세요
ICC_PMR(Interrupt Controller Interrupt Priority Mask Register)에 설정되는 값에 의미에 대해서 질문드립니다.
Purpose
Provides an interrupt priority filter. Only interrupts with a higher priority than the value in this register are signaled to the PE.
implemented priority bits가 [7:4]라고 가정하면
prio는 0x00 부터 0xF0까지 총 16개의 단계를 가지게 됩니다
그리고
arch/arm64/include/asm/ptrace.h 파일에서
아래에 열거된 define의 주석 내용에 따라 (line 30)
#define GIC_PRIO_IRQON 0xf0
#define GIC_PRIO_IRQOFF (GIC_PRIO_IRQON & ~0x80) -> 0x70
"pmr에 설정되는 값이 낮을수록 더 많은 IRQ를 마스크한다 -> 값이 낮을수록 우선순위가 높다"
라고 이해하고 있습니다
여기에서 이해가 되지 않은 내용은
GIC_PRIO_IRQOFF가 가지는 값입니다
주석의 내용은 다음과 같은데
" To mask interrupts, we clear the most significant bit of PMR."
최상위 비트의 의미가 무엇이기에
해당 비트를 clear하는 것으로 IRQ OFF를 정의할 수 있을까요?
댓글 5
-
문c(문영일)
2020.02.10 22:21
-
rnsscman
2020.02.11 22:16
답변 감사드립니다 :D
답변주신 내용 중에
"인터럽트 priority filter 값에 설정한 값보다 작은 값, 즉 더 높은 우선순위들만 통과될 수 있습니다."와
그 뒤에 내용이 잘 이해되지 않아 추가 질문드립니다.
오해와 혼란을 막기 위해 "우선순위" 표현은 쓰지 않겠습니다.
v5.1 기준으로 GIC_PRIO_IRQOFF는 0x70으로 되어 있습니다
이 값보다 작은 값들만 통과될 수 있다면 필터링되는 인터럽트는 0x70 ~ 0xFF 인데
문맥적으로 필터링되는 인터럽트는 커널이 사용하는 인터럽트에 해당하는 0x80~0xFF가 되어야할 것으로 보입니다
그래서 제가 생각하는 것은 PMR에 설정된 값과
"같거나 작은 값"의 인터럽트가 통과될 수 있는 것으로 (PMR에 설정된 값보다 큰 값의 인터럽트는 필터링 되는 것으로)
보이는데 제가 잘못 이해한 것인가요?
-
문c(문영일)
2020.02.11 23:10
커널은 priority filter 값과 상관없이 0x00~0x7f를 수신하지 못합니다. 따라서 priority filter 값으로 0x70 또는 bit7만 클리어하여도 모든 인터럽트를 수신하지 못하게됩니다.
(참고로 여기서 filter는 block의 의미입니다. priority filter를 0x70으로 설정시 0x71~0xff가 block 되고,
0x00~0x70은 통과되지만 커널이 받는 영역이 아닙니다.)
-
rnsscman
2020.02.13 21:01
코드 구현이 제 생각과 달라서 이해하기 어려웠는데
설명 덕분에 내용을 받아들일 수 있을 것 같습니다
감사합니다!
-
문c(문영일)
2020.02.25 23:55
아래 참고 글을 수정 중인데, 위 질의 관련한 항목의 일부 내용을 조금 더 추가하였습니다.
Pesudo-NMI 제목을 참고하시길 바랍니다.
.
안녕하세요? 문c 블로그(http://jake.dothome.co.kr)의 문영일입니다.
인터럽트 컨트롤러 관련 내용은 다음을 참고하시기 바랍니다.
- 참고: Interrupts -1- (Interrupt Controller) | 문c
위의 내용은 아직 arm 커널 v4.0 코드로 설명되어 있고, priority filter의 bit7에 대해서 자세히 설명하지 않은 상태입니다.
곧 arm64 커널 v5.4 코드로 갱신 전에 이 댓글에서 일부 설명을 하겠습니다.
- - - - - -
발생한 인터럽트를 cpu에 전달하기까지 여러 단계를 거치는데, 그중 priority 처리에 대해서만 말씀드리겠습니다.
먼저 Distributor 블록에서 수신한 n번 인터럽트는 GICD_IPRIRITY<n>에 설정된 priority를 사용하게 됩니다.
최대 256단계를 사용하는 경우 priority 값은 0x00~0xff까지 사용되며 가장 높은 우선 순위가 0x00이고, 가장 낮은 우선 순위가 0xff입니다. 그리고 몇 개 레지스터를 거쳐 CPU interface 블록의 ICC_PMR_EL1 레지스터에 설정한 인터럽트 priority filter를 통과해야 cpu에 인터럽트가 전달될 수 있습니다.
인터럽트 priority filter 값에 설정한 값보다 작은 값, 즉 더 높은 우선순위들만 통과될 수 있습니다.
그런데 우선순위 높은 0x00~0x7f는 리눅스 커널이 아닌 secure EL3 권한을 사용하는 secure-firmware에서 처리되는 인터럽트입니다. 이에 반해 non-secure EL1 권한을 사용하는 커널은 0x80~0xff 범위의 낮은 인터럽트 번호를 사용합니다.
이러한 관계로 커널은 0x80~0xff 우선순위 범위에 해당하는 인터럽트를 받는데, priority filter의 bit7을 클리어하는 것만으로 커널이 수신할 인터럽트 priority 0x80~0xff가 모두 블록 되어 처리되지 않습니다.
priority 값을 간단히 분류하여 설명드렸지만, 실제로는 더 복잡합니다. 커널에서 이 값을 기록할 때와 읽어들일 때에도 다르게 처리됩니다. 자세한 내용은 다음에 더 드리기로 하겠습니다.
감사합니다.