Port-newsmips archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
timecounter changes for newsmips
I wrote the following patch which converts newsmips to tc.
In this change:
1) only NWS-5000 has a high resolution timer
2) the timer NEWS5000_FREERUN is assumed to tick once per usec. That
seems what the current code.
3) I assume it wraps on a 32-bit boundary (i.e counts 0-ffffffff)
If these assumptions are good, then the code should run. I don't have
news docs, so I'm just interpreting the pre-existing code. I'd
appreciate it if folks can test, and commit as appropriate.
-- Garrett
--
Garrett D'Amore, Principal Software Engineer
Tadpole Computer / Computing Technologies Division,
General Dynamics C4 Systems
http://www.tadpolecomputer.com/
Phone: 951 325-2134 Fax: 951 325-2191
Index: sys/arch/newsmips/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/include/types.h,v
retrieving revision 1.8
diff -d -p -u -r1.8 types.h
--- sys/arch/newsmips/include/types.h 4 Sep 2006 20:33:24 -0000 1.8
+++ sys/arch/newsmips/include/types.h 12 Sep 2006 22:21:11 -0000
@@ -4,6 +4,7 @@
#define __HAVE_GENERIC_SOFT_INTERRUPTS
#define __HAVE_GENERIC_TODR
+#define __HAVE_TIMECOUNTER
/* MIPS specific options */
#define __HAVE_BOOTINFO_H
Index: sys/arch/newsmips/newsmips/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/newsmips/machdep.c,v
retrieving revision 1.83
diff -d -p -u -r1.83 machdep.c
--- sys/arch/newsmips/newsmips/machdep.c 9 Apr 2006 01:18:14 -0000
1.83
+++ sys/arch/newsmips/newsmips/machdep.c 12 Sep 2006 22:21:11 -0000
@@ -159,7 +159,6 @@ phys_ram_seg_t mem_clusters[VM_PHYSSEG_M
int mem_cluster_cnt;
struct idrom idrom;
-void (*readmicrotime)(struct timeval *tvp);
void (*hardware_intr)(uint32_t, uint32_t, uint32_t, uint32_t);
void (*enable_intr)(void);
void (*disable_intr)(void);
@@ -622,33 +621,6 @@ haltsys:
/*NOTREACHED*/
}
-/*
- * Return the best possible estimate of the time in the timeval
- * to which tvp points. Unfortunately, we can't read the hardware registers.
- * We guarantee that the time will be greater than the value obtained by a
- * previous call.
- */
-void
-microtime(struct timeval *tvp)
-{
- int s = splclock();
- static struct timeval lasttime;
-
- if (readmicrotime)
- readmicrotime(tvp);
- else
- *tvp = time;
-
- if (tvp->tv_sec == lasttime.tv_sec &&
- tvp->tv_usec <= lasttime.tv_usec &&
- (tvp->tv_usec = lasttime.tv_usec + 1) >= 1000000) {
- tvp->tv_sec++;
- tvp->tv_usec -= 1000000;
- }
- lasttime = *tvp;
- splx(s);
-}
-
void
delay(int n)
{
Index: sys/arch/newsmips/newsmips/news5000.c
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/newsmips/news5000.c,v
retrieving revision 1.15
diff -d -p -u -r1.15 news5000.c
--- sys/arch/newsmips/newsmips/news5000.c 11 Dec 2005 12:18:25 -0000
1.15
+++ sys/arch/newsmips/newsmips/news5000.c 12 Sep 2006 22:21:11 -0000
@@ -32,6 +32,7 @@ __KERNEL_RCSID(0, "$NetBSD: news5000.c,v
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/timetc.h>
#include <machine/adrsmap.h>
#include <machine/cpu.h>
@@ -40,18 +41,15 @@ __KERNEL_RCSID(0, "$NetBSD: news5000.c,v
#include <newsmips/apbus/apbusvar.h>
#include <newsmips/newsmips/machid.h>
-extern void (*readmicrotime)(struct timeval *tvp);
-
static void news5000_level1_intr(void);
static void news5000_level0_intr(void);
static void news5000_enable_intr(void);
static void news5000_disable_intr(void);
static void news5000_enable_timer(void);
-static void news5000_readmicrotime(struct timeval *);
static void news5000_readidrom(uint8_t *);
-
-static u_int freerun_off;
+static void news5000_tc_init(void);
+static uint32_t news5000_getfreerun(struct timecounter *);
/*
* Handle news5000 interrupts.
@@ -81,7 +79,6 @@ news5000_intr(uint32_t status, uint32_t
if (int2stat & NEWS5000_INT2_TIMER0) {
*(volatile uint32_t *)NEWS5000_TIMER0 = 1;
- freerun_off = *(volatile uint32_t *)NEWS5000_FREERUN;
cf.pc = pc;
cf.sr = status;
@@ -226,22 +223,26 @@ news5000_enable_timer(void)
*(volatile uint32_t *)NEWS5000_INTEN2 = NEWS5000_INT2_TIMER0;
}
+static uint32_t
+news5000_getfreerun(struct timecounter *tc)
+{
+ return *(volatile uint32_t *)NEWS5000_FREERUN;
+}
+
static void
-news5000_readmicrotime(struct timeval *tvp)
+news5000_tc_init(void)
{
- uint32_t freerun;
+ static struct timecounter tc = {
+ .tc_get_timecount = news5000_getfreerun,
+ .tc_frequency = 1000000,
+ .tc_counter_mask = ~0,
+ .tc_name = "news5000_freerun",
+ .tc_quality = 100,
+ };
- *tvp = time;
- freerun = *(volatile uint32_t *)NEWS5000_FREERUN;
- freerun -= freerun_off;
- if (freerun > 1000000)
- freerun = 1000000;
- tvp->tv_usec += freerun;
- if (tvp->tv_usec >= 1000000) {
- tvp->tv_usec -= 1000000;
- tvp->tv_sec++;
- }
+ tc_init(&tc);
}
+
static void
news5000_readidrom(uint8_t *rom)
@@ -264,11 +265,12 @@ news5000_init(void)
enable_timer = news5000_enable_timer;
news5000_readidrom((uint8_t *)&idrom);
- readmicrotime = news5000_readmicrotime;
hostid = idrom.id_serial;
/* XXX reset uPD72067 FDC to avoid spurious interrupts */
#define NEWS5000_FDC_FDOUT 0xbed20000
#define FDO_FRST 0x04
*(volatile uint8_t *)NEWS5000_FDC_FDOUT = FDO_FRST;
+
+ news5000_tc_init();
}
Home |
Main Index |
Thread Index |
Old Index