[coreboot-gerrit] Patch set updated for coreboot: 5f0b194 Intel 5000: udelay.c: Work around 32-bit overflow
Paul Menzel (paulepanter@users.sourceforge.net)
gerrit at coreboot.org
Sun May 12 00:32:28 CEST 2013
Paul Menzel (paulepanter at users.sourceforge.net) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3219
-gerrit
commit 5f0b1948a506bd569fc16668670e9811acb87792
Author: Paul Menzel <paulepanter at users.sourceforge.net>
Date: Wed May 8 16:24:38 2013 +0200
Intel 5000: udelay.c: Work around 32-bit overflow
Port the following commit over to the Intel 5000 northbridge.
commit 8bacc40fc7bd07365c2992b260ddbd45cd6e4518
Author: Nico Huber <nico.huber at secunet.com>
Date: Thu Jul 19 16:16:59 2012 +0200
Fix udelay() implementation for i945 romstage
Reviewed-on: http://review.coreboot.org/1254
Change-Id: I5c113bb0b2fed7b93feb3dcb1b5d962e1442963a
Signed-off-by: Paul Menzel <paulepanter at users.sourceforge.net>
---
src/northbridge/intel/i5000/udelay.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/src/northbridge/intel/i5000/udelay.c b/src/northbridge/intel/i5000/udelay.c
index ce4c7b3..caee73f 100644
--- a/src/northbridge/intel/i5000/udelay.c
+++ b/src/northbridge/intel/i5000/udelay.c
@@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2008 coresystems GmbH
+ * 2012 secunet Security Networks AG
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,6 +24,17 @@
#include <cpu/x86/msr.h>
#include <cpu/intel/speedstep.h>
+/* Simple 32- to 64-bit multiplication. Uses 16-bit words to avoid overflow. */
+static inline void multiply_to_tsc(tsc_t *const tsc, const u32 a, const u32 b)
+{
+ tsc->lo = (a & 0xffff) * (b & 0xffff);
+ tsc->hi = ((tsc->lo >> 16)
+ + ((a & 0xffff) * (b >> 16))
+ + ((b & 0xffff) * (a >> 16)));
+ tsc->lo = ((tsc->hi & 0xffff) << 16) | (tsc->lo & 0xffff);
+ tsc->hi = ((a >> 16) * (b >> 16)) + (tsc->hi >> 16);
+}
+
/**
* Intel Core(tm) cpus always run the TSC at the maximum possible CPU clock
*/
@@ -34,7 +46,6 @@ void udelay(u32 us)
msr_t msr;
u32 fsb = 0, divisor;
u32 d; /* ticks per us */
- u32 dn = 0x1000000 / 2; /* how many us before we need to use hi */
msr = rdmsr(MSR_FSB_FREQ);
switch (msr.lo & 0x07) {
@@ -64,10 +75,9 @@ void udelay(u32 us)
msr = rdmsr(0x198);
divisor = (msr.hi >> 8) & 0x1f;
- d = fsb * divisor;
+ d = (fsb * divisor) / 4; /* CPU clock is always a quarter. */
- tscd.hi = us / dn;
- tscd.lo = (us - tscd.hi * dn) * d;
+ multiply_to_tsc(&tscd, us, d);
tsc1 = rdtsc();
dword = tsc1.lo + tscd.lo;
@@ -81,5 +91,6 @@ void udelay(u32 us)
do {
tsc = rdtsc();
- } while ((tsc.hi < tsc1.hi) || ((tsc.hi == tsc1.hi) && (tsc.lo < tsc1.lo)));
+ } while ((tsc.hi < tsc1.hi)
+ || ((tsc.hi == tsc1.hi) && (tsc.lo < tsc1.lo)));
}
More information about the coreboot-gerrit
mailing list