1 /*
2  * Copyright (c) 2023 Intel corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file IRQ offload - x8664 implementation
9  */
10 
11 #include <zephyr/kernel.h>
12 #include <zephyr/init.h>
13 #include <zephyr/irq_offload.h>
14 #include <kernel_arch_data.h>
15 
16 #define NR_IRQ_VECTORS (IV_NR_VECTORS - IV_IRQS)  /* # vectors free for IRQs */
17 
18 extern void (*x86_irq_funcs[NR_IRQ_VECTORS])(const void *arg);
19 extern const void *x86_irq_args[NR_IRQ_VECTORS];
20 
21 static void (*irq_offload_funcs[CONFIG_MP_MAX_NUM_CPUS])(const void *arg);
22 static const void *irq_offload_args[CONFIG_MP_MAX_NUM_CPUS];
23 
dispatcher(const void * arg)24 static void dispatcher(const void *arg)
25 {
26 	uint8_t cpu_id = _current_cpu->id;
27 
28 	if (irq_offload_funcs[cpu_id] != NULL) {
29 		irq_offload_funcs[cpu_id](irq_offload_args[cpu_id]);
30 	}
31 }
32 
arch_irq_offload(irq_offload_routine_t routine,const void * parameter)33 void arch_irq_offload(irq_offload_routine_t routine, const void *parameter)
34 {
35 	int key = arch_irq_lock();
36 	uint8_t cpu_id = _current_cpu->id;
37 
38 	irq_offload_funcs[cpu_id] = routine;
39 	irq_offload_args[cpu_id] = parameter;
40 
41 	__asm__ volatile("int %0" : : "i" (CONFIG_IRQ_OFFLOAD_VECTOR)
42 			  : "memory");
43 
44 	arch_irq_unlock(key);
45 }
46 
arch_irq_offload_init(void)47 void arch_irq_offload_init(void)
48 {
49 	x86_irq_funcs[CONFIG_IRQ_OFFLOAD_VECTOR - IV_IRQS] = dispatcher;
50 }
51