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