Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 8 Aug 2006 16:21:13 GMT
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 103453 for review
Message-ID:  <200608081621.k78GLDgY011123@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=103453

Change 103453 by gonzo@gonzo_hq on 2006/08/08 16:21:08

	o Set bootverbose for more detailed boot log.
	o Split tick_init into two routines:
	    - tick_init_params detects frequency and set
	      para,eters required for DELAY.
	    - tick_init is called in cpu_initclocks as it should be.
	o Add generic MIPS32 clock device code. 
	o Add DELAY implementation for introduced clock device.

Affected files ...

.. //depot/projects/mips2/src/sys/mips/include/clock.h#3 edit
.. //depot/projects/mips2/src/sys/mips/mips/machdep.c#19 edit
.. //depot/projects/mips2/src/sys/mips/mips/tick.c#3 edit

Differences ...

==== //depot/projects/mips2/src/sys/mips/include/clock.h#3 (text+ko) ====

@@ -32,7 +32,11 @@
 #define wall_cmos_clock 0
 #define adjkerntz 0
 
+void	tick_init_params(void);
 void	tick_init(void);
 int	sysbeep(int pitch, int period);
 
+extern uint64_t	counter_freq;
+extern int	clocks_running;
+
 #endif /* !_MACHINE_CLOCK_H_ */

==== //depot/projects/mips2/src/sys/mips/mips/machdep.c#19 (text+ko) ====

@@ -53,23 +53,24 @@
 #include <vm/vm_pager.h>
 
 #include <machine/cache.h>
+#include <machine/clock.h>
 #include <machine/cpu.h>
+#include <machine/cpuinfo.h>
 #include <machine/cpufunc.h>
-#include <machine/cpuinfo.h>
 #include <machine/cpuregs.h>
 #include <machine/hwfunc.h>
+#include <machine/intr_machdep.h>
 #include <machine/locore.h>
 #include <machine/md_var.h>
 #include <machine/pte.h>
 #include <machine/tlb.h>
-#include <machine/clock.h>
 
 #ifdef DDB
 #include <ddb/ddb.h>
 #endif
 
 int cold = 1;
-int clocks_running;
+int clocks_running = 0;
 
 long realmem = 0;
 extern int *end;
@@ -91,6 +92,7 @@
 	int i;
 
 	printf("entry: mips_init()\n");
+	bootverbose = 1;
 
 	realmem = btoc(64 << 20);
 
@@ -339,10 +341,9 @@
 void
 platform_start(int argc, char **argv)
 {
-
 	cninit();
 	mips_init();
-	tick_init();
+	tick_init_params();
 }
 
 void setPQL2(int *const size, int *const ways);
@@ -367,7 +368,8 @@
 void
 cpu_initclocks()
 {
-
+	tick_init();
+	clocks_running = 1;
 }
 
 void
@@ -383,15 +385,6 @@
 }
 
 /*
- * Wait for about n microseconds (at least!).
- */
-void
-DELAY(int n)
-{
-
-}
-
-/*
  * XXX Needed by syscons
  */
 int

==== //depot/projects/mips2/src/sys/mips/mips/tick.c#3 (text+ko) ====

@@ -1,15 +1,16 @@
 /*-
  * Copyright (c) 2006 Bruce M. Simpson
+ * Copyright (c) 2003-2004 Juli Mallett. 
  * 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.
+ *	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.
+ *	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 AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -37,19 +38,34 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/sysctl.h>
-#include <sys/time.h>
-#include <sys/timetc.h>
+#include <sys/bus.h>
 #include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
 #include <sys/power.h>
 #include <sys/smp.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+
 #include <machine/clock.h>
 #include <machine/locore.h>
 #include <machine/md_var.h>
 
 uint64_t	counter_freq;
+uint64_t	counts_per_hz;
+uint32_t	counts_per_usec;
 int		counter_is_broken;
 u_int		counter_present;
 
+/*
+ * Device methods
+ */
+static int clock_probe(device_t);
+static void clock_identify(driver_t *, device_t);
+static int clock_attach(device_t);
+
+
+
 static	unsigned counter_get_timecount(struct timecounter *tc);
 
 static struct timecounter counter_timecounter = {
@@ -64,7 +80,6 @@
 static uint64_t
 tick_ticker(void)
 {
-
 	return ((uint64_t)mips_rd_count());
 }
 
@@ -73,14 +88,14 @@
 #endif
 
 void
-tick_init(void)
+tick_init_params(void)
 {
 #ifdef notyet
 	u_int64_t counterval[2];
 #endif
 
 	if (bootverbose)
-	        printf("Calibrating MIPS32 clock ... ");
+		printf("Calibrating MIPS32 clock ... ");
 #ifdef notyet
 	counterval[0] = mips_rd_count();
 	DELAY(1000000);
@@ -90,19 +105,27 @@
 #else
 	/* XXX: The boot monitor told us the CPU frequency. */
 	{
-	    char *cp = yamon_getenv("khz");
-	    printf("cp: %s", cp);
-	    if (cp == NULL) {
-		printf("cannot determine clock frequency\n");
-		return;
-	    }
-	    counter_freq = strtol(cp, (char **)NULL, 10) * 1000 ;
+		char *cp = yamon_getenv("khz");
+		printf("cp: %s\n", cp);
+		if (cp == NULL) {
+			printf("cannot determine clock frequency, defaulting to 10MHz\n");
+			counter_freq = 10000000;
+		} else
+			counter_freq = strtol(cp, (char **)NULL, 10) * 1000 ;
 	}
 #endif
+
+	counts_per_hz = counter_freq / hz;
+	counts_per_usec = counter_freq / 1000000;
+
 	if (bootverbose)
 		printf("MIPS32 clock: %ju Hz\n", (intmax_t)counter_freq);
+
 	set_cputicker(tick_ticker, counter_freq, 1);
+}
 
+void tick_init(void)
+{
 	if (counter_freq != 0 && !counter_is_broken) {
 		counter_timecounter.tc_frequency = counter_freq;
 		tc_init(&counter_timecounter);
@@ -127,7 +150,7 @@
 }
 
 SYSCTL_PROC(_machdep, OID_AUTO, counter_freq, CTLTYPE_QUAD | CTLFLAG_RW,
-    0, sizeof(u_int), sysctl_machdep_counter_freq, "IU", "");
+	0, sizeof(u_int), sysctl_machdep_counter_freq, "IU", "");
 
 static unsigned
 counter_get_timecount(struct timecounter *tc)
@@ -135,3 +158,125 @@
 
 	return (mips_rd_count());
 }
+
+/*
+ * Wait for about n microseconds (at least!).
+ */
+void
+DELAY(int n)
+{
+	uint32_t cur, last, delta, usecs;
+	/*
+	 * This works by polling the timer and counting the
+	 * number of microseconds that go by.
+	 */
+	last = mips_rd_count();
+	delta = usecs = 0;
+
+	while (n > usecs) {
+		cur = mips_rd_count();
+
+		/* Check to see if the timer has wrapped around. */
+		if (last < cur)
+			delta += (last + (counts_per_hz - cur));
+		else
+			delta += (last - cur);
+
+		last = cur;
+
+		if (delta >= counts_per_usec) {
+			usecs += delta / counts_per_usec;
+			delta %= counts_per_usec;
+		}
+	}
+}
+
+/*
+ * Device section of file below
+ */  
+static void
+clock_intr(void *arg)
+{
+	struct trapframe	*tf;
+	register_t		usermode, pc;
+
+	/*
+	 * Set next clock edge.
+	 */
+
+	mips_wr_compare(mips_rd_count() + counter_freq / hz);
+
+
+	/*
+	 * Magic.  Setting up with an arg of NULL means we get passed tf.
+	 */
+	tf = arg;
+	usermode = tf->tf_regs[TF_SR] & MIPS_SR_KSU_USER;
+	pc = tf->tf_regs[TF_EPC];
+
+	if (clocks_running)
+	{
+		hardclock(usermode, pc);
+	}
+
+}
+
+static int
+clock_probe(device_t dev)
+{
+	if (device_get_unit(dev) != 0)
+		panic("can't attach more clocks");
+
+	device_set_desc(dev, "Generic MIPS32 ticker");
+	return (0);
+}
+
+static void
+clock_identify(driver_t *drv, device_t parent)
+{
+	BUS_ADD_CHILD(parent, 0, "clock", 0);
+}
+
+static int
+clock_attach(device_t dev)
+{
+	struct resource *irq;
+	int error;
+	int rid;
+
+	rid = 0;
+	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 5, 5, 1, RF_ACTIVE);
+	if (irq == NULL) {
+		device_printf(dev, "failed to allocate irq\n");
+		return (ENXIO);
+	}
+	error = bus_setup_intr(dev, irq,
+				   INTR_TYPE_CLK | INTR_MPSAFE | INTR_FAST,
+				   clock_intr, NULL, NULL);
+	if (error != 0) {
+		device_printf(dev, "bus_setup_intr returned %d\n", error);
+		return (error);
+	}
+
+	mips_wr_compare(mips_rd_count() + counter_freq/hz);
+	return (0);
+}
+
+static device_method_t clock_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		clock_probe),
+	DEVMETHOD(device_identify,	clock_identify),
+	DEVMETHOD(device_attach,	clock_attach),
+	DEVMETHOD(device_detach,	bus_generic_detach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+
+	{ 0, 0 }
+};
+
+static driver_t clock_driver = {
+	"clock", clock_methods, 32
+};
+
+static devclass_t clock_devclass;
+
+DRIVER_MODULE(clock, nexus, clock_driver, clock_devclass, 0, 0);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608081621.k78GLDgY011123>