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>