linux/arch/x86/boot/tty.c
<<
>>
Prefs
   1/* -*- linux-c -*- ------------------------------------------------------- *
   2 *
   3 *   Copyright (C) 1991, 1992 Linus Torvalds
   4 *   Copyright 2007 rPath, Inc. - All Rights Reserved
   5 *   Copyright 2009 Intel Corporation; author H. Peter Anvin
   6 *
   7 *   This file is part of the Linux kernel, and is made available under
   8 *   the terms of the GNU General Public License version 2.
   9 *
  10 * ----------------------------------------------------------------------- */
  11
  12/*
  13 * Very simple screen and serial I/O
  14 */
  15
  16#include "boot.h"
  17
  18int early_serial_base;
  19
  20#define XMTRDY          0x20
  21
  22#define TXR             0       /*  Transmit register (WRITE) */
  23#define LSR             5       /*  Line Status               */
  24
  25/*
  26 * These functions are in .inittext so they can be used to signal
  27 * error during initialization.
  28 */
  29
  30static void __attribute__((section(".inittext"))) serial_putchar(int ch)
  31{
  32        unsigned timeout = 0xffff;
  33
  34        while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
  35                cpu_relax();
  36
  37        outb(ch, early_serial_base + TXR);
  38}
  39
  40static void __attribute__((section(".inittext"))) bios_putchar(int ch)
  41{
  42        struct biosregs ireg;
  43
  44        initregs(&ireg);
  45        ireg.bx = 0x0007;
  46        ireg.cx = 0x0001;
  47        ireg.ah = 0x0e;
  48        ireg.al = ch;
  49        intcall(0x10, &ireg, NULL);
  50}
  51
  52void __attribute__((section(".inittext"))) putchar(int ch)
  53{
  54        if (ch == '\n')
  55                putchar('\r');  /* \n -> \r\n */
  56
  57        bios_putchar(ch);
  58
  59        if (early_serial_base != 0)
  60                serial_putchar(ch);
  61}
  62
  63void __attribute__((section(".inittext"))) puts(const char *str)
  64{
  65        while (*str)
  66                putchar(*str++);
  67}
  68
  69/*
  70 * Read the CMOS clock through the BIOS, and return the
  71 * seconds in BCD.
  72 */
  73
  74static u8 gettime(void)
  75{
  76        struct biosregs ireg, oreg;
  77
  78        initregs(&ireg);
  79        ireg.ah = 0x02;
  80        intcall(0x1a, &ireg, &oreg);
  81
  82        return oreg.dh;
  83}
  84
  85/*
  86 * Read from the keyboard
  87 */
  88int getchar(void)
  89{
  90        struct biosregs ireg, oreg;
  91
  92        initregs(&ireg);
  93        /* ireg.ah = 0x00; */
  94        intcall(0x16, &ireg, &oreg);
  95
  96        return oreg.al;
  97}
  98
  99static int kbd_pending(void)
 100{
 101        struct biosregs ireg, oreg;
 102
 103        initregs(&ireg);
 104        ireg.ah = 0x01;
 105        intcall(0x16, &ireg, &oreg);
 106
 107        return !(oreg.eflags & X86_EFLAGS_ZF);
 108}
 109
 110void kbd_flush(void)
 111{
 112        for (;;) {
 113                if (!kbd_pending())
 114                        break;
 115                getchar();
 116        }
 117}
 118
 119int getchar_timeout(void)
 120{
 121        int cnt = 30;
 122        int t0, t1;
 123
 124        t0 = gettime();
 125
 126        while (cnt) {
 127                if (kbd_pending())
 128                        return getchar();
 129
 130                t1 = gettime();
 131                if (t0 != t1) {
 132                        cnt--;
 133                        t0 = t1;
 134                }
 135        }
 136
 137        return 0;               /* Timeout! */
 138}
 139
 140