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