debuggers.hg
changeset 4586:8ce73ebd1311
bitkeeper revision 1.1308 (4260510bQdQyEJ4w-XdZSU5iSTB_Pg)
The attached patch apic.patch updates xen/arch/x86/apic.c so that it is based on linux 2.6.10 code. A few changes made to linux required reworking functions in other files as well so I held off on those changes. For example, setup_APIC_timer(void *) changed to setup_APIC_timer(unsigned int). The change has no real bearing on the Xen code -- it's just a question of how close to linux one wants to be. However, that change goes with a change to smp_call_function which would affect quite a few other files/functions so I left it as is. Most of the other changes are trivial.
xen/ac_timer.h was included but not needed by apic.c so I removed it from the list of #includes.
The new apic.c includes two new files: asm/io_ports.h and asm/mach_apic.h. Patches to create those files are included as well.
The attached patch apic.patch updates xen/arch/x86/apic.c so that it is based on linux 2.6.10 code. A few changes made to linux required reworking functions in other files as well so I held off on those changes. For example, setup_APIC_timer(void *) changed to setup_APIC_timer(unsigned int). The change has no real bearing on the Xen code -- it's just a question of how close to linux one wants to be. However, that change goes with a change to smp_call_function which would affect quite a few other files/functions so I left it as is. Most of the other changes are trivial.
xen/ac_timer.h was included but not needed by apic.c so I removed it from the list of #includes.
The new apic.c includes two new files: asm/io_ports.h and asm/mach_apic.h. Patches to create those files are included as well.
author | iap10@freefall.cl.cam.ac.uk |
---|---|
date | Fri Apr 15 23:40:59 2005 +0000 (2005-04-15) |
parents | 73ef7f1fc714 |
children | d3c7465e457a |
files | .rootkeys xen/arch/x86/apic.c xen/include/asm-x86/io_ports.h xen/include/asm-x86/mach_apic.h |
line diff
1.1 --- a/.rootkeys Fri Apr 15 23:32:51 2005 +0000 1.2 +++ b/.rootkeys Fri Apr 15 23:40:59 2005 +0000 1.3 @@ -1323,8 +1323,10 @@ 3ddb79c3TMDjkxVndKFKnGiwY0HzDg xen/inclu 1.4 4204e7acwXDo-5iAAiO2eQbtDeYZXA xen/include/asm-x86/init.h 1.5 3ddb79c3fQ_O3o5NHK2N8AJdk0Ea4Q xen/include/asm-x86/io.h 1.6 3ddb79c2TKeScYHQZreTdHqYNLbehQ xen/include/asm-x86/io_apic.h 1.7 +42605109qxLSrHVE2SRhGXmgk907iw xen/include/asm-x86/io_ports.h 1.8 3ddb79c2L7rTlFzazOLW1XuSZefpFw xen/include/asm-x86/irq.h 1.9 404f1b93OjLO4bFfBXYNaJdIqlNz-Q xen/include/asm-x86/ldt.h 1.10 +4260510aYPj2kr6rMbBfMxcvvmXndQ xen/include/asm-x86/mach_apic.h 1.11 3ddb79c3I98vWcQR8xEo34JMJ4Ahyw xen/include/asm-x86/mc146818rtc.h 1.12 40ec25fd7cSvbP7Biw91zaU_g0xsEQ xen/include/asm-x86/mm.h 1.13 3ddb79c3n_UbPuxlkNxvvLycClIkxA xen/include/asm-x86/mpspec.h
2.1 --- a/xen/arch/x86/apic.c Fri Apr 15 23:32:51 2005 +0000 2.2 +++ b/xen/arch/x86/apic.c Fri Apr 15 23:40:59 2005 +0000 2.3 @@ -1,4 +1,6 @@ 2.4 /* 2.5 + * based on linux-2.6.10/arch/i386/kernel/apic.c 2.6 + * 2.7 * Local APIC handling, local APIC timers 2.8 * 2.9 * (c) 1999, 2000 Ingo Molnar <mingo@redhat.com> 2.10 @@ -10,11 +12,11 @@ 2.11 * for testing these extensively. 2.12 * Maciej W. Rozycki : Various updates and fixes. 2.13 * Mikael Pettersson : Power Management for UP-APIC. 2.14 + * Pavel Machek and 2.15 + * Mikael Pettersson : PM converted to driver model. 2.16 */ 2.17 2.18 - 2.19 #include <xen/config.h> 2.20 -#include <xen/ac_timer.h> 2.21 #include <xen/perfc.h> 2.22 #include <xen/errno.h> 2.23 #include <xen/init.h> 2.24 @@ -32,7 +34,8 @@ 2.25 #include <asm/hardirq.h> 2.26 #include <asm/apic.h> 2.27 #include <asm/io_apic.h> 2.28 - 2.29 +#include <asm/mach_apic.h> 2.30 +#include <asm/io_ports.h> 2.31 2.32 /* Using APIC to generate smp_local_timer_interrupt? */ 2.33 int using_apic_timer = 0; 2.34 @@ -80,6 +83,16 @@ void clear_local_APIC(void) 2.35 apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED); 2.36 } 2.37 2.38 +#if 0 2.39 +/* lets not touch this if we didn't frob it */ 2.40 +#ifdef CONFIG_X86_MCE_P4THERMAL 2.41 + if (maxlvt >= 5) { 2.42 + v = apic_read(APIC_LVTTHMR); 2.43 + apic_write_around(APIC_LVTTHMR, v | APIC_LVT_MASKED); 2.44 + } 2.45 +#endif 2.46 +#endif 2.47 + 2.48 /* 2.49 * Clean APIC state for other OSs: 2.50 */ 2.51 @@ -90,9 +103,17 @@ void clear_local_APIC(void) 2.52 apic_write_around(APIC_LVTERR, APIC_LVT_MASKED); 2.53 if (maxlvt >= 4) 2.54 apic_write_around(APIC_LVTPC, APIC_LVT_MASKED); 2.55 + 2.56 +#if 0 2.57 +#ifdef CONFIG_X86_MCE_P4THERMAL 2.58 + if (maxlvt >= 5) 2.59 + apic_write_around(APIC_LVTTHMR, APIC_LVT_MASKED); 2.60 +#endif 2.61 +#endif 2.62 + 2.63 v = GET_APIC_VERSION(apic_read(APIC_LVR)); 2.64 if (APIC_INTEGRATED(v)) { /* !82489DX */ 2.65 - if (maxlvt > 3) 2.66 + if (maxlvt > 3) /* Due to Pentium errata 3AP and 11AP. */ 2.67 apic_write(APIC_ESR, 0); 2.68 apic_read(APIC_ESR); 2.69 } 2.70 @@ -113,6 +134,9 @@ void __init connect_bsp_APIC(void) 2.71 outb(0x70, 0x22); 2.72 outb(0x01, 0x23); 2.73 } 2.74 +#if 0 2.75 + enable_apic_mode(); 2.76 +#endif 2.77 } 2.78 2.79 void disconnect_bsp_APIC(void) 2.80 @@ -193,12 +217,6 @@ int __init verify_local_APIC(void) 2.81 */ 2.82 reg0 = apic_read(APIC_ID); 2.83 Dprintk("Getting ID: %x\n", reg0); 2.84 - apic_write(APIC_ID, reg0 ^ APIC_ID_MASK); 2.85 - reg1 = apic_read(APIC_ID); 2.86 - Dprintk("Getting ID: %x\n", reg1); 2.87 - apic_write(APIC_ID, reg0); 2.88 - if (reg1 != (reg0 ^ APIC_ID_MASK)) 2.89 - return 0; 2.90 2.91 /* 2.92 * The next two are just to see if we have sane values. 2.93 @@ -215,6 +233,10 @@ int __init verify_local_APIC(void) 2.94 2.95 void __init sync_Arb_IDs(void) 2.96 { 2.97 + /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */ 2.98 + unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); 2.99 + if (ver >= 0x14) /* P4 or higher */ 2.100 + return; 2.101 /* 2.102 * Wait for idle. 2.103 */ 2.104 @@ -240,15 +262,17 @@ void __init init_bsp_APIC(void) 2.105 { 2.106 } 2.107 2.108 -static unsigned long calculate_ldr(unsigned long old) 2.109 -{ 2.110 - unsigned long id = 1UL << smp_processor_id(); 2.111 - return (old & ~APIC_LDR_MASK)|SET_APIC_LOGICAL_ID(id); 2.112 -} 2.113 - 2.114 void __init setup_local_APIC (void) 2.115 { 2.116 - unsigned long value, ver, maxlvt; 2.117 + unsigned long oldvalue, value, ver, maxlvt; 2.118 + 2.119 + /* Pound the ESR really hard over the head with a big hammer - mbligh */ 2.120 + if (esr_disable) { 2.121 + apic_write(APIC_ESR, 0); 2.122 + apic_write(APIC_ESR, 0); 2.123 + apic_write(APIC_ESR, 0); 2.124 + apic_write(APIC_ESR, 0); 2.125 + } 2.126 2.127 value = apic_read(APIC_LVR); 2.128 ver = GET_APIC_VERSION(value); 2.129 @@ -256,8 +280,10 @@ void __init setup_local_APIC (void) 2.130 if ((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f) 2.131 __error_in_apic_c(); 2.132 2.133 - /* Double-check wether this APIC is really registered. */ 2.134 - if (!test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map)) 2.135 + /* 2.136 + * Double-check whether this APIC is really registered. 2.137 + */ 2.138 + if (!apic_id_registered()) 2.139 BUG(); 2.140 2.141 /* 2.142 @@ -265,19 +291,7 @@ void __init setup_local_APIC (void) 2.143 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel 2.144 * document number 292116). So here it goes... 2.145 */ 2.146 - 2.147 - /* 2.148 - * In clustered apic mode, the firmware does this for us 2.149 - * Put the APIC into flat delivery mode. 2.150 - * Must be "all ones" explicitly for 82489DX. 2.151 - */ 2.152 - apic_write_around(APIC_DFR, APIC_DFR_FLAT); 2.153 - 2.154 - /* 2.155 - * Set up the logical destination ID. 2.156 - */ 2.157 - value = apic_read(APIC_LDR); 2.158 - apic_write_around(APIC_LDR, calculate_ldr(value)); 2.159 + init_apic_ldr(); 2.160 2.161 /* 2.162 * Set Task Priority to 'accept all'. We never change this 2.163 @@ -297,10 +311,35 @@ void __init setup_local_APIC (void) 2.164 */ 2.165 value |= APIC_SPIV_APIC_ENABLED; 2.166 2.167 + /* 2.168 + * Some unknown Intel IO/APIC (or APIC) errata is biting us with 2.169 + * certain networking cards. If high frequency interrupts are 2.170 + * happening on a particular IOAPIC pin, plus the IOAPIC routing 2.171 + * entry is masked/unmasked at a high rate as well then sooner or 2.172 + * later IOAPIC line gets 'stuck', no more interrupts are received 2.173 + * from the device. If focus CPU is disabled then the hang goes 2.174 + * away, oh well :-( 2.175 + * 2.176 + * [ This bug can be reproduced easily with a level-triggered 2.177 + * PCI Ne2000 networking cards and PII/PIII processors, dual 2.178 + * BX chipset. ] 2.179 + */ 2.180 + /* 2.181 + * Actually disabling the focus CPU check just makes the hang less 2.182 + * frequent as it makes the interrupt distributon model be more 2.183 + * like LRU than MRU (the short-term load is more even across CPUs). 2.184 + * See also the comment in end_level_ioapic_irq(). --macro 2.185 + */ 2.186 +#if 1 2.187 /* Enable focus processor (bit==0) */ 2.188 value &= ~APIC_SPIV_FOCUS_DISABLED; 2.189 - 2.190 - /* Set spurious IRQ vector */ 2.191 +#else 2.192 + /* Disable focus processor (bit==1) */ 2.193 + value |= APIC_SPIV_FOCUS_DISABLED; 2.194 +#endif 2.195 + /* 2.196 + * Set spurious IRQ vector 2.197 + */ 2.198 value |= SPURIOUS_APIC_VECTOR; 2.199 apic_write_around(APIC_SPIV, value); 2.200 2.201 @@ -315,7 +354,7 @@ void __init setup_local_APIC (void) 2.202 * TODO: set up through-local-APIC from through-I/O-APIC? --macro 2.203 */ 2.204 value = apic_read(APIC_LVT0) & APIC_LVT_MASKED; 2.205 - if (!smp_processor_id()) { 2.206 + if (!smp_processor_id() && (pic_mode || !value)) { 2.207 value = APIC_DM_EXTINT; 2.208 printk("enabled ExtINT on CPU#%d\n", smp_processor_id()); 2.209 } else { 2.210 @@ -335,33 +374,43 @@ void __init setup_local_APIC (void) 2.211 value |= APIC_LVT_LEVEL_TRIGGER; 2.212 apic_write_around(APIC_LVT1, value); 2.213 2.214 - if (APIC_INTEGRATED(ver)) { /* !82489DX */ 2.215 + if (APIC_INTEGRATED(ver) && !esr_disable) { /* !82489DX */ 2.216 maxlvt = get_maxlvt(); 2.217 if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ 2.218 apic_write(APIC_ESR, 0); 2.219 - value = apic_read(APIC_ESR); 2.220 - printk("ESR value before enabling vector: %08lx\n", value); 2.221 + oldvalue = apic_read(APIC_ESR); 2.222 2.223 - value = ERROR_APIC_VECTOR; /* enables sending errors */ 2.224 + value = ERROR_APIC_VECTOR; // enables sending errors 2.225 apic_write_around(APIC_LVTERR, value); 2.226 - /* spec says clear errors after enabling vector. */ 2.227 + /* 2.228 + * spec says clear errors after enabling vector. 2.229 + */ 2.230 if (maxlvt > 3) 2.231 apic_write(APIC_ESR, 0); 2.232 value = apic_read(APIC_ESR); 2.233 - printk("ESR value after enabling vector: %08lx\n", value); 2.234 + if (value != oldvalue) 2.235 + printk("ESR value before enabling vector: 0x%08lx " 2.236 + "after: 0x%08lx\n", oldvalue, value); 2.237 } else { 2.238 + if (esr_disable) 2.239 + /* 2.240 + * Something untraceble is creating bad interrupts on 2.241 + * secondary quads ... for the moment, just leave the 2.242 + * ESR disabled - we can't do anything useful with the 2.243 + * errors anyway - mbligh 2.244 + */ 2.245 + printk("Leaving ESR disabled.\n"); 2.246 + else 2.247 printk("No ESR for 82489DX.\n"); 2.248 } 2.249 2.250 - if ( (smp_processor_id() == 0) && (nmi_watchdog == NMI_LOCAL_APIC) ) 2.251 + if (nmi_watchdog == NMI_LOCAL_APIC) 2.252 setup_apic_nmi_watchdog(); 2.253 +#if 0 2.254 + apic_pm_activate(); 2.255 +#endif 2.256 } 2.257 2.258 - 2.259 -static inline void apic_pm_init1(void) { } 2.260 -static inline void apic_pm_init2(void) { } 2.261 - 2.262 - 2.263 /* 2.264 * Detect and enable local APICs on non-SMP boards. 2.265 * Original code written by Keir Fraser. 2.266 @@ -372,19 +421,23 @@ static int __init detect_init_APIC (void 2.267 u32 h, l, features; 2.268 extern void get_cpu_vendor(struct cpuinfo_x86*); 2.269 2.270 +#if 0 2.271 + /* Disabled by kernel option? */ 2.272 + if (enable_local_apic < 0) 2.273 + return -1; 2.274 +#endif 2.275 + 2.276 /* Workaround for us being called before identify_cpu(). */ 2.277 get_cpu_vendor(&boot_cpu_data); 2.278 2.279 switch (boot_cpu_data.x86_vendor) { 2.280 case X86_VENDOR_AMD: 2.281 - if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) 2.282 - break; 2.283 - if (boot_cpu_data.x86 == 15 && cpu_has_apic) 2.284 + if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) || 2.285 + (boot_cpu_data.x86 == 15)) 2.286 break; 2.287 goto no_apic; 2.288 case X86_VENDOR_INTEL: 2.289 - if (boot_cpu_data.x86 == 6 || 2.290 - (boot_cpu_data.x86 == 15 && cpu_has_apic) || 2.291 + if (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15 || 2.292 (boot_cpu_data.x86 == 5 && cpu_has_apic)) 2.293 break; 2.294 goto no_apic; 2.295 @@ -394,9 +447,21 @@ static int __init detect_init_APIC (void 2.296 2.297 if (!cpu_has_apic) { 2.298 /* 2.299 + * Over-ride BIOS and try to enable the local 2.300 + * APIC only if "lapic" specified. 2.301 + */ 2.302 +#if 0 2.303 + if (enable_local_apic <= 0) { 2.304 + printk("Local APIC disabled by BIOS -- " 2.305 + "you can enable it with \"lapic\"\n"); 2.306 + return -1; 2.307 + } 2.308 +#endif 2.309 + /* 2.310 * Some BIOSes disable the local APIC in the 2.311 * APIC_BASE MSR. This can only be done in 2.312 - * software for Intel P6 and AMD K7 (Model > 1). 2.313 + * software for Intel P6 or later and AMD K7 2.314 + * (Model > 1) or later. 2.315 */ 2.316 rdmsr(MSR_IA32_APICBASE, l, h); 2.317 if (!(l & MSR_IA32_APICBASE_ENABLE)) { 2.318 @@ -407,17 +472,17 @@ static int __init detect_init_APIC (void 2.319 enabled_via_apicbase = 1; 2.320 } 2.321 } 2.322 - 2.323 - /* The APIC feature bit should now be enabled in `cpuid' */ 2.324 + /* 2.325 + * The APIC feature bit should now be enabled 2.326 + * in `cpuid' 2.327 + */ 2.328 features = cpuid_edx(1); 2.329 if (!(features & (1 << X86_FEATURE_APIC))) { 2.330 printk("Could not enable APIC!\n"); 2.331 return -1; 2.332 } 2.333 - 2.334 - set_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability); 2.335 + set_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); 2.336 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; 2.337 - boot_cpu_physical_apicid = 0; 2.338 2.339 /* The BIOS may have set up the APIC at some other address */ 2.340 rdmsr(MSR_IA32_APICBASE, l, h); 2.341 @@ -428,21 +493,26 @@ static int __init detect_init_APIC (void 2.342 nmi_watchdog = NMI_LOCAL_APIC; 2.343 2.344 printk("Found and enabled local APIC!\n"); 2.345 - apic_pm_init1(); 2.346 + 2.347 +#if 0 2.348 + apic_pm_activate(); 2.349 +#endif 2.350 + 2.351 return 0; 2.352 2.353 - no_apic: 2.354 +no_apic: 2.355 printk("No local APIC present or hardware disabled\n"); 2.356 return -1; 2.357 } 2.358 2.359 void __init init_apic_mappings(void) 2.360 { 2.361 - unsigned long apic_phys = 0; 2.362 + unsigned long apic_phys; 2.363 2.364 /* 2.365 - * If no local APIC can be found then set up a fake all zeroes page to 2.366 - * simulate the local APIC and another one for the IO-APIC. 2.367 + * If no local APIC can be found then set up a fake all 2.368 + * zeroes page to simulate the local APIC and another 2.369 + * one for the IO-APIC. 2.370 */ 2.371 if (!smp_found_config && detect_init_APIC()) { 2.372 apic_phys = alloc_xenheap_page(); 2.373 @@ -462,12 +532,26 @@ void __init init_apic_mappings(void) 2.374 2.375 #ifdef CONFIG_X86_IO_APIC 2.376 { 2.377 - unsigned long ioapic_phys = 0, idx = FIX_IO_APIC_BASE_0; 2.378 + unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; 2.379 int i; 2.380 2.381 for (i = 0; i < nr_ioapics; i++) { 2.382 - if (smp_found_config) 2.383 + if (smp_found_config) { 2.384 ioapic_phys = mp_ioapics[i].mpc_apicaddr; 2.385 + if (!ioapic_phys) { 2.386 + printk(KERN_ERR 2.387 + "WARNING: bogus zero IO-APIC " 2.388 + "address found in MPTABLE, " 2.389 + "disabling IO/APIC support!\n"); 2.390 + smp_found_config = 0; 2.391 + skip_ioapic_setup = 1; 2.392 + goto fake_ioapic_page; 2.393 + } 2.394 + } else { 2.395 +fake_ioapic_page: 2.396 + ioapic_phys = alloc_xenheap_page(); 2.397 + ioapic_phys = __pa(ioapic_phys); 2.398 + } 2.399 set_fixmap_nocache(idx, ioapic_phys); 2.400 Dprintk("mapped IOAPIC to %08lx (%08lx)\n", 2.401 fix_to_virt(idx), ioapic_phys); 2.402 @@ -504,33 +588,49 @@ static unsigned int __init get_8254_time 2.403 { 2.404 /*extern spinlock_t i8253_lock;*/ 2.405 /*unsigned long flags;*/ 2.406 + 2.407 unsigned int count; 2.408 + 2.409 /*spin_lock_irqsave(&i8253_lock, flags);*/ 2.410 - outb_p(0x00, 0x43); 2.411 - count = inb_p(0x40); 2.412 - count |= inb_p(0x40) << 8; 2.413 + 2.414 + outb_p(0x00, PIT_MODE); 2.415 + count = inb_p(PIT_CH0); 2.416 + count |= inb_p(PIT_CH0) << 8; 2.417 + 2.418 /*spin_unlock_irqrestore(&i8253_lock, flags);*/ 2.419 + 2.420 return count; 2.421 } 2.422 2.423 -void __init wait_8254_wraparound(void) 2.424 +/* next tick in 8254 can be caught by catching timer wraparound */ 2.425 +static void __init wait_8254_wraparound(void) 2.426 { 2.427 unsigned int curr_count, prev_count=~0; 2.428 int delta; 2.429 + 2.430 curr_count = get_8254_timer_count(); 2.431 + 2.432 do { 2.433 prev_count = curr_count; 2.434 curr_count = get_8254_timer_count(); 2.435 delta = curr_count-prev_count; 2.436 + 2.437 /* 2.438 - * This limit for delta seems arbitrary, but it isn't, it's slightly 2.439 - * above the level of error a buggy Mercury/Neptune chipset timer can 2.440 - * cause. 2.441 + * This limit for delta seems arbitrary, but it isn't, it's 2.442 + * slightly above the level of error a buggy Mercury/Neptune 2.443 + * chipset timer can cause. 2.444 */ 2.445 + 2.446 } while (delta < 300); 2.447 } 2.448 2.449 /* 2.450 + * Default initialization for 8254 timers. If we use other timers like HPET, 2.451 + * we override this later 2.452 + */ 2.453 +void (*wait_timer_tick)(void) = wait_8254_wraparound; 2.454 + 2.455 +/* 2.456 * This function sets up the local APIC timer, with a timeout of 2.457 * 'clocks' APIC bus clock. During calibration we actually call 2.458 * this function with a very large value and read the current time after 2.459 @@ -541,14 +641,32 @@ void __init wait_8254_wraparound(void) 2.460 * We do reads before writes even if unnecessary, to get around the 2.461 * P5 APIC double write bug. 2.462 */ 2.463 + 2.464 #define APIC_DIVISOR 1 2.465 + 2.466 static void __setup_APIC_LVTT(unsigned int clocks) 2.467 { 2.468 - unsigned int lvtt1_value, tmp_value; 2.469 - lvtt1_value = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV)|LOCAL_TIMER_VECTOR; 2.470 - apic_write_around(APIC_LVTT, lvtt1_value); 2.471 + unsigned int lvtt_value, tmp_value, ver; 2.472 + 2.473 + ver = GET_APIC_VERSION(apic_read(APIC_LVR)); 2.474 + lvtt_value = APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR; 2.475 + if (!APIC_INTEGRATED(ver)) 2.476 + lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV); 2.477 + apic_write_around(APIC_LVTT, lvtt_value); 2.478 + 2.479 +#if 0 2.480 + /* 2.481 + * Divide PICLK by 16 2.482 + */ 2.483 + tmp_value = apic_read(APIC_TDCR); 2.484 + apic_write_around(APIC_TDCR, (tmp_value 2.485 + & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) 2.486 + | APIC_TDR_DIV_16); 2.487 +#endif 2.488 + 2.489 tmp_value = apic_read(APIC_TDCR); 2.490 apic_write_around(APIC_TDCR, (tmp_value | APIC_TDR_DIV_1)); 2.491 + 2.492 apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR); 2.493 } 2.494 2.495 @@ -569,7 +687,7 @@ void setup_APIC_timer(void * data) 2.496 /* 2.497 * In this function we calibrate APIC bus clocks to the external timer. 2.498 * 2.499 - * As a result we have the Bys Speed and CPU speed in Hz. 2.500 + * As a result we have the Bus Speed and CPU speed in Hz. 2.501 * 2.502 * We want to do the calibration only once (for CPU0). CPUs connected by the 2.503 * same APIC bus have the very same bus frequency. 2.504 @@ -586,48 +704,61 @@ int __init calibrate_APIC_clock(void) 2.505 int i; 2.506 const int LOOPS = HZ/10; 2.507 2.508 +#if 0 2.509 + apic_printk(APIC_VERBOSE, "calibrating APIC timer ...\n"); 2.510 +#endif 2.511 printk("Calibrating APIC timer for CPU%d...\n", smp_processor_id()); 2.512 2.513 - /* Put whatever arbitrary (but long enough) timeout 2.514 + /* 2.515 + * Put whatever arbitrary (but long enough) timeout 2.516 * value into the APIC clock, we just want to get the 2.517 - * counter running for calibration. */ 2.518 + * counter running for calibration. 2.519 + */ 2.520 __setup_APIC_LVTT(1000000000); 2.521 2.522 - /* The timer chip counts down to zero. Let's wait 2.523 + /* 2.524 + * The timer chip counts down to zero. Let's wait 2.525 * for a wraparound to start exact measurement: 2.526 - * (the current tick might have been already half done) */ 2.527 - wait_8254_wraparound(); 2.528 + * (the current tick might have been already half done) 2.529 + */ 2.530 + 2.531 + wait_timer_tick(); 2.532 2.533 - /* We wrapped around just now. Let's start: */ 2.534 + /* 2.535 + * We wrapped around just now. Let's start: 2.536 + */ 2.537 + if (cpu_has_tsc) 2.538 rdtscll(t1); 2.539 tt1 = apic_read(APIC_TMCCT); 2.540 2.541 - /* Let's wait LOOPS wraprounds: */ 2.542 + /* 2.543 + * Let's wait LOOPS wraprounds: 2.544 + */ 2.545 for (i = 0; i < LOOPS; i++) 2.546 - wait_8254_wraparound(); 2.547 + wait_timer_tick(); 2.548 2.549 tt2 = apic_read(APIC_TMCCT); 2.550 + if (cpu_has_tsc) 2.551 rdtscll(t2); 2.552 2.553 - /* The APIC bus clock counter is 32 bits only, it 2.554 + /* 2.555 + * The APIC bus clock counter is 32 bits only, it 2.556 * might have overflown, but note that we use signed 2.557 * longs, thus no extra care needed. 2.558 - * underflown to be exact, as the timer counts down ;) */ 2.559 + * 2.560 + * underflown to be exact, as the timer counts down ;) 2.561 + */ 2.562 + 2.563 result = (tt1-tt2)*APIC_DIVISOR/LOOPS; 2.564 2.565 - printk("..... CPU speed is %ld.%04ld MHz.\n", 2.566 - ((long)(t2-t1)/LOOPS) / (1000000/HZ), 2.567 - ((long)(t2-t1)/LOOPS) % (1000000/HZ)); 2.568 + if (cpu_has_tsc) 2.569 + printk("..... CPU clock speed is %ld.%04ld MHz.\n", 2.570 + ((long)(t2-t1)/LOOPS)/(1000000/HZ), 2.571 + ((long)(t2-t1)/LOOPS)%(1000000/HZ)); 2.572 2.573 - printk("..... Bus speed is %ld.%04ld MHz.\n", 2.574 - result / (1000000/HZ), 2.575 - result % (1000000/HZ)); 2.576 - 2.577 - /* 2.578 - * KAF: Moved this to time.c where it's calculated relative to the TSC. 2.579 - * Therefore works on machines with no local APIC. 2.580 - */ 2.581 - /*cpu_freq = (u64)(((t2-t1)/LOOPS)*HZ);*/ 2.582 + printk("..... host bus clock speed is %ld.%04ld MHz.\n", 2.583 + result/(1000000/HZ), 2.584 + result%(1000000/HZ)); 2.585 2.586 /* set up multipliers for accurate timer code */ 2.587 bus_freq = result*HZ; 2.588 @@ -637,6 +768,7 @@ int __init calibrate_APIC_clock(void) 2.589 printk("..... bus_scale = 0x%08X\n", bus_scale); 2.590 /* reset APIC to zero timeout value */ 2.591 __setup_APIC_LVTT(0); 2.592 + 2.593 return result; 2.594 } 2.595 2.596 @@ -729,13 +861,17 @@ void smp_apic_timer_interrupt(struct xen 2.597 raise_softirq(AC_TIMER_SOFTIRQ); 2.598 } 2.599 2.600 + 2.601 /* 2.602 * This interrupt should _never_ happen with our APIC/SMP architecture 2.603 */ 2.604 -asmlinkage void smp_spurious_interrupt(void) 2.605 +asmlinkage void smp_spurious_interrupt(struct xen_regs *regs) 2.606 { 2.607 unsigned long v; 2.608 2.609 +#if 0 2.610 + irq_enter(); 2.611 +#endif 2.612 /* 2.613 * Check if this really is a spurious interrupt and ACK it 2.614 * if it is a vectored one. Just in case... 2.615 @@ -748,16 +884,22 @@ asmlinkage void smp_spurious_interrupt(v 2.616 /* see sw-dev-man vol 3, chapter 7.4.13.5 */ 2.617 printk("spurious APIC interrupt on CPU#%d, should never happen.\n", 2.618 smp_processor_id()); 2.619 +#if 0 2.620 + irq_exit(); 2.621 +#endif 2.622 } 2.623 2.624 /* 2.625 * This interrupt should never happen with our APIC/SMP architecture 2.626 */ 2.627 2.628 -asmlinkage void smp_error_interrupt(void) 2.629 +asmlinkage void smp_error_interrupt(struct xen_regs *regs) 2.630 { 2.631 unsigned long v, v1; 2.632 2.633 +#if 0 2.634 + irq_enter(); 2.635 +#endif 2.636 /* First tickle the hardware, only then report what went on. -- REW */ 2.637 v = apic_read(APIC_ESR); 2.638 apic_write(APIC_ESR, 0); 2.639 @@ -775,8 +917,11 @@ asmlinkage void smp_error_interrupt(void 2.640 6: Received illegal vector 2.641 7: Illegal register address 2.642 */ 2.643 - printk ("APIC error on CPU%d: %02lx(%02lx)\n", 2.644 + Dprintk("APIC error on CPU%d: %02lx(%02lx)\n", 2.645 smp_processor_id(), v , v1); 2.646 +#if 0 2.647 + irq_exit(); 2.648 +#endif 2.649 } 2.650 2.651 /* 2.652 @@ -785,14 +930,18 @@ asmlinkage void smp_error_interrupt(void 2.653 */ 2.654 int __init APIC_init_uniprocessor (void) 2.655 { 2.656 +#if 0 2.657 + if (enable_local_apic < 0) 2.658 + clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); 2.659 +#endif 2.660 + 2.661 if (!smp_found_config && !cpu_has_apic) 2.662 return -1; 2.663 2.664 /* 2.665 * Complain if the BIOS pretends there is one. 2.666 */ 2.667 - if (!cpu_has_apic&&APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) 2.668 - { 2.669 + if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { 2.670 printk("BIOS bug, local APIC #%d not detected!...\n", 2.671 boot_cpu_physical_apicid); 2.672 return -1; 2.673 @@ -805,17 +954,26 @@ int __init APIC_init_uniprocessor (void) 2.674 #ifdef CONFIG_SMP 2.675 cpu_online_map = 1; 2.676 #endif 2.677 +#if 0 2.678 + phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid); 2.679 +#endif 2.680 phys_cpu_present_map = 1; 2.681 apic_write_around(APIC_ID, boot_cpu_physical_apicid); 2.682 2.683 - apic_pm_init2(); 2.684 - 2.685 setup_local_APIC(); 2.686 2.687 +#if 0 2.688 + if (nmi_watchdog == NMI_LOCAL_APIC) 2.689 + check_nmi_watchdog(); 2.690 +#endif 2.691 #ifdef CONFIG_X86_IO_APIC 2.692 - if (smp_found_config && nr_ioapics) 2.693 + if (smp_found_config) 2.694 + if (!skip_ioapic_setup && nr_ioapics) 2.695 setup_IO_APIC(); 2.696 #endif 2.697 +#if 0 2.698 + setup_boot_APIC_clock(); 2.699 +#endif 2.700 setup_APIC_clocks(); 2.701 2.702 return 0;
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/xen/include/asm-x86/io_ports.h Fri Apr 15 23:40:59 2005 +0000 3.3 @@ -0,0 +1,30 @@ 3.4 +/* 3.5 + * based on linux-2.6.10/include/asm-i386/mach-default/io_ports.h 3.6 + * 3.7 + * Machine specific IO port address definition for generic. 3.8 + * Written by Osamu Tomita <tomita@cinet.co.jp> 3.9 + */ 3.10 +#ifndef _MACH_IO_PORTS_H 3.11 +#define _MACH_IO_PORTS_H 3.12 + 3.13 +/* i8253A PIT registers */ 3.14 +#define PIT_MODE 0x43 3.15 +#define PIT_CH0 0x40 3.16 +#define PIT_CH2 0x42 3.17 + 3.18 +/* i8259A PIC registers */ 3.19 +#define PIC_MASTER_CMD 0x20 3.20 +#define PIC_MASTER_IMR 0x21 3.21 +#define PIC_MASTER_ISR PIC_MASTER_CMD 3.22 +#define PIC_MASTER_POLL PIC_MASTER_ISR 3.23 +#define PIC_MASTER_OCW3 PIC_MASTER_ISR 3.24 +#define PIC_SLAVE_CMD 0xa0 3.25 +#define PIC_SLAVE_IMR 0xa1 3.26 + 3.27 +/* i8259A PIC related value */ 3.28 +#define PIC_CASCADE_IR 2 3.29 +#define MASTER_ICW4_DEFAULT 0x01 3.30 +#define SLAVE_ICW4_DEFAULT 0x01 3.31 +#define PIC_ICW4_AEOI 2 3.32 + 3.33 +#endif /* !_MACH_IO_PORTS_H */
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/xen/include/asm-x86/mach_apic.h Fri Apr 15 23:40:59 2005 +0000 4.3 @@ -0,0 +1,32 @@ 4.4 +/* 4.5 + * based on linux-2.6.10/include/asm-i386/mach-default/mach_apic.h 4.6 + * 4.7 + */ 4.8 +#ifndef __ASM_MACH_APIC_H 4.9 +#define __ASM_MACH_APIC_H 4.10 + 4.11 +#define APIC_DFR_VALUE (APIC_DFR_FLAT) 4.12 +#define esr_disable (0) 4.13 + 4.14 +/* 4.15 + * Set up the logical destination ID. 4.16 + * 4.17 + * Intel recommends to set DFR, LDR and TPR before enabling 4.18 + * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel 4.19 + * document number 292116). So here it goes... 4.20 + */ 4.21 +static inline void init_apic_ldr(void) 4.22 +{ 4.23 + unsigned long val; 4.24 + 4.25 + apic_write_around(APIC_DFR, APIC_DFR_VALUE); 4.26 + val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; 4.27 + val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); 4.28 + apic_write_around(APIC_LDR, val); 4.29 +} 4.30 + 4.31 +static inline int apic_id_registered(void) 4.32 +{ 4.33 + return test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map); 4.34 +} 4.35 +#endif /* __ASM_MACH_APIC_H */