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/i386/pit.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) 1991,1990,1989 Carnegie Mellon University
    4  * Copyright (c) 1991 IBM Corporation 
    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  * and that the name IBM not be used in advertising or publicity 
   13  * pertaining to distribution of the software without specific, written
   14  * prior permission.
   15  * 
   16  * CARNEGIE MELLON AND IBM ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   17  * CONDITION.  CARNEGIE MELLON AND IBM DISCLAIM ANY LIABILITY OF ANY KIND FOR
   18  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   19  * 
   20  * Carnegie Mellon requests users of this software to return to
   21  * 
   22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   23  *  School of Computer Science
   24  *  Carnegie Mellon University
   25  *  Pittsburgh PA 15213-3890
   26  * 
   27  * any improvements or extensions that they make and grant Carnegie Mellon
   28  * the rights to redistribute these changes.
   29  */
   30 
   31 /* 
   32  * HISTORY
   33  * $Log:        pit.c,v $
   34  * Revision 2.11  93/02/04  07:56:56  danner
   35  *      Make spinwait() and tenmicrosec() [findspeed() & microtime()]
   36  *      available for everyone.  They once were but they were incorrect.
   37  *      Re-add tenmicrosec for PS2.
   38  *      [92/02/25           dbg@ibm]
   39  * 
   40  * Revision 2.9  91/10/07  17:25:03  af
   41  *      tenmicrosec() was all wrong has been expunged, since noone uses
   42  *      it.
   43  *      [91/09/04            rvb]
   44  * 
   45  * Revision 2.8  91/06/19  11:55:29  rvb
   46  *      cputypes.h->platforms.h
   47  *      [91/06/12  13:45:16  rvb]
   48  * 
   49  * Revision 2.7  91/05/14  16:14:40  mrt
   50  *      Correcting copyright
   51  * 
   52  * Revision 2.6  91/02/05  17:14:03  mrt
   53  *      Changed to new Mach copyright
   54  *      [91/02/01  17:37:14  mrt]
   55  * 
   56  * Revision 2.5  91/01/09  19:25:33  rpd
   57  *      Fixed clkstart to reset clock interrupt priority, etc.
   58  *      [91/01/09            rpd]
   59  * 
   60  *      Flush dead EXL code.
   61  *      [90/11/27  11:38:08  rvb]
   62  * 
   63  * Revision 2.3  90/08/27  21:57:57  dbg
   64  *      Fix Intel Copyright as per B. Davies authorization.
   65  *      [90/08/14            dbg]
   66  *      Add Intel copyright.
   67  *      [90/01/08            rvb]
   68  *      splall/backall -> splon/sploff
   69  *      [89/10/20            rvb]
   70  * 
   71  * Revision 2.2  90/05/03  15:36:34  dbg
   72  *      Converted for pure kernel.
   73  *      [90/02/20            dbg]
   74  * 
   75  * Revision 2.2  89/09/25  12:32:40  rvb
   76  *      File was provided by Intel 9/18/89.
   77  *      [89/09/23            rvb]
   78  * 
   79  */
   80 
   81 /*
   82   Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
   83 
   84                 All Rights Reserved
   85 
   86 Permission to use, copy, modify, and distribute this software and
   87 its documentation for any purpose and without fee is hereby
   88 granted, provided that the above copyright notice appears in all
   89 copies and that both the copyright notice and this permission notice
   90 appear in supporting documentation, and that the name of Intel
   91 not be used in advertising or publicity pertaining to distribution
   92 of the software without specific, written prior permission.
   93 
   94 INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
   95 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
   96 IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
   97 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
   98 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
   99 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  100 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  101 */
  102 
  103 #include <platforms.h>
  104 #include <kern/time_out.h>
  105 #include <i386/ipl.h>
  106 #include <i386/pit.h>
  107 
  108 int pitctl_port  = PITCTL_PORT;         /* For 386/20 Board */
  109 int pitctr0_port = PITCTR0_PORT;        /* For 386/20 Board */
  110 int pitctr1_port = PITCTR1_PORT;        /* For 386/20 Board */
  111 int pitctr2_port = PITCTR2_PORT;        /* For 386/20 Board */
  112 /* We want PIT 0 in square wave mode */
  113 
  114 int pit0_mode = PIT_C0|PIT_SQUAREMODE|PIT_READMODE ;
  115 
  116 
  117 unsigned int delaycount;                /* loop count in trying to delay for
  118                                          * 1 millisecond
  119                                          */
  120 unsigned long microdata=50;             /* loop count for 10 microsecond wait.
  121                                            MUST be initialized for those who
  122                                            insist on calling "tenmicrosec"
  123                                            it before the clock has been
  124                                            initialized.
  125                                          */
  126 unsigned int clknumb = CLKNUM;          /* interrupt interval for timer 0 */
  127 
  128 #ifdef PS2
  129 extern int clock_int_handler();
  130 
  131 #include <sys/types.h>
  132 #include <i386ps2/abios.h>
  133 static struct generic_request *clock_request_block;
  134 static int     clock_flags;
  135 char cqbuf[200];        /*XXX temporary.. should use kmem_alloc or whatever..*/
  136 #endif  /* PS2 */
  137 
  138 clkstart()
  139 {
  140         unsigned int    flags;
  141         unsigned char   byte;
  142         int s;
  143 
  144         intpri[0] = SPLHI;
  145         form_pic_mask();
  146 
  147         findspeed();
  148         microfind();
  149         s = sploff();         /* disable interrupts */
  150 
  151 #ifdef  PS2
  152         abios_clock_start();
  153 #endif /* PS2 */
  154 
  155         /* Since we use only timer 0, we program that.
  156          * 8254 Manual specifically says you do not need to program
  157          * timers you do not use
  158          */
  159         outb(pitctl_port, pit0_mode);
  160         clknumb = CLKNUM/hz;
  161         byte = clknumb;
  162         outb(pitctr0_port, byte);
  163         byte = clknumb>>8;
  164         outb(pitctr0_port, byte); 
  165         splon(s);         /* restore interrupt state */
  166 }
  167 
  168 #define COUNT   10000   /* should be a multiple of 1000! */
  169 
  170 findspeed()
  171 {
  172         unsigned int flags;
  173         unsigned char byte;
  174         unsigned int leftover;
  175         int i;
  176         int j;
  177         int s;
  178 
  179         s = sploff();                 /* disable interrupts */
  180         /* Put counter in count down mode */
  181 #define PIT_COUNTDOWN PIT_READMODE|PIT_NDIVMODE
  182         outb(pitctl_port, PIT_COUNTDOWN);
  183         /* output a count of -1 to counter 0 */
  184         outb(pitctr0_port, 0xff);
  185         outb(pitctr0_port, 0xff);
  186         delaycount = COUNT;
  187         spinwait(1);
  188         /* Read the value left in the counter */
  189         byte = inb(pitctr0_port);       /* least siginifcant */
  190         leftover = inb(pitctr0_port);   /* most significant */
  191         leftover = (leftover<<8) + byte ;
  192         /* Formula for delaycount is :
  193          *  (loopcount * timer clock speed)/ (counter ticks * 1000)
  194          * 1000 is for figuring out milliseconds 
  195          */
  196         /* we arrange calculation so that it doesn't overflow */
  197         delaycount = ((COUNT/1000) * CLKNUM) / (0xffff-leftover);
  198         printf("findspeed: delaycount=%d (tics=%d)\n",
  199                delaycount, (0xffff-leftover));
  200         splon(s);         /* restore interrupt state */
  201 }
  202 
  203 #ifdef PS2
  204 
  205 abios_clock_start()
  206 {
  207         struct generic_request  temp_request_block;
  208         int rc;
  209 
  210         nmi_enable();   /* has to happen somewhere! */
  211         temp_request_block.r_current_req_blck_len = ABIOS_MIN_REQ_SIZE;
  212         temp_request_block.r_logical_id = abios_next_LID(SYSTIME_ID,
  213                                                         ABIOS_FIRST_LID);
  214         temp_request_block.r_unit = 0;
  215         temp_request_block.r_function = ABIOS_LOGICAL_PARAMETER;
  216         temp_request_block.r_return_code = ABIOS_UNDEFINED;
  217 
  218         abios_common_start(&temp_request_block,0);
  219         if (temp_request_block.r_return_code != ABIOS_DONE) {
  220                 panic("couldn init abios time code!\n");
  221               }
  222 
  223         /*
  224          * now build the clock request for the hardware system clock
  225          */
  226         clock_request_block = (struct generic_request *)cqbuf;
  227         clock_request_block->r_current_req_blck_len =
  228                                 temp_request_block.r_request_block_length;
  229         clock_request_block->r_logical_id = temp_request_block.r_logical_id;
  230         clock_request_block->r_unit = 0;
  231         clock_request_block->r_function = ABIOS_DEFAULT_INTERRUPT;
  232         clock_request_block->r_return_code = ABIOS_UNDEFINED;
  233         clock_flags = temp_request_block.r_logical_id_flags;
  234 }
  235 
  236 ackrtclock()
  237 {
  238         if (clock_request_block) {
  239           clock_request_block->r_return_code = ABIOS_UNDEFINED;
  240           abios_common_interrupt(clock_request_block,clock_flags);
  241         }
  242       }
  243 #endif /* PS2 */
  244 
  245 
  246 spinwait(millis)
  247         int millis;             /* number of milliseconds to delay */
  248 {
  249         int i, j;
  250 
  251         for (i=0;i<millis;i++)
  252                 for (j=0;j<delaycount;j++)
  253                         ;
  254 }
  255 
  256 #define MICROCOUNT      1000    /* keep small to prevent overflow */
  257 microfind()
  258 {
  259         unsigned int flags;
  260         unsigned char byte;
  261         unsigned short leftover;
  262         int s;
  263 
  264 
  265         s = sploff();                 /* disable interrupts */
  266 
  267         /* Put counter in count down mode */
  268         outb(pitctl_port, PIT_COUNTDOWN);
  269         /* output a count of -1 to counter 0 */
  270         outb(pitctr0_port, 0xff);
  271         outb(pitctr0_port, 0xff);
  272         microdata=MICROCOUNT;
  273         tenmicrosec();
  274         /* Read the value left in the counter */
  275         byte = inb(pitctr0_port);       /* least siginifcant */
  276         leftover = inb(pitctr0_port);   /* most significant */
  277         leftover = (leftover<<8) + byte ;
  278         /* Formula for delaycount is :
  279          *  (loopcount * timer clock speed)/ (counter ticks * 1000)
  280          *  Note also that 1000 is for figuring out milliseconds
  281          */
  282         microdata = (MICROCOUNT * CLKNUM) / ((0xffff-leftover)*100000);
  283         if (!microdata)
  284                 microdata++;
  285 
  286         splon(s);         /* restore interrupt state */
  287 }

Cache object: d425671a4148801e18dba284a6ee9582


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