From owner-p4-projects@FreeBSD.ORG Tue Aug 8 16:21:20 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 73BAB16A4E5; Tue, 8 Aug 2006 16:21:20 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3322716A4E0 for ; Tue, 8 Aug 2006 16:21:20 +0000 (UTC) (envelope-from gonzo@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id BBF6D43D5F for ; Tue, 8 Aug 2006 16:21:13 +0000 (GMT) (envelope-from gonzo@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k78GLDom011126 for ; Tue, 8 Aug 2006 16:21:13 GMT (envelope-from gonzo@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k78GLDgY011123 for perforce@freebsd.org; Tue, 8 Aug 2006 16:21:13 GMT (envelope-from gonzo@FreeBSD.org) Date: Tue, 8 Aug 2006 16:21:13 GMT Message-Id: <200608081621.k78GLDgY011123@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to gonzo@FreeBSD.org using -f From: Oleksandr Tymoshenko To: Perforce Change Reviews Cc: Subject: PERFORCE change 103453 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Aug 2006 16:21:20 -0000 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 #include +#include #include +#include #include -#include #include #include +#include #include #include #include #include -#include #ifdef DDB #include #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 #include #include -#include -#include +#include #include +#include +#include #include #include +#include +#include + #include #include #include 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);