xref: /openbmc/linux/arch/s390/boot/pgm_check_info.c (revision 3ca8b855)
1724dc336SVasily Gorbik // SPDX-License-Identifier: GPL-2.0
2724dc336SVasily Gorbik #include <linux/kernel.h>
3724dc336SVasily Gorbik #include <linux/string.h>
4724dc336SVasily Gorbik #include <asm/lowcore.h>
53ca8b855SVasily Gorbik #include <asm/setup.h>
6724dc336SVasily Gorbik #include <asm/sclp.h>
7724dc336SVasily Gorbik #include "boot.h"
8724dc336SVasily Gorbik 
9724dc336SVasily Gorbik const char hex_asc[] = "0123456789abcdef";
10724dc336SVasily Gorbik 
11724dc336SVasily Gorbik #define add_val_as_hex(dst, val)					       \
12724dc336SVasily Gorbik 	__add_val_as_hex(dst, (const unsigned char *)&val, sizeof(val))
13724dc336SVasily Gorbik 
14724dc336SVasily Gorbik static char *__add_val_as_hex(char *dst, const unsigned char *src, size_t count)
15724dc336SVasily Gorbik {
16724dc336SVasily Gorbik 	while (count--)
17724dc336SVasily Gorbik 		dst = hex_byte_pack(dst, *src++);
18724dc336SVasily Gorbik 	return dst;
19724dc336SVasily Gorbik }
20724dc336SVasily Gorbik 
21724dc336SVasily Gorbik static char *add_str(char *dst, char *src)
22724dc336SVasily Gorbik {
23724dc336SVasily Gorbik 	strcpy(dst, src);
24724dc336SVasily Gorbik 	return dst + strlen(dst);
25724dc336SVasily Gorbik }
26724dc336SVasily Gorbik 
27724dc336SVasily Gorbik void print_pgm_check_info(void)
28724dc336SVasily Gorbik {
29724dc336SVasily Gorbik 	struct psw_bits *psw = &psw_bits(S390_lowcore.psw_save_area);
30724dc336SVasily Gorbik 	unsigned short ilc = S390_lowcore.pgm_ilc >> 1;
31724dc336SVasily Gorbik 	char buf[256];
32724dc336SVasily Gorbik 	int row, col;
33724dc336SVasily Gorbik 	char *p;
34724dc336SVasily Gorbik 
35724dc336SVasily Gorbik 	add_str(buf, "Linux version ");
36724dc336SVasily Gorbik 	strlcat(buf, kernel_version, sizeof(buf));
37724dc336SVasily Gorbik 	sclp_early_printk(buf);
38724dc336SVasily Gorbik 
39724dc336SVasily Gorbik 	p = add_str(buf, "Kernel fault: interruption code ");
40724dc336SVasily Gorbik 	p = add_val_as_hex(buf + strlen(buf), S390_lowcore.pgm_code);
41724dc336SVasily Gorbik 	p = add_str(p, " ilc:");
42724dc336SVasily Gorbik 	*p++ = hex_asc_lo(ilc);
43724dc336SVasily Gorbik 	add_str(p, "\n");
44724dc336SVasily Gorbik 	sclp_early_printk(buf);
45724dc336SVasily Gorbik 
463ca8b855SVasily Gorbik 	if (kaslr_enabled) {
473ca8b855SVasily Gorbik 		p = add_str(buf, "Kernel random base: ");
483ca8b855SVasily Gorbik 		p = add_val_as_hex(p, __kaslr_offset);
493ca8b855SVasily Gorbik 		add_str(p, "\n");
503ca8b855SVasily Gorbik 		sclp_early_printk(buf);
513ca8b855SVasily Gorbik 	}
523ca8b855SVasily Gorbik 
53724dc336SVasily Gorbik 	p = add_str(buf, "PSW : ");
54724dc336SVasily Gorbik 	p = add_val_as_hex(p, S390_lowcore.psw_save_area.mask);
55724dc336SVasily Gorbik 	p = add_str(p, " ");
56724dc336SVasily Gorbik 	p = add_val_as_hex(p, S390_lowcore.psw_save_area.addr);
57724dc336SVasily Gorbik 	add_str(p, "\n");
58724dc336SVasily Gorbik 	sclp_early_printk(buf);
59724dc336SVasily Gorbik 
60724dc336SVasily Gorbik 	p = add_str(buf, "      R:");
61724dc336SVasily Gorbik 	*p++ = hex_asc_lo(psw->per);
62724dc336SVasily Gorbik 	p = add_str(p, " T:");
63724dc336SVasily Gorbik 	*p++ = hex_asc_lo(psw->dat);
64724dc336SVasily Gorbik 	p = add_str(p, " IO:");
65724dc336SVasily Gorbik 	*p++ = hex_asc_lo(psw->io);
66724dc336SVasily Gorbik 	p = add_str(p, " EX:");
67724dc336SVasily Gorbik 	*p++ = hex_asc_lo(psw->ext);
68724dc336SVasily Gorbik 	p = add_str(p, " Key:");
69724dc336SVasily Gorbik 	*p++ = hex_asc_lo(psw->key);
70724dc336SVasily Gorbik 	p = add_str(p, " M:");
71724dc336SVasily Gorbik 	*p++ = hex_asc_lo(psw->mcheck);
72724dc336SVasily Gorbik 	p = add_str(p, " W:");
73724dc336SVasily Gorbik 	*p++ = hex_asc_lo(psw->wait);
74724dc336SVasily Gorbik 	p = add_str(p, " P:");
75724dc336SVasily Gorbik 	*p++ = hex_asc_lo(psw->pstate);
76724dc336SVasily Gorbik 	p = add_str(p, " AS:");
77724dc336SVasily Gorbik 	*p++ = hex_asc_lo(psw->as);
78724dc336SVasily Gorbik 	p = add_str(p, " CC:");
79724dc336SVasily Gorbik 	*p++ = hex_asc_lo(psw->cc);
80724dc336SVasily Gorbik 	p = add_str(p, " PM:");
81724dc336SVasily Gorbik 	*p++ = hex_asc_lo(psw->pm);
82724dc336SVasily Gorbik 	p = add_str(p, " RI:");
83724dc336SVasily Gorbik 	*p++ = hex_asc_lo(psw->ri);
84724dc336SVasily Gorbik 	p = add_str(p, " EA:");
85724dc336SVasily Gorbik 	*p++ = hex_asc_lo(psw->eaba);
86724dc336SVasily Gorbik 	add_str(p, "\n");
87724dc336SVasily Gorbik 	sclp_early_printk(buf);
88724dc336SVasily Gorbik 
89724dc336SVasily Gorbik 	for (row = 0; row < 4; row++) {
90724dc336SVasily Gorbik 		p = add_str(buf, row == 0 ? "GPRS:" : "     ");
91724dc336SVasily Gorbik 		for (col = 0; col < 4; col++) {
92724dc336SVasily Gorbik 			p = add_str(p, " ");
93724dc336SVasily Gorbik 			p = add_val_as_hex(p, S390_lowcore.gpregs_save_area[row * 4 + col]);
94724dc336SVasily Gorbik 		}
95724dc336SVasily Gorbik 		add_str(p, "\n");
96724dc336SVasily Gorbik 		sclp_early_printk(buf);
97724dc336SVasily Gorbik 	}
98724dc336SVasily Gorbik }
99