# GIC: 하드웨어 인터럽트 번호를 커널 처리기로 넘기기

v6.18.37 / drivers/irqchip/irq-gic-v3.c

장치가 인터럽트를 발생시키면 CPU는 GIC에서 어떤 인터럽트인지 확인하고 Linux IRQ 체계에 전달합니다. 하드웨어 번호와 Linux가 관리하는 번호는 같은 숫자라고 가정할 수 없습니다. 아래 함수는 이미 읽은 번호를 받아 특수 번호를 거르고 irq domain으로 처리기를 찾는 구간입니다.

## __gic_handle_irq

```c

static void __gic_handle_irq(u32 irqnr, struct pt_regs *regs)
{
	if (gic_irqnr_is_special(irqnr))
		return;

	gic_complete_ack(irqnr);

	if (generic_handle_domain_irq(gic_data.domain, irqnr)) {
		WARN_ONCE(true, "Unexpected interrupt (irqnr %u)\n", irqnr);
		gic_deactivate_unhandled(irqnr);
	}
}

```

### 867행

```c

static void __gic_handle_irq(u32 irqnr, struct pt_regs *regs)

```

이미 읽은 GIC 인터럽트 번호와 저장된 예외 문맥을 받아 일반 IRQ 처리를 진행합니다. 이 함수 자체가 IAR을 읽는 것은 아닙니다.

### 869행

```c

	if (gic_irqnr_is_special(irqnr))

```

irqnr가 GIC의 특수 번호 범주인지 확인합니다. 모든 숫자가 실제 장치 IRQ를 뜻하지는 않습니다.

### 870행

```c

		return;

```

특수 번호라면 일반 장치 처리기를 찾지 않고 끝냅니다.

### 872행

```c

	gic_complete_ack(irqnr);

```

인터럽트 수락 뒤 필요한 GIC 상태 처리를 수행합니다. EOI 모드 등의 세부 동작은 보조 함수 구현에 있습니다.

### 874행

```c

	if (generic_handle_domain_irq(gic_data.domain, irqnr)) {

```

GIC irq domain에서 하드웨어 번호를 해석하여 등록된 IRQ 처리 경로를 호출합니다. 0이 아닌 반환이면 처리에 문제가 있음을 의미합니다.

### 875행

```c

		WARN_ONCE(true, "Unexpected interrupt (irqnr %u)\n", irqnr);

```

예상하지 못한 인터럽트 번호를 한 번 경고하여 원인을 추적할 수 있게 합니다.

### 876행

```c

		gic_deactivate_unhandled(irqnr);

```

처리되지 않은 인터럽트를 GIC 쪽에서 비활성화하는 정리를 수행합니다. 정상 장치 드라이버의 원인 해소와는 다른 오류 경로입니다.

