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

nonstdio.c (3152B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (C) 1996-2005 Paul Mackerras.
      4 */
      5#include <linux/string.h>
      6#include <asm/udbg.h>
      7#include <asm/time.h>
      8#include "nonstdio.h"
      9
     10static bool paginating, paginate_skipping;
     11static unsigned long paginate_lpp; /* Lines Per Page */
     12static unsigned long paginate_pos;
     13
     14void xmon_start_pagination(void)
     15{
     16	paginating = true;
     17	paginate_skipping = false;
     18	paginate_pos = 0;
     19}
     20
     21void xmon_end_pagination(void)
     22{
     23	paginating = false;
     24}
     25
     26void xmon_set_pagination_lpp(unsigned long lpp)
     27{
     28	paginate_lpp = lpp;
     29}
     30
     31static int xmon_readchar(void)
     32{
     33	if (udbg_getc)
     34		return udbg_getc();
     35	return -1;
     36}
     37
     38static int xmon_write(const char *ptr, int nb)
     39{
     40	int rv = 0;
     41	const char *p = ptr, *q;
     42	const char msg[] = "[Hit a key (a:all, q:truncate, any:next page)]";
     43
     44	if (nb <= 0)
     45		return rv;
     46
     47	if (paginating && paginate_skipping)
     48		return nb;
     49
     50	if (paginate_lpp) {
     51		while (paginating && (q = strchr(p, '\n'))) {
     52			rv += udbg_write(p, q - p + 1);
     53			p = q + 1;
     54			paginate_pos++;
     55
     56			if (paginate_pos >= paginate_lpp) {
     57				udbg_write(msg, strlen(msg));
     58
     59				switch (xmon_readchar()) {
     60				case 'a':
     61					paginating = false;
     62					break;
     63				case 'q':
     64					paginate_skipping = true;
     65					break;
     66				default:
     67					/* nothing */
     68					break;
     69				}
     70
     71				paginate_pos = 0;
     72				udbg_write("\r\n", 2);
     73
     74				if (paginate_skipping)
     75					return nb;
     76			}
     77		}
     78	}
     79
     80	return rv + udbg_write(p, nb - (p - ptr));
     81}
     82
     83int xmon_putchar(int c)
     84{
     85	char ch = c;
     86
     87	if (c == '\n')
     88		xmon_putchar('\r');
     89	return xmon_write(&ch, 1) == 1? c: -1;
     90}
     91
     92static char line[256];
     93static char *lineptr;
     94static int lineleft;
     95
     96static int xmon_getchar(void)
     97{
     98	int c;
     99
    100	if (lineleft == 0) {
    101		lineptr = line;
    102		for (;;) {
    103			c = xmon_readchar();
    104			if (c == -1 || c == 4)
    105				break;
    106			if (c == '\r' || c == '\n') {
    107				*lineptr++ = '\n';
    108				xmon_putchar('\n');
    109				break;
    110			}
    111			switch (c) {
    112			case 0177:
    113			case '\b':
    114				if (lineptr > line) {
    115					xmon_putchar('\b');
    116					xmon_putchar(' ');
    117					xmon_putchar('\b');
    118					--lineptr;
    119				}
    120				break;
    121			case 'U' & 0x1F:
    122				while (lineptr > line) {
    123					xmon_putchar('\b');
    124					xmon_putchar(' ');
    125					xmon_putchar('\b');
    126					--lineptr;
    127				}
    128				break;
    129			default:
    130				if (lineptr >= &line[sizeof(line) - 1])
    131					xmon_putchar('\a');
    132				else {
    133					xmon_putchar(c);
    134					*lineptr++ = c;
    135				}
    136			}
    137		}
    138		lineleft = lineptr - line;
    139		lineptr = line;
    140	}
    141	if (lineleft == 0)
    142		return -1;
    143	--lineleft;
    144	return *lineptr++;
    145}
    146
    147char *xmon_gets(char *str, int nb)
    148{
    149	char *p;
    150	int c;
    151
    152	for (p = str; p < str + nb - 1; ) {
    153		c = xmon_getchar();
    154		if (c == -1) {
    155			if (p == str)
    156				return NULL;
    157			break;
    158		}
    159		*p++ = c;
    160		if (c == '\n')
    161			break;
    162	}
    163	*p = 0;
    164	return str;
    165}
    166
    167void xmon_printf(const char *format, ...)
    168{
    169	va_list args;
    170	static char xmon_outbuf[1024];
    171	int rc, n;
    172
    173	va_start(args, format);
    174	n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
    175	va_end(args);
    176
    177	rc = xmon_write(xmon_outbuf, n);
    178
    179	if (n && rc == 0) {
    180		/* No udbg hooks, fallback to printk() - dangerous */
    181		pr_cont("%s", xmon_outbuf);
    182	}
    183}
    184
    185void xmon_puts(const char *str)
    186{
    187	xmon_write(str, strlen(str));
    188}