diff options
Diffstat (limited to 'include/asm-x86/apic.h')
-rw-r--r-- | include/asm-x86/apic.h | 80 |
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 | ||
56 | extern int is_vsmp_box(void); | 56 | extern int is_vsmp_box(void); |
57 | extern void xapic_wait_icr_idle(void); | ||
58 | extern u32 safe_xapic_wait_icr_idle(void); | ||
59 | extern u64 xapic_icr_read(void); | ||
60 | extern void xapic_icr_write(u32, u32); | ||
61 | extern int setup_profiling_timer(unsigned int); | ||
57 | 62 | ||
58 | static inline void native_apic_write(unsigned long reg, u32 v) | 63 | static 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 | ||
67 | static inline u32 native_apic_read(unsigned long reg) | 72 | static 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 | ||
72 | extern void apic_wait_icr_idle(void); | 77 | static inline void native_apic_msr_write(u32 reg, u32 v) |
73 | extern 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 | |||
86 | static 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 | ||
98 | extern int x2apic, x2apic_preenabled; | ||
99 | extern void check_x2apic(void); | ||
100 | extern void enable_x2apic(void); | ||
101 | extern void enable_IR_x2apic(void); | ||
102 | extern void x2apic_icr_write(u32 low, u32 id); | ||
103 | #endif | ||
104 | |||
105 | struct 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 | |||
114 | extern 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 | |||
74 | extern int get_physical_broadcast(void); | 123 | extern int get_physical_broadcast(void); |
75 | 124 | ||
125 | #ifdef CONFIG_X86_64 | ||
126 | static 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 | |||
76 | static inline void ack_APIC_irq(void) | 134 | static 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 */ |