summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2005-06-04 21:55:51 +0000
committermarcel <marcel@FreeBSD.org>2005-06-04 21:55:51 +0000
commitbbde8d81978bf136ee11066b3a217c2237566ce6 (patch)
tree40c57547d9f92cfb030edcf4d943b96638c11972 /sys/boot
parentf1c26a9917b41db8f8f147a22576945ea521bb0b (diff)
downloadFreeBSD-src-bbde8d81978bf136ee11066b3a217c2237566ce6.zip
FreeBSD-src-bbde8d81978bf136ee11066b3a217c2237566ce6.tar.gz
Fix getsecs(). It was not counting the seconds right. The immediate
and visible effect of the bug what that autoboot would boot a kernel after only a couple of seconds had passed instead of waiting the full 10 seconds it's supposed to wait by default. Add my copyright notice, since one was missing and I reimplemented the one and only function in this file. MFC after: 1 week
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/alpha/libalpha/getsecs.c65
1 files changed, 46 insertions, 19 deletions
diff --git a/sys/boot/alpha/libalpha/getsecs.c b/sys/boot/alpha/libalpha/getsecs.c
index 18c8770..e4e175c 100644
--- a/sys/boot/alpha/libalpha/getsecs.c
+++ b/sys/boot/alpha/libalpha/getsecs.c
@@ -1,5 +1,27 @@
-/*
- * $NetBSD: getsecs.c,v 1.5 1998/01/05 07:02:49 perry Exp $
+/*-
+ * Copyright (c) 2005 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
@@ -9,31 +31,36 @@ __FBSDID("$FreeBSD$");
#include <machine/prom.h>
#include <machine/rpb.h>
+static unsigned long lastpcc;
+static int tnsec;
+
+/*
+ * Count the number of elapsed seconds since this function was called first.
+ * The algorithm uses the processor's cycle counter, which means that it'd
+ * better be called frequently (on a 433Mhz machine this means at least once
+ * every 9 seconds or so).
+ */
int
getsecs()
{
- static long tnsec;
- static long lastpcc, wrapsecs;
- long curpcc;
+ struct rpb *hwrpb = (struct rpb *)HWRPB_ADDR;
+ unsigned long curpcc;
+ int delta;
if (tnsec == 0) {
tnsec = 1;
- lastpcc = alpha_rpcc() & 0xffffffff;
- wrapsecs = (0xffffffff /
- ((struct rpb *)HWRPB_ADDR)->rpb_cc_freq) + 1;
-
-#if 0
- printf("getsecs: cc freq = %d, time to wrap = %d\n",
- ((struct rpb *)HWRPB_ADDR)->rpb_cc_freq, wrapsecs);
-#endif
+ lastpcc = alpha_rpcc() & 0xfffffffful;
+ return (tnsec);
}
- curpcc = alpha_rpcc() & 0xffffffff;
+ curpcc = alpha_rpcc() & 0xfffffffful;
if (curpcc < lastpcc)
- curpcc += 0x100000000;
-
- tnsec += ((curpcc - lastpcc) * 1000000000) / ((struct rpb *)HWRPB_ADDR)->rpb_cc_freq;
- lastpcc = curpcc;
+ curpcc += 0x100000000ul;
- return (tnsec / 1000000000);
+ delta = (curpcc - lastpcc) / hwrpb->rpb_cc_freq;
+ if (delta) {
+ tnsec += delta;
+ lastpcc = curpcc & 0xfffffffful;
+ }
+ return (tnsec);
}
OpenPOWER on IntegriCloud