root/arch/i386/stand/libsa/bioscons.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pc_probe
  2. pc_init
  3. pc_getc
  4. pc_getshifts
  5. pc_putc
  6. com_probe
  7. com_init
  8. com_getc
  9. comspeed
  10. com_putc

    1 /*      $OpenBSD: bioscons.c,v 1.29 2007/04/27 10:08:34 tom Exp $       */
    2 
    3 /*
    4  * Copyright (c) 1997-1999 Michael Shalayeff
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
   20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   22  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   25  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   26  * THE POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/types.h>
   30 #include <machine/biosvar.h>
   31 #include <machine/pio.h>
   32 #include <dev/isa/isareg.h>
   33 #include <dev/ic/mc146818reg.h>
   34 #include <dev/ic/comreg.h>
   35 #include <dev/ic/ns16450reg.h>
   36 /* #include <i386/isa/nvram.h> */
   37 #include <dev/cons.h>
   38 #include <lib/libsa/stand.h>
   39 #include "debug.h"
   40 #include "biosdev.h"
   41 
   42 /* XXX cannot trust NVRAM on this.  Maybe later we make a real probe.  */
   43 #if 0
   44 #define PRESENT_MASK (NVRAM_EQUIPMENT_KBD|NVRAM_EQUIPMENT_DISPLAY)
   45 #else
   46 #define PRESENT_MASK 0
   47 #endif
   48 
   49 void
   50 pc_probe(struct consdev *cn)
   51 {
   52         cn->cn_pri = CN_INTERNAL;
   53         cn->cn_dev = makedev(12, 0);
   54         printf(" pc%d", minor(cn->cn_dev));
   55 
   56 #if 0
   57         outb(IO_RTC, NVRAM_EQUIPMENT);
   58         if ((inb(IO_RTC+1) & PRESENT_MASK) == PRESENT_MASK) {
   59                 cn->cn_pri = CN_INTERNAL;
   60                 /* XXX from i386/conf.c */
   61                 cn->cn_dev = makedev(12, 0);
   62                 printf(" pc%d", minor(cn->cn_dev));
   63         }
   64 #endif
   65 }
   66 
   67 void
   68 pc_init(struct consdev *cn)
   69 {
   70 }
   71 
   72 int
   73 pc_getc(dev_t dev)
   74 {
   75         register int rv;
   76 
   77         if (dev & 0x80) {
   78                 __asm __volatile(DOINT(0x16) "; setnz %b0" : "=a" (rv) :
   79                     "0" (0x100) : "%ecx", "%edx", "cc" );
   80                 return (rv & 0xff);
   81         }
   82 
   83         /*
   84          * Wait for a character to actually become available.  Appears to
   85          * be necessary on (at least) the Intel Mac Mini.
   86          */
   87         do {
   88                 __asm __volatile(DOINT(0x16) "; setnz %b0" : "=a" (rv) :
   89                     "0" (0x100) : "%ecx", "%edx", "cc" );
   90         } while ((rv & 0xff) == 0);
   91 
   92         __asm __volatile(DOINT(0x16) : "=a" (rv) : "0" (0x000) :
   93             "%ecx", "%edx", "cc" );
   94 
   95         return (rv & 0xff);
   96 }
   97 
   98 int
   99 pc_getshifts(dev_t dev)
  100 {
  101         register int rv;
  102 
  103         __asm __volatile(DOINT(0x16) : "=a" (rv) : "0" (0x200) :
  104             "%ecx", "%edx", "cc" );
  105 
  106         return (rv & 0xff);
  107 }
  108 
  109 void
  110 pc_putc(dev_t dev, int c)
  111 {
  112         __asm __volatile(DOINT(0x10) : : "a" (c | 0xe00), "b" (1) :
  113             "%ecx", "%edx", "cc" );
  114 }
  115 
  116 const int comports[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
  117 
  118 void
  119 com_probe(struct consdev *cn)
  120 {
  121         register int i, n;
  122 
  123         /* get equip. (9-11 # of coms) */
  124         __asm __volatile(DOINT(0x11) : "=a" (n) : : "%ecx", "%edx", "cc");
  125         n >>= 9;
  126         n &= 7;
  127         for (i = 0; i < n; i++)
  128                 printf(" com%d", i);
  129         if (n) {
  130                 cn->cn_pri = CN_NORMAL;
  131                 /* XXX from i386/conf.c */
  132                 cn->cn_dev = makedev(8, 0);
  133         }
  134 }
  135 
  136 void
  137 com_init(struct consdev *cn)
  138 {
  139         register int unit = minor(cn->cn_dev);
  140 
  141         /* let bios do necessary init first, 9600-N-1 */
  142         __asm __volatile(DOINT(0x14) : : "a" (0xe3), "d" (unit) :
  143             "%ecx", "cc" );
  144 }
  145 
  146 int
  147 com_getc(dev_t dev)
  148 {
  149         register int rv;
  150 
  151         if (dev & 0x80) {
  152                 __asm __volatile(DOINT(0x14) : "=a" (rv) :
  153                     "0" (0x300), "d" (minor(dev&0x7f)) : "%ecx", "cc" );
  154                 return ((rv & 0x100) == 0x100);
  155         }
  156 
  157         do
  158                 __asm __volatile(DOINT(0x14) : "=a" (rv) :
  159                     "0" (0x200), "d" (minor(dev)) : "%ecx", "cc" );
  160         while (rv & 0x8000);
  161 
  162         return (rv & 0xff);
  163 }
  164 
  165 /* call with sp == 0 to query the current speed */
  166 int com_speed = 9600;  /* default speed is 9600 baud */
  167 int
  168 comspeed(dev_t dev, int sp)
  169 {
  170         int i, newsp;
  171         int err;
  172 
  173         if (sp <= 0)
  174                 return com_speed;
  175         /* valid baud rate? */
  176         if (115200 < sp || sp < 75)
  177                 return -1;
  178 
  179         /*
  180          * Accepted speeds:
  181          *   75 150 300 600 1200 2400 4800 9600 19200 38400 76800 and
  182          *   14400 28800 57600 115200
  183          */
  184         for (i = sp; i != 75 && i != 14400; i >>= 1)
  185                 if (i & 1)
  186                         return -1;
  187 
  188 /* ripped screaming from dev/ic/com.c */
  189 #define divrnd(n, q)    (((n)*2/(q)+1)/2)       /* divide and round off */
  190         newsp = divrnd((COM_FREQ / 16), sp);
  191         if (newsp <= 0)
  192                 return -1;
  193         err = divrnd((COM_FREQ / 16) * 1000, sp * newsp) - 1000;
  194         if (err < 0)
  195                 err = -err;
  196         if (err > COM_TOLERANCE)
  197                 return -1;
  198 #undef  divrnd
  199 
  200         if (cn_tab && cn_tab->cn_dev == dev && com_speed != sp) {
  201                 printf("com%d: changing speed to %d baud in 5 seconds, "
  202                     "change your terminal to match!\n\a",
  203                     minor(dev), sp);
  204                 sleep(5);
  205         }
  206 
  207         outb(comports[minor(dev)] + com_cfcr, LCR_DLAB);
  208         outb(comports[minor(dev)] + com_dlbl, newsp);
  209         outb(comports[minor(dev)] + com_dlbh, newsp>>8);
  210         outb(comports[minor(dev)] + com_cfcr, LCR_8BITS);
  211         printf("\ncom%d: %d baud\n", minor(dev), sp);
  212 
  213         newsp = com_speed;
  214         com_speed = sp;
  215         return newsp;
  216 }
  217 
  218 void
  219 com_putc(dev_t dev, int c)
  220 {
  221         register int rv;
  222 
  223         dev = minor(dev) & 0x7f;
  224 
  225         /* check online (DSR) */
  226         __asm __volatile(DOINT(0x14) : "=a" (rv) :
  227             "0" (0x300), "d" (dev) : "%ecx", "cc" );
  228         if ( (rv & 0x20) == 0)
  229                 return;
  230 
  231         /* send character */
  232         __asm __volatile(DOINT(0x14) : "=a" (rv) :
  233             "0" (c | 0x100), "d" (dev) : "%ecx", "cc" );
  234 }

/* [<][>][^][v][top][bottom][index][help] */