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.h96
1 files changed, 82 insertions, 14 deletions
diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h
index 133c998161ca..ef1d72dbdfe0 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
@@ -38,8 +40,6 @@ extern void generic_apic_probe(void);
38extern unsigned int apic_verbosity; 40extern unsigned int apic_verbosity;
39extern int local_apic_timer_c2_ok; 41extern int local_apic_timer_c2_ok;
40 42
41extern int ioapic_force;
42
43extern int disable_apic; 43extern int disable_apic;
44/* 44/*
45 * Basic functions accessing APICs. 45 * Basic functions accessing APICs.
@@ -47,15 +47,18 @@ extern int disable_apic;
47#ifdef CONFIG_PARAVIRT 47#ifdef CONFIG_PARAVIRT
48#include <asm/paravirt.h> 48#include <asm/paravirt.h>
49#else 49#else
50#define apic_write native_apic_write
51#define apic_read native_apic_read
52#define setup_boot_clock setup_boot_APIC_clock 50#define setup_boot_clock setup_boot_APIC_clock
53#define setup_secondary_clock setup_secondary_APIC_clock 51#define setup_secondary_clock setup_secondary_APIC_clock
54#endif 52#endif
55 53
56extern int is_vsmp_box(void); 54extern int is_vsmp_box(void);
55extern void xapic_wait_icr_idle(void);
56extern u32 safe_xapic_wait_icr_idle(void);
57extern u64 xapic_icr_read(void);
58extern void xapic_icr_write(u32, u32);
59extern int setup_profiling_timer(unsigned int);
57 60
58static inline void native_apic_write(unsigned long reg, u32 v) 61static inline void native_apic_mem_write(u32 reg, u32 v)
59{ 62{
60 volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg); 63 volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
61 64
@@ -64,21 +67,86 @@ static inline void native_apic_write(unsigned long reg, u32 v)
64 ASM_OUTPUT2("0" (v), "m" (*addr))); 67 ASM_OUTPUT2("0" (v), "m" (*addr)));
65} 68}
66 69
67static inline u32 native_apic_read(unsigned long reg) 70static inline u32 native_apic_mem_read(u32 reg)
68{ 71{
69 return *((volatile u32 *)(APIC_BASE + reg)); 72 return *((volatile u32 *)(APIC_BASE + reg));
70} 73}
71 74
72extern void apic_wait_icr_idle(void); 75static inline void native_apic_msr_write(u32 reg, u32 v)
73extern u32 safe_apic_wait_icr_idle(void); 76{
77 if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR ||
78 reg == APIC_LVR)
79 return;
80
81 wrmsr(APIC_BASE_MSR + (reg >> 4), v, 0);
82}
83
84static inline u32 native_apic_msr_read(u32 reg)
85{
86 u32 low, high;
87
88 if (reg == APIC_DFR)
89 return -1;
90
91 rdmsr(APIC_BASE_MSR + (reg >> 4), low, high);
92 return low;
93}
94
95#ifndef CONFIG_X86_32
96extern int x2apic, x2apic_preenabled;
97extern void check_x2apic(void);
98extern void enable_x2apic(void);
99extern void enable_IR_x2apic(void);
100extern void x2apic_icr_write(u32 low, u32 id);
101static inline int x2apic_enabled(void)
102{
103 int msr, msr2;
104
105 if (!cpu_has_x2apic)
106 return 0;
107
108 rdmsr(MSR_IA32_APICBASE, msr, msr2);
109 if (msr & X2APIC_ENABLE)
110 return 1;
111 return 0;
112}
113#else
114#define x2apic_enabled() 0
115#endif
116
117struct apic_ops {
118 u32 (*read)(u32 reg);
119 void (*write)(u32 reg, u32 v);
120 u64 (*icr_read)(void);
121 void (*icr_write)(u32 low, u32 high);
122 void (*wait_icr_idle)(void);
123 u32 (*safe_wait_icr_idle)(void);
124};
125
126extern struct apic_ops *apic_ops;
127
128#define apic_read (apic_ops->read)
129#define apic_write (apic_ops->write)
130#define apic_icr_read (apic_ops->icr_read)
131#define apic_icr_write (apic_ops->icr_write)
132#define apic_wait_icr_idle (apic_ops->wait_icr_idle)
133#define safe_apic_wait_icr_idle (apic_ops->safe_wait_icr_idle)
134
74extern int get_physical_broadcast(void); 135extern int get_physical_broadcast(void);
75 136
137#ifdef CONFIG_X86_64
138static inline void ack_x2APIC_irq(void)
139{
140 /* Docs say use 0 for future compatibility */
141 native_apic_msr_write(APIC_EOI, 0);
142}
143#endif
144
145
76static inline void ack_APIC_irq(void) 146static inline void ack_APIC_irq(void)
77{ 147{
78 /* 148 /*
79 * ack_APIC_irq() actually gets compiled as a single instruction: 149 * 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. 150 * ... yummie.
83 */ 151 */
84 152
@@ -128,4 +196,4 @@ static inline void init_apic_mappings(void) { }
128 196
129#endif /* !CONFIG_X86_LOCAL_APIC */ 197#endif /* !CONFIG_X86_LOCAL_APIC */
130 198
131#endif /* __ASM_APIC_H */ 199#endif /* ASM_X86__APIC_H */