| 1 | /* @title: IPIs */ |
| 2 | #pragma once |
| 3 | #include <stdbool.h> |
| 4 | #include <stdint.h> |
| 5 | #include <types/types.h> |
| 6 | |
| 7 | struct cpu_mask; |
| 8 | |
| 9 | enum ipi_mask_flags { |
| 10 | IPI_MASK_EXACT = 0, /* Only CPUs in the mask take the IPI */ |
| 11 | IPI_MASK_SUPERSET_OK = 1 << 0, /* Others may too */ |
| 12 | }; |
| 13 | |
| 14 | /* Broadcast instead of exact if (sends_needed - 1) * 256 |
| 15 | * >= bystanders * IPI_BCAST_RATIO_Q8 where ratio is (bystander interrupt cost / |
| 16 | * cost of one send) */ |
| 17 | #define IPI_BCAST_RATIO_Q8 (16 * 256) |
| 18 | |
| 19 | void ipi_send(cpu_id_t cpu, uint8_t vector); |
| 20 | |
| 21 | /* Fails instead of waiting if a send is still in flight */ |
| 22 | bool ipi_send_try(cpu_id_t cpu, uint8_t vector); |
| 23 | |
| 24 | /* How many IPIs does it take to bother targets? */ |
| 25 | size_t ipi_send_cost(const struct cpu_mask *targets); |
| 26 | |
| 27 | /* Picks shorthand / KVM PV / x2APIC cluster / physical per call */ |
| 28 | void ipi_send_mask(const struct cpu_mask *targets, uint8_t vector, |
| 29 | enum ipi_mask_flags flags); |
| 30 | |
| 31 | void nmi_send(cpu_id_t cpu); |
| 32 | |
| 33 | /* NMIs every CPU except `self`, for the panic path */ |
| 34 | void nmi_send_others(cpu_id_t self); |
| 35 | |