[kvm-unit-tests GIT PULL 04/26] lib: s390x: sclp: Add compat handling for HMC ASCII consoles

Nico Boehr
2023-11-10T13:54:32Z

From: Janosch Frank <frankja@linux.ibm.com>

Without the \r the output of the HMC ASCII console takes a lot of
additional effort to read in comparison to the line mode console.

Additionally we add a console clear for the HMC ASCII console so that
old messages from a previously running operating system are not
polluting the console.

Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Link: https://lore.kernel.org/r/20231031095519.73311-3-frankja@linux.ibm.com
Signed-off-by: Nico Boehr <nrb@linux.ibm.com>
---
lib/s390x/sclp-console.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/lib/s390x/sclp-console.c b/lib/s390x/sclp-console.c
index 19c74e4..6c965b6 100644
--- a/lib/s390x/sclp-console.c
+++ b/lib/s390x/sclp-console.c
@@ -11,6 +11,7 @@
#include <asm/arch_def.h>
#include <asm/io.h>
#include <asm/spinlock.h>
+#include "hardware.h"
#include "sclp.h"

/*
@@ -85,6 +86,8 @@ static uint8_t _ascebc[256] = {
0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
};

+static bool lpar_ascii_compat;
+
static char lm_buff[120];
static unsigned char lm_buff_off;
static struct spinlock lm_buff_lock;
@@ -97,14 +100,29 @@ static void sclp_print_ascii(const char *str)
{
int len = strlen(str);
WriteEventData *sccb = (void *)_sccb;
+ char *str_dest = (char *)&sccb->msg;
+ int src_ind, dst_ind;

sclp_mark_busy();
memset(sccb, 0, sizeof(*sccb));
+
+ for (src_ind = 0, dst_ind = 0;
+ src_ind < len && dst_ind < (PAGE_SIZE / 2);
+ src_ind++, dst_ind++) {
+ str_dest[dst_ind] = str[src_ind];
+ /* Add a \r to the \n for HMC ASCII console */
+ if (str[src_ind] == '\n' && lpar_ascii_compat) {
+ dst_ind++;
+ str_dest[dst_ind] = '\r';
+ }
+ }
+
+ /* Len might have changed because of the compat behavior */
+ len = dst_ind;
sccb->h.length = offsetof(WriteEventData, msg) + len;
sccb->h.function_code = SCLP_FC_NORMAL_WRITE;
sccb->ebh.length = sizeof(EventBufferHeader) + len;
sccb->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
- memcpy(&sccb->msg, str, len);

sclp_service_call(SCLP_CMD_WRITE_EVENT_DATA, sccb);
}
@@ -218,8 +236,13 @@ static void sclp_console_disable_read(void)

void sclp_console_setup(void)
{
+ lpar_ascii_compat = detect_host() == HOST_IS_LPAR;
+
/* We send ASCII and line mode. */
sclp_write_event_mask(0, SCLP_EVENT_MASK_MSG_ASCII | SCLP_EVENT_MASK_MSG);
+ /* Hard terminal reset to clear screen for HMC ASCII console */
+ if (lpar_ascii_compat)
+ sclp_print_ascii("\ec");
}

void sclp_print(const char *str)
--
2.41.0