18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <linux/kernel.h> 38c2ecf20Sopenharmony_ci#include <linux/string.h> 48c2ecf20Sopenharmony_ci#include <asm/lowcore.h> 58c2ecf20Sopenharmony_ci#include <asm/setup.h> 68c2ecf20Sopenharmony_ci#include <asm/sclp.h> 78c2ecf20Sopenharmony_ci#include "boot.h" 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ciconst char hex_asc[] = "0123456789abcdef"; 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#define add_val_as_hex(dst, val) \ 128c2ecf20Sopenharmony_ci __add_val_as_hex(dst, (const unsigned char *)&val, sizeof(val)) 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic char *__add_val_as_hex(char *dst, const unsigned char *src, size_t count) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci while (count--) 178c2ecf20Sopenharmony_ci dst = hex_byte_pack(dst, *src++); 188c2ecf20Sopenharmony_ci return dst; 198c2ecf20Sopenharmony_ci} 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistatic char *add_str(char *dst, char *src) 228c2ecf20Sopenharmony_ci{ 238c2ecf20Sopenharmony_ci strcpy(dst, src); 248c2ecf20Sopenharmony_ci return dst + strlen(dst); 258c2ecf20Sopenharmony_ci} 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_civoid print_pgm_check_info(void) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci struct psw_bits *psw = &psw_bits(S390_lowcore.psw_save_area); 308c2ecf20Sopenharmony_ci unsigned short ilc = S390_lowcore.pgm_ilc >> 1; 318c2ecf20Sopenharmony_ci char buf[256]; 328c2ecf20Sopenharmony_ci int row, col; 338c2ecf20Sopenharmony_ci char *p; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci add_str(buf, "Linux version "); 368c2ecf20Sopenharmony_ci strlcat(buf, kernel_version, sizeof(buf) - 1); 378c2ecf20Sopenharmony_ci strlcat(buf, "\n", sizeof(buf)); 388c2ecf20Sopenharmony_ci sclp_early_printk(buf); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci p = add_str(buf, "Kernel fault: interruption code "); 418c2ecf20Sopenharmony_ci p = add_val_as_hex(buf + strlen(buf), S390_lowcore.pgm_code); 428c2ecf20Sopenharmony_ci p = add_str(p, " ilc:"); 438c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(ilc); 448c2ecf20Sopenharmony_ci add_str(p, "\n"); 458c2ecf20Sopenharmony_ci sclp_early_printk(buf); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci if (kaslr_enabled) { 488c2ecf20Sopenharmony_ci p = add_str(buf, "Kernel random base: "); 498c2ecf20Sopenharmony_ci p = add_val_as_hex(p, __kaslr_offset); 508c2ecf20Sopenharmony_ci add_str(p, "\n"); 518c2ecf20Sopenharmony_ci sclp_early_printk(buf); 528c2ecf20Sopenharmony_ci } 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci p = add_str(buf, "PSW : "); 558c2ecf20Sopenharmony_ci p = add_val_as_hex(p, S390_lowcore.psw_save_area.mask); 568c2ecf20Sopenharmony_ci p = add_str(p, " "); 578c2ecf20Sopenharmony_ci p = add_val_as_hex(p, S390_lowcore.psw_save_area.addr); 588c2ecf20Sopenharmony_ci add_str(p, "\n"); 598c2ecf20Sopenharmony_ci sclp_early_printk(buf); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci p = add_str(buf, " R:"); 628c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(psw->per); 638c2ecf20Sopenharmony_ci p = add_str(p, " T:"); 648c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(psw->dat); 658c2ecf20Sopenharmony_ci p = add_str(p, " IO:"); 668c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(psw->io); 678c2ecf20Sopenharmony_ci p = add_str(p, " EX:"); 688c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(psw->ext); 698c2ecf20Sopenharmony_ci p = add_str(p, " Key:"); 708c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(psw->key); 718c2ecf20Sopenharmony_ci p = add_str(p, " M:"); 728c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(psw->mcheck); 738c2ecf20Sopenharmony_ci p = add_str(p, " W:"); 748c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(psw->wait); 758c2ecf20Sopenharmony_ci p = add_str(p, " P:"); 768c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(psw->pstate); 778c2ecf20Sopenharmony_ci p = add_str(p, " AS:"); 788c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(psw->as); 798c2ecf20Sopenharmony_ci p = add_str(p, " CC:"); 808c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(psw->cc); 818c2ecf20Sopenharmony_ci p = add_str(p, " PM:"); 828c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(psw->pm); 838c2ecf20Sopenharmony_ci p = add_str(p, " RI:"); 848c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(psw->ri); 858c2ecf20Sopenharmony_ci p = add_str(p, " EA:"); 868c2ecf20Sopenharmony_ci *p++ = hex_asc_lo(psw->eaba); 878c2ecf20Sopenharmony_ci add_str(p, "\n"); 888c2ecf20Sopenharmony_ci sclp_early_printk(buf); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci for (row = 0; row < 4; row++) { 918c2ecf20Sopenharmony_ci p = add_str(buf, row == 0 ? "GPRS:" : " "); 928c2ecf20Sopenharmony_ci for (col = 0; col < 4; col++) { 938c2ecf20Sopenharmony_ci p = add_str(p, " "); 948c2ecf20Sopenharmony_ci p = add_val_as_hex(p, S390_lowcore.gpregs_save_area[row * 4 + col]); 958c2ecf20Sopenharmony_ci } 968c2ecf20Sopenharmony_ci add_str(p, "\n"); 978c2ecf20Sopenharmony_ci sclp_early_printk(buf); 988c2ecf20Sopenharmony_ci } 998c2ecf20Sopenharmony_ci} 100