diff --git a/arch/arm/src/armv7-a/arm_gicv2.c b/arch/arm/src/armv7-a/arm_gicv2.c index 1469a5624e952..4f1a66912b4ba 100644 --- a/arch/arm/src/armv7-a/arm_gicv2.c +++ b/arch/arm/src/armv7-a/arm_gicv2.c @@ -167,11 +167,8 @@ void arm_gic0_initialize(void) DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL)); DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL)); - -# ifdef CONFIG_SMP_CALL DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL, nxsched_smp_call_handler, NULL)); -# endif #endif arm_gic_dump("Exit arm_gic0_initialize", true, 0); @@ -672,7 +669,21 @@ int arm_gic_irq_trigger(int irq, bool edge) return -EINVAL; } -#ifdef CONFIG_SMP_CALL +#ifdef CONFIG_SMP +/**************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Send smp call to target cpu. + * + * Input Parameters: + * cpuset - The set of CPUs to receive the SGI. + * + * Returned Value: + * None. + * + ****************************************************************************/ + void up_send_smp_call(cpu_set_t cpuset) { up_trigger_irq(GIC_SMP_CPUCALL, cpuset); diff --git a/arch/arm/src/armv7-r/arm_gicv2.c b/arch/arm/src/armv7-r/arm_gicv2.c index fb77ad1c923a7..d7513d252dce8 100644 --- a/arch/arm/src/armv7-r/arm_gicv2.c +++ b/arch/arm/src/armv7-r/arm_gicv2.c @@ -161,11 +161,8 @@ void arm_gic0_initialize(void) DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL)); DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL)); - -# ifdef CONFIG_SMP_CALL DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL, nxsched_smp_call_handler, NULL)); -# endif #endif arm_gic_dump("Exit arm_gic0_initialize", true, 0); @@ -662,7 +659,21 @@ int arm_gic_irq_trigger(int irq, bool edge) return -EINVAL; } -# ifdef CONFIG_SMP_CALL +# ifdef CONFIG_SMP +/**************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Send smp call to target cpu. + * + * Input Parameters: + * cpuset - The set of CPUs to receive the SGI. + * + * Returned Value: + * None. + * + ****************************************************************************/ + void up_send_smp_call(cpu_set_t cpuset) { up_trigger_irq(GIC_SMP_CPUCALL, cpuset); diff --git a/arch/arm/src/armv8-r/arm_gicv3.c b/arch/arm/src/armv8-r/arm_gicv3.c index 5360a078338f5..ca39b14265faa 100644 --- a/arch/arm/src/armv8-r/arm_gicv3.c +++ b/arch/arm/src/armv8-r/arm_gicv3.c @@ -569,11 +569,8 @@ static void gicv3_dist_init(void) /* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */ DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL)); - -# ifdef CONFIG_SMP_CALL DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL, nxsched_smp_call_handler, NULL)); -# endif #endif } @@ -845,7 +842,21 @@ void arm_gic_secondary_init(void) arm_gic_init(); } -# ifdef CONFIG_SMP_CALL +# ifdef CONFIG_SMP +/*************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Send smp call to target cpu. + * + * Input Parameters: + * cpuset - The set of CPUs to receive the SGI. + * + * Returned Value: + * None. + * + ***************************************************************************/ + void up_send_smp_call(cpu_set_t cpuset) { up_trigger_irq(GIC_SMP_CPUCALL, cpuset); diff --git a/arch/arm/src/cxd56xx/cxd56_cpupause.c b/arch/arm/src/cxd56xx/cxd56_cpupause.c index 2e1a6a9542862..b5e83fe2adc0f 100644 --- a/arch/arm/src/cxd56xx/cxd56_cpupause.c +++ b/arch/arm/src/cxd56xx/cxd56_cpupause.c @@ -318,6 +318,8 @@ int arm_pause_handler(int irq, void *c, void *arg) int cpu = up_cpu_index(); int ret = OK; + nxsched_smp_call_handler(irq, c, arg); + DPRINTF("cpu%d will be paused\n", cpu); /* Clear SW_INT for APP_DSP(cpu) */ @@ -362,6 +364,59 @@ int arm_pause_handler(int irq, void *c, void *arg) return ret; } +/**************************************************************************** + * Name: up_cpu_pause_async + * + * Description: + * pause task execution on the CPU + * check whether there are tasks delivered to specified cpu + * and try to run them. + * + * Input Parameters: + * cpu - The index of the CPU to be paused. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + * Assumptions: + * Called from within a critical section; + * + ****************************************************************************/ + +inline_function int up_cpu_pause_async(int cpu) +{ + /* Generate IRQ for CPU(cpu) */ + + putreg32(1, CXD56_CPU_P2_INT + (4 * cpu)); + + return OK; +} + +/**************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Send smp call to target cpu. + * + * Input Parameters: + * cpuset - The set of CPUs to receive the SGI. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_send_smp_call(cpu_set_t cpuset) +{ + int cpu; + + for (; cpuset != 0; cpuset &= ~(1 << cpu)) + { + cpu = ffs(cpuset) - 1; + up_cpu_pause_async(cpu); + } +} + /**************************************************************************** * Name: up_cpu_pause * @@ -410,7 +465,7 @@ int up_cpu_pause(int cpu) /* Generate IRQ for CPU(cpu) */ - putreg32(1, CXD56_CPU_P2_INT + (4 * cpu)); + up_cpu_pause_async(cpu); /* Wait for the other CPU to unlock g_cpu_paused meaning that * it is fully paused and ready for up_cpu_resume(); diff --git a/arch/arm/src/lc823450/lc823450_cpupause.c b/arch/arm/src/lc823450/lc823450_cpupause.c index fc5a246157b24..ef54111f4025f 100644 --- a/arch/arm/src/lc823450/lc823450_cpupause.c +++ b/arch/arm/src/lc823450/lc823450_cpupause.c @@ -238,6 +238,8 @@ int lc823450_pause_handler(int irq, void *c, void *arg) { int cpu = up_cpu_index(); + nxsched_smp_call_handler(irq, c, arg); + /* Clear : Pause IRQ */ if (irq == LC823450_IRQ_CTXM3_01) @@ -277,6 +279,66 @@ int lc823450_pause_handler(int irq, void *c, void *arg) return OK; } +/**************************************************************************** + * Name: up_cpu_pause_async + * + * Description: + * pause task execution on the CPU + * check whether there are tasks delivered to specified cpu + * and try to run them. + * + * Input Parameters: + * cpu - The index of the CPU to be paused. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + * Assumptions: + * Called from within a critical section; + * + ****************************************************************************/ + +inline_function int up_cpu_pause_async(int cpu) +{ + /* Execute Pause IRQ to CPU(cpu) */ + + if (cpu == 1) + { + putreg32(IPIREG_INTISR0_1, IPIREG); + } + else + { + putreg32(IPIREG_INTISR1_1, IPIREG); + } + + return OK; +} + +/**************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Send smp call to target cpu. + * + * Input Parameters: + * cpuset - The set of CPUs to receive the SGI. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_send_smp_call(cpu_set_t cpuset) +{ + int cpu; + + for (; cpuset != 0; cpuset &= ~(1 << cpu)) + { + cpu = ffs(cpuset) - 1; + up_cpu_pause_async(cpu); + } +} + /**************************************************************************** * Name: up_cpu_pause * @@ -325,14 +387,7 @@ int up_cpu_pause(int cpu) /* Execute Pause IRQ to CPU(cpu) */ - if (cpu == 1) - { - putreg32(IPIREG_INTISR0_1, IPIREG); - } - else - { - putreg32(IPIREG_INTISR1_1, IPIREG); - } + up_cpu_pause_async(cpu); /* Wait for the other CPU to unlock g_cpu_paused meaning that * it is fully paused and ready for up_cpu_resume(); diff --git a/arch/arm/src/rp2040/rp2040_cpupause.c b/arch/arm/src/rp2040/rp2040_cpupause.c index 44e100ef41976..22436c1830669 100644 --- a/arch/arm/src/rp2040/rp2040_cpupause.c +++ b/arch/arm/src/rp2040/rp2040_cpupause.c @@ -280,6 +280,8 @@ int arm_pause_handler(int irq, void *c, void *arg) int irqreq; uint32_t stat; + nxsched_smp_call_handler(irq, c, arg); + stat = getreg32(RP2040_SIO_FIFO_ST); if (stat & (RP2040_SIO_FIFO_ST_ROE | RP2040_SIO_FIFO_ST_WOF)) { @@ -333,6 +335,61 @@ int arm_pause_handler(int irq, void *c, void *arg) return OK; } +/**************************************************************************** + * Name: up_cpu_pause_async + * + * Description: + * pause task execution on the CPU + * check whether there are tasks delivered to specified cpu + * and try to run them. + * + * Input Parameters: + * cpu - The index of the CPU to be paused. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + * Assumptions: + * Called from within a critical section; + * + ****************************************************************************/ + +inline_function int up_cpu_pause_async(int cpu) +{ + /* Generate IRQ for CPU(cpu) */ + + while (!(getreg32(RP2040_SIO_FIFO_ST) & RP2040_SIO_FIFO_ST_RDY)) + ; + putreg32(0, RP2040_SIO_FIFO_WR); + + return OK; +} + +/**************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Send smp call to target cpu. + * + * Input Parameters: + * cpuset - The set of CPUs to receive the SGI. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_send_smp_call(cpu_set_t cpuset) +{ + int cpu; + + for (; cpuset != 0; cpuset &= ~(1 << cpu)) + { + cpu = ffs(cpuset) - 1; + up_cpu_pause_async(cpu); + } +} + /**************************************************************************** * Name: up_cpu_pause * @@ -383,9 +440,7 @@ int up_cpu_pause(int cpu) /* Generate IRQ for CPU(cpu) */ - while (!(getreg32(RP2040_SIO_FIFO_ST) & RP2040_SIO_FIFO_ST_RDY)) - ; - putreg32(0, RP2040_SIO_FIFO_WR); + up_cpu_pause_async(cpu); /* Wait for the other CPU to unlock g_cpu_paused meaning that * it is fully paused and ready for up_cpu_resume(); diff --git a/arch/arm/src/sam34/sam4cm_cpupause.c b/arch/arm/src/sam34/sam4cm_cpupause.c index dc80b3cc9d11b..d3a621df1c0eb 100644 --- a/arch/arm/src/sam34/sam4cm_cpupause.c +++ b/arch/arm/src/sam34/sam4cm_cpupause.c @@ -240,6 +240,8 @@ int arm_pause_handler(int irq, void *c, void *arg) { int cpu = up_cpu_index(); + nxsched_smp_call_handler(irq, c, arg); + /* Clear : Pause IRQ */ /* IPC Interrupt Clear Command Register (write-only) */ @@ -268,6 +270,68 @@ int arm_pause_handler(int irq, void *c, void *arg) return OK; } +/**************************************************************************** + * Name: up_cpu_pause_async + * + * Description: + * pause task execution on the CPU + * check whether there are tasks delivered to specified cpu + * and try to run them. + * + * Input Parameters: + * cpu - The index of the CPU to be paused. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + * Assumptions: + * Called from within a critical section; + * + ****************************************************************************/ + +inline_function int up_cpu_pause_async(int cpu) +{ + /* Execute Pause IRQ to CPU(cpu) */ + + /* Set IPC Interrupt (IRQ0) (write-only) */ + + if (cpu == 1) + { + putreg32(0x1, SAM_IPC1_ISCR); + } + else + { + putreg32(0x1, SAM_IPC0_ISCR); + } + + return OK; +} + +/**************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Send smp call to target cpu. + * + * Input Parameters: + * cpuset - The set of CPUs to receive the SGI. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_send_smp_call(cpu_set_t cpuset) +{ + int cpu; + + for (; cpuset != 0; cpuset &= ~(1 << cpu)) + { + cpu = ffs(cpuset) - 1; + up_cpu_pause_async(cpu); + } +} + /**************************************************************************** * Name: up_cpu_pause * @@ -318,14 +382,7 @@ int up_cpu_pause(int cpu) /* Set IPC Interrupt (IRQ0) (write-only) */ - if (cpu == 1) - { - putreg32(0x1, SAM_IPC1_ISCR); - } - else - { - putreg32(0x1, SAM_IPC0_ISCR); - } + up_cpu_pause_async(cpu); /* Wait for the other CPU to unlock g_cpu_paused meaning that * it is fully paused and ready for up_cpu_resume(); diff --git a/arch/arm64/src/common/arm64_gicv2.c b/arch/arm64/src/common/arm64_gicv2.c index 6b7a16f767c50..33a1ced3206b4 100644 --- a/arch/arm64/src/common/arm64_gicv2.c +++ b/arch/arm64/src/common/arm64_gicv2.c @@ -911,11 +911,8 @@ static void arm_gic0_initialize(void) /* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */ DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL)); - -# ifdef CONFIG_SMP_CALL DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL, nxsched_smp_call_handler, NULL)); -# endif #endif } @@ -1487,7 +1484,21 @@ int arm64_gic_raise_sgi(unsigned int sgi, uint16_t cpuset) return 0; } -# ifdef CONFIG_SMP_CALL +# ifdef CONFIG_SMP +/**************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Send smp call to target cpu. + * + * Input Parameters: + * cpuset - The set of CPUs to receive the SGI. + * + * Returned Value: + * None. + * + ****************************************************************************/ + void up_send_smp_call(cpu_set_t cpuset) { up_trigger_irq(GIC_SMP_CPUCALL, cpuset); diff --git a/arch/arm64/src/common/arm64_gicv3.c b/arch/arm64/src/common/arm64_gicv3.c index 24a3220344fef..689f56ecb840e 100644 --- a/arch/arm64/src/common/arm64_gicv3.c +++ b/arch/arm64/src/common/arm64_gicv3.c @@ -656,11 +656,8 @@ static void gicv3_dist_init(void) /* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */ DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL)); - -# ifdef CONFIG_SMP_CALL DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL, nxsched_smp_call_handler, NULL)); -# endif #endif } @@ -957,9 +954,7 @@ static void arm64_gic_init(void) #ifdef CONFIG_SMP up_enable_irq(GIC_SMP_CPUPAUSE); -# ifdef CONFIG_SMP_CALL up_enable_irq(GIC_SMP_CPUCALL); -# endif #endif } @@ -987,7 +982,21 @@ void arm64_gic_secondary_init(void) arm64_gic_init(); } -# ifdef CONFIG_SMP_CALL +# ifdef CONFIG_SMP +/*************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Send smp call to target cpu. + * + * Input Parameters: + * cpuset - The set of CPUs to receive the SGI. + * + * Returned Value: + * None. + * + ***************************************************************************/ + void up_send_smp_call(cpu_set_t cpuset) { up_trigger_irq(GIC_SMP_CPUCALL, cpuset); diff --git a/arch/risc-v/src/common/riscv_cpupause.c b/arch/risc-v/src/common/riscv_cpupause.c index be6708edbd634..624cd7e33fce4 100644 --- a/arch/risc-v/src/common/riscv_cpupause.c +++ b/arch/risc-v/src/common/riscv_cpupause.c @@ -229,6 +229,8 @@ int riscv_pause_handler(int irq, void *c, void *arg) { int cpu = up_cpu_index(); + nxsched_smp_call_handler(irq, c, arg); + /* Clear IPI (Inter-Processor-Interrupt) */ riscv_ipi_clear(cpu); @@ -259,6 +261,31 @@ int riscv_pause_handler(int irq, void *c, void *arg) return OK; } +/**************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Send smp call to target cpu. + * + * Input Parameters: + * cpuset - The set of CPUs to receive the SGI. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_send_smp_call(cpu_set_t cpuset) +{ + int cpu; + + for (; cpuset != 0; cpuset &= ~(1 << cpu)) + { + cpu = ffs(cpuset) - 1; + riscv_ipi_send(cpu); + } +} + /**************************************************************************** * Name: up_cpu_pause * diff --git a/arch/sim/src/sim/posix/sim_hostirq.c b/arch/sim/src/sim/posix/sim_hostirq.c index 4bcc050859157..ca38ab799a3a8 100644 --- a/arch/sim/src/sim/posix/sim_hostirq.c +++ b/arch/sim/src/sim/posix/sim_hostirq.c @@ -141,6 +141,7 @@ void up_irqinitialize(void) /* Register the pause handler */ sim_init_ipi(SIGUSR1); + sim_init_func_call_ipi(SIGUSR2); #endif } diff --git a/arch/sim/src/sim/posix/sim_hostsmp.c b/arch/sim/src/sim/posix/sim_hostsmp.c index d60efdc75f387..f338c5b38ac75 100644 --- a/arch/sim/src/sim/posix/sim_hostsmp.c +++ b/arch/sim/src/sim/posix/sim_hostsmp.c @@ -263,3 +263,15 @@ void host_send_ipi(int cpu) { pthread_kill(g_cpu_thread[cpu], SIGUSR1); } + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Name: host_send_func_call_ipi(int cpu) + ****************************************************************************/ + +void host_send_func_call_ipi(int cpu) +{ + pthread_kill(g_cpu_thread[cpu], SIGUSR2); +} +#endif diff --git a/arch/sim/src/sim/sim_internal.h b/arch/sim/src/sim/sim_internal.h index d8a03ac31820f..0b445befa8377 100644 --- a/arch/sim/src/sim/sim_internal.h +++ b/arch/sim/src/sim/sim_internal.h @@ -251,6 +251,7 @@ void sim_sigdeliver(void); void host_cpu0_start(void); int host_cpu_start(int cpu, void *stack, size_t size); void host_send_ipi(int cpu); +void host_send_func_call_ipi(int cpu); #endif /* sim_smpsignal.c **********************************************************/ diff --git a/arch/sim/src/sim/sim_smpsignal.c b/arch/sim/src/sim/sim_smpsignal.c index aef103b19426e..97f2e8ff42246 100644 --- a/arch/sim/src/sim/sim_smpsignal.c +++ b/arch/sim/src/sim/sim_smpsignal.c @@ -447,3 +447,44 @@ int up_cpu_resume(int cpu) return OK; } + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Name: sim_init_func_call_ipi + * + * Description: + * Attach the CPU function call request interrupt to the NuttX logic. + * + * Input Parameters: + * irq - the SIGUSR2 interrupt number + * + * Returned Value: + * On success returns OK (0), otherwise a negative value. + ****************************************************************************/ + +int sim_init_func_call_ipi(int irq) +{ + up_enable_irq(irq); + return irq_attach(irq, nxsched_smp_call_handler, NULL); +} + +/**************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Notify the cpuset cpus handler function calls. + * + ****************************************************************************/ + +void up_send_smp_call(cpu_set_t cpuset) +{ + int cpu; + + for (; cpuset != 0; cpuset &= ~(1 << cpu)) + { + cpu = ffs(cpuset) - 1; + host_send_func_call_ipi(cpu); + } +} +#endif diff --git a/arch/sparc/src/s698pm/s698pm_cpupause.c b/arch/sparc/src/s698pm/s698pm_cpupause.c index 3e7101a66dfaf..a0e5777be21ab 100644 --- a/arch/sparc/src/s698pm/s698pm_cpupause.c +++ b/arch/sparc/src/s698pm/s698pm_cpupause.c @@ -228,6 +228,8 @@ int s698pm_pause_handler(int irq, void *c, void *arg) { int cpu = up_cpu_index(); + nxsched_smp_call_handler(irq, c, arg); + /* Clear IPI (Inter-Processor-Interrupt) */ putreg32(1 << S698PM_IPI_VECTOR, S698PM_IRQREG_ICLEAR); @@ -258,6 +260,62 @@ int s698pm_pause_handler(int irq, void *c, void *arg) return OK; } +/**************************************************************************** + * Name: up_cpu_pause_async + * + * Description: + * pause task execution on the CPU + * check whether there are tasks delivered to specified cpu + * and try to run them. + * + * Input Parameters: + * cpu - The index of the CPU to be paused. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + * Assumptions: + * Called from within a critical section; + * + ****************************************************************************/ + +inline_function int up_cpu_pause_async(int cpu) +{ + uintptr_t regaddr; + + /* Execute Pause IRQ to CPU(cpu) */ + + regaddr = (uintptr_t)S698PM_IRQREG_P0_FORCE + (4 * cpu); + putreg32(1 << S698PM_IPI_VECTOR, regaddr); + + return OK; +} + +/**************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Send smp call to target cpu. + * + * Input Parameters: + * cpuset - The set of CPUs to receive the SGI. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_send_smp_call(cpu_set_t cpuset) +{ + int cpu; + + for (; cpuset != 0; cpuset &= ~(1 << cpu)) + { + cpu = ffs(cpuset) - 1; + up_cpu_pause_async(cpu); + } +} + /**************************************************************************** * Name: up_cpu_pause * @@ -280,8 +338,6 @@ int s698pm_pause_handler(int irq, void *c, void *arg) int up_cpu_pause(int cpu) { - uintptr_t regaddr; - sinfo("cpu=%d\n", cpu); #ifdef CONFIG_SCHED_INSTRUMENTATION @@ -308,8 +364,7 @@ int up_cpu_pause(int cpu) /* Execute Pause IRQ to CPU(cpu) */ - regaddr = (uintptr_t)S698PM_IRQREG_P0_FORCE + (4 * cpu); - putreg32(1 << S698PM_IPI_VECTOR, regaddr); + up_cpu_pause_async(cpu); /* Wait for the other CPU to unlock g_cpu_paused meaning that * it is fully paused and ready for up_cpu_resume(); diff --git a/arch/x86_64/src/intel64/intel64_cpupause.c b/arch/x86_64/src/intel64/intel64_cpupause.c index 22dcfff1387bf..d315df705b558 100644 --- a/arch/x86_64/src/intel64/intel64_cpupause.c +++ b/arch/x86_64/src/intel64/intel64_cpupause.c @@ -236,6 +236,8 @@ int up_pause_handler(int irq, void *c, void *arg) { int cpu = up_cpu_index(); + nxsched_smp_call_handler(irq, c, arg); + /* Check for false alarms. Such false could occur as a consequence of * some deadlock breaking logic that might have already serviced the SG2 * interrupt by calling up_cpu_paused. @@ -293,6 +295,25 @@ inline_function int up_cpu_async_pause(int cpu) return OK; } +/**************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Send smp call to target cpu. + * + * Input Parameters: + * cpuset - The set of CPUs to receive the SGI. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_send_smp_call(cpu_set_t cpuset) +{ + up_trigger_irq(SMP_IPI_IRQ, cpuset); +} + /**************************************************************************** * Name: up_cpu_pause * diff --git a/arch/xtensa/src/common/xtensa_cpupause.c b/arch/xtensa/src/common/xtensa_cpupause.c index 12cfcfa5498d5..0100c70f17fad 100644 --- a/arch/xtensa/src/common/xtensa_cpupause.c +++ b/arch/xtensa/src/common/xtensa_cpupause.c @@ -244,6 +244,31 @@ void xtensa_pause_handler(void) } } +/**************************************************************************** + * Name: up_send_smp_call + * + * Description: + * Send smp call to target cpu. + * + * Input Parameters: + * cpuset - The set of CPUs to receive the SGI. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_send_smp_call(cpu_set_t cpuset) +{ + int cpu; + + for (; cpuset != 0; cpuset &= ~(1 << cpu)) + { + cpu = ffs(cpuset) - 1; + xtensa_intercpu_interrupt(cpu, CPU_INTCODE_PAUSE); + } +} + /**************************************************************************** * Name: up_cpu_pause * diff --git a/arch/xtensa/src/esp32/esp32_intercpu_interrupt.c b/arch/xtensa/src/esp32/esp32_intercpu_interrupt.c index ad9d059a5da32..a8ec670e1e739 100644 --- a/arch/xtensa/src/esp32/esp32_intercpu_interrupt.c +++ b/arch/xtensa/src/esp32/esp32_intercpu_interrupt.c @@ -83,11 +83,13 @@ static int IRAM_ATTR esp32_fromcpu_interrupt(int fromcpu) int IRAM_ATTR esp32_fromcpu0_interrupt(int irq, void *context, void *arg) { + nxsched_smp_call_handler(irq, context, arg); return esp32_fromcpu_interrupt(0); } int IRAM_ATTR esp32_fromcpu1_interrupt(int irq, void *context, void *arg) { + nxsched_smp_call_handler(irq, context, arg); return esp32_fromcpu_interrupt(1); } diff --git a/arch/xtensa/src/esp32s3/esp32s3_intercpu_interrupt.c b/arch/xtensa/src/esp32s3/esp32s3_intercpu_interrupt.c index 2ee7601f60abb..f0374756e20cf 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_intercpu_interrupt.c +++ b/arch/xtensa/src/esp32s3/esp32s3_intercpu_interrupt.c @@ -84,11 +84,13 @@ static int IRAM_ATTR esp32s3_fromcpu_interrupt(int fromcpu) int IRAM_ATTR esp32s3_fromcpu0_interrupt(int irq, void *context, void *arg) { + nxsched_smp_call_handler(irq, context, arg); return esp32s3_fromcpu_interrupt(0); } int IRAM_ATTR esp32s3_fromcpu1_interrupt(int irq, void *context, void *arg) { + nxsched_smp_call_handler(irq, context, arg); return esp32s3_fromcpu_interrupt(1); } diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 99eb6d2ef8f8b..2bb1ea607bbbd 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -1735,7 +1735,7 @@ void up_secure_irq(int irq, bool secure); # define up_secure_irq(i, s) #endif -#ifdef CONFIG_SMP_CALL +#ifdef CONFIG_SMP /**************************************************************************** * Name: up_send_smp_call * diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index f08ed4e3a4f8e..4d35f36229bb1 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -779,7 +779,7 @@ typedef CODE void (*nxsched_foreach_t)(FAR struct tcb_s *tcb, FAR void *arg); /* This is the callback type used by nxsched_smp_call() */ -#ifdef CONFIG_SMP_CALL +#ifdef CONFIG_SMP typedef CODE int (*nxsched_smp_call_t)(FAR void *arg); #endif @@ -1623,7 +1623,7 @@ void nxsched_dumponexit(void); # define nxsched_dumponexit() #endif /* CONFIG_DUMP_ON_EXIT */ -#ifdef CONFIG_SMP_CALL +#ifdef CONFIG_SMP /**************************************************************************** * Name: nxsched_smp_call_handler * diff --git a/sched/Kconfig b/sched/Kconfig index 0bb2f02e4a556..943a15453f6a2 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -389,12 +389,6 @@ config SMP_DEFAULT_CPUSET Set the Default CPU bits. The way to use the unset CPU is to call the sched_setaffinity function to bind a task to the CPU. bit0 means CPU0. -config SMP_CALL - bool "Support SMP function call" - default n - ---help--- - Enable to support SMP function call. - endif # SMP choice diff --git a/sched/sched/CMakeLists.txt b/sched/sched/CMakeLists.txt index 4f5b4c624f2ab..51f85506e173a 100644 --- a/sched/sched/CMakeLists.txt +++ b/sched/sched/CMakeLists.txt @@ -120,7 +120,7 @@ if(CONFIG_DUMP_ON_EXIT) list(APPEND SRCS sched_dumponexit.c) endif() -if(CONFIG_SMP_CALL) +if(CONFIG_SMP) list(APPEND SRCS sched_smp.c) endif() diff --git a/sched/sched/Make.defs b/sched/sched/Make.defs index 8c94be1778f44..0ff392281a8e2 100644 --- a/sched/sched/Make.defs +++ b/sched/sched/Make.defs @@ -96,7 +96,7 @@ ifeq ($(CONFIG_DUMP_ON_EXIT),y) CSRCS += sched_dumponexit.c endif -ifeq ($(CONFIG_SMP_CALL),y) +ifeq ($(CONFIG_SMP),y) CSRCS += sched_smp.c endif