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/sqt/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  * Mach Operating System
    3  * Copyright (c) 1993,1992,1991 Carnegie Mellon University
    4  * Copyright (c) 1991 Sequent Computer Systems
    5  * All Rights Reserved.
    6  * 
    7  * Permission to use, copy, modify and distribute this software and its
    8  * documentation is hereby granted, provided that both the copyright
    9  * notice and this permission notice appear in all copies of the
   10  * software, derivative works or modified versions, and any portions
   11  * thereof, and that both notices appear in supporting documentation.
   12  * 
   13  * CARNEGIE MELLON AND SEQUENT COMPUTER SYSTEMS ALLOW FREE USE OF
   14  * THIS SOFTWARE IN ITS "AS IS" CONDITION.  CARNEGIE MELLON AND
   15  * SEQUENT COMPUTER SYSTEMS DISCLAIM ANY LIABILITY OF ANY KIND FOR
   16  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   17  * 
   18  * Carnegie Mellon requests users of this software to return to
   19  * 
   20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   21  *  School of Computer Science
   22  *  Carnegie Mellon University
   23  *  Pittsburgh PA 15213-3890
   24  * 
   25  * any improvements or extensions that they make and grant Carnegie Mellon
   26  * the rights to redistribute these changes.
   27  */
   28 
   29 /*
   30  * HISTORY
   31  * $Log:        clock.c,v $
   32  * Revision 2.4  93/11/17  18:45:58  dbg
   33  *      Added clock device code for new real-time clocks.  Clock rate is
   34  *      (currently) fixed.
   35  *      [93/04/16            dbg]
   36  * 
   37  * Revision 2.3  91/07/31  18:00:21  dbg
   38  *      Changed copyright.
   39  *      [91/07/31            dbg]
   40  * 
   41  * Revision 2.2  91/05/08  12:55:04  dbg
   42  *      Adapted from Sequent Symmetry sources.
   43  *      [91/04/26  14:50:24  dbg]
   44  * 
   45  */
   46 
   47 #ifndef lint
   48 static  char    rcsid[] = "$Header: clock.c,v 2.4 93/11/17 18:45:58 dbg Exp $";
   49 #endif
   50 
   51 /*
   52  * Machine-dependent clock routines.
   53  *
   54  * Included are the time-of-day clock initialization and
   55  * the per processor real-time clock initialization.
   56  */
   57 
   58 /*
   59  * Revision 1.2  89/07/20  18:05:38  kak
   60  * moved balance includes
   61  * 
   62  * Revision 1.1  89/07/05  13:15:27  kak
   63  * Initial revision
   64  * 
   65  */
   66 
   67 #include <mach/boolean.h>
   68 #include <mach/time_spec.h>
   69 
   70 #include <kern/clock.h>
   71 #include <kern/kern_io.h>
   72 #include <device/device_types.h>
   73 #include <device/clock_dev.h>
   74 #include <device/clock_status.h>
   75 #include <machine/machspl.h>
   76 
   77 #include <sqt/cfg.h>
   78 #include <sqt/clock.h>
   79 #include <sqt/slic.h>
   80 
   81 #include <sqt/ioconf.h>
   82 #include <sqt/vm_defs.h>
   83 #include <sqt/hwparam.h>
   84 #include <sqt/intctl.h>
   85 
   86 #include <sqtsec/sec.h>
   87 
   88 extern u_char   cons_scsi;              /* console scsi slic address */
   89 
   90 /* For time-of-day handling */
   91 struct  sec_cib *todcib;
   92 struct  sec_gmode todgm;        /* getmodes command */
   93 struct  sec_smode todsm;        /* setmodes command */
   94 
   95 #define CLOCKSQT_DEFAULT_RESOLUTION     (NANOSEC_PER_SEC/HZ)    /* 100 hz */
   96 
   97 mach_clock_data_t               clocksqt0;
   98 
   99 void    clocksqt_setresolution(mach_clock_t);           /* forward */
  100 void    clocksqt_enable_interrupts(mach_clock_t);
  101 void    clocksqt_write(mach_clock_t, time_spec_t);
  102 time_spec_t clocksqt_read(void);
  103 
  104 struct clock_ops clocksqt_ops = {
  105         clocksqt_setresolution,
  106         clocksqt_write,
  107         clocksqt_enable_interrupts
  108 };
  109 
  110 void clocksqt_init(void)
  111 {
  112         mach_clock_t    clock = &clocksqt0;
  113         time_spec_t     cur_time;
  114 
  115         clock_init(clock, &clocksqt_ops);
  116 
  117         clock->resolution = CLOCKSQT_DEFAULT_RESOLUTION;        /* @100 hz */
  118         clocksqt_setresolution(clock);
  119 
  120         sys_clock = &clocksqt0;
  121 
  122         /*
  123          *      Read the current time from the TOD clock
  124          */
  125         cur_time = clocksqt_read();
  126 
  127         clocksqt0.check_seconds    = cur_time.seconds;
  128         clocksqt0.time.nanoseconds = cur_time.nanoseconds;
  129         clocksqt0.time.seconds     = cur_time.seconds;
  130 }
  131 
  132 /*
  133  * startrtclock()
  134  *      Start the real-time clock.
  135  *
  136  * Startrtclock restarts the real-time clock, which provides
  137  * hardclock interrupts to kern_clock.c.  On Sequent HW, this
  138  * is one-time only per processor (eg, no restart, clock reprimes
  139  * itself).
  140  *
  141  * Called by localinit() during selfinit().
  142  * This turns on the processor-local SLIC timer.
  143  *
  144  * For testing/performance measurement convenience, enable_local_clock
  145  * allows the per-processor clock to be left OFF.  Need to patch the
  146  * kernel binary or system memory to effect this.
  147  */
  148 static  boolean_t       enable_local_clock = TRUE;      /* default ON */
  149 
  150 void clocksqt_setresolution(
  151         mach_clock_t    clock)
  152 {
  153         register struct cpuslic *sl = va_slic;
  154         spl_t   s;
  155 
  156         if (!enable_local_clock)
  157                 return;
  158 
  159         /*
  160          * Stop updates while we fix it 
  161          */
  162         s = splhi();
  163 
  164         sl->sl_trv = ((sys_clock_rate * 1000000) / (SL_TIMERDIV * HZ)) - 1;
  165         /* clear prescaler, load reload value */
  166         sl->sl_tcont = 0;
  167         sl->sl_tctl = SL_TIMERINT | LCLKBIN;    /* timer on in given bin */
  168 
  169         splx(s);
  170 }
  171 
  172 /*
  173  *      Enable interrupts from MC clock chip
  174  */
  175 void clocksqt_enable_interrupts(
  176         mach_clock_t    clock)
  177 {
  178         clocksqt_setresolution(clock);
  179 }
  180 
  181 io_return_t clk_open(
  182         int     dev)
  183 {
  184         if (dev != 0)
  185             return D_NO_SUCH_DEVICE;
  186 
  187         return clock_open(&clocksqt0);
  188 }
  189 
  190 io_return_t clk_close(
  191         int     dev)
  192 {
  193         return D_SUCCESS;
  194 }
  195 
  196 
  197 io_return_t clk_getstat(
  198         int             dev,
  199         int             flavor,
  200         dev_status_t    stat,
  201         natural_t       *count)
  202 {
  203         return clock_getstat(&clocksqt0, flavor, stat, count);
  204 }
  205 
  206 io_return_t clk_setstat(
  207         int             dev,
  208         int             flavor,
  209         dev_status_t    stat,
  210         natural_t       count)
  211 {
  212         /*
  213          *      Can`t change resolution (would have to
  214          *      change it on all CPUs)
  215          */
  216         return clock_setstat(&clocksqt0, flavor, stat, count);
  217 }
  218 
  219 vm_offset_t clk_mmap(
  220         dev_t           dev,
  221         vm_offset_t     off,
  222         vm_prot_t       prot)
  223 {
  224         return clock_map_page(&clocksqt0, off, prot);
  225 }
  226 
  227 io_return_t clk_info(
  228         int             dev,
  229         int             flavor,
  230         mach_clock_t    *info)
  231 {
  232         if (flavor == D_INFO_CLOCK) {
  233             *info = &clocksqt0;
  234             return D_SUCCESS;
  235         }
  236         else {
  237             return D_INVALID_OPERATION;
  238         }
  239 }
  240 
  241 /*
  242  * Routines to manipulate the SCED based time-of-day register.
  243  * TOD clock interrupt handling done by todclock in kern_clock.c
  244  *
  245  *
  246  * Inittodr initializes the time-of-day hardware which provides
  247  * date functions. This starts the time-of-day clock.
  248  *
  249  */
  250 time_spec_t clocksqt_read(void)
  251 {
  252         time_spec_t todr = { 0, 0 };
  253         register struct sec_gmode *todgmptr = &todgm;
  254         register int i;
  255         spl_t s_ipl;
  256 
  257         if (todcib == 0) {
  258                 printf("todcib null - inittodr returning!\n");
  259                 return todr;
  260         }
  261 
  262         /*
  263          * Find console SCED and check if the TOD clock has
  264          * failed powerup diagnostics.
  265          */
  266         for (i = 0; i < NSEC; i++) {
  267                 /* is SEC there? */
  268                 if ((SECvec & (1 << i)) == 0)
  269                         continue;
  270 
  271                 if (SEC_desc[i].sec_is_cons)
  272                         break;
  273         }
  274         if (SEC_desc[i].sec_diag_flags & CFG_S_TOD) {
  275                 /*
  276                  * Clear todr if TOD failed powerup diagnostics.
  277                  */
  278                 printf("WARNING: TOD failed powerup diagnostics\n");
  279         } else {
  280                 /*
  281                  * get the current time-of-day from the SCED tod clock.
  282                  */
  283                 todgmptr->gm_status = 0;
  284                 todcib->cib_inst = SINST_GETMODE;
  285                 todcib->cib_status = KVTOPHYS(&todgm, int *);
  286                 s_ipl = splhi();
  287                 mIntr(cons_scsi, TODCLKBIN, SDEV_TOD);
  288                 splx(s_ipl);
  289 
  290                 while ((todgmptr->gm_status & SINST_INSDONE) == 0)
  291                         continue;
  292 
  293                 if (todgmptr->gm_status != SINST_INSDONE)
  294                         panic("Cannot get TOD value");
  295 
  296                 todr.seconds = todgmptr->gm_un.gm_tod.tod_newtime;
  297         }
  298 
  299         if (todr.seconds < 13*SECYR) {
  300                 printf("WARNING: TOD value bad -- ");
  301                 printf("Setting TOD to default time\n");
  302                 todr.seconds = 13*SECYR + 19*SECDAY + (2*SECDAY)/3;
  303         }
  304 
  305         /*
  306          * Return the time.
  307          */
  308 
  309         return todr;
  310 }
  311 
  312 /*
  313  *      Set TOD clock from clock.
  314  */
  315 void clocksqt_write(
  316         mach_clock_t    clock,
  317         time_spec_t     new_time)
  318 {
  319         register struct sec_smode *todsmptr = &todsm;
  320         spl_t s_ipl;
  321 
  322         /*
  323          *      Update hardware, to nearest second
  324          */
  325         todsmptr->sm_status = 0;
  326         todsmptr->sm_un.sm_tod.tod_freq = TODFREQ;
  327         todcib->cib_inst = SINST_SETMODE;
  328         todcib->cib_status = KVTOPHYS(&todsm, int *);
  329 
  330         s_ipl = splhi();
  331         todsmptr->sm_un.sm_tod.tod_newtime = new_time.seconds;
  332 
  333         /*
  334          * Bin 3 is sufficient, helps avoid SLIC-bus lockup.
  335          */
  336         mIntr(cons_scsi, 3, SDEV_TOD);
  337         splx(s_ipl);
  338 
  339         while ((todsmptr->sm_status & SINST_INSDONE) == 0)
  340                 continue;
  341 
  342         if (todsmptr->sm_status != SINST_INSDONE)
  343                 panic("Cannot set TOD value");
  344 }

Cache object: 745b3ed761bdb0be334a0bf10d8dabd3


[ 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.