The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/powerpc/powerpc/clock.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
    3  * Copyright (C) 1995, 1996 TooLs GmbH.
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. All advertising materials mentioning features or use of this software
   15  *    must display the following acknowledgement:
   16  *      This product includes software developed by TooLs GmbH.
   17  * 4. The name of TooLs GmbH may not be used to endorse or promote products
   18  *    derived from this software without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
   21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   23  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   30  *
   31  *      $NetBSD: clock.c,v 1.9 2000/01/19 02:52:19 msaitoh Exp $
   32  */
   33 /*
   34  * Copyright (C) 2001 Benno Rice.
   35  * All rights reserved.
   36  *
   37  * Redistribution and use in source and binary forms, with or without
   38  * modification, are permitted provided that the following conditions
   39  * are met:
   40  * 1. Redistributions of source code must retain the above copyright
   41  *    notice, this list of conditions and the following disclaimer.
   42  * 2. Redistributions in binary form must reproduce the above copyright
   43  *    notice, this list of conditions and the following disclaimer in the
   44  *    documentation and/or other materials provided with the distribution.
   45  *
   46  * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
   47  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   48  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   49  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   50  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   51  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   52  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   53  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   54  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   55  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   56  */
   57 
   58 #include <sys/cdefs.h>
   59 __FBSDID("$FreeBSD: releng/7.4/sys/powerpc/powerpc/clock.c 173609 2007-11-14 16:41:31Z grehan $");
   60 
   61 #include <sys/param.h>
   62 #include <sys/systm.h>
   63 #include <sys/kernel.h>
   64 #include <sys/sysctl.h>
   65 #include <sys/bus.h>
   66 #include <sys/clock.h>
   67 #include <sys/timetc.h>
   68 #include <sys/interrupt.h>
   69 
   70 #include <dev/ofw/openfirm.h>
   71 
   72 #include <machine/clock.h>
   73 #include <machine/cpu.h>
   74 #include <machine/intr.h>
   75 #include <machine/md_var.h>
   76 
   77 /*
   78  * Initially we assume a processor with a bus frequency of 12.5 MHz.
   79  */
   80 u_int                   tickspending;
   81 u_long                  ns_per_tick = 80;
   82 static u_long           ticks_per_sec = 12500000;
   83 static long             ticks_per_intr;
   84 static volatile u_long  lasttb;
   85 
   86 #define DIFF19041970    2082844800
   87 
   88 static int              clockinitted = 0;
   89 
   90 static timecounter_get_t        decr_get_timecount;
   91 
   92 static struct timecounter       decr_timecounter = {
   93         decr_get_timecount,     /* get_timecount */
   94         0,                      /* no poll_pps */
   95         ~0u,                    /* counter_mask */
   96         0,                      /* frequency */
   97         "decrementer"           /* name */
   98 };
   99 
  100 void
  101 inittodr(time_t base)
  102 {
  103         time_t          deltat;
  104         u_int           rtc_time;
  105         struct timespec ts;
  106         phandle_t       phandle;
  107         ihandle_t       ihandle;
  108         char            rtcpath[128];
  109         u_int           rtcsecs;
  110 
  111         /*
  112          * If we can't read from RTC, use the fs time.
  113          */
  114         phandle = OF_finddevice("rtc");
  115         if (phandle != -1) {
  116                 OF_package_to_path(phandle, rtcpath, sizeof(rtcpath));
  117                 ihandle = OF_open(rtcpath);
  118                 if (ihandle != -1) {
  119                         if (OF_call_method("read-rtc", ihandle,
  120                             0, 1, &rtcsecs))
  121                                 printf("RTC call method error\n");
  122                         else {
  123                                 ts.tv_sec = rtcsecs - DIFF19041970;
  124                                 ts.tv_nsec = 0;
  125                                 tc_setclock(&ts);
  126                                 return;
  127                         }
  128                 }
  129         }
  130 
  131         {
  132                 ts.tv_sec = base;
  133                 ts.tv_nsec = 0;
  134                 tc_setclock(&ts);
  135                 return;
  136         }
  137         clockinitted = 1;
  138         ts.tv_sec = rtc_time - DIFF19041970;
  139 
  140         deltat = ts.tv_sec - base;
  141         if (deltat < 0) {
  142                 deltat = -deltat;
  143         }
  144         if (deltat < 2 * SECDAY) {
  145                 tc_setclock(&ts);
  146                 return;
  147         }
  148 
  149         printf("WARNING: clock %s %d days",
  150             ts.tv_sec < base ? "lost" : "gained", (int)(deltat / SECDAY));
  151 
  152         printf(" -- CHECK AND RESET THE DATE!\n");
  153 }
  154 
  155 /*
  156  * Similar to the above
  157  */
  158 void
  159 resettodr()
  160 {
  161 
  162 }
  163 
  164 void
  165 decr_intr(struct trapframe *frame)
  166 {
  167         u_long          tb;
  168         long            tick;
  169         int             nticks;
  170 
  171         /*
  172          * Check whether we are initialized.
  173          */
  174         if (!ticks_per_intr)
  175                 return;
  176 
  177         /*
  178          * Based on the actual time delay since the last decrementer reload,
  179          * we arrange for earlier interrupt next time.
  180          */
  181         __asm ("mftb %0; mfdec %1" : "=r"(tb), "=r"(tick));
  182         for (nticks = 0; tick < 0; nticks++)
  183                 tick += ticks_per_intr;
  184         mtdec(tick);
  185         /*
  186          * lasttb is used during microtime. Set it to the virtual
  187          * start of this tick interval.
  188          */
  189         lasttb = tb + tick - ticks_per_intr;
  190 
  191         nticks += tickspending;
  192         tickspending = 0;
  193 
  194         /*
  195          * Reenable interrupts
  196          */
  197 #if 0
  198         msr = mfmsr();
  199         mtmsr(msr | PSL_EE | PSL_RI);
  200 #endif
  201         /*
  202          * Do standard timer interrupt stuff.
  203          * Do softclock stuff only on the last iteration.
  204          */
  205 #if 0
  206         while (--nticks > 0) {
  207                 hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
  208         }
  209 #endif
  210         hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
  211 }
  212 
  213 void
  214 decr_init(void)
  215 {
  216         int qhandle, phandle;
  217         char name[32];
  218         unsigned int msr;
  219 
  220         phandle = 0;
  221 
  222         /*
  223          * Get this info during autoconf?                               XXX
  224          */
  225         for (qhandle = OF_peer(0); qhandle; qhandle = phandle) {
  226                 if (OF_getprop(qhandle, "device_type", name, sizeof name) >= 0
  227                     && !strcmp(name, "cpu")
  228                     && OF_getprop(qhandle, "timebase-frequency",
  229                                   &ticks_per_sec, sizeof ticks_per_sec) >= 0) {
  230                         /*
  231                          * Should check for correct CPU here?           XXX
  232                          */
  233                         msr = mfmsr();
  234                         mtmsr(msr & ~(PSL_EE|PSL_RI));
  235 
  236                         ns_per_tick = 1000000000 / ticks_per_sec;
  237                         ticks_per_intr = ticks_per_sec / hz;
  238                         __asm __volatile ("mftb %0" : "=r"(lasttb));
  239                         mtdec(ticks_per_intr);
  240 
  241                         mtmsr(msr);
  242 
  243                         break;
  244                 }
  245                 if ((phandle = OF_child(qhandle)))
  246                         continue;
  247                 while (qhandle) {
  248                         if ((phandle = OF_peer(qhandle)))
  249                                 break;
  250                         qhandle = OF_parent(qhandle);
  251                 }
  252         }
  253         if (!phandle)
  254                 panic("no cpu node");
  255 }
  256 
  257 void
  258 decr_tc_init(void)
  259 {
  260         decr_timecounter.tc_frequency = ticks_per_sec;
  261         tc_init(&decr_timecounter);
  262 }
  263 
  264 static __inline u_quad_t
  265 mftb(void)
  266 {
  267         u_long          scratch;
  268         u_quad_t        tb;
  269 
  270         __asm ("1: mftbu %0; mftb %0+1; mftbu %1; cmpw 0,%0,%1; bne 1b"
  271               : "=r"(tb), "=r"(scratch));
  272         return tb;
  273 }
  274 
  275 static unsigned
  276 decr_get_timecount(struct timecounter *tc)
  277 {
  278         return mftb();
  279 }
  280 
  281 /*
  282  * Wait for about n microseconds (at least!).
  283  */
  284 void
  285 DELAY(int n)
  286 {
  287         u_quad_t        tb, ttb;
  288 
  289         tb = mftb();
  290         ttb = tb + (n * 1000 + ns_per_tick - 1) / ns_per_tick;
  291         while (tb < ttb)
  292                 tb = mftb();
  293 }
  294 
  295 /*
  296  * Nothing to do.
  297  */
  298 void
  299 cpu_startprofclock(void)
  300 {
  301 
  302         /* Do nothing */
  303 }
  304 
  305 void
  306 cpu_stopprofclock(void)
  307 {
  308 }
  309 
  310 /*
  311  * XXX Needed by syscons
  312  */
  313 int
  314 sysbeep(int pitch, int period)
  315 {
  316 
  317         return (0);
  318 }

Cache object: 4ef84c00eada6edefd8cfd06c2e5f02a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.