1 /*
2  * Copyright (C) 2018-2022 Intel Corporation.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <types.h>
8 #include <asm/lib/bits.h>
9 #include <asm/cpu.h>
10 #include <asm/per_cpu.h>
11 #include <softirq.h>
12 
13 static softirq_handler softirq_handlers[NR_SOFTIRQS];
14 
init_softirq(void)15 void init_softirq(void)
16 {
17 }
18 
19 /*
20  * @pre: nr will not equal or large than NR_SOFTIRQS
21  */
register_softirq(uint16_t nr,softirq_handler handler)22 void register_softirq(uint16_t nr, softirq_handler handler)
23 {
24 	softirq_handlers[nr] = handler;
25 }
26 
27 /*
28  * @pre: nr will not equal or large than NR_SOFTIRQS
29  */
fire_softirq(uint16_t nr)30 void fire_softirq(uint16_t nr)
31 {
32 	bitmap_set_lock(nr, &per_cpu(softirq_pending, get_pcpu_id()));
33 }
34 
do_softirq_internal(uint16_t cpu_id)35 static void do_softirq_internal(uint16_t cpu_id)
36 {
37 	volatile uint64_t *softirq_pending_bitmap =
38 			&per_cpu(softirq_pending, cpu_id);
39 	uint16_t nr = ffs64(*softirq_pending_bitmap);
40 
41 	while (nr < NR_SOFTIRQS) {
42 		bitmap_clear_lock(nr, softirq_pending_bitmap);
43 		(*softirq_handlers[nr])(cpu_id);
44 		nr = ffs64(*softirq_pending_bitmap);
45 	}
46 }
47 
48 /*
49  * @pre: this function will only be called with irq disabled
50  */
do_softirq(void)51 void do_softirq(void)
52 {
53 	uint16_t cpu_id = get_pcpu_id();
54 
55 	if (per_cpu(softirq_servicing, cpu_id) == 0U) {
56 		per_cpu(softirq_servicing, cpu_id) = 1U;
57 
58 		CPU_IRQ_ENABLE_ON_CONFIG();
59 		do_softirq_internal(cpu_id);
60 		CPU_IRQ_DISABLE_ON_CONFIG();
61 
62 		do_softirq_internal(cpu_id);
63 		per_cpu(softirq_servicing, cpu_id) = 0U;
64 	}
65 }
66