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