PERFORCE change 103453 for review
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Tue Aug 8 16:21:20 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=103453
Change 103453 by gonzo at 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);
More information about the p4-projects
mailing list