diff options
author | Suresh Siddha <suresh.b.siddha@intel.com> | 2008-07-10 14:16:52 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-12 02:45:01 -0400 |
commit | 13c88fb58d0112d47f7839f24a755715c6218822 (patch) | |
tree | 32fb7ab893b6bcb687ad31bd841acf311a113252 | |
parent | 1cb11583a6c4ceda7426eb36f7bf0419da8dfbc2 (diff) |
x64, x2apic/intr-remap: x2apic ops for x2apic mode support
x2apic ops for x2apic mode support. This uses MSR interface and differs
slightly from the xapic register layout.
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: akpm@linux-foundation.org
Cc: arjan@linux.intel.com
Cc: andi@firstfloor.org
Cc: ebiederm@xmission.com
Cc: jbarnes@virtuousgeek.org
Cc: steiner@sgi.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/kernel/apic_64.c | 35 | ||||
-rw-r--r-- | include/asm-x86/apic.h | 22 | ||||
-rw-r--r-- | include/asm-x86/apicdef.h | 3 |
3 files changed, 60 insertions, 0 deletions
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index 9bb040689b31..a969ef78e12a 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -171,6 +171,41 @@ struct apic_ops __read_mostly *apic_ops = &xapic_ops; | |||
171 | 171 | ||
172 | EXPORT_SYMBOL_GPL(apic_ops); | 172 | EXPORT_SYMBOL_GPL(apic_ops); |
173 | 173 | ||
174 | static void x2apic_wait_icr_idle(void) | ||
175 | { | ||
176 | /* no need to wait for icr idle in x2apic */ | ||
177 | return; | ||
178 | } | ||
179 | |||
180 | static u32 safe_x2apic_wait_icr_idle(void) | ||
181 | { | ||
182 | /* no need to wait for icr idle in x2apic */ | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | void x2apic_icr_write(u32 low, u32 id) | ||
187 | { | ||
188 | wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low); | ||
189 | } | ||
190 | |||
191 | u64 x2apic_icr_read(void) | ||
192 | { | ||
193 | unsigned long val; | ||
194 | |||
195 | rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val); | ||
196 | return val; | ||
197 | } | ||
198 | |||
199 | static struct apic_ops x2apic_ops = { | ||
200 | .read = native_apic_msr_read, | ||
201 | .write = native_apic_msr_write, | ||
202 | .write_atomic = native_apic_msr_write, | ||
203 | .icr_read = x2apic_icr_read, | ||
204 | .icr_write = x2apic_icr_write, | ||
205 | .wait_icr_idle = x2apic_wait_icr_idle, | ||
206 | .safe_wait_icr_idle = safe_x2apic_wait_icr_idle, | ||
207 | }; | ||
208 | |||
174 | /** | 209 | /** |
175 | * enable_NMI_through_LVT0 - enable NMI through local vector table 0 | 210 | * enable_NMI_through_LVT0 - enable NMI through local vector table 0 |
176 | */ | 211 | */ |
diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index 6fda195337c5..bb54928373ca 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h | |||
@@ -7,6 +7,8 @@ | |||
7 | #include <asm/apicdef.h> | 7 | #include <asm/apicdef.h> |
8 | #include <asm/processor.h> | 8 | #include <asm/processor.h> |
9 | #include <asm/system.h> | 9 | #include <asm/system.h> |
10 | #include <asm/cpufeature.h> | ||
11 | #include <asm/msr.h> | ||
10 | 12 | ||
11 | #define ARCH_APICTIMER_STOPS_ON_C3 1 | 13 | #define ARCH_APICTIMER_STOPS_ON_C3 1 |
12 | 14 | ||
@@ -73,6 +75,26 @@ static inline u32 native_apic_mem_read(u32 reg) | |||
73 | return *((volatile u32 *)(APIC_BASE + reg)); | 75 | return *((volatile u32 *)(APIC_BASE + reg)); |
74 | } | 76 | } |
75 | 77 | ||
78 | static inline void native_apic_msr_write(u32 reg, u32 v) | ||
79 | { | ||
80 | if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR || | ||
81 | reg == APIC_LVR) | ||
82 | return; | ||
83 | |||
84 | wrmsr(APIC_BASE_MSR + (reg >> 4), v, 0); | ||
85 | } | ||
86 | |||
87 | static inline u32 native_apic_msr_read(u32 reg) | ||
88 | { | ||
89 | u32 low, high; | ||
90 | |||
91 | if (reg == APIC_DFR) | ||
92 | return -1; | ||
93 | |||
94 | rdmsr(APIC_BASE_MSR + (reg >> 4), low, high); | ||
95 | return low; | ||
96 | } | ||
97 | |||
76 | #ifdef CONFIG_X86_32 | 98 | #ifdef CONFIG_X86_32 |
77 | extern void apic_wait_icr_idle(void); | 99 | extern void apic_wait_icr_idle(void); |
78 | extern u32 safe_apic_wait_icr_idle(void); | 100 | extern u32 safe_apic_wait_icr_idle(void); |
diff --git a/include/asm-x86/apicdef.h b/include/asm-x86/apicdef.h index 6b9008c78731..bcae297b30b2 100644 --- a/include/asm-x86/apicdef.h +++ b/include/asm-x86/apicdef.h | |||
@@ -105,6 +105,7 @@ | |||
105 | #define APIC_TMICT 0x380 | 105 | #define APIC_TMICT 0x380 |
106 | #define APIC_TMCCT 0x390 | 106 | #define APIC_TMCCT 0x390 |
107 | #define APIC_TDCR 0x3E0 | 107 | #define APIC_TDCR 0x3E0 |
108 | #define APIC_SELF_IPI 0x3F0 | ||
108 | #define APIC_TDR_DIV_TMBASE (1 << 2) | 109 | #define APIC_TDR_DIV_TMBASE (1 << 2) |
109 | #define APIC_TDR_DIV_1 0xB | 110 | #define APIC_TDR_DIV_1 0xB |
110 | #define APIC_TDR_DIV_2 0x0 | 111 | #define APIC_TDR_DIV_2 0x0 |
@@ -128,6 +129,8 @@ | |||
128 | #define APIC_EILVT3 0x530 | 129 | #define APIC_EILVT3 0x530 |
129 | 130 | ||
130 | #define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) | 131 | #define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) |
132 | #define APIC_BASE_MSR 0x800 | ||
133 | #define X2APIC_ENABLE (1UL << 10) | ||
131 | 134 | ||
132 | #ifdef CONFIG_X86_32 | 135 | #ifdef CONFIG_X86_32 |
133 | # define MAX_IO_APICS 64 | 136 | # define MAX_IO_APICS 64 |