aboutsummaryrefslogtreecommitdiff
path: root/src/cpu/x86
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2019-10-31 13:25:23 +0200
committerKyösti Mälkki <kyosti.malkki@gmail.com>2019-11-02 06:28:28 +0000
commit432516586e7f646aa2a8ac0cbdf8e80ac44f97d0 (patch)
treea411145396973618996752e9ae24401b1ee8a240 /src/cpu/x86
parente1c0cb737c201b736b15e098d50f196e88a57ff8 (diff)
cpu/x86: Move calibrate_tsc_with_pit() to drivers/pc80
Change-Id: Ia8d8dc23ee0b51d62c83f5ba640b3a9aea4e744b Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/36507 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Diffstat (limited to 'src/cpu/x86')
-rw-r--r--src/cpu/x86/tsc/delay_tsc.c78
1 files changed, 1 insertions, 77 deletions
diff --git a/src/cpu/x86/tsc/delay_tsc.c b/src/cpu/x86/tsc/delay_tsc.c
index 0784822b30..afcd1d1f7d 100644
--- a/src/cpu/x86/tsc/delay_tsc.c
+++ b/src/cpu/x86/tsc/delay_tsc.c
@@ -12,90 +12,14 @@
*/
#include <arch/early_variables.h>
-#include <console/console.h>
-#include <arch/io.h>
#include <cpu/x86/tsc.h>
+#include <pc80/i8254.h>
#include <smp/spinlock.h>
#include <delay.h>
#include <thread.h>
static unsigned long clocks_per_usec CAR_GLOBAL;
-#define CLOCK_TICK_RATE 1193180U /* Underlying HZ */
-
-/* ------ Calibrate the TSC -------
- * Too much 64-bit arithmetic here to do this cleanly in C, and for
- * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
- * output busy loop as low as possible. We avoid reading the CTC registers
- * directly because of the awkward 8-bit access mechanism of the 82C54
- * device.
- */
-
-#define CALIBRATE_INTERVAL ((2*CLOCK_TICK_RATE)/1000) /* 2ms */
-#define CALIBRATE_DIVISOR (2*1000) /* 2ms / 2000 == 1usec */
-
-static unsigned long calibrate_tsc_with_pit(void)
-{
- /* Set the Gate high, disable speaker */
- outb((inb(0x61) & ~0x02) | 0x01, 0x61);
-
- /*
- * Now let's take care of CTC channel 2
- *
- * Set the Gate high, program CTC channel 2 for mode 0,
- * (interrupt on terminal count mode), binary count,
- * load 5 * LATCH count, (LSB and MSB) to begin countdown.
- */
- outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */
-
- outb(CALIBRATE_INTERVAL & 0xff, 0x42); /* LSB of count */
- outb(CALIBRATE_INTERVAL >> 8, 0x42); /* MSB of count */
-
- {
- tsc_t start;
- tsc_t end;
- unsigned long count;
-
- start = rdtsc();
- count = 0;
- do {
- count++;
- } while ((inb(0x61) & 0x20) == 0);
- end = rdtsc();
-
- /* Error: ECTCNEVERSET */
- if (count <= 1)
- goto bad_ctc;
-
- /* 64-bit subtract - gcc just messes up with long longs */
- __asm__("subl %2,%0\n\t"
- "sbbl %3,%1"
- : "=a" (end.lo), "=d" (end.hi)
- : "g" (start.lo), "g" (start.hi),
- "0" (end.lo), "1" (end.hi));
-
- /* Error: ECPUTOOFAST */
- if (end.hi)
- goto bad_ctc;
-
-
- /* Error: ECPUTOOSLOW */
- if (end.lo <= CALIBRATE_DIVISOR)
- goto bad_ctc;
-
- return DIV_ROUND_UP(end.lo, CALIBRATE_DIVISOR);
- }
-
- /*
- * 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:
- printk(BIOS_ERR, "bad_ctc\n");
- return 0;
-}
-
static unsigned long calibrate_tsc(void)
{
if (CONFIG(TSC_CONSTANT_RATE))