Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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