From: Richard Henderson <rth@redhat.com>
To: torvalds@transmeta.com, alan@redhat.com
Cc: linux-kernel@vger.kernel.org
Subject: alpha 2.4.13: cycle detection sanity checks
Date: Fri, 26 Oct 2001 01:41:33 -0700 [thread overview]
Message-ID: <20011026014133.A1422@redhat.com> (raw)
Ivan Kokshaysky and others recently put in code to fix some cycle
counter detection problems on UP2000 systems. It turns out that
PC164 and LX164 systems have different broken hardware, and the
new code turns up completely bogus numbers like 1.9GHz on those
systems.
The following adds some knowledge about what sort of hardware
actually exists, so that we can determine that the computed
value is completely out of line.
Worst case (say if someone overclocked their system) we'll fail
to believe both of our computations and accept (with a warning)
the value given by the PROM (which is sometimes wrong, which is
why we're trying to compute the value in the first place).
r~
--- linux/arch/alpha/kernel/time.c Thu Oct 4 18:47:08 2001
+++ 2.4.13/arch/alpha/kernel/time.c Thu Oct 25 13:37:24 2001
@@ -169,6 +169,50 @@ common_init_rtc(void)
init_rtc_irq();
}
+
+/* Validate a computed cycle counter result against the known bounds for
+ the given processor core. There's too much brokenness in the way of
+ timing hardware for any one method to work everywhere. :-(
+
+ Return 0 if the result cannot be trusted, otherwise return the argument. */
+
+static unsigned long __init
+validate_cc_value(unsigned long cc)
+{
+ static struct bounds {
+ unsigned int min, max;
+ } cpu_hz[] __initdata = {
+ [EV3_CPU] = { 50000000, 200000000 }, /* guess */
+ [EV4_CPU] = { 150000000, 300000000 },
+ [LCA4_CPU] = { 150000000, 300000000 }, /* guess */
+ [EV45_CPU] = { 200000000, 300000000 },
+ [EV5_CPU] = { 266000000, 333333333 },
+ [EV56_CPU] = { 366000000, 667000000 },
+ [PCA56_CPU] = { 400000000, 600000000 }, /* guess */
+ [PCA57_CPU] = { 500000000, 600000000 }, /* guess */
+ [EV6_CPU] = { 466000000, 600000000 },
+ [EV67_CPU] = { 600000000, 833333333 }, /* guess */
+ /* ??? EV68 is shipping. No hwrpb value?
+ Christopher C. Chimelis sez 667-833MHz. */
+ };
+
+ struct percpu_struct *cpu;
+ unsigned int index;
+
+ cpu = (struct percpu_struct *)((char*)hwrpb + hwrpb->processor_offset);
+ index = cpu->type & 0xffffffff;
+
+ /* If index out of bounds, no way to validate. */
+ if (index >= sizeof(cpu_hz)/sizeof(cpu_hz[0]))
+ return cc;
+
+ if (cc < cpu_hz[index].min || cc > cpu_hz[index].max)
+ return 0;
+
+ return cc;
+}
+
+
/*
* Calibrate CPU clock using legacy 8254 timer/counter. Stolen from
* arch/i386/time.c.
@@ -180,8 +224,7 @@ common_init_rtc(void)
static unsigned long __init
calibrate_cc_with_pic(void)
{
- int cc;
- unsigned long count = 0;
+ int cc, count = 0;
/* Set the Gate high, disable speaker */
outb((inb(0x61) & ~0x02) | 0x01, 0x61);
@@ -200,30 +243,18 @@ calibrate_cc_with_pic(void)
cc = rpcc();
do {
count++;
- } while ((inb(0x61) & 0x20) == 0);
+ } while ((inb(0x61) & 0x20) == 0 && count > 0);
cc = rpcc() - cc;
- /* Error: ECTCNEVERSET */
+ /* Error: ECTCNEVERSET or ECPUTOOFAST. */
if (count <= 1)
- goto bad_ctc;
+ return 0;
- /* Error: ECPUTOOFAST */
- if (count >> 32)
- goto bad_ctc;
-
- /* Error: ECPUTOOSLOW */
+ /* Error: ECPUTOOSLOW. */
if (cc <= CALIBRATE_TIME)
- goto bad_ctc;
-
- return ((long)cc * 1000000) / CALIBRATE_TIME;
+ return 0;
- /*
- * The CTC wasn't reliable: we got a hit on the very first read,
- * or the CPU was so fast/slow that the quotient wouldn't fit in
- * 32 bits..
- */
- bad_ctc:
- return 0;
+ return (cc * 1000000UL) / CALIBRATE_TIME;
}
/* The Linux interpretation of the CMOS clock register contents:
@@ -249,31 +280,35 @@ time_init(void)
/* Calibrate CPU clock -- attempt #1. */
if (!est_cycle_freq)
- est_cycle_freq = calibrate_cc_with_pic();
+ est_cycle_freq = validate_cc_value(calibrate_cc_with_pic());
cc1 = rpcc_after_update_in_progress();
/* Calibrate CPU clock -- attempt #2. */
if (!est_cycle_freq) {
cc2 = rpcc_after_update_in_progress();
- est_cycle_freq = cc2 - cc1;
+ est_cycle_freq = validate_cc_value(cc2 - cc1);
cc1 = cc2;
}
- /* If the given value is within 1% of what we calculated,
- accept it. Otherwise, use what we found. */
cycle_freq = hwrpb->cycle_freq;
- one_percent = cycle_freq / 100;
- diff = cycle_freq - est_cycle_freq;
- if (diff < 0)
- diff = -diff;
- if (diff > one_percent) {
- cycle_freq = est_cycle_freq;
- printk("HWRPB cycle frequency bogus. Estimated %lu Hz\n",
- cycle_freq);
- }
- else {
- est_cycle_freq = 0;
+ if (est_cycle_freq) {
+ /* If the given value is within 1% of what we calculated,
+ accept it. Otherwise, use what we found. */
+ one_percent = cycle_freq / 100;
+ diff = cycle_freq - est_cycle_freq;
+ if (diff < 0)
+ diff = -diff;
+ if (diff > one_percent) {
+ cycle_freq = est_cycle_freq;
+ printk("HWRPB cycle frequency bogus. "
+ "Estimated %lu Hz\n", cycle_freq);
+ } else {
+ est_cycle_freq = 0;
+ }
+ } else if (! validate_cc_value (cycle_freq)) {
+ printk("HWRPB cycle frequency bogus, "
+ "and unable to estimate a proper value!\n");
}
/* From John Bowman <bowman@math.ualberta.ca>: allow the values
next reply other threads:[~2001-10-26 8:41 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-10-26 8:41 Richard Henderson [this message]
2001-10-26 10:14 ` alpha 2.4.13: cycle detection sanity checks Ivan Kokshaysky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20011026014133.A1422@redhat.com \
--to=rth@redhat.com \
--cc=alan@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@transmeta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.