1 /*
2 * Copyright (c) 2014 Travis Geiselbrecht
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8
9 #include <kernel/mp.h>
10
11 #include <arch/atomic.h>
12 #include <arch/mp.h>
13 #include <assert.h>
14 #include <kernel/spinlock.h>
15 #include <lk/debug.h>
16 #include <lk/trace.h>
17 #include <stdlib.h>
18
19 #define LOCAL_TRACE 0
20
21 #if WITH_SMP
22 /* a global state structure, aligned on cpu cache line to minimize aliasing */
23 struct mp_state mp __CPU_ALIGN;
24
mp_init(void)25 void mp_init(void) {
26 }
27
mp_reschedule(mp_cpu_mask_t target,uint flags)28 void mp_reschedule(mp_cpu_mask_t target, uint flags) {
29 uint local_cpu = arch_curr_cpu_num();
30
31 LTRACEF("local %d, target 0x%x\n", local_cpu, target);
32
33 /* mask out cpus that are not active and the local cpu */
34 target &= mp.active_cpus;
35
36 /* mask out cpus that are currently running realtime code */
37 if ((flags & MP_RESCHEDULE_FLAG_REALTIME) == 0) {
38 target &= ~mp.realtime_cpus;
39 }
40 target &= ~(1U << local_cpu);
41
42 LTRACEF("local %d, post mask target now 0x%x\n", local_cpu, target);
43
44 arch_mp_send_ipi(target, MP_IPI_RESCHEDULE);
45 }
46
mp_set_curr_cpu_active(bool active)47 void mp_set_curr_cpu_active(bool active) {
48 atomic_or((volatile int *)&mp.active_cpus, 1U << arch_curr_cpu_num());
49 }
50
mp_mbx_reschedule_irq(void)51 enum handler_return mp_mbx_reschedule_irq(void) {
52 uint cpu = arch_curr_cpu_num();
53
54 LTRACEF("cpu %u\n", cpu);
55
56 THREAD_STATS_INC(reschedule_ipis);
57
58 return (mp.active_cpus & (1U << cpu)) ? INT_RESCHEDULE : INT_NO_RESCHEDULE;
59 }
60 #endif
61