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

serial.c (3642B)


      1/*
      2 * Generic serial console support
      3 *
      4 * Author: Mark A. Greer <mgreer@mvista.com>
      5 *
      6 * Code in serial_edit_cmdline() copied from <file:arch/ppc/boot/simple/misc.c>
      7 * and was written by Matt Porter <mporter@kernel.crashing.org>.
      8 *
      9 * 2001,2006 (c) MontaVista Software, Inc.  This file is licensed under
     10 * the terms of the GNU General Public License version 2.  This program
     11 * is licensed "as is" without any warranty of any kind, whether express
     12 * or implied.
     13 */
     14#include <stdarg.h>
     15#include <stddef.h>
     16#include "types.h"
     17#include "string.h"
     18#include "stdio.h"
     19#include "io.h"
     20#include "ops.h"
     21
     22static int serial_open(void)
     23{
     24	struct serial_console_data *scdp = console_ops.data;
     25	return scdp->open();
     26}
     27
     28static void serial_write(const char *buf, int len)
     29{
     30	struct serial_console_data *scdp = console_ops.data;
     31
     32	while (*buf != '\0')
     33		scdp->putc(*buf++);
     34}
     35
     36static void serial_edit_cmdline(char *buf, int len, unsigned int timeout)
     37{
     38	int timer = 0, count;
     39	char ch, *cp;
     40	struct serial_console_data *scdp = console_ops.data;
     41
     42	cp = buf;
     43	count = strlen(buf);
     44	cp = &buf[count];
     45	count++;
     46
     47	do {
     48		if (scdp->tstc()) {
     49			while (((ch = scdp->getc()) != '\n') && (ch != '\r')) {
     50				/* Test for backspace/delete */
     51				if ((ch == '\b') || (ch == '\177')) {
     52					if (cp != buf) {
     53						cp--;
     54						count--;
     55						printf("\b \b");
     56					}
     57				/* Test for ^x/^u (and wipe the line) */
     58				} else if ((ch == '\030') || (ch == '\025')) {
     59					while (cp != buf) {
     60						cp--;
     61						count--;
     62						printf("\b \b");
     63					}
     64				} else if (count < len) {
     65						*cp++ = ch;
     66						count++;
     67						scdp->putc(ch);
     68				}
     69			}
     70			break;  /* Exit 'timer' loop */
     71		}
     72		udelay(1000);  /* 1 msec */
     73	} while (timer++ < timeout);
     74	*cp = 0;
     75}
     76
     77static void serial_close(void)
     78{
     79	struct serial_console_data *scdp = console_ops.data;
     80
     81	if (scdp->close)
     82		scdp->close();
     83}
     84
     85static void *serial_get_stdout_devp(void)
     86{
     87	void *devp;
     88	char devtype[MAX_PROP_LEN];
     89	char path[MAX_PATH_LEN];
     90
     91	devp = finddevice("/chosen");
     92	if (devp == NULL)
     93		goto err_out;
     94
     95	if (getprop(devp, "linux,stdout-path", path, MAX_PATH_LEN) > 0 ||
     96		getprop(devp, "stdout-path", path, MAX_PATH_LEN) > 0) {
     97		devp = finddevice(path);
     98		if (devp == NULL)
     99			goto err_out;
    100
    101		if ((getprop(devp, "device_type", devtype, sizeof(devtype)) > 0)
    102				&& !strcmp(devtype, "serial"))
    103			return devp;
    104	}
    105err_out:
    106	return NULL;
    107}
    108
    109static struct serial_console_data serial_cd;
    110
    111/* Node's "compatible" property determines which serial driver to use */
    112int serial_console_init(void)
    113{
    114	void *devp;
    115	int rc = -1;
    116
    117	devp = serial_get_stdout_devp();
    118	if (devp == NULL)
    119		goto err_out;
    120
    121	if (dt_is_compatible(devp, "ns16550") ||
    122	    dt_is_compatible(devp, "pnpPNP,501"))
    123		rc = ns16550_console_init(devp, &serial_cd);
    124#ifdef CONFIG_CPM
    125	else if (dt_is_compatible(devp, "fsl,cpm1-scc-uart") ||
    126	         dt_is_compatible(devp, "fsl,cpm1-smc-uart") ||
    127	         dt_is_compatible(devp, "fsl,cpm2-scc-uart") ||
    128	         dt_is_compatible(devp, "fsl,cpm2-smc-uart"))
    129		rc = cpm_console_init(devp, &serial_cd);
    130#endif
    131#ifdef CONFIG_PPC_MPC52xx
    132	else if (dt_is_compatible(devp, "fsl,mpc5200-psc-uart"))
    133		rc = mpc5200_psc_console_init(devp, &serial_cd);
    134#endif
    135#ifdef CONFIG_PPC_POWERNV
    136	else if (dt_is_compatible(devp, "ibm,opal-console-raw"))
    137		rc = opal_console_init(devp, &serial_cd);
    138#endif
    139
    140	/* Add other serial console driver calls here */
    141
    142	if (!rc) {
    143		console_ops.open = serial_open;
    144		console_ops.write = serial_write;
    145		console_ops.close = serial_close;
    146		console_ops.data = &serial_cd;
    147
    148		if (serial_cd.getc)
    149			console_ops.edit_cmdline = serial_edit_cmdline;
    150
    151		return 0;
    152	}
    153err_out:
    154	return -1;
    155}