1 /*
2  * Copyright (c) 2024 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <zephyr/kernel.h>
7 #include <zephyr/irq_offload.h>
8 #include <kernel_arch_data.h>
9 #include <x86_mmu.h>
10 #include <zephyr/init.h>
11 #include <ksched.h>
12 
13 #define NR_IRQ_VECTORS (IV_NR_VECTORS - IV_IRQS)  /* # vectors free for IRQs */
14 
15 extern void (*x86_irq_funcs[NR_IRQ_VECTORS])(const void *arg);
16 extern const void *x86_irq_args[NR_IRQ_VECTORS];
17 
18 
arch_smp_init(void)19 int arch_smp_init(void)
20 {
21 	/*
22 	 * z_sched_ipi() doesn't have the same signature as a typical ISR, so
23 	 * we fudge it with a cast. the argument is ignored, no harm done.
24 	 */
25 
26 	x86_irq_funcs[CONFIG_SCHED_IPI_VECTOR - IV_IRQS] =
27 		(void *) z_sched_ipi;
28 
29 	/* TLB shootdown handling */
30 	x86_irq_funcs[CONFIG_TLB_IPI_VECTOR - IV_IRQS] = z_x86_tlb_ipi;
31 	return 0;
32 }
33 
34 /*
35  * it is not clear exactly how/where/why to abstract this, as it
36  * assumes the use of a local APIC (but there's no other mechanism).
37  */
arch_sched_broadcast_ipi(void)38 void arch_sched_broadcast_ipi(void)
39 {
40 	z_loapic_ipi(0, LOAPIC_ICR_IPI_OTHERS, CONFIG_SCHED_IPI_VECTOR);
41 }
42 
arch_sched_directed_ipi(uint32_t cpu_bitmap)43 void arch_sched_directed_ipi(uint32_t cpu_bitmap)
44 {
45 	unsigned int num_cpus = arch_num_cpus();
46 
47 	for (unsigned int i = 0; i < num_cpus; i++) {
48 		if ((cpu_bitmap & BIT(i)) == 0) {
49 			continue;
50 		}
51 
52 		z_loapic_ipi(i, LOAPIC_ICR_IPI_SPECIFIC, CONFIG_SCHED_IPI_VECTOR);
53 	}
54 }
55