ia64/xen-unstable

annotate xen/arch/x86/apic.c @ 1452:92b8e1efa784

bitkeeper revision 1.952 (40c8935a3XSRdQfnx5RoO7XgaggvOQ)

Towards x86_64 support. Merged a bunch of the existing x86_64 stuff
back into a generic 'x86' architecture. Aim is to share as much
as possible between 32- and 64-bit worlds.
author kaf24@scramble.cl.cam.ac.uk
date Thu Jun 10 16:59:06 2004 +0000 (2004-06-10)
parents
children 4f79516ed019
rev   line source
kaf24@1452 1 /*
kaf24@1452 2 * Local APIC handling, local APIC timers
kaf24@1452 3 *
kaf24@1452 4 * (c) 1999, 2000 Ingo Molnar <mingo@redhat.com>
kaf24@1452 5 *
kaf24@1452 6 * Fixes
kaf24@1452 7 * Maciej W. Rozycki : Bits for genuine 82489DX APICs;
kaf24@1452 8 * thanks to Eric Gilmore
kaf24@1452 9 * and Rolf G. Tews
kaf24@1452 10 * for testing these extensively.
kaf24@1452 11 * Maciej W. Rozycki : Various updates and fixes.
kaf24@1452 12 * Mikael Pettersson : Power Management for UP-APIC.
kaf24@1452 13 */
kaf24@1452 14
kaf24@1452 15
kaf24@1452 16 #include <xen/config.h>
kaf24@1452 17 #include <xen/init.h>
kaf24@1452 18 #include <xen/sched.h>
kaf24@1452 19 #include <xen/irq.h>
kaf24@1452 20 #include <xen/delay.h>
kaf24@1452 21 #include <asm/mc146818rtc.h>
kaf24@1452 22 #include <asm/msr.h>
kaf24@1452 23 #include <xen/errno.h>
kaf24@1452 24 #include <asm/atomic.h>
kaf24@1452 25 #include <xen/smp.h>
kaf24@1452 26 #include <xen/interrupt.h>
kaf24@1452 27 #include <asm/mpspec.h>
kaf24@1452 28 #include <asm/flushtlb.h>
kaf24@1452 29 #include <asm/hardirq.h>
kaf24@1452 30 #include <asm/apic.h>
kaf24@1452 31 #include <xen/mm.h>
kaf24@1452 32 #include <asm/io_apic.h>
kaf24@1452 33 #include <asm/timex.h>
kaf24@1452 34 #include <xen/ac_timer.h>
kaf24@1452 35 #include <xen/perfc.h>
kaf24@1452 36
kaf24@1452 37
kaf24@1452 38 /* Using APIC to generate smp_local_timer_interrupt? */
kaf24@1452 39 int using_apic_timer = 0;
kaf24@1452 40
kaf24@1452 41 static int enabled_via_apicbase;
kaf24@1452 42
kaf24@1452 43 int get_maxlvt(void)
kaf24@1452 44 {
kaf24@1452 45 unsigned int v, ver, maxlvt;
kaf24@1452 46
kaf24@1452 47 v = apic_read(APIC_LVR);
kaf24@1452 48 ver = GET_APIC_VERSION(v);
kaf24@1452 49 /* 82489DXs do not report # of LVT entries. */
kaf24@1452 50 maxlvt = APIC_INTEGRATED(ver) ? GET_APIC_MAXLVT(v) : 2;
kaf24@1452 51 return maxlvt;
kaf24@1452 52 }
kaf24@1452 53
kaf24@1452 54 void clear_local_APIC(void)
kaf24@1452 55 {
kaf24@1452 56 int maxlvt;
kaf24@1452 57 unsigned long v;
kaf24@1452 58
kaf24@1452 59 maxlvt = get_maxlvt();
kaf24@1452 60
kaf24@1452 61 /*
kaf24@1452 62 * Masking an LVT entry on a P6 can trigger a local APIC error
kaf24@1452 63 * if the vector is zero. Mask LVTERR first to prevent this.
kaf24@1452 64 */
kaf24@1452 65 if (maxlvt >= 3) {
kaf24@1452 66 v = ERROR_APIC_VECTOR; /* any non-zero vector will do */
kaf24@1452 67 apic_write_around(APIC_LVTERR, v | APIC_LVT_MASKED);
kaf24@1452 68 }
kaf24@1452 69 /*
kaf24@1452 70 * Careful: we have to set masks only first to deassert
kaf24@1452 71 * any level-triggered sources.
kaf24@1452 72 */
kaf24@1452 73 v = apic_read(APIC_LVTT);
kaf24@1452 74 apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED);
kaf24@1452 75 v = apic_read(APIC_LVT0);
kaf24@1452 76 apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
kaf24@1452 77 v = apic_read(APIC_LVT1);
kaf24@1452 78 apic_write_around(APIC_LVT1, v | APIC_LVT_MASKED);
kaf24@1452 79 if (maxlvt >= 4) {
kaf24@1452 80 v = apic_read(APIC_LVTPC);
kaf24@1452 81 apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED);
kaf24@1452 82 }
kaf24@1452 83
kaf24@1452 84 /*
kaf24@1452 85 * Clean APIC state for other OSs:
kaf24@1452 86 */
kaf24@1452 87 apic_write_around(APIC_LVTT, APIC_LVT_MASKED);
kaf24@1452 88 apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
kaf24@1452 89 apic_write_around(APIC_LVT1, APIC_LVT_MASKED);
kaf24@1452 90 if (maxlvt >= 3)
kaf24@1452 91 apic_write_around(APIC_LVTERR, APIC_LVT_MASKED);
kaf24@1452 92 if (maxlvt >= 4)
kaf24@1452 93 apic_write_around(APIC_LVTPC, APIC_LVT_MASKED);
kaf24@1452 94 v = GET_APIC_VERSION(apic_read(APIC_LVR));
kaf24@1452 95 if (APIC_INTEGRATED(v)) { /* !82489DX */
kaf24@1452 96 if (maxlvt > 3)
kaf24@1452 97 apic_write(APIC_ESR, 0);
kaf24@1452 98 apic_read(APIC_ESR);
kaf24@1452 99 }
kaf24@1452 100 }
kaf24@1452 101
kaf24@1452 102 void __init connect_bsp_APIC(void)
kaf24@1452 103 {
kaf24@1452 104 if (pic_mode) {
kaf24@1452 105 /*
kaf24@1452 106 * Do not trust the local APIC being empty at bootup.
kaf24@1452 107 */
kaf24@1452 108 clear_local_APIC();
kaf24@1452 109 /*
kaf24@1452 110 * PIC mode, enable APIC mode in the IMCR, i.e.
kaf24@1452 111 * connect BSP's local APIC to INT and NMI lines.
kaf24@1452 112 */
kaf24@1452 113 printk("leaving PIC mode, enabling APIC mode.\n");
kaf24@1452 114 outb(0x70, 0x22);
kaf24@1452 115 outb(0x01, 0x23);
kaf24@1452 116 }
kaf24@1452 117 }
kaf24@1452 118
kaf24@1452 119 void disconnect_bsp_APIC(void)
kaf24@1452 120 {
kaf24@1452 121 if (pic_mode) {
kaf24@1452 122 /*
kaf24@1452 123 * Put the board back into PIC mode (has an effect
kaf24@1452 124 * only on certain older boards). Note that APIC
kaf24@1452 125 * interrupts, including IPIs, won't work beyond
kaf24@1452 126 * this point! The only exception are INIT IPIs.
kaf24@1452 127 */
kaf24@1452 128 printk("disabling APIC mode, entering PIC mode.\n");
kaf24@1452 129 outb(0x70, 0x22);
kaf24@1452 130 outb(0x00, 0x23);
kaf24@1452 131 }
kaf24@1452 132 }
kaf24@1452 133
kaf24@1452 134 void disable_local_APIC(void)
kaf24@1452 135 {
kaf24@1452 136 unsigned long value;
kaf24@1452 137
kaf24@1452 138 clear_local_APIC();
kaf24@1452 139
kaf24@1452 140 /*
kaf24@1452 141 * Disable APIC (implies clearing of registers
kaf24@1452 142 * for 82489DX!).
kaf24@1452 143 */
kaf24@1452 144 value = apic_read(APIC_SPIV);
kaf24@1452 145 value &= ~APIC_SPIV_APIC_ENABLED;
kaf24@1452 146 apic_write_around(APIC_SPIV, value);
kaf24@1452 147
kaf24@1452 148 if (enabled_via_apicbase) {
kaf24@1452 149 unsigned int l, h;
kaf24@1452 150 rdmsr(MSR_IA32_APICBASE, l, h);
kaf24@1452 151 l &= ~MSR_IA32_APICBASE_ENABLE;
kaf24@1452 152 wrmsr(MSR_IA32_APICBASE, l, h);
kaf24@1452 153 }
kaf24@1452 154 }
kaf24@1452 155
kaf24@1452 156 /*
kaf24@1452 157 * This is to verify that we're looking at a real local APIC.
kaf24@1452 158 * Check these against your board if the CPUs aren't getting
kaf24@1452 159 * started for no apparent reason.
kaf24@1452 160 */
kaf24@1452 161 int __init verify_local_APIC(void)
kaf24@1452 162 {
kaf24@1452 163 unsigned int reg0, reg1;
kaf24@1452 164
kaf24@1452 165 /*
kaf24@1452 166 * The version register is read-only in a real APIC.
kaf24@1452 167 */
kaf24@1452 168 reg0 = apic_read(APIC_LVR);
kaf24@1452 169 Dprintk("Getting VERSION: %x\n", reg0);
kaf24@1452 170 apic_write(APIC_LVR, reg0 ^ APIC_LVR_MASK);
kaf24@1452 171 reg1 = apic_read(APIC_LVR);
kaf24@1452 172 Dprintk("Getting VERSION: %x\n", reg1);
kaf24@1452 173
kaf24@1452 174 /*
kaf24@1452 175 * The two version reads above should print the same
kaf24@1452 176 * numbers. If the second one is different, then we
kaf24@1452 177 * poke at a non-APIC.
kaf24@1452 178 */
kaf24@1452 179 if (reg1 != reg0)
kaf24@1452 180 return 0;
kaf24@1452 181
kaf24@1452 182 /*
kaf24@1452 183 * Check if the version looks reasonably.
kaf24@1452 184 */
kaf24@1452 185 reg1 = GET_APIC_VERSION(reg0);
kaf24@1452 186 if (reg1 == 0x00 || reg1 == 0xff)
kaf24@1452 187 return 0;
kaf24@1452 188 reg1 = get_maxlvt();
kaf24@1452 189 if (reg1 < 0x02 || reg1 == 0xff)
kaf24@1452 190 return 0;
kaf24@1452 191
kaf24@1452 192 /*
kaf24@1452 193 * The ID register is read/write in a real APIC.
kaf24@1452 194 */
kaf24@1452 195 reg0 = apic_read(APIC_ID);
kaf24@1452 196 Dprintk("Getting ID: %x\n", reg0);
kaf24@1452 197 apic_write(APIC_ID, reg0 ^ APIC_ID_MASK);
kaf24@1452 198 reg1 = apic_read(APIC_ID);
kaf24@1452 199 Dprintk("Getting ID: %x\n", reg1);
kaf24@1452 200 apic_write(APIC_ID, reg0);
kaf24@1452 201 if (reg1 != (reg0 ^ APIC_ID_MASK))
kaf24@1452 202 return 0;
kaf24@1452 203
kaf24@1452 204 /*
kaf24@1452 205 * The next two are just to see if we have sane values.
kaf24@1452 206 * They're only really relevant if we're in Virtual Wire
kaf24@1452 207 * compatibility mode, but most boxes are anymore.
kaf24@1452 208 */
kaf24@1452 209 reg0 = apic_read(APIC_LVT0);
kaf24@1452 210 Dprintk("Getting LVT0: %x\n", reg0);
kaf24@1452 211 reg1 = apic_read(APIC_LVT1);
kaf24@1452 212 Dprintk("Getting LVT1: %x\n", reg1);
kaf24@1452 213
kaf24@1452 214 return 1;
kaf24@1452 215 }
kaf24@1452 216
kaf24@1452 217 void __init sync_Arb_IDs(void)
kaf24@1452 218 {
kaf24@1452 219 /*
kaf24@1452 220 * Wait for idle.
kaf24@1452 221 */
kaf24@1452 222 apic_wait_icr_idle();
kaf24@1452 223
kaf24@1452 224 Dprintk("Synchronizing Arb IDs.\n");
kaf24@1452 225 apic_write_around(APIC_ICR, APIC_DEST_ALLINC | APIC_INT_LEVELTRIG
kaf24@1452 226 | APIC_DM_INIT);
kaf24@1452 227 }
kaf24@1452 228
kaf24@1452 229 extern void __error_in_apic_c (void);
kaf24@1452 230
kaf24@1452 231 /*
kaf24@1452 232 * WAS: An initial setup of the virtual wire mode.
kaf24@1452 233 * NOW: We don't bother doing anything. All we need at this point
kaf24@1452 234 * is to receive timer ticks, so that 'jiffies' is incremented.
kaf24@1452 235 * If we're SMP, then we can assume BIOS did setup for us.
kaf24@1452 236 * If we're UP, then the APIC should be disabled (it is at reset).
kaf24@1452 237 * If we're UP and APIC is enabled, then BIOS is clever and has
kaf24@1452 238 * probably done initial interrupt routing for us.
kaf24@1452 239 */
kaf24@1452 240 void __init init_bsp_APIC(void)
kaf24@1452 241 {
kaf24@1452 242 }
kaf24@1452 243
kaf24@1452 244 static unsigned long calculate_ldr(unsigned long old)
kaf24@1452 245 {
kaf24@1452 246 unsigned long id = 1UL << smp_processor_id();
kaf24@1452 247 return (old & ~APIC_LDR_MASK)|SET_APIC_LOGICAL_ID(id);
kaf24@1452 248 }
kaf24@1452 249
kaf24@1452 250 void __init setup_local_APIC (void)
kaf24@1452 251 {
kaf24@1452 252 unsigned long value, ver, maxlvt;
kaf24@1452 253
kaf24@1452 254 value = apic_read(APIC_LVR);
kaf24@1452 255 ver = GET_APIC_VERSION(value);
kaf24@1452 256
kaf24@1452 257 if ((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f)
kaf24@1452 258 __error_in_apic_c();
kaf24@1452 259
kaf24@1452 260 /* Double-check wether this APIC is really registered. */
kaf24@1452 261 if (!test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map))
kaf24@1452 262 BUG();
kaf24@1452 263
kaf24@1452 264 /*
kaf24@1452 265 * Intel recommends to set DFR, LDR and TPR before enabling
kaf24@1452 266 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
kaf24@1452 267 * document number 292116). So here it goes...
kaf24@1452 268 */
kaf24@1452 269
kaf24@1452 270 /*
kaf24@1452 271 * In clustered apic mode, the firmware does this for us
kaf24@1452 272 * Put the APIC into flat delivery mode.
kaf24@1452 273 * Must be "all ones" explicitly for 82489DX.
kaf24@1452 274 */
kaf24@1452 275 apic_write_around(APIC_DFR, APIC_DFR_FLAT);
kaf24@1452 276
kaf24@1452 277 /*
kaf24@1452 278 * Set up the logical destination ID.
kaf24@1452 279 */
kaf24@1452 280 value = apic_read(APIC_LDR);
kaf24@1452 281 apic_write_around(APIC_LDR, calculate_ldr(value));
kaf24@1452 282
kaf24@1452 283 /*
kaf24@1452 284 * Set Task Priority to 'accept all'. We never change this
kaf24@1452 285 * later on.
kaf24@1452 286 */
kaf24@1452 287 value = apic_read(APIC_TASKPRI);
kaf24@1452 288 value &= ~APIC_TPRI_MASK;
kaf24@1452 289 apic_write_around(APIC_TASKPRI, value);
kaf24@1452 290
kaf24@1452 291 /*
kaf24@1452 292 * Now that we are all set up, enable the APIC
kaf24@1452 293 */
kaf24@1452 294 value = apic_read(APIC_SPIV);
kaf24@1452 295 value &= ~APIC_VECTOR_MASK;
kaf24@1452 296 /*
kaf24@1452 297 * Enable APIC
kaf24@1452 298 */
kaf24@1452 299 value |= APIC_SPIV_APIC_ENABLED;
kaf24@1452 300
kaf24@1452 301 /* Enable focus processor (bit==0) */
kaf24@1452 302 value &= ~APIC_SPIV_FOCUS_DISABLED;
kaf24@1452 303
kaf24@1452 304 /* Set spurious IRQ vector */
kaf24@1452 305 value |= SPURIOUS_APIC_VECTOR;
kaf24@1452 306 apic_write_around(APIC_SPIV, value);
kaf24@1452 307
kaf24@1452 308 /*
kaf24@1452 309 * Set up LVT0, LVT1:
kaf24@1452 310 *
kaf24@1452 311 * set up through-local-APIC on the BP's LINT0. This is not
kaf24@1452 312 * strictly necessery in pure symmetric-IO mode, but sometimes
kaf24@1452 313 * we delegate interrupts to the 8259A.
kaf24@1452 314 */
kaf24@1452 315 /*
kaf24@1452 316 * TODO: set up through-local-APIC from through-I/O-APIC? --macro
kaf24@1452 317 */
kaf24@1452 318 value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
kaf24@1452 319 if (!smp_processor_id()) {
kaf24@1452 320 value = APIC_DM_EXTINT;
kaf24@1452 321 printk("enabled ExtINT on CPU#%d\n", smp_processor_id());
kaf24@1452 322 } else {
kaf24@1452 323 value = APIC_DM_EXTINT | APIC_LVT_MASKED;
kaf24@1452 324 printk("masked ExtINT on CPU#%d\n", smp_processor_id());
kaf24@1452 325 }
kaf24@1452 326 apic_write_around(APIC_LVT0, value);
kaf24@1452 327
kaf24@1452 328 /*
kaf24@1452 329 * only the BP should see the LINT1 NMI signal, obviously.
kaf24@1452 330 */
kaf24@1452 331 if (!smp_processor_id())
kaf24@1452 332 value = APIC_DM_NMI;
kaf24@1452 333 else
kaf24@1452 334 value = APIC_DM_NMI | APIC_LVT_MASKED;
kaf24@1452 335 if (!APIC_INTEGRATED(ver)) /* 82489DX */
kaf24@1452 336 value |= APIC_LVT_LEVEL_TRIGGER;
kaf24@1452 337 apic_write_around(APIC_LVT1, value);
kaf24@1452 338
kaf24@1452 339 if (APIC_INTEGRATED(ver)) { /* !82489DX */
kaf24@1452 340 maxlvt = get_maxlvt();
kaf24@1452 341 if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
kaf24@1452 342 apic_write(APIC_ESR, 0);
kaf24@1452 343 value = apic_read(APIC_ESR);
kaf24@1452 344 printk("ESR value before enabling vector: %08lx\n", value);
kaf24@1452 345
kaf24@1452 346 value = ERROR_APIC_VECTOR; /* enables sending errors */
kaf24@1452 347 apic_write_around(APIC_LVTERR, value);
kaf24@1452 348 /* spec says clear errors after enabling vector. */
kaf24@1452 349 if (maxlvt > 3)
kaf24@1452 350 apic_write(APIC_ESR, 0);
kaf24@1452 351 value = apic_read(APIC_ESR);
kaf24@1452 352 printk("ESR value after enabling vector: %08lx\n", value);
kaf24@1452 353 } else {
kaf24@1452 354 printk("No ESR for 82489DX.\n");
kaf24@1452 355 }
kaf24@1452 356
kaf24@1452 357 if ( (smp_processor_id() == 0) && (nmi_watchdog == NMI_LOCAL_APIC) )
kaf24@1452 358 setup_apic_nmi_watchdog();
kaf24@1452 359 }
kaf24@1452 360
kaf24@1452 361
kaf24@1452 362 static inline void apic_pm_init1(void) { }
kaf24@1452 363 static inline void apic_pm_init2(void) { }
kaf24@1452 364
kaf24@1452 365
kaf24@1452 366 /*
kaf24@1452 367 * Detect and enable local APICs on non-SMP boards.
kaf24@1452 368 * Original code written by Keir Fraser.
kaf24@1452 369 */
kaf24@1452 370
kaf24@1452 371 static int __init detect_init_APIC (void)
kaf24@1452 372 {
kaf24@1452 373 u32 h, l, features;
kaf24@1452 374 extern void get_cpu_vendor(struct cpuinfo_x86*);
kaf24@1452 375
kaf24@1452 376 /* Workaround for us being called before identify_cpu(). */
kaf24@1452 377 get_cpu_vendor(&boot_cpu_data);
kaf24@1452 378
kaf24@1452 379 switch (boot_cpu_data.x86_vendor) {
kaf24@1452 380 case X86_VENDOR_AMD:
kaf24@1452 381 if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1)
kaf24@1452 382 break;
kaf24@1452 383 if (boot_cpu_data.x86 == 15 && cpu_has_apic)
kaf24@1452 384 break;
kaf24@1452 385 goto no_apic;
kaf24@1452 386 case X86_VENDOR_INTEL:
kaf24@1452 387 if (boot_cpu_data.x86 == 6 ||
kaf24@1452 388 (boot_cpu_data.x86 == 15 && cpu_has_apic) ||
kaf24@1452 389 (boot_cpu_data.x86 == 5 && cpu_has_apic))
kaf24@1452 390 break;
kaf24@1452 391 goto no_apic;
kaf24@1452 392 default:
kaf24@1452 393 goto no_apic;
kaf24@1452 394 }
kaf24@1452 395
kaf24@1452 396 if (!cpu_has_apic) {
kaf24@1452 397 /*
kaf24@1452 398 * Some BIOSes disable the local APIC in the
kaf24@1452 399 * APIC_BASE MSR. This can only be done in
kaf24@1452 400 * software for Intel P6 and AMD K7 (Model > 1).
kaf24@1452 401 */
kaf24@1452 402 rdmsr(MSR_IA32_APICBASE, l, h);
kaf24@1452 403 if (!(l & MSR_IA32_APICBASE_ENABLE)) {
kaf24@1452 404 printk("Local APIC disabled by BIOS -- reenabling.\n");
kaf24@1452 405 l &= ~MSR_IA32_APICBASE_BASE;
kaf24@1452 406 l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
kaf24@1452 407 wrmsr(MSR_IA32_APICBASE, l, h);
kaf24@1452 408 enabled_via_apicbase = 1;
kaf24@1452 409 }
kaf24@1452 410 }
kaf24@1452 411
kaf24@1452 412 /* The APIC feature bit should now be enabled in `cpuid' */
kaf24@1452 413 features = cpuid_edx(1);
kaf24@1452 414 if (!(features & (1 << X86_FEATURE_APIC))) {
kaf24@1452 415 printk("Could not enable APIC!\n");
kaf24@1452 416 return -1;
kaf24@1452 417 }
kaf24@1452 418
kaf24@1452 419 set_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability);
kaf24@1452 420 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
kaf24@1452 421 boot_cpu_physical_apicid = 0;
kaf24@1452 422
kaf24@1452 423 /* The BIOS may have set up the APIC at some other address */
kaf24@1452 424 rdmsr(MSR_IA32_APICBASE, l, h);
kaf24@1452 425 if (l & MSR_IA32_APICBASE_ENABLE)
kaf24@1452 426 mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
kaf24@1452 427
kaf24@1452 428 if (nmi_watchdog != NMI_NONE)
kaf24@1452 429 nmi_watchdog = NMI_LOCAL_APIC;
kaf24@1452 430
kaf24@1452 431 printk("Found and enabled local APIC!\n");
kaf24@1452 432 apic_pm_init1();
kaf24@1452 433 return 0;
kaf24@1452 434
kaf24@1452 435 no_apic:
kaf24@1452 436 printk("No local APIC present or hardware disabled\n");
kaf24@1452 437 return -1;
kaf24@1452 438 }
kaf24@1452 439
kaf24@1452 440 void __init init_apic_mappings(void)
kaf24@1452 441 {
kaf24@1452 442 unsigned long apic_phys = 0;
kaf24@1452 443
kaf24@1452 444 /*
kaf24@1452 445 * If no local APIC can be found then set up a fake all zeroes page to
kaf24@1452 446 * simulate the local APIC and another one for the IO-APIC.
kaf24@1452 447 */
kaf24@1452 448 if (!smp_found_config && detect_init_APIC()) {
kaf24@1452 449 apic_phys = get_free_page(GFP_KERNEL);
kaf24@1452 450 apic_phys = __pa(apic_phys);
kaf24@1452 451 } else
kaf24@1452 452 apic_phys = mp_lapic_addr;
kaf24@1452 453
kaf24@1452 454 set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
kaf24@1452 455 Dprintk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys);
kaf24@1452 456
kaf24@1452 457 /*
kaf24@1452 458 * Fetch the APIC ID of the BSP in case we have a
kaf24@1452 459 * default configuration (or the MP table is broken).
kaf24@1452 460 */
kaf24@1452 461 if (boot_cpu_physical_apicid == -1U)
kaf24@1452 462 boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
kaf24@1452 463
kaf24@1452 464 #ifdef CONFIG_X86_IO_APIC
kaf24@1452 465 {
kaf24@1452 466 unsigned long ioapic_phys = 0, idx = FIX_IO_APIC_BASE_0;
kaf24@1452 467 int i;
kaf24@1452 468
kaf24@1452 469 for (i = 0; i < nr_ioapics; i++) {
kaf24@1452 470 if (smp_found_config)
kaf24@1452 471 ioapic_phys = mp_ioapics[i].mpc_apicaddr;
kaf24@1452 472 set_fixmap_nocache(idx, ioapic_phys);
kaf24@1452 473 Dprintk("mapped IOAPIC to %08lx (%08lx)\n",
kaf24@1452 474 __fix_to_virt(idx), ioapic_phys);
kaf24@1452 475 idx++;
kaf24@1452 476 }
kaf24@1452 477 }
kaf24@1452 478 #endif
kaf24@1452 479 }
kaf24@1452 480
kaf24@1452 481 /*****************************************************************************
kaf24@1452 482 * APIC calibration
kaf24@1452 483 *
kaf24@1452 484 * The APIC is programmed in bus cycles.
kaf24@1452 485 * Timeout values should specified in real time units.
kaf24@1452 486 * The "cheapest" time source is the cyclecounter.
kaf24@1452 487 *
kaf24@1452 488 * Thus, we need a mappings from: bus cycles <- cycle counter <- system time
kaf24@1452 489 *
kaf24@1452 490 * The calibration is currently a bit shoddy since it requires the external
kaf24@1452 491 * timer chip to generate periodic timer interupts.
kaf24@1452 492 *****************************************************************************/
kaf24@1452 493
kaf24@1452 494 /* used for system time scaling */
kaf24@1452 495 static unsigned int bus_freq;
kaf24@1452 496 static u32 bus_cycle; /* length of one bus cycle in pico-seconds */
kaf24@1452 497 static u32 bus_scale; /* scaling factor convert ns to bus cycles */
kaf24@1452 498
kaf24@1452 499 /*
kaf24@1452 500 * The timer chip is already set up at HZ interrupts per second here,
kaf24@1452 501 * but we do not accept timer interrupts yet. We only allow the BP
kaf24@1452 502 * to calibrate.
kaf24@1452 503 */
kaf24@1452 504 static unsigned int __init get_8254_timer_count(void)
kaf24@1452 505 {
kaf24@1452 506 /*extern spinlock_t i8253_lock;*/
kaf24@1452 507 /*unsigned long flags;*/
kaf24@1452 508 unsigned int count;
kaf24@1452 509 /*spin_lock_irqsave(&i8253_lock, flags);*/
kaf24@1452 510 outb_p(0x00, 0x43);
kaf24@1452 511 count = inb_p(0x40);
kaf24@1452 512 count |= inb_p(0x40) << 8;
kaf24@1452 513 /*spin_unlock_irqrestore(&i8253_lock, flags);*/
kaf24@1452 514 return count;
kaf24@1452 515 }
kaf24@1452 516
kaf24@1452 517 void __init wait_8254_wraparound(void)
kaf24@1452 518 {
kaf24@1452 519 unsigned int curr_count, prev_count=~0;
kaf24@1452 520 int delta;
kaf24@1452 521 curr_count = get_8254_timer_count();
kaf24@1452 522 do {
kaf24@1452 523 prev_count = curr_count;
kaf24@1452 524 curr_count = get_8254_timer_count();
kaf24@1452 525 delta = curr_count-prev_count;
kaf24@1452 526 /*
kaf24@1452 527 * This limit for delta seems arbitrary, but it isn't, it's slightly
kaf24@1452 528 * above the level of error a buggy Mercury/Neptune chipset timer can
kaf24@1452 529 * cause.
kaf24@1452 530 */
kaf24@1452 531 } while (delta < 300);
kaf24@1452 532 }
kaf24@1452 533
kaf24@1452 534 /*
kaf24@1452 535 * This function sets up the local APIC timer, with a timeout of
kaf24@1452 536 * 'clocks' APIC bus clock. During calibration we actually call
kaf24@1452 537 * this function with a very large value and read the current time after
kaf24@1452 538 * a well defined period of time as expired.
kaf24@1452 539 *
kaf24@1452 540 * Calibration is only performed once, for CPU0!
kaf24@1452 541 *
kaf24@1452 542 * We do reads before writes even if unnecessary, to get around the
kaf24@1452 543 * P5 APIC double write bug.
kaf24@1452 544 */
kaf24@1452 545 #define APIC_DIVISOR 1
kaf24@1452 546 static void __setup_APIC_LVTT(unsigned int clocks)
kaf24@1452 547 {
kaf24@1452 548 unsigned int lvtt1_value, tmp_value;
kaf24@1452 549 lvtt1_value = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV)|LOCAL_TIMER_VECTOR;
kaf24@1452 550 apic_write_around(APIC_LVTT, lvtt1_value);
kaf24@1452 551 tmp_value = apic_read(APIC_TDCR);
kaf24@1452 552 apic_write_around(APIC_TDCR, (tmp_value | APIC_TDR_DIV_1));
kaf24@1452 553 apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR);
kaf24@1452 554 }
kaf24@1452 555
kaf24@1452 556 /*
kaf24@1452 557 * this is done for every CPU from setup_APIC_clocks() below.
kaf24@1452 558 * We setup each local APIC with a zero timeout value for now.
kaf24@1452 559 * Unlike Linux, we don't have to wait for slices etc.
kaf24@1452 560 */
kaf24@1452 561 void setup_APIC_timer(void * data)
kaf24@1452 562 {
kaf24@1452 563 unsigned long flags;
kaf24@1452 564 __save_flags(flags);
kaf24@1452 565 __sti();
kaf24@1452 566 __setup_APIC_LVTT(0);
kaf24@1452 567 __restore_flags(flags);
kaf24@1452 568 }
kaf24@1452 569
kaf24@1452 570 /*
kaf24@1452 571 * In this function we calibrate APIC bus clocks to the external timer.
kaf24@1452 572 *
kaf24@1452 573 * As a result we have the Bys Speed and CPU speed in Hz.
kaf24@1452 574 *
kaf24@1452 575 * We want to do the calibration only once (for CPU0). CPUs connected by the
kaf24@1452 576 * same APIC bus have the very same bus frequency.
kaf24@1452 577 *
kaf24@1452 578 * This bit is a bit shoddy since we use the very same periodic timer interrupt
kaf24@1452 579 * we try to eliminate to calibrate the APIC.
kaf24@1452 580 */
kaf24@1452 581
kaf24@1452 582 int __init calibrate_APIC_clock(void)
kaf24@1452 583 {
kaf24@1452 584 unsigned long long t1 = 0, t2 = 0;
kaf24@1452 585 long tt1, tt2;
kaf24@1452 586 long result;
kaf24@1452 587 int i;
kaf24@1452 588 const int LOOPS = HZ/10;
kaf24@1452 589
kaf24@1452 590 printk("Calibrating APIC timer for CPU%d...\n", smp_processor_id());
kaf24@1452 591
kaf24@1452 592 /* Put whatever arbitrary (but long enough) timeout
kaf24@1452 593 * value into the APIC clock, we just want to get the
kaf24@1452 594 * counter running for calibration. */
kaf24@1452 595 __setup_APIC_LVTT(1000000000);
kaf24@1452 596
kaf24@1452 597 /* The timer chip counts down to zero. Let's wait
kaf24@1452 598 * for a wraparound to start exact measurement:
kaf24@1452 599 * (the current tick might have been already half done) */
kaf24@1452 600 wait_8254_wraparound();
kaf24@1452 601
kaf24@1452 602 /* We wrapped around just now. Let's start: */
kaf24@1452 603 rdtscll(t1);
kaf24@1452 604 tt1 = apic_read(APIC_TMCCT);
kaf24@1452 605
kaf24@1452 606 /* Let's wait LOOPS wraprounds: */
kaf24@1452 607 for (i = 0; i < LOOPS; i++)
kaf24@1452 608 wait_8254_wraparound();
kaf24@1452 609
kaf24@1452 610 tt2 = apic_read(APIC_TMCCT);
kaf24@1452 611 rdtscll(t2);
kaf24@1452 612
kaf24@1452 613 /* The APIC bus clock counter is 32 bits only, it
kaf24@1452 614 * might have overflown, but note that we use signed
kaf24@1452 615 * longs, thus no extra care needed.
kaf24@1452 616 * underflown to be exact, as the timer counts down ;) */
kaf24@1452 617 result = (tt1-tt2)*APIC_DIVISOR/LOOPS;
kaf24@1452 618
kaf24@1452 619 printk("..... CPU speed is %ld.%04ld MHz.\n",
kaf24@1452 620 ((long)(t2-t1)/LOOPS) / (1000000/HZ),
kaf24@1452 621 ((long)(t2-t1)/LOOPS) % (1000000/HZ));
kaf24@1452 622
kaf24@1452 623 printk("..... Bus speed is %ld.%04ld MHz.\n",
kaf24@1452 624 result / (1000000/HZ),
kaf24@1452 625 result % (1000000/HZ));
kaf24@1452 626
kaf24@1452 627 /*
kaf24@1452 628 * KAF: Moved this to time.c where it's calculated relative to the TSC.
kaf24@1452 629 * Therefore works on machines with no local APIC.
kaf24@1452 630 */
kaf24@1452 631 /*cpu_freq = (u64)(((t2-t1)/LOOPS)*HZ);*/
kaf24@1452 632
kaf24@1452 633 /* set up multipliers for accurate timer code */
kaf24@1452 634 bus_freq = result*HZ;
kaf24@1452 635 bus_cycle = (u32) (1000000000000LL/bus_freq); /* in pico seconds */
kaf24@1452 636 bus_scale = (1000*262144)/bus_cycle;
kaf24@1452 637
kaf24@1452 638 printk("..... bus_scale = 0x%08X\n", bus_scale);
kaf24@1452 639 /* reset APIC to zero timeout value */
kaf24@1452 640 __setup_APIC_LVTT(0);
kaf24@1452 641 return result;
kaf24@1452 642 }
kaf24@1452 643
kaf24@1452 644 /*
kaf24@1452 645 * initialise the APIC timers for all CPUs
kaf24@1452 646 * we start with the first and find out processor frequency and bus speed
kaf24@1452 647 */
kaf24@1452 648 void __init setup_APIC_clocks (void)
kaf24@1452 649 {
kaf24@1452 650 printk("Using local APIC timer interrupts.\n");
kaf24@1452 651 using_apic_timer = 1;
kaf24@1452 652 __cli();
kaf24@1452 653 /* calibrate CPU0 for CPU speed and BUS speed */
kaf24@1452 654 bus_freq = calibrate_APIC_clock();
kaf24@1452 655 /* Now set up the timer for real. */
kaf24@1452 656 setup_APIC_timer((void *)bus_freq);
kaf24@1452 657 __sti();
kaf24@1452 658 /* and update all other cpus */
kaf24@1452 659 smp_call_function(setup_APIC_timer, (void *)bus_freq, 1, 1);
kaf24@1452 660 }
kaf24@1452 661
kaf24@1452 662 #undef APIC_DIVISOR
kaf24@1452 663
kaf24@1452 664 /*
kaf24@1452 665 * reprogram the APIC timer. Timeoutvalue is in ns from start of boot
kaf24@1452 666 * returns 1 on success
kaf24@1452 667 * returns 0 if the timeout value is too small or in the past.
kaf24@1452 668 */
kaf24@1452 669 int reprogram_ac_timer(s_time_t timeout)
kaf24@1452 670 {
kaf24@1452 671 s_time_t now;
kaf24@1452 672 s_time_t expire;
kaf24@1452 673 u64 apic_tmict;
kaf24@1452 674
kaf24@1452 675 /*
kaf24@1452 676 * We use this value because we don't trust zero (we think it may just
kaf24@1452 677 * cause an immediate interrupt). At least this is guaranteed to hold it
kaf24@1452 678 * off for ages (esp. since the clock ticks on bus clock, not cpu clock!).
kaf24@1452 679 */
kaf24@1452 680 if ( timeout == 0 )
kaf24@1452 681 {
kaf24@1452 682 apic_tmict = 0xffffffff;
kaf24@1452 683 goto reprogram;
kaf24@1452 684 }
kaf24@1452 685
kaf24@1452 686 now = NOW();
kaf24@1452 687 expire = timeout - now; /* value from now */
kaf24@1452 688
kaf24@1452 689 if ( expire <= 0 )
kaf24@1452 690 {
kaf24@1452 691 Dprintk("APICT[%02d] Timeout in the past 0x%08X%08X > 0x%08X%08X\n",
kaf24@1452 692 smp_processor_id(), (u32)(now>>32),
kaf24@1452 693 (u32)now, (u32)(timeout>>32),(u32)timeout);
kaf24@1452 694 return 0;
kaf24@1452 695 }
kaf24@1452 696
kaf24@1452 697 /*
kaf24@1452 698 * If we don't have local APIC then we just poll the timer list off the
kaf24@1452 699 * PIT interrupt. Cheesy but good enough to work on eg. VMware :-)
kaf24@1452 700 */
kaf24@1452 701 if ( !cpu_has_apic )
kaf24@1452 702 return 1;
kaf24@1452 703
kaf24@1452 704 /* conversion to bus units */
kaf24@1452 705 apic_tmict = (((u64)bus_scale) * expire)>>18;
kaf24@1452 706
kaf24@1452 707 if ( apic_tmict >= 0xffffffff )
kaf24@1452 708 {
kaf24@1452 709 Dprintk("APICT[%02d] Timeout value too large\n", smp_processor_id());
kaf24@1452 710 apic_tmict = 0xffffffff;
kaf24@1452 711 }
kaf24@1452 712
kaf24@1452 713 if ( apic_tmict == 0 )
kaf24@1452 714 {
kaf24@1452 715 Dprintk("APICT[%02d] timeout value too small\n", smp_processor_id());
kaf24@1452 716 return 0;
kaf24@1452 717 }
kaf24@1452 718
kaf24@1452 719 reprogram:
kaf24@1452 720 /* Program the timer. */
kaf24@1452 721 apic_write(APIC_TMICT, (unsigned long)apic_tmict);
kaf24@1452 722
kaf24@1452 723 return 1;
kaf24@1452 724 }
kaf24@1452 725
kaf24@1452 726 unsigned int apic_timer_irqs [NR_CPUS];
kaf24@1452 727
kaf24@1452 728 void smp_apic_timer_interrupt(struct pt_regs * regs)
kaf24@1452 729 {
kaf24@1452 730 int cpu = smp_processor_id();
kaf24@1452 731
kaf24@1452 732 ack_APIC_irq();
kaf24@1452 733
kaf24@1452 734 apic_timer_irqs[cpu]++;
kaf24@1452 735 perfc_incrc(apic_timer);
kaf24@1452 736
kaf24@1452 737 __cpu_raise_softirq(cpu, AC_TIMER_SOFTIRQ);
kaf24@1452 738 }
kaf24@1452 739
kaf24@1452 740 /*
kaf24@1452 741 * This interrupt should _never_ happen with our APIC/SMP architecture
kaf24@1452 742 */
kaf24@1452 743 asmlinkage void smp_spurious_interrupt(void)
kaf24@1452 744 {
kaf24@1452 745 unsigned long v;
kaf24@1452 746
kaf24@1452 747 /*
kaf24@1452 748 * Check if this really is a spurious interrupt and ACK it
kaf24@1452 749 * if it is a vectored one. Just in case...
kaf24@1452 750 * Spurious interrupts should not be ACKed.
kaf24@1452 751 */
kaf24@1452 752 v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1));
kaf24@1452 753 if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
kaf24@1452 754 ack_APIC_irq();
kaf24@1452 755
kaf24@1452 756 /* see sw-dev-man vol 3, chapter 7.4.13.5 */
kaf24@1452 757 printk("spurious APIC interrupt on CPU#%d, should never happen.\n",
kaf24@1452 758 smp_processor_id());
kaf24@1452 759 }
kaf24@1452 760
kaf24@1452 761 /*
kaf24@1452 762 * This interrupt should never happen with our APIC/SMP architecture
kaf24@1452 763 */
kaf24@1452 764
kaf24@1452 765 asmlinkage void smp_error_interrupt(void)
kaf24@1452 766 {
kaf24@1452 767 unsigned long v, v1;
kaf24@1452 768
kaf24@1452 769 /* First tickle the hardware, only then report what went on. -- REW */
kaf24@1452 770 v = apic_read(APIC_ESR);
kaf24@1452 771 apic_write(APIC_ESR, 0);
kaf24@1452 772 v1 = apic_read(APIC_ESR);
kaf24@1452 773 ack_APIC_irq();
kaf24@1452 774 atomic_inc(&irq_err_count);
kaf24@1452 775
kaf24@1452 776 /* Here is what the APIC error bits mean:
kaf24@1452 777 0: Send CS error
kaf24@1452 778 1: Receive CS error
kaf24@1452 779 2: Send accept error
kaf24@1452 780 3: Receive accept error
kaf24@1452 781 4: Reserved
kaf24@1452 782 5: Send illegal vector
kaf24@1452 783 6: Received illegal vector
kaf24@1452 784 7: Illegal register address
kaf24@1452 785 */
kaf24@1452 786 printk ("APIC error on CPU%d: %02lx(%02lx)\n",
kaf24@1452 787 smp_processor_id(), v , v1);
kaf24@1452 788 }
kaf24@1452 789
kaf24@1452 790 /*
kaf24@1452 791 * This initializes the IO-APIC and APIC hardware if this is
kaf24@1452 792 * a UP kernel.
kaf24@1452 793 */
kaf24@1452 794 int __init APIC_init_uniprocessor (void)
kaf24@1452 795 {
kaf24@1452 796 if (!smp_found_config && !cpu_has_apic)
kaf24@1452 797 return -1;
kaf24@1452 798
kaf24@1452 799 /*
kaf24@1452 800 * Complain if the BIOS pretends there is one.
kaf24@1452 801 */
kaf24@1452 802 if (!cpu_has_apic&&APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]))
kaf24@1452 803 {
kaf24@1452 804 printk("BIOS bug, local APIC #%d not detected!...\n",
kaf24@1452 805 boot_cpu_physical_apicid);
kaf24@1452 806 return -1;
kaf24@1452 807 }
kaf24@1452 808
kaf24@1452 809 verify_local_APIC();
kaf24@1452 810
kaf24@1452 811 connect_bsp_APIC();
kaf24@1452 812
kaf24@1452 813 #ifdef CONFIG_SMP
kaf24@1452 814 cpu_online_map = 1;
kaf24@1452 815 #endif
kaf24@1452 816 phys_cpu_present_map = 1;
kaf24@1452 817 apic_write_around(APIC_ID, boot_cpu_physical_apicid);
kaf24@1452 818
kaf24@1452 819 apic_pm_init2();
kaf24@1452 820
kaf24@1452 821 setup_local_APIC();
kaf24@1452 822
kaf24@1452 823 #ifdef CONFIG_X86_IO_APIC
kaf24@1452 824 if (smp_found_config && nr_ioapics)
kaf24@1452 825 setup_IO_APIC();
kaf24@1452 826 #endif
kaf24@1452 827 setup_APIC_clocks();
kaf24@1452 828
kaf24@1452 829 return 0;
kaf24@1452 830 }