apic.h 5.4 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 36 37 38 39

#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)


extern void generic_apic_probe(void);

#ifdef CONFIG_X86_LOCAL_APIC

40
extern unsigned int apic_verbosity;
T
Thomas Gleixner 已提交
41 42
extern int local_apic_timer_c2_ok;

43
extern int disable_apic;
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

#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 已提交
59 60 61 62 63
/*
 * Basic functions accessing APICs.
 */
#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
64
#else
T
Thomas Gleixner 已提交
65 66
#define setup_boot_clock setup_boot_APIC_clock
#define setup_secondary_clock setup_secondary_APIC_clock
67
#endif
T
Thomas Gleixner 已提交
68

69
extern int is_vsmp_box(void);
70 71 72 73
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);
74

75
static inline void native_apic_mem_write(u32 reg, u32 v)
T
Thomas Gleixner 已提交
76
{
77
	volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
T
Thomas Gleixner 已提交
78

79 80 81
	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 已提交
82 83
}

84
static inline u32 native_apic_mem_read(u32 reg)
T
Thomas Gleixner 已提交
85 86 87 88
{
	return *((volatile u32 *)(APIC_BASE + reg));
}

89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
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 已提交
109
#ifndef CONFIG_X86_32
110
extern int x2apic;
111 112 113 114
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);
115 116 117 118 119 120 121 122 123 124 125 126 127 128
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 已提交
129
#endif
130 131 132 133 134 135 136 137 138 139 140 141

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;

142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
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();
}
171

T
Thomas Gleixner 已提交
172 173
extern int get_physical_broadcast(void);

174 175 176 177 178 179 180 181 182
#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 已提交
183 184 185
static inline void ack_APIC_irq(void)
{
	/*
186
	 * ack_APIC_irq() actually gets compiled as a single instruction
T
Thomas Gleixner 已提交
187 188 189 190
	 * ... yummie.
	 */

	/* Docs say use 0 for future compatibility */
191
	apic_write(APIC_EOI, 0);
T
Thomas Gleixner 已提交
192 193 194 195 196 197 198 199 200 201 202 203 204
}

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);
205
extern void end_local_APIC_setup(void);
T
Thomas Gleixner 已提交
206 207 208 209
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);
210
extern void enable_NMI_through_LVT0(void);
T
Thomas Gleixner 已提交
211 212 213 214 215

/*
 * On 32bit this is mach-xxx local
 */
#ifdef CONFIG_X86_64
216
extern void early_init_lapic_mapping(void);
217 218 219 220 221 222
extern int apic_is_clustered_box(void);
#else
static inline int apic_is_clustered_box(void)
{
	return 0;
}
T
Thomas Gleixner 已提交
223 224
#endif

225 226
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 已提交
227 228 229 230 231


#else /* !CONFIG_X86_LOCAL_APIC */
static inline void lapic_shutdown(void) { }
#define local_apic_timer_c2_ok		1
232
static inline void init_apic_mappings(void) { }
233
static inline void disable_local_APIC(void) { }
T
Thomas Gleixner 已提交
234 235 236

#endif /* !CONFIG_X86_LOCAL_APIC */

I
Ingo Molnar 已提交
237 238 239 240
#ifdef CONFIG_X86_64
#define	SET_APIC_ID(x)		(apic->set_apic_id(x))
#else

241
#ifdef CONFIG_X86_LOCAL_APIC
I
Ingo Molnar 已提交
242
static inline unsigned default_get_apic_id(unsigned long x)
I
Ingo Molnar 已提交
243 244 245 246 247 248 249 250
{
	unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));

	if (APIC_XAPIC(ver))
		return (x >> 24) & 0xFF;
	else
		return (x >> 24) & 0x0F;
}
251
#endif
I
Ingo Molnar 已提交
252 253 254

#endif

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