1 #ifndef __ASM_APIC_H
2 #define __ASM_APIC_H
3
4 #include <asm/apicdef.h>
5 #include <asm/fixmap.h>
6 #include <asm/msr.h>
7
8 #define Dprintk(x...) do {} while (0)
9
10 /*
11 * Debugging macros
12 */
13 #define APIC_QUIET 0
14 #define APIC_VERBOSE 1
15 #define APIC_DEBUG 2
16
17 #define SET_APIC_LOGICAL_ID(x) (((x)<<24))
18
19 /* Possible APIC states */
20 enum apic_mode {
21 APIC_MODE_INVALID, /* Not set yet */
22 APIC_MODE_DISABLED, /* If uniprocessor, or MP in uniprocessor mode */
23 APIC_MODE_XAPIC, /* xAPIC mode - default upon chipset reset */
24 APIC_MODE_X2APIC /* x2APIC mode - common for large MP machines */
25 };
26
27 extern u8 apic_verbosity;
28 extern bool directed_eoi_enabled;
29
30 void check_x2apic_preenabled(void);
31 void x2apic_bsp_setup(void);
32 void x2apic_ap_setup(void);
33 const struct genapic *apic_x2apic_probe(void);
34
35 /*
36 * Define the default level of output to be very little
37 * This can be turned up by using apic=verbose for more
38 * information and apic=debug for _lots_ of information.
39 * apic_verbosity is defined in apic.c
40 */
41 #define apic_printk(v, s, a...) do { \
42 if ((v) <= apic_verbosity) \
43 printk(s, ##a); \
44 } while (0)
45
46
47 /*
48 * Basic functions accessing APICs.
49 */
50
apic_mem_write(unsigned long reg,u32 v)51 static __inline void apic_mem_write(unsigned long reg, u32 v)
52 {
53 *((volatile u32 *)(APIC_BASE+reg)) = v;
54 }
55
apic_mem_write_atomic(unsigned long reg,u32 v)56 static __inline void apic_mem_write_atomic(unsigned long reg, u32 v)
57 {
58 (void)xchg((volatile u32 *)(APIC_BASE+reg), v);
59 }
60
apic_mem_read(unsigned long reg)61 static __inline u32 apic_mem_read(unsigned long reg)
62 {
63 return *((volatile u32 *)(APIC_BASE+reg));
64 }
65
66 /* NOTE: in x2APIC mode, we should use apic_icr_write()/apic_icr_read() to
67 * access the 64-bit ICR register.
68 */
69
apic_wrmsr(unsigned long reg,uint64_t msr_content)70 static __inline void apic_wrmsr(unsigned long reg, uint64_t msr_content)
71 {
72 if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR ||
73 reg == APIC_LVR)
74 return;
75
76 wrmsrl(APIC_MSR_BASE + (reg >> 4), msr_content);
77 }
78
apic_rdmsr(unsigned long reg)79 static __inline uint64_t apic_rdmsr(unsigned long reg)
80 {
81 uint64_t msr_content;
82
83 if (reg == APIC_DFR)
84 return -1u;
85
86 rdmsrl(APIC_MSR_BASE + (reg >> 4), msr_content);
87 return msr_content;
88 }
89
apic_write(unsigned long reg,u32 v)90 static __inline void apic_write(unsigned long reg, u32 v)
91 {
92
93 if ( x2apic_enabled )
94 apic_wrmsr(reg, v);
95 else
96 apic_mem_write(reg, v);
97 }
98
apic_write_atomic(unsigned long reg,u32 v)99 static __inline void apic_write_atomic(unsigned long reg, u32 v)
100 {
101 if ( x2apic_enabled )
102 apic_wrmsr(reg, v);
103 else
104 apic_mem_write_atomic(reg, v);
105 }
106
apic_read(unsigned long reg)107 static __inline u32 apic_read(unsigned long reg)
108 {
109 if ( x2apic_enabled )
110 return apic_rdmsr(reg);
111 else
112 return apic_mem_read(reg);
113 }
114
apic_icr_read(void)115 static __inline u64 apic_icr_read(void)
116 {
117 u32 lo, hi;
118
119 if ( x2apic_enabled )
120 return apic_rdmsr(APIC_ICR);
121 else
122 {
123 lo = apic_mem_read(APIC_ICR);
124 hi = apic_mem_read(APIC_ICR2);
125 }
126
127 return ((u64)lo) | (((u64)hi) << 32);
128 }
129
apic_icr_write(u32 low,u32 dest)130 static __inline void apic_icr_write(u32 low, u32 dest)
131 {
132 if ( x2apic_enabled )
133 apic_wrmsr(APIC_ICR, low | ((uint64_t)dest << 32));
134 else
135 {
136 apic_mem_write(APIC_ICR2, dest << 24);
137 apic_mem_write(APIC_ICR, low);
138 }
139 }
140
apic_isr_read(u8 vector)141 static __inline bool_t apic_isr_read(u8 vector)
142 {
143 return (apic_read(APIC_ISR + ((vector & ~0x1f) >> 1)) >>
144 (vector & 0x1f)) & 1;
145 }
146
get_apic_id(void)147 static __inline u32 get_apic_id(void) /* Get the physical APIC id */
148 {
149 u32 id = apic_read(APIC_ID);
150 return x2apic_enabled ? id : GET_xAPIC_ID(id);
151 }
152
153 void apic_wait_icr_idle(void);
154
155 int get_physical_broadcast(void);
156
ack_APIC_irq(void)157 static inline void ack_APIC_irq(void)
158 {
159 /* Docs say use 0 for future compatibility */
160 apic_write(APIC_EOI, 0);
161 }
162
163 extern int get_maxlvt(void);
164 extern void clear_local_APIC(void);
165 extern void connect_bsp_APIC (void);
166 extern void disconnect_bsp_APIC (int virt_wire_setup);
167 extern void disable_local_APIC (void);
168 extern int verify_local_APIC (void);
169 extern void cache_APIC_registers (void);
170 extern void sync_Arb_IDs (void);
171 extern void init_bsp_APIC (void);
172 extern void setup_local_APIC(bool bsp);
173 extern void init_apic_mappings (void);
174 extern void smp_local_timer_interrupt (struct cpu_user_regs *regs);
175 extern void setup_boot_APIC_clock (void);
176 extern void setup_secondary_APIC_clock (void);
177 extern void setup_apic_nmi_watchdog (void);
178 extern void disable_lapic_nmi_watchdog(void);
179 extern int reserve_lapic_nmi(void);
180 extern void release_lapic_nmi(void);
181 extern void self_nmi(void);
182 extern void disable_timer_nmi_watchdog(void);
183 extern void enable_timer_nmi_watchdog(void);
184 extern bool nmi_watchdog_tick(const struct cpu_user_regs *regs);
185 extern int APIC_init_uniprocessor (void);
186 extern void disable_APIC_timer(void);
187 extern void enable_APIC_timer(void);
188 extern int lapic_suspend(void);
189 extern int lapic_resume(void);
190 extern void record_boot_APIC_mode(void);
191 extern enum apic_mode current_local_apic_mode(void);
192 extern void check_for_unexpected_msi(unsigned int vector);
193
194 extern void check_nmi_watchdog(void);
195
196 extern unsigned int nmi_watchdog;
197 #define NMI_NONE 0
198 #define NMI_IO_APIC 1
199 #define NMI_LOCAL_APIC 2
200
201 #endif /* __ASM_APIC_H */
202