1 | #ifndef _ASM_X86_IPI_H |
2 | #define _ASM_X86_IPI_H |
3 | |
4 | #ifdef CONFIG_X86_LOCAL_APIC |
5 | |
6 | /* |
7 | * Copyright 2004 James Cleverdon, IBM. |
8 | * Subject to the GNU Public License, v.2 |
9 | * |
10 | * Generic APIC InterProcessor Interrupt code. |
11 | * |
12 | * Moved to include file by James Cleverdon from |
13 | * arch/x86-64/kernel/smp.c |
14 | * |
15 | * Copyrights from kernel/smp.c: |
16 | * |
17 | * (c) 1995 Alan Cox, Building #3 <alan@redhat.com> |
18 | * (c) 1998-99, 2000 Ingo Molnar <mingo@redhat.com> |
19 | * (c) 2002,2003 Andi Kleen, SuSE Labs. |
20 | * Subject to the GNU Public License, v.2 |
21 | */ |
22 | |
23 | #include <asm/hw_irq.h> |
24 | #include <asm/apic.h> |
25 | #include <asm/smp.h> |
26 | |
27 | /* |
28 | * the following functions deal with sending IPIs between CPUs. |
29 | * |
30 | * We use 'broadcast', CPU->CPU IPIs and self-IPIs too. |
31 | */ |
32 | |
33 | static inline unsigned int __prepare_ICR(unsigned int shortcut, int vector, |
34 | unsigned int dest) |
35 | { |
36 | unsigned int icr = shortcut | dest; |
37 | |
38 | switch (vector) { |
39 | default: |
40 | icr |= APIC_DM_FIXED | vector; |
41 | break; |
42 | case NMI_VECTOR: |
43 | icr |= APIC_DM_NMI; |
44 | break; |
45 | } |
46 | return icr; |
47 | } |
48 | |
49 | static inline int __prepare_ICR2(unsigned int mask) |
50 | { |
51 | return SET_APIC_DEST_FIELD(mask); |
52 | } |
53 | |
54 | static inline void __xapic_wait_icr_idle(void) |
55 | { |
56 | while (native_apic_mem_read(APIC_ICR) & APIC_ICR_BUSY) |
57 | cpu_relax(); |
58 | } |
59 | |
60 | void __default_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest); |
61 | |
62 | /* |
63 | * This is used to send an IPI with no shorthand notation (the destination is |
64 | * specified in bits 56 to 63 of the ICR). |
65 | */ |
66 | void __default_send_IPI_dest_field(unsigned int mask, int vector, unsigned int dest); |
67 | |
68 | extern void default_send_IPI_single(int cpu, int vector); |
69 | extern void default_send_IPI_single_phys(int cpu, int vector); |
70 | extern void default_send_IPI_mask_sequence_phys(const struct cpumask *mask, |
71 | int vector); |
72 | extern void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask, |
73 | int vector); |
74 | |
75 | /* Avoid include hell */ |
76 | #define NMI_VECTOR 0x02 |
77 | |
78 | extern int no_broadcast; |
79 | |
80 | static inline void __default_local_send_IPI_allbutself(int vector) |
81 | { |
82 | if (no_broadcast || vector == NMI_VECTOR) |
83 | apic->send_IPI_mask_allbutself(cpu_online_mask, vector); |
84 | else |
85 | __default_send_IPI_shortcut(APIC_DEST_ALLBUT, vector, apic->dest_logical); |
86 | } |
87 | |
88 | static inline void __default_local_send_IPI_all(int vector) |
89 | { |
90 | if (no_broadcast || vector == NMI_VECTOR) |
91 | apic->send_IPI_mask(cpu_online_mask, vector); |
92 | else |
93 | __default_send_IPI_shortcut(APIC_DEST_ALLINC, vector, apic->dest_logical); |
94 | } |
95 | |
96 | #ifdef CONFIG_X86_32 |
97 | extern void default_send_IPI_mask_sequence_logical(const struct cpumask *mask, |
98 | int vector); |
99 | extern void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask, |
100 | int vector); |
101 | extern void default_send_IPI_mask_logical(const struct cpumask *mask, |
102 | int vector); |
103 | extern void default_send_IPI_allbutself(int vector); |
104 | extern void default_send_IPI_all(int vector); |
105 | extern void default_send_IPI_self(int vector); |
106 | #endif |
107 | |
108 | #endif |
109 | |
110 | #endif /* _ASM_X86_IPI_H */ |
111 | |