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 I/O
  14 * XXX: Probably should add very simple serial I/O?
  15 */
  16
  17#include "boot.h"
  18
  19/*
  20 * These functions are in .inittext so they can be used to signal
  21 * error during initialization.
  22 */
  23
  24void __attribute__((section(".inittext"))) putchar(int ch)
  25{
  26        struct biosregs ireg;
  27
  28        if (ch == '\n')
  29                putchar('\r');  /* \n -> \r\n */
  30
  31        initregs(&ireg);
  32        ireg.bx = 0x0007;
  33        ireg.cx = 0x0001;
  34        ireg.ah = 0x0e;
  35        ireg.al = ch;
  36        intcall(0x10, &ireg, NULL);
  37}
  38
  39void __attribute__((section(".inittext"))) puts(const char *str)
  40{
  41        while (*str)
  42                putchar(*str++);
  43}
  44
  45/*
  46 * Read the CMOS clock through the BIOS, and return the
  47 * seconds in BCD.
  48 */
  49
  50static u8 gettime(void)
  51{
  52        struct biosregs ireg, oreg;
  53
  54        initregs(&ireg);
  55        ireg.ah = 0x02;
  56        intcall(0x1a, &ireg, &oreg);
  57
  58        return oreg.dh;
  59}
  60
  61/*
  62 * Read from the keyboard
  63 */
  64int getchar(void)
  65{
  66        struct biosregs ireg, oreg;
  67
  68        initregs(&ireg);
  69        /* ireg.ah = 0x00; */
  70        intcall(0x16, &ireg, &oreg);
  71
  72        return oreg.al;
  73}
  74
  75static int kbd_pending(void)
  76{
  77        struct biosregs ireg, oreg;
  78
  79        initregs(&ireg);
  80        ireg.ah = 0x01;
  81        intcall(0x16, &ireg, &oreg);
  82
  83        return !(oreg.eflags & X86_EFLAGS_ZF);
  84}
  85
  86void kbd_flush(void)
  87{
  88        for (;;) {
  89                if (!kbd_pending())
  90                        break;
  91                getchar();
  92        }
  93}
  94
  95int getchar_timeout(void)
  96{
  97        int cnt = 30;
  98        int t0, t1;
  99
 100        t0 = gettime();
 101
 102        while (cnt) {
 103                if (kbd_pending())
 104                        return getchar();
 105
 106                t1 = gettime();
 107                if (t0 != t1) {
 108                        cnt--;
 109                        t0 = t1;
 110                }
 111        }
 112
 113        return 0;               /* Timeout! */
 114}
 115