1/* @title: IPIs */
2#pragma once
3#include <stdbool.h>
4#include <stdint.h>
5#include <types/types.h>
6
7struct cpu_mask;
8
9enum 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
19void ipi_send(cpu_id_t cpu, uint8_t vector);
20
21/* Fails instead of waiting if a send is still in flight */
22bool ipi_send_try(cpu_id_t cpu, uint8_t vector);
23
24/* How many IPIs does it take to bother targets? */
25size_t ipi_send_cost(const struct cpu_mask *targets);
26
27/* Picks shorthand / KVM PV / x2APIC cluster / physical per call */
28void ipi_send_mask(const struct cpu_mask *targets, uint8_t vector,
29 enum ipi_mask_flags flags);
30
31void nmi_send(cpu_id_t cpu);
32
33/* NMIs every CPU except `self`, for the panic path */
34void nmi_send_others(cpu_id_t self);
35