patch-2.4.19 linux-2.4.19/arch/i386/kernel/apic.c
Next file: linux-2.4.19/arch/i386/kernel/apm.c
Previous file: linux-2.4.19/arch/i386/kernel/acpitable.c
Back to the patch index
Back to the overall index
- Lines: 96
- Date:
Fri Aug 2 17:39:42 2002
- Orig file:
linux-2.4.18/arch/i386/kernel/apic.c
- Orig date:
Mon Feb 25 11:37:52 2002
diff -urN linux-2.4.18/arch/i386/kernel/apic.c linux-2.4.19/arch/i386/kernel/apic.c
@@ -582,12 +582,17 @@
* Detect and enable local APICs on non-SMP boards.
* Original code written by Keir Fraser.
*/
+int dont_enable_local_apic __initdata = 0;
static int __init detect_init_APIC (void)
{
u32 h, l, features;
extern void get_cpu_vendor(struct cpuinfo_x86*);
+ /* Disabled by DMI scan or kernel option? */
+ if (dont_enable_local_apic)
+ return -1;
+
/* Workaround for us being called before identify_cpu(). */
get_cpu_vendor(&boot_cpu_data);
@@ -679,7 +684,15 @@
for (i = 0; i < nr_ioapics; i++) {
if (smp_found_config) {
ioapic_phys = mp_ioapics[i].mpc_apicaddr;
+ if (!ioapic_phys) {
+ printk(KERN_ERR "WARNING: bogus zero IO-APIC address found in MPTABLE, disabling IO/APIC support!\n");
+
+ smp_found_config = 0;
+ skip_ioapic_setup = 1;
+ goto fake_ioapic_page;
+ }
} else {
+fake_ioapic_page:
ioapic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
ioapic_phys = __pa(ioapic_phys);
}
@@ -796,8 +809,7 @@
*/
slice = clocks / (smp_num_cpus+1);
- printk("cpu: %d, clocks: %d, slice: %d\n",
- smp_processor_id(), clocks, slice);
+ printk("cpu: %d, clocks: %d, slice: %d\n", smp_processor_id(), clocks, slice);
/*
* Wait for IRQ0's slice:
@@ -820,8 +832,7 @@
__setup_APIC_LVTT(clocks);
- printk("CPU%d<T0:%d,T1:%d,D:%d,S:%d,C:%d>\n",
- smp_processor_id(), t0, t1, delta, slice, clocks);
+ printk("CPU%d<T0:%d,T1:%d,D:%d,S:%d,C:%d>\n", smp_processor_id(), t0, t1, delta, slice, clocks);
__restore_flags(flags);
}
@@ -905,8 +916,14 @@
static unsigned int calibration_result;
+int dont_use_local_apic_timer __initdata = 0;
+
void __init setup_APIC_clocks (void)
{
+ /* Disabled by DMI scan or kernel option? */
+ if (dont_use_local_apic_timer)
+ return;
+
printk("Using local APIC timer interrupts.\n");
using_apic_timer = 1;
@@ -924,6 +941,26 @@
smp_call_function(setup_APIC_timer, (void *)calibration_result, 1, 1);
}
+void __init disable_APIC_timer(void)
+{
+ if (using_apic_timer) {
+ unsigned long v;
+
+ v = apic_read(APIC_LVTT);
+ apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED);
+ }
+}
+
+void enable_APIC_timer(void)
+{
+ if (using_apic_timer) {
+ unsigned long v;
+
+ v = apic_read(APIC_LVTT);
+ apic_write_around(APIC_LVTT, v & ~APIC_LVT_MASKED);
+ }
+}
+
/*
* the frequency of the profiling timer can be changed
* by writing a multiplier value into /proc/profile.
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)