aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86/apic.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-x86/apic.h')
-rw-r--r--include/asm-x86/apic.h80
1 files changed, 68 insertions, 12 deletions
diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h
index 133c998161ca..d76a0839abe9 100644
--- a/include/asm-x86/apic.h
+++ b/include/asm-x86/apic.h
@@ -1,5 +1,5 @@
1#ifndef _ASM_X86_APIC_H 1#ifndef ASM_X86__APIC_H
2#define _ASM_X86_APIC_H 2#define ASM_X86__APIC_H
3 3
4#include <linux/pm.h> 4#include <linux/pm.h>
5#include <linux/delay.h> 5#include <linux/delay.h>
@@ -9,6 +9,8 @@
9#include <asm/apicdef.h> 9#include <asm/apicdef.h>
10#include <asm/processor.h> 10#include <asm/processor.h>
11#include <asm/system.h> 11#include <asm/system.h>
12#include <asm/cpufeature.h>
13#include <asm/msr.h>
12 14
13#define ARCH_APICTIMER_STOPS_ON_C3 1 15#define ARCH_APICTIMER_STOPS_ON_C3 1
14 16
@@ -47,15 +49,18 @@ extern int disable_apic;
47#ifdef CONFIG_PARAVIRT 49#ifdef CONFIG_PARAVIRT
48#include <asm/paravirt.h> 50#include <asm/paravirt.h>
49#else 51#else
50#define apic_write native_apic_write
51#define apic_read native_apic_read
52#define setup_boot_clock setup_boot_APIC_clock 52#define setup_boot_clock setup_boot_APIC_clock
53#define setup_secondary_clock setup_secondary_APIC_clock 53#define setup_secondary_clock setup_secondary_APIC_clock
54#endif 54#endif
55 55
56extern int is_vsmp_box(void); 56extern int is_vsmp_box(void);
57extern void xapic_wait_icr_idle(void);
58extern u32 safe_xapic_wait_icr_idle(void);
59extern u64 xapic_icr_read(void);
60extern void xapic_icr_write(u32, u32);
61extern int setup_profiling_timer(unsigned int);
57 62
58static inline void native_apic_write(unsigned long reg, u32 v) 63static inline void native_apic_mem_write(u32 reg, u32 v)
59{ 64{
60 volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg); 65 volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
61 66
@@ -64,21 +69,72 @@ static inline void native_apic_write(unsigned long reg, u32 v)
64 ASM_OUTPUT2("0" (v), "m" (*addr))); 69 ASM_OUTPUT2("0" (v), "m" (*addr)));
65} 70}
66 71
67static inline u32 native_apic_read(unsigned long reg) 72static inline u32 native_apic_mem_read(u32 reg)
68{ 73{
69 return *((volatile u32 *)(APIC_BASE + reg)); 74 return *((volatile u32 *)(APIC_BASE + reg));
70} 75}
71 76
72extern void apic_wait_icr_idle(void); 77static inline void native_apic_msr_write(u32 reg, u32 v)
73extern u32 safe_apic_wait_icr_idle(void); 78{
79 if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR ||
80 reg == APIC_LVR)
81 return;
82
83 wrmsr(APIC_BASE_MSR + (reg >> 4), v, 0);
84}
85
86static inline u32 native_apic_msr_read(u32 reg)
87{
88 u32 low, high;
89
90 if (reg == APIC_DFR)
91 return -1;
92
93 rdmsr(APIC_BASE_MSR + (reg >> 4), low, high);
94 return low;
95}
96
97#ifndef CONFIG_X86_32
98extern int x2apic, x2apic_preenabled;
99extern void check_x2apic(void);
100extern void enable_x2apic(void);
101extern void enable_IR_x2apic(void);
102extern void x2apic_icr_write(u32 low, u32 id);
103#endif
104
105struct apic_ops {
106 u32 (*read)(u32 reg);
107 void (*write)(u32 reg, u32 v);
108 u64 (*icr_read)(void);
109 void (*icr_write)(u32 low, u32 high);
110 void (*wait_icr_idle)(void);
111 u32 (*safe_wait_icr_idle)(void);
112};
113
114extern struct apic_ops *apic_ops;
115
116#define apic_read (apic_ops->read)
117#define apic_write (apic_ops->write)
118#define apic_icr_read (apic_ops->icr_read)
119#define apic_icr_write (apic_ops->icr_write)
120#define apic_wait_icr_idle (apic_ops->wait_icr_idle)
121#define safe_apic_wait_icr_idle (apic_ops->safe_wait_icr_idle)
122
74extern int get_physical_broadcast(void); 123extern int get_physical_broadcast(void);
75 124
125#ifdef CONFIG_X86_64
126static inline void ack_x2APIC_irq(void)
127{
128 /* Docs say use 0 for future compatibility */
129 native_apic_msr_write(APIC_EOI, 0);
130}
131#endif
132
133
76static inline void ack_APIC_irq(void) 134static inline void ack_APIC_irq(void)
77{ 135{
78 /* 136 /*
79 * ack_APIC_irq() actually gets compiled as a single instruction: 137 * ack_APIC_irq() actually gets compiled as a single instruction
80 * - a single rmw on Pentium/82489DX
81 * - a single write on P6+ cores (CONFIG_X86_GOOD_APIC)
82 * ... yummie. 138 * ... yummie.
83 */ 139 */
84 140
@@ -128,4 +184,4 @@ static inline void init_apic_mappings(void) { }
128 184
129#endif /* !CONFIG_X86_LOCAL_APIC */ 185#endif /* !CONFIG_X86_LOCAL_APIC */
130 186
131#endif /* __ASM_APIC_H */ 187#endif /* ASM_X86__APIC_H */