xref: /openbmc/linux/arch/s390/boot/pgm_check_info.c (revision 70a59dd8)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/kernel.h>
3 #include <linux/string.h>
4 #include <asm/lowcore.h>
5 #include <asm/setup.h>
6 #include <asm/sclp.h>
7 #include "boot.h"
8 
9 const char hex_asc[] = "0123456789abcdef";
10 
11 #define add_val_as_hex(dst, val)					       \
12 	__add_val_as_hex(dst, (const unsigned char *)&val, sizeof(val))
13 
14 static char *__add_val_as_hex(char *dst, const unsigned char *src, size_t count)
15 {
16 	while (count--)
17 		dst = hex_byte_pack(dst, *src++);
18 	return dst;
19 }
20 
21 static char *add_str(char *dst, char *src)
22 {
23 	strcpy(dst, src);
24 	return dst + strlen(dst);
25 }
26 
27 void print_pgm_check_info(void)
28 {
29 	struct psw_bits *psw = &psw_bits(S390_lowcore.psw_save_area);
30 	unsigned short ilc = S390_lowcore.pgm_ilc >> 1;
31 	char buf[256];
32 	int row, col;
33 	char *p;
34 
35 	add_str(buf, "Linux version ");
36 	strlcat(buf, kernel_version, sizeof(buf) - 1);
37 	strlcat(buf, "\n", sizeof(buf));
38 	sclp_early_printk(buf);
39 
40 	p = add_str(buf, "Kernel fault: interruption code ");
41 	p = add_val_as_hex(buf + strlen(buf), S390_lowcore.pgm_code);
42 	p = add_str(p, " ilc:");
43 	*p++ = hex_asc_lo(ilc);
44 	add_str(p, "\n");
45 	sclp_early_printk(buf);
46 
47 	if (kaslr_enabled) {
48 		p = add_str(buf, "Kernel random base: ");
49 		p = add_val_as_hex(p, __kaslr_offset);
50 		add_str(p, "\n");
51 		sclp_early_printk(buf);
52 	}
53 
54 	p = add_str(buf, "PSW : ");
55 	p = add_val_as_hex(p, S390_lowcore.psw_save_area.mask);
56 	p = add_str(p, " ");
57 	p = add_val_as_hex(p, S390_lowcore.psw_save_area.addr);
58 	add_str(p, "\n");
59 	sclp_early_printk(buf);
60 
61 	p = add_str(buf, "      R:");
62 	*p++ = hex_asc_lo(psw->per);
63 	p = add_str(p, " T:");
64 	*p++ = hex_asc_lo(psw->dat);
65 	p = add_str(p, " IO:");
66 	*p++ = hex_asc_lo(psw->io);
67 	p = add_str(p, " EX:");
68 	*p++ = hex_asc_lo(psw->ext);
69 	p = add_str(p, " Key:");
70 	*p++ = hex_asc_lo(psw->key);
71 	p = add_str(p, " M:");
72 	*p++ = hex_asc_lo(psw->mcheck);
73 	p = add_str(p, " W:");
74 	*p++ = hex_asc_lo(psw->wait);
75 	p = add_str(p, " P:");
76 	*p++ = hex_asc_lo(psw->pstate);
77 	p = add_str(p, " AS:");
78 	*p++ = hex_asc_lo(psw->as);
79 	p = add_str(p, " CC:");
80 	*p++ = hex_asc_lo(psw->cc);
81 	p = add_str(p, " PM:");
82 	*p++ = hex_asc_lo(psw->pm);
83 	p = add_str(p, " RI:");
84 	*p++ = hex_asc_lo(psw->ri);
85 	p = add_str(p, " EA:");
86 	*p++ = hex_asc_lo(psw->eaba);
87 	add_str(p, "\n");
88 	sclp_early_printk(buf);
89 
90 	for (row = 0; row < 4; row++) {
91 		p = add_str(buf, row == 0 ? "GPRS:" : "     ");
92 		for (col = 0; col < 4; col++) {
93 			p = add_str(p, " ");
94 			p = add_val_as_hex(p, S390_lowcore.gpregs_save_area[row * 4 + col]);
95 		}
96 		add_str(p, "\n");
97 		sclp_early_printk(buf);
98 	}
99 }
100