当某个cpu想让其他cpu停下来时,会发送该IPI中断,主要的接口是machine_halt,machine_power_off,machine_restart,这些接口都会调用smp_send_stop来触发IPI_CPU_STOP中断,target cpu接收到该中断后,调用local_cpu_stop()函数: <arch/arm64/kernel/smp.c>830staticvoidlocal_cpu_stop(void)831{832set_cpu_online(sm...
比如唤醒其它 CPU 时, 调用路径为 arch_send_wakeup_ipi_mask -> smp_cross_call -> gic_raise_softirq,对应的参数为目标 CPU 以及 0 (0号SGI中断为唤醒中断). 注2:cpuhp_setup 开头的函数都是和 CPU hotplug 相关的,可以理解为注册在 CPU 热插拔时执行的回调函数, 这里的调用注册了 gic_starting_cpu ...
GIC驱动中,使用struct gic_chip_data结构体来描述GIC控制器的信息,整个驱动都是围绕着该结构体的初始化,驱动中将函数指针都初始化好,实际的工作是由中断信号触发,也就是在中断来临的时候去进行回调; struct irq_chip结构,描述的是中断控制器的底层操作函数集,这些函数集最终完成对控制器硬件的操作; struct irq_doma...
gic_cpu_mask[cpuid] = readl_gicd(GICD_ITARGETSR) & 0xff; pr_debug("gicv2 gic mask of cpu%d: 0x%x\n", cpuid, gic_cpu_mask[cpuid]); if (gic_cpu_mask[cpuid] == 0) gic_cpu_mask[cpuid] = 1 << cpuid; /* The first 32 interrupts (PPI and SGI) are banked per-cpu, so...
void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) { #ifdef BSP_USING_GICV2 arm_gic_send_sgi(0, ipi_vector, cpu_mask, 0); #elif defined(BSP_USING_GICV3) arm_gic_send_affinity_sgi(0, ipi_vector, (unsigned int *)&cpu_mask, GICV3_ROUTED_TO_SPEC); ...
VOID HalIrqSendIpi(UINT32 target, UINT32 ipi) { GicSgi(ipi, target); } VOID HalIrqSetAffinity(UINT32 irq, UINT32 cpuMask) { UINT64 affinity = MpidrToAffinity(NextCpu(0, cpuMask)); /* When ARE is on, use router */
+agintc_send_ipi(int sgi, int targetmask) +{ + int val = (sgi << 24) | (targetmask); + + __asm volatile ("msr "STR(ICC_SGI1R)", %x0" ::"r" (val)); +} Index: arch/arm64/conf/GENERIC === RCS file: /cvs/src/sys/arch/arm64/conf/GENERIC,v retrieving revision 1.23 ...
static void gicv2_mask_irq(uint32_t irq) { unsigned long flags; spin_lock_irqsave(&gicv2_lock, flags); // 写 0 无效,所以可以直接写入值 1UL << (irq % 32) // irq / 32 表示第几个 GICD_ICENABLER 寄存器 // (irq / 32) * 4,按字节算偏移,乘以 4 ...