apic.h 5.5 KB
Newer Older
H
H. Peter Anvin 已提交
1 2
#ifndef _ASM_X86_APIC_H
#define _ASM_X86_APIC_H
T
Thomas Gleixner 已提交
3 4 5

#include <linux/pm.h>
#include <linux/delay.h>
6 7

#include <asm/alternative.h>
T
Thomas Gleixner 已提交
8 9 10 11
#include <asm/fixmap.h>
#include <asm/apicdef.h>
#include <asm/processor.h>
#include <asm/system.h>
12 13
#include <asm/cpufeature.h>
#include <asm/msr.h>
T
Thomas Gleixner 已提交
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

#define ARCH_APICTIMER_STOPS_ON_C3	1

/*
 * Debugging macros
 */
#define APIC_QUIET   0
#define APIC_VERBOSE 1
#define APIC_DEBUG   2

/*
 * Define the default level of output to be very little
 * This can be turned up by using apic=verbose for more
 * information and apic=debug for _lots_ of information.
 * apic_verbosity is defined in apic.c
 */
#define apic_printk(v, s, a...) do {       \
		if ((v) <= apic_verbosity) \
			printk(s, ##a);    \
	} while (0)


36
#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
T
Thomas Gleixner 已提交
37
extern void generic_apic_probe(void);
38 39 40 41 42
#else
static inline void generic_apic_probe(void)
{
}
#endif
T
Thomas Gleixner 已提交
43 44 45

#ifdef CONFIG_X86_LOCAL_APIC

46
extern unsigned int apic_verbosity;
T
Thomas Gleixner 已提交
47 48
extern int local_apic_timer_c2_ok;

49
extern int disable_apic;
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

#ifdef CONFIG_SMP
extern void __inquire_remote_apic(int apicid);
#else /* CONFIG_SMP */
static inline void __inquire_remote_apic(int apicid)
{
}
#endif /* CONFIG_SMP */

static inline void default_inquire_remote_apic(int apicid)
{
	if (apic_verbosity >= APIC_DEBUG)
		__inquire_remote_apic(apicid);
}

T
Thomas Gleixner 已提交
65 66 67 68 69
/*
 * Basic functions accessing APICs.
 */
#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
70
#else
T
Thomas Gleixner 已提交
71 72
#define setup_boot_clock setup_boot_APIC_clock
#define setup_secondary_clock setup_secondary_APIC_clock
73
#endif
T
Thomas Gleixner 已提交
74

75
extern int is_vsmp_box(void);
76 77 78 79
extern void xapic_wait_icr_idle(void);
extern u32 safe_xapic_wait_icr_idle(void);
extern void xapic_icr_write(u32, u32);
extern int setup_profiling_timer(unsigned int);
80

81
static inline void native_apic_mem_write(u32 reg, u32 v)
T
Thomas Gleixner 已提交
82
{
83
	volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
T
Thomas Gleixner 已提交
84

85 86 87
	alternative_io("movl %0, %1", "xchgl %0, %1", X86_FEATURE_11AP,
		       ASM_OUTPUT2("=r" (v), "=m" (*addr)),
		       ASM_OUTPUT2("0" (v), "m" (*addr)));
T
Thomas Gleixner 已提交
88 89
}

90
static inline u32 native_apic_mem_read(u32 reg)
T
Thomas Gleixner 已提交
91 92 93 94
{
	return *((volatile u32 *)(APIC_BASE + reg));
}

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
static inline void native_apic_msr_write(u32 reg, u32 v)
{
	if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR ||
	    reg == APIC_LVR)
		return;

	wrmsr(APIC_BASE_MSR + (reg >> 4), v, 0);
}

static inline u32 native_apic_msr_read(u32 reg)
{
	u32 low, high;

	if (reg == APIC_DFR)
		return -1;

	rdmsr(APIC_BASE_MSR + (reg >> 4), low, high);
	return low;
}

Y
Yinghai Lu 已提交
115
#ifndef CONFIG_X86_32
116
extern int x2apic;
117 118 119 120
extern void check_x2apic(void);
extern void enable_x2apic(void);
extern void enable_IR_x2apic(void);
extern void x2apic_icr_write(u32 low, u32 id);
121 122 123 124 125 126 127 128 129 130 131 132 133 134
static inline int x2apic_enabled(void)
{
	int msr, msr2;

	if (!cpu_has_x2apic)
		return 0;

	rdmsr(MSR_IA32_APICBASE, msr, msr2);
	if (msr & X2APIC_ENABLE)
		return 1;
	return 0;
}
#else
#define x2apic_enabled()	0
Y
Yinghai Lu 已提交
135
#endif
136 137 138 139 140 141 142 143 144 145 146 147

struct apic_ops {
	u32 (*read)(u32 reg);
	void (*write)(u32 reg, u32 v);
	u64 (*icr_read)(void);
	void (*icr_write)(u32 low, u32 high);
	void (*wait_icr_idle)(void);
	u32 (*safe_wait_icr_idle)(void);
};

extern struct apic_ops *apic_ops;

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
static inline u32 apic_read(u32 reg)
{
	return apic_ops->read(reg);
}

static inline void apic_write(u32 reg, u32 val)
{
	apic_ops->write(reg, val);
}

static inline u64 apic_icr_read(void)
{
	return apic_ops->icr_read();
}

static inline void apic_icr_write(u32 low, u32 high)
{
	apic_ops->icr_write(low, high);
}

static inline void apic_wait_icr_idle(void)
{
	apic_ops->wait_icr_idle();
}

static inline u32 safe_apic_wait_icr_idle(void)
{
	return apic_ops->safe_wait_icr_idle();
}
177

T
Thomas Gleixner 已提交
178 179
extern int get_physical_broadcast(void);

180 181 182 183 184 185 186 187 188
#ifdef CONFIG_X86_64
static inline void ack_x2APIC_irq(void)
{
	/* Docs say use 0 for future compatibility */
	native_apic_msr_write(APIC_EOI, 0);
}
#endif


T
Thomas Gleixner 已提交
189 190 191
static inline void ack_APIC_irq(void)
{
	/*
192
	 * ack_APIC_irq() actually gets compiled as a single instruction
T
Thomas Gleixner 已提交
193 194 195 196
	 * ... yummie.
	 */

	/* Docs say use 0 for future compatibility */
197
	apic_write(APIC_EOI, 0);
T
Thomas Gleixner 已提交
198 199 200 201 202 203 204 205 206 207 208 209 210
}

extern int lapic_get_maxlvt(void);
extern void clear_local_APIC(void);
extern void connect_bsp_APIC(void);
extern void disconnect_bsp_APIC(int virt_wire_setup);
extern void disable_local_APIC(void);
extern void lapic_shutdown(void);
extern int verify_local_APIC(void);
extern void cache_APIC_registers(void);
extern void sync_Arb_IDs(void);
extern void init_bsp_APIC(void);
extern void setup_local_APIC(void);
211
extern void end_local_APIC_setup(void);
T
Thomas Gleixner 已提交
212 213 214 215
extern void init_apic_mappings(void);
extern void setup_boot_APIC_clock(void);
extern void setup_secondary_APIC_clock(void);
extern int APIC_init_uniprocessor(void);
216
extern void enable_NMI_through_LVT0(void);
T
Thomas Gleixner 已提交
217 218 219 220 221

/*
 * On 32bit this is mach-xxx local
 */
#ifdef CONFIG_X86_64
222
extern void early_init_lapic_mapping(void);
223 224 225 226 227 228
extern int apic_is_clustered_box(void);
#else
static inline int apic_is_clustered_box(void)
{
	return 0;
}
T
Thomas Gleixner 已提交
229 230
#endif

231 232
extern u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask);
extern u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask);
T
Thomas Gleixner 已提交
233 234 235 236 237


#else /* !CONFIG_X86_LOCAL_APIC */
static inline void lapic_shutdown(void) { }
#define local_apic_timer_c2_ok		1
238
static inline void init_apic_mappings(void) { }
239
static inline void disable_local_APIC(void) { }
T
Thomas Gleixner 已提交
240 241 242

#endif /* !CONFIG_X86_LOCAL_APIC */

I
Ingo Molnar 已提交
243 244 245 246
#ifdef CONFIG_X86_64
#define	SET_APIC_ID(x)		(apic->set_apic_id(x))
#else

247
#ifdef CONFIG_X86_LOCAL_APIC
I
Ingo Molnar 已提交
248
static inline unsigned default_get_apic_id(unsigned long x)
I
Ingo Molnar 已提交
249 250 251 252 253 254 255 256
{
	unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));

	if (APIC_XAPIC(ver))
		return (x >> 24) & 0xFF;
	else
		return (x >> 24) & 0x0F;
}
257
#endif
I
Ingo Molnar 已提交
258 259 260

#endif

H
H. Peter Anvin 已提交
261
#endif /* _ASM_X86_APIC_H */