1 // © 2021 Qualcomm Innovation Center, Inc. All rights reserved. 2 // 3 // SPDX-License-Identifier: BSD-3-Clause 4 5 // Routines for handling inter-processor interrupts. 6 // 7 // Modules may register an IPI reason code, and an associated handler for the 8 // ipi_received event. When an IPI is targeted at an online CPU, and has not 9 // been masked by that CPU, the handler for the IPI's reason code will be run on 10 // the CPU. Handlers run with preemption disabled, and may run from the idle 11 // thread or an interrupt handler; they return a boolean value which indicates 12 // whether a reschedule is needed. 13 // 14 // Each handler call is preceded by an acquire barrier which synchronises with 15 // the release barrier that was performed when the IPI was sent. Any subsequent 16 // IPI send operation that does not synchronise with that acquire barrier is 17 // guaranteed to trigger another call to the handler. A duplicate IPI send that 18 // does synchronise with the handler's acquire barrier may or may not trigger 19 // another handler call. 20 // 21 // If a _relaxed function is used to send an IPI, the targeted CPU(s) will 22 // handle the IPI next time they switch contexts. There is no particular promise 23 // of timely handling, even on idle CPUs. 24 // 25 // If an _idle function is used to send an IPI, it is guaranteed to be handled 26 // quickly whenever the targeted CPU(s) are idle. It will avoid interrupting a 27 // busy CPU if possible. This may be an alias of the corresponding _relaxed 28 // function if relaxed IPIs are guaranteed to wake idle CPUs; otherwise it is an 29 // alias of the corresponding normal IPI function. The _idle functions in the 30 // IPI module interface cannot wake the target CPU from suspend, therefore, 31 // using these functions incorrectly may lead to an indefinite CPU suspend, 32 // causing the system to hang. 33 // 34 // All of the receive-side functions below must be called with preemption 35 // disabled, except where noted. 36 37 // Send the specified IPI to all online CPUs other than the caller. 38 // 39 // This implies a release barrier. 40 void 41 ipi_others(ipi_reason_t ipi) REQUIRE_PREEMPT_DISABLED; 42 43 // Send the specified IPI to all online CPUs other than the caller, with low 44 // priority. 45 // 46 // This implies a release barrier. 47 void 48 ipi_others_relaxed(ipi_reason_t ipi) REQUIRE_PREEMPT_DISABLED; 49 50 // Send the specified IPI to all online CPUs other than the caller, with low 51 // priority, guaranteeing that idle CPUs will wake. 52 // 53 // This implies a release barrier. 54 // 55 // Do not use with the intention of waking a suspended CPU. 56 void 57 ipi_others_idle(ipi_reason_t ipi) REQUIRE_PREEMPT_DISABLED; 58 59 // Send the specified IPI to a single CPU. 60 // 61 // This implies a release barrier. 62 void 63 ipi_one(ipi_reason_t ipi, cpu_index_t cpu); 64 65 // Send the specified IPI to a single CPU, with low priority. 66 // 67 // This implies a release barrier. 68 void 69 ipi_one_relaxed(ipi_reason_t ipi, cpu_index_t cpu); 70 71 // Send the specified IPI to a single CPU, with low priority, guaranteeing that 72 // it will wake if idle. 73 // 74 // This implies a release barrier. 75 // 76 // Do not use with the intention of waking a suspended CPU. 77 void 78 ipi_one_idle(ipi_reason_t ipi, cpu_index_t cpu); 79 80 // Atomically check and clear the specified IPI reason. 81 // 82 // This can be used to prevent redundant invocations of an IPI handler. Call 83 // it immediately prior to taking the same action that the handler would take. 84 // However, note that it may incorrectly return false when called in an IPI 85 // handler, including a handler for a different IPI than the one being cleared. 86 // 87 // This function executes an acquire operation before returning true, equivalent 88 // to the acquire operation that is executed before calling a handler. 89 // 90 // If possible, this function will cancel any pending physical IPIs that other 91 // CPUs have asserted to signal the IPI, but note that not all interrupt 92 // controllers can reliably cancel an IPI without handling it. 93 // 94 // This function may be safely called with preemption enabled, from any context. 95 // However, its result must be ignored if it is called in an IPI handler or with 96 // preemption enabled. 97 bool 98 ipi_clear(ipi_reason_t ipi) REQUIRE_PREEMPT_DISABLED; 99 100 // Atomically check and clear the specified IPI, assuming it was a relaxed IPI. 101 // 102 // This can be used to prevent redundant invocations of an IPI handler. Call 103 // it immediately prior to taking the same action that the handler would take. 104 // 105 // This function executes an acquire operation before returning true, equivalent 106 // to the acquire operation that is executed before calling a handler. 107 // 108 // This function does not attempt to cancel pending physical IPIs, and therefore 109 // can avoid the cost of interacting with the interrupt controller for IPIs that 110 // are always, or mostly, raised using the _relaxed functions. 111 bool 112 ipi_clear_relaxed(ipi_reason_t ipi) REQUIRE_PREEMPT_DISABLED; 113 114 // Immediately handle any relaxed IPIs. 115 // 116 // Returns true if a reschedule is needed. 117 bool 118 ipi_handle_relaxed(void) REQUIRE_PREEMPT_DISABLED; 119