# IRQ controller: GICv3, local APIC/IOAPIC와 RISC-V INTC

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

장치의 인터럽트를 처리한 뒤에는 컨트롤러에도 처리 상태를 갱신해야 합니다. arm64의 GIC, x86의 APIC 계열, RISC-V의 PLIC/AIA 등은 확인과 완료 방식이 다릅니다. 대표로 GICv3의 일반 EOI 콜백을 읽으며 Linux IRQ 번호와 하드웨어 INTID를 구분합니다.

## gic_eoi_irq

```c

static void gic_eoi_irq(struct irq_data *d)
{
	write_gicreg(irqd_to_hwirq(d), ICC_EOIR1_EL1);
	isb();

	if (gic_arm64_erratum_2941627_needed(d)) {
		/*
		 * Make sure the GIC stream deactivate packet
		 * issued by ICC_EOIR1_EL1 has completed before
		 * deactivating through GICD_IACTIVER.
		 */
		dsb(sy);
		gic_poke_irq(d, GICD_ICACTIVER);
	}
}

```

### 719행

```c

static void gic_eoi_irq(struct irq_data *d)

```

일반 GIC EOI 경로의 IRQ chip 콜백입니다. 다른 EOImode용 콜백도 있으므로 모든 GIC 종료를 이 한 함수로 일반화하지 않습니다.

### 721행

```c

	write_gicreg(irqd_to_hwirq(d), ICC_EOIR1_EL1);

```

irq_data에서 하드웨어 INTID를 얻어 ICC_EOIR1_EL1에 씁니다. Linux IRQ 번호를 그대로 쓰는 것이 아니라 GIC가 이해하는 번호를 사용합니다.

### 722행

```c

	isb();

```

ISB로 CPU 인터페이스 시스템 레지스터 접근 뒤의 명령 실행을 동기화합니다.

### 724행

```c

	if (gic_arm64_erratum_2941627_needed(d)) {

```

해당 인터럽트 처리에 Arm erratum 2941627 보완이 필요한지 검사합니다. 참인 시스템에서만 추가 경로를 실행합니다.

### 730행

```c

		dsb(sy);

```

EOIR로 발생한 GIC stream deactivate가 필요한 완료 조건을 만족하도록 DSB SY를 수행합니다. 앞의 ISB와 다른 역할입니다.

### 731행

```c

		gic_poke_irq(d, GICD_ICACTIVER);

```

해당 인터럽트의 active 상태를 GICD_ICACTIVER에 쓰는 방식으로 지웁니다. active는 현재 처리 중임을 나타내는 상태이며 IRQ의 enable 비트를 내려 앞으로의 수신을 차단하는 동작과 다릅니다. 앞의 완료 처리만으로 충분하지 않은 하드웨어 erratum 조건에서 추가로 수행합니다.

