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

Cache object: 7d7a7650b01ad035ff3cab359f16d11d


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