cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tty.c (2276B)


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