// SPDX-License-Identifier: GPL-2.0+ /* * vio driver interface to hvc_console.c * * This code was moved here to allow the remaining code to be reused as a * generic polling mode with semi-reliable transport driver core to the * console and tty subsystems. * * * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM * Copyright (C) 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp. * Copyright (C) 2004 IBM Corporation * * Additional Author(s): * Ryan S. Arnold <rsa@us.ibm.com> * * TODO: * * - handle error in sending hvsi protocol packets * - retry nego on subsequent sends ?
*/
/* * Work around a HV bug where it gives us a null * after every \r. -- paulus
*/ for (i = 1; i < pv->left; ++i) { if (pv->buf[i] == 0 && pv->buf[i-1] == '\r') {
--pv->left; if (i < pv->left) {
memmove(&pv->buf[i], &pv->buf[i+1],
pv->left - i);
}
}
}
}
/** * hvterm_raw_put_chars: send characters to firmware for given vterm adapter * @vtermno: The virtual terminal number. * @buf: The characters to send. Because of the underlying hypercall in * hvc_put_chars(), this buffer must be at least 16 bytes long, even if * you are sending fewer chars. * @count: number of chars to send.
*/ static ssize_t hvterm_raw_put_chars(uint32_t vtermno, const u8 *buf,
size_t count)
{ struct hvterm_priv *pv = hvterm_privs[vtermno];
staticvoid udbg_hvc_putc(char c)
{ int count = -1; unsignedchar bounce_buffer[16];
if (!hvterm_privs[0]) return;
if (c == '\n')
udbg_hvc_putc('\r');
do { switch(hvterm_privs[0]->proto) { case HV_PROTOCOL_RAW: /* * hvterm_raw_put_chars requires at least a 16-byte * buffer, so go via the bounce buffer
*/
bounce_buffer[0] = c;
count = hvterm_raw_put_chars(0, bounce_buffer, 1); break; case HV_PROTOCOL_HVSI:
count = hvterm_hvsi_put_chars(0, &c, 1); break;
}
} while (count == 0 || count == -EAGAIN);
}
staticint udbg_hvc_getc_poll(void)
{ int rc = 0; char c;
if (!hvterm_privs[0]) return -1;
switch(hvterm_privs[0]->proto) { case HV_PROTOCOL_RAW:
rc = hvterm_raw_get_chars(0, &c, 1); break; case HV_PROTOCOL_HVSI:
rc = hvterm_hvsi_get_chars(0, &c, 1); break;
} if (!rc) return -1; return c;
}
staticint udbg_hvc_getc(void)
{ int ch;
if (!hvterm_privs[0]) return -1;
for (;;) {
ch = udbg_hvc_getc_poll(); if (ch == -1) { /* This shouldn't be needed...but... */ volatileunsignedlong delay; for (delay=0; delay < 2000000; delay++)
;
} else { return ch;
}
}
}
/* find the boot console from /chosen/stdout */ /* Check if it's a virtual terminal */ if (!of_node_name_prefix(of_stdout, "vty")) return;
termno = of_get_property(of_stdout, "reg", NULL); if (termno == NULL) return;
hvterm_priv0.termno = of_read_number(termno, 1);
spin_lock_init(&hvterm_priv0.buf_lock);
hvterm_privs[0] = &hvterm_priv0;
/* Check the protocol */ if (of_device_is_compatible(of_stdout, "hvterm1")) {
hvterm_priv0.proto = HV_PROTOCOL_RAW;
ops = &hvterm_raw_ops;
} elseif (of_device_is_compatible(of_stdout, "hvterm-protocol")) {
hvterm_priv0.proto = HV_PROTOCOL_HVSI;
ops = &hvterm_hvsi_ops;
hvsilib_init(&hvterm_priv0.hvsi, hvc_get_chars, hvc_put_chars,
hvterm_priv0.termno, 1); /* HVSI, perform the handshake now */
hvsilib_establish(&hvterm_priv0.hvsi);
} else return;
udbg_putc = udbg_hvc_putc;
udbg_getc = udbg_hvc_getc;
udbg_getc_poll = udbg_hvc_getc_poll; #ifdef HVC_OLD_HVSI /* When using the old HVSI driver don't register the HVC * backend for HVSI, only do udbg
*/ if (hvterm_priv0.proto == HV_PROTOCOL_HVSI) return; #endif /* Check whether the user has requested a different console. */ if (!strstr(boot_command_line, "console="))
add_preferred_console("hvc", 0, NULL);
hvc_instantiate(0, 0, ops);
}
/* call this from early_init() for a working debug console on * vterm capable LPAR machines
*/ #ifdef CONFIG_PPC_EARLY_DEBUG_LPAR void __init udbg_init_debug_lpar(void)
{ /* * If we're running as a hypervisor then we definitely can't call the * hypervisor to print debug output (we *are* the hypervisor), so don't * register if we detect that MSR_HV=1.
*/ if (mfmsr() & MSR_HV) return;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.