lkml.org 
[lkml]   [1999]   [Jul]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: Intel Xpress Server - IO APIC trouble - Kernel panic: IO APIC + timer doesn't work!
On Wed, 21 Jul 1999, Sunshine wrote:

> I am having some trouble getting any smp kernel to run on my ancient Pentium
> system. The problem I am having is that ( from what I have read in various
> linux smp documents) the my old Intel motherboard mp table is lying about
> the IRQ for the Real Time Clock. Thus preventing me from booting. The
> system boots up and detects both processors and then right after the IO-APIC
> starts I get this:
>
> enabling symetric IO mode... done
> ENABLING IO-APIC
> ... No explicit IRQ entries, using default mptable.
> changing APIC ID to 2 <-- I am not sure if I recalled this from memory
> right
> IO APIC pin 2, 13 not connected.
> .. MP-BIOS bug: 8254 timer not connected to IO-APIC
> ...trying to set up timer as ExtINT... failed
^^^^^^
> ...tryng to set up timer as BP IRQ... failed
> Kernel panic: IO APIC + timer doesn't work!
> In swapper task - not syncing
[...]
> Linux version 2.2.5-15smp (root@porky.devel.redhat.com) (gcc version
> egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)) #1 SMP Mon Apr 19 22:03:51
> EDT 1999
> Intel MultiProcessor Specification v1.1
> Virtual Wire compatibility mode.
^^^^^^^^^^^^
> I/O APIC at 0xFEC00000.
> Bus #0 is EISA with no IRQ8 chaining
> Processors: 2
> mapped APIC to ffffe000 (fee00000)
> mapped IOAPIC to ffffd000 (fec00000)
> Detected 66664407 Hz processor.
> Console: colour VGA+ 80x25
> Calibrating delay loop... 26.52 BogoMIPS
> Memory: 62752k/65536k available (1044k kernel code, 416k reserved, 968k
> data, 68k init)
> VFS: Diskquotas version dquot_6.4.0 initialized
> Checking 386/387 coupling... Hmm, FPU using exception 16 error reporting
> with FDIV bug.
> Checking 'hlt' instruction... OK.
> Intel Pentium with F0 0F bug - workaround enabled.
> POSIX conformance testing by UNIFIX
> per-CPU timeslice cutoff: 1.57 usecs.
> CPU0: Intel Pentium 60/66 stepping 05
> calibrating APIC timer ...
> ..... CPU clock speed is 66.6638 MHz.
> ..... system bus clock speed is 533.3073 MHz.
^^^^^^^^^^^^
> Booting processor 1 eip 2000
> Calibrating delay loop... 26.62 BogoMIPS
> OK.
> CPU1: Intel Pentium 60/66 stepping 05
> Total of 2 processors activated (53.15 BogoMIPS).

[I've marked log entries I am referring to below.]

Have you noticed your local APIC timers get calibrated wrong? The value
of 533.3073 MHz does not certainly match your bus clock, but if you divide
it by 16 then you get the right value of 33 MHz (that's the speed of APIC
bus, not the system one, BTW). As the APIC timer, once calibrated, is
used as the reference clock, your system may miss the interrupt when
performing 8254 setup.

Actually, I cannot really imagine 8254 not working as ExtINT, as that's
basically the way interrupts work when a system starts in the virtual wire
compatibility mode (and your does).

Basically current kernel versions do not handle 82489DX APICs at all
(these are the separate chips used for pre-Pentium 75 setups which include
i486 and Pentium60/66 boards). I sent an apropriate patch to set up
82489DXs correctly to linux-kernel a few weeks ago but (as usually)
haven't got any feedback. I don't have such an old SMP system, so while I
can assure it does not hurt systems with integrated local-APICs, I can't
be sure it solves all problems with 82489DXs. I'm providing the patch
again (see below).

I would be pleased if you run it once, at least, and report me the
results (a dmesg output would be appreciated). Note, the patch is against
2.3.10 but I tested it against 2.2.10 and it applied cleanly. You should
have no problems with 2.2.5, too.

Good luck!

Maciej

--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +

diff -u --recursive --new-file linux-2.3.10.macro/arch/i386/kernel/smp.c linux-2.3.10/arch/i386/kernel/smp.c
--- linux-2.3.10.macro/arch/i386/kernel/smp.c Thu Jul 1 23:09:00 1999
+++ linux-2.3.10/arch/i386/kernel/smp.c Mon Jul 12 15:43:27 1999
@@ -30,6 +30,7 @@
* Alan Cox : Added EBDA scanning
* Ingo Molnar : various cleanups and rewrites
* Tigran Aivazian : fixed "0.00 in /proc/uptime on SMP" bug.
+ * Maciej W. Rozycki : Bits for genuine 82489DX timers.
*/

#include <linux/config.h>
@@ -1962,14 +1963,16 @@
* interrupt and broadcast it as an NMI to all CPUs, so no pain.
*/
tmp_value = apic_read(APIC_LVTT);
- lvtt1_value = APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR;
- apic_write(APIC_LVTT , lvtt1_value);
+ lvtt1_value = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV)
+ | APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR;
+ apic_write(APIC_LVTT, lvtt1_value);

/*
* Divide PICLK by 16
*/
tmp_value = apic_read(APIC_TDCR);
- apic_write(APIC_TDCR , (tmp_value & ~APIC_TDR_DIV_1 )
+ apic_write(APIC_TDCR, (tmp_value
+ & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE))
| APIC_TDR_DIV_16);

tmp_value = apic_read(APIC_TMICT);
@@ -2026,29 +2029,44 @@
*/
setup_APIC_timer(1000000000);

- /*
- * The timer chip counts down to zero. Let's wait
- * for a wraparound to start exact measurement:
- * (the current tick might have been already half done)
- */
+ if (cpu_data[smp_processor_id()].x86_capability & X86_FEATURE_TSC) {
+ /*
+ * The timer chip counts down to zero. Let's wait
+ * for a wraparound to start exact measurement:
+ * (the current tick might have been already half done)
+ */

- wait_8254_wraparound ();
+ wait_8254_wraparound ();

- /*
- * We wrapped around just now. Let's start:
- */
- rdtscll(t1);
- tt1=apic_read(APIC_TMCCT);
+ /*
+ * We wrapped around just now. Let's start:
+ */
+ rdtscll(t1);
+ tt1=apic_read(APIC_TMCCT);

#define LOOPS (HZ/10)
- /*
- * Let's wait LOOPS wraprounds:
- */
- for (i=0; i<LOOPS; i++)
+ /*
+ * Let's wait LOOPS wraprounds:
+ */
+ for (i=0; i<LOOPS; i++)
+ wait_8254_wraparound ();
+
+ tt2=apic_read(APIC_TMCCT);
+ rdtscll(t2);
+ } else {
+ /*
+ * Same as above but without TSC.
+ */
+
wait_8254_wraparound ();

- tt2=apic_read(APIC_TMCCT);
- rdtscll(t2);
+ tt1=apic_read(APIC_TMCCT);
+
+ for (i=0; i<LOOPS; i++)
+ wait_8254_wraparound ();
+
+ tt2=apic_read(APIC_TMCCT);
+ }

/*
* The APIC bus clock counter is 32 bits only, it
@@ -2060,16 +2078,18 @@

calibration_result = (tt1-tt2)*APIC_DIVISOR/LOOPS;

- SMP_PRINTK(("\n..... %ld CPU clocks in 1 timer chip tick.",
- (unsigned long)(t2-t1)/LOOPS));
+ if (cpu_data[smp_processor_id()].x86_capability & X86_FEATURE_TSC)
+ SMP_PRINTK(("\n..... %ld CPU clocks in 1 timer chip tick.",
+ (unsigned long)(t2-t1)/LOOPS));

SMP_PRINTK(("\n..... %ld APIC bus clocks in 1 timer chip tick.",
calibration_result));


- printk("\n..... CPU clock speed is %ld.%04ld MHz.\n",
- ((long)(t2-t1)/LOOPS)/(1000000/HZ),
- ((long)(t2-t1)/LOOPS)%(1000000/HZ) );
+ if (cpu_data[smp_processor_id()].x86_capability & X86_FEATURE_TSC)
+ printk("\n..... CPU clock speed is %ld.%04ld MHz.\n",
+ ((long)(t2-t1)/LOOPS)/(1000000/HZ),
+ ((long)(t2-t1)/LOOPS)%(1000000/HZ) );

printk("..... system bus clock speed is %ld.%04ld MHz.\n",
calibration_result/(1000000/HZ),
diff -u --recursive --new-file linux-2.3.10.macro/include/asm-i386/i82489.h linux-2.3.10/include/asm-i386/i82489.h
--- linux-2.3.10.macro/include/asm-i386/i82489.h Tue Jan 26 23:33:51 1999
+++ linux-2.3.10/include/asm-i386/i82489.h Sun Jul 11 21:55:42 1999
@@ -5,6 +5,7 @@
* Offsets for programming the 82489 and Pentium integrated APIC
*
* Alan Cox <Alan.Cox@linux.org>, 1995.
+ * Maciej W. Rozycki <macro@ds2.pg.gda.pl>, 1999.
*/
#define APIC_PHYS_BASE 0xfee00000 /* IA s/w dev Vol 3, Section 7.4 */

@@ -62,8 +63,14 @@
#define GET_APIC_DEST_FIELD(x) (((x)>>24)&0xFF)
#define SET_APIC_DEST_FIELD(x) ((x)<<24)
#define APIC_LVTT 0x320
-#define APIC_LVT0 0x350
+#define APIC_LVT_TIMER_BASE_MASK (0x3<<18)
+#define GET_APIC_TIMER_BASE(x) (((x)>>18)&0x3)
+#define SET_APIC_TIMER_BASE(x) (((x)<<18))
+#define APIC_TIMER_BASE_CLKIN 0x0
+#define APIC_TIMER_BASE_TMBASE 0x1
+#define APIC_TIMER_BASE_DIV 0x2
#define APIC_LVT_TIMER_PERIODIC (1<<17)
+#define APIC_LVT0 0x350
#define APIC_LVT_MASKED (1<<16)
#define APIC_LVT_LEVEL_TRIGGER (1<<15)
#define APIC_LVT_REMOTE_IRR (1<<14)
@@ -79,6 +86,7 @@
#define APIC_TMICT 0x380
#define APIC_TMCCT 0x390
#define APIC_TDCR 0x3E0
+#define APIC_TDR_DIV_TMBASE (1<<2)
#define APIC_TDR_DIV_1 0xB
#define APIC_TDR_DIV_2 0x0
#define APIC_TDR_DIV_4 0x1



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:53    [W:0.056 / U:0.096 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site