1742a265aSHari Bathini /* SPDX-License-Identifier: GPL-2.0-or-later */ 2742a265aSHari Bathini /* 3742a265aSHari Bathini * Firmware-Assisted Dump support on POWER platform (OPAL). 4742a265aSHari Bathini * 5742a265aSHari Bathini * Copyright 2019, Hari Bathini, IBM Corporation. 6742a265aSHari Bathini */ 7742a265aSHari Bathini 8742a265aSHari Bathini #ifndef _POWERNV_OPAL_FADUMP_H 9742a265aSHari Bathini #define _POWERNV_OPAL_FADUMP_H 10742a265aSHari Bathini 116f713d18SHari Bathini #include <asm/reg.h> 126f713d18SHari Bathini 13742a265aSHari Bathini /* 14742a265aSHari Bathini * OPAL FADump metadata structure format version 15742a265aSHari Bathini * 16742a265aSHari Bathini * OPAL FADump kernel metadata structure stores kernel metadata needed to 17742a265aSHari Bathini * register-for/process crash dump. Format version is used to keep a tab on 18742a265aSHari Bathini * the changes in the structure format. The changes, if any, to the format 19742a265aSHari Bathini * are expected to be minimal and backward compatible. 20742a265aSHari Bathini */ 21742a265aSHari Bathini #define OPAL_FADUMP_VERSION 0x1 22742a265aSHari Bathini 23742a265aSHari Bathini /* Maximum number of memory regions kernel supports */ 24742a265aSHari Bathini #define OPAL_FADUMP_MAX_MEM_REGS 128 25742a265aSHari Bathini 26742a265aSHari Bathini /* 27742a265aSHari Bathini * OPAL FADump kernel metadata 28742a265aSHari Bathini * 29742a265aSHari Bathini * The address of this structure will be registered with f/w for retrieving 30742a265aSHari Bathini * and processing during crash dump. 31742a265aSHari Bathini */ 32742a265aSHari Bathini struct opal_fadump_mem_struct { 33742a265aSHari Bathini u8 version; 34742a265aSHari Bathini u8 reserved[3]; 35742a265aSHari Bathini u16 region_cnt; /* number of regions */ 36742a265aSHari Bathini u16 registered_regions; /* Regions registered for MPIPL */ 37742a265aSHari Bathini u64 fadumphdr_addr; 38742a265aSHari Bathini struct opal_mpipl_region rgn[OPAL_FADUMP_MAX_MEM_REGS]; 39742a265aSHari Bathini } __packed; 40742a265aSHari Bathini 415000a17aSHari Bathini /* 425000a17aSHari Bathini * CPU state data 435000a17aSHari Bathini * 445000a17aSHari Bathini * CPU state data information is provided by f/w. The format for this data 455000a17aSHari Bathini * is defined in the HDAT spec. Version is used to keep a tab on the changes 465000a17aSHari Bathini * in this CPU state data format. Changes to this format are unlikely, but 475000a17aSHari Bathini * if there are any changes, please refer to latest HDAT specification. 485000a17aSHari Bathini */ 495000a17aSHari Bathini #define HDAT_FADUMP_CPU_DATA_VER 1 505000a17aSHari Bathini 515000a17aSHari Bathini #define HDAT_FADUMP_CORE_INACTIVE (0x0F) 525000a17aSHari Bathini 535000a17aSHari Bathini /* HDAT thread header for register entries */ 545000a17aSHari Bathini struct hdat_fadump_thread_hdr { 555000a17aSHari Bathini __be32 pir; 565000a17aSHari Bathini /* 0x00 - 0x0F - The corresponding stop state of the core */ 575000a17aSHari Bathini u8 core_state; 585000a17aSHari Bathini u8 reserved[3]; 595000a17aSHari Bathini 605000a17aSHari Bathini __be32 offset; /* Offset to Register Entries array */ 615000a17aSHari Bathini __be32 ecnt; /* Number of entries */ 625000a17aSHari Bathini __be32 esize; /* Alloc size of each array entry in bytes */ 635000a17aSHari Bathini __be32 eactsz; /* Actual size of each array entry in bytes */ 645000a17aSHari Bathini } __packed; 655000a17aSHari Bathini 665000a17aSHari Bathini /* Register types populated by f/w */ 675000a17aSHari Bathini #define HDAT_FADUMP_REG_TYPE_GPR 0x01 685000a17aSHari Bathini #define HDAT_FADUMP_REG_TYPE_SPR 0x02 695000a17aSHari Bathini 705000a17aSHari Bathini /* ID numbers used by f/w while populating certain registers */ 715000a17aSHari Bathini #define HDAT_FADUMP_REG_ID_NIP 0x7D0 725000a17aSHari Bathini #define HDAT_FADUMP_REG_ID_MSR 0x7D1 735000a17aSHari Bathini #define HDAT_FADUMP_REG_ID_CCR 0x7D2 745000a17aSHari Bathini 755000a17aSHari Bathini /* HDAT register entry. */ 765000a17aSHari Bathini struct hdat_fadump_reg_entry { 775000a17aSHari Bathini __be32 reg_type; 785000a17aSHari Bathini __be32 reg_num; 795000a17aSHari Bathini __be64 reg_val; 805000a17aSHari Bathini } __packed; 815000a17aSHari Bathini 826f713d18SHari Bathini static inline void opal_fadump_set_regval_regnum(struct pt_regs *regs, 836f713d18SHari Bathini u32 reg_type, u32 reg_num, 846f713d18SHari Bathini u64 reg_val) 856f713d18SHari Bathini { 866f713d18SHari Bathini if (reg_type == HDAT_FADUMP_REG_TYPE_GPR) { 876f713d18SHari Bathini if (reg_num < 32) 886f713d18SHari Bathini regs->gpr[reg_num] = reg_val; 896f713d18SHari Bathini return; 906f713d18SHari Bathini } 916f713d18SHari Bathini 926f713d18SHari Bathini switch (reg_num) { 936f713d18SHari Bathini case SPRN_CTR: 946f713d18SHari Bathini regs->ctr = reg_val; 956f713d18SHari Bathini break; 966f713d18SHari Bathini case SPRN_LR: 976f713d18SHari Bathini regs->link = reg_val; 986f713d18SHari Bathini break; 996f713d18SHari Bathini case SPRN_XER: 1006f713d18SHari Bathini regs->xer = reg_val; 1016f713d18SHari Bathini break; 1026f713d18SHari Bathini case SPRN_DAR: 1036f713d18SHari Bathini regs->dar = reg_val; 1046f713d18SHari Bathini break; 1056f713d18SHari Bathini case SPRN_DSISR: 1066f713d18SHari Bathini regs->dsisr = reg_val; 1076f713d18SHari Bathini break; 1086f713d18SHari Bathini case HDAT_FADUMP_REG_ID_NIP: 1096f713d18SHari Bathini regs->nip = reg_val; 1106f713d18SHari Bathini break; 1116f713d18SHari Bathini case HDAT_FADUMP_REG_ID_MSR: 1126f713d18SHari Bathini regs->msr = reg_val; 1136f713d18SHari Bathini break; 1146f713d18SHari Bathini case HDAT_FADUMP_REG_ID_CCR: 1156f713d18SHari Bathini regs->ccr = reg_val; 1166f713d18SHari Bathini break; 1176f713d18SHari Bathini } 1186f713d18SHari Bathini } 1196f713d18SHari Bathini 1206f713d18SHari Bathini static inline void opal_fadump_read_regs(char *bufp, unsigned int regs_cnt, 1216f713d18SHari Bathini unsigned int reg_entry_size, 1226f713d18SHari Bathini bool cpu_endian, 1236f713d18SHari Bathini struct pt_regs *regs) 1246f713d18SHari Bathini { 1256f713d18SHari Bathini struct hdat_fadump_reg_entry *reg_entry; 1266f713d18SHari Bathini u64 val; 1276f713d18SHari Bathini int i; 1286f713d18SHari Bathini 1296f713d18SHari Bathini memset(regs, 0, sizeof(struct pt_regs)); 1306f713d18SHari Bathini 1316f713d18SHari Bathini for (i = 0; i < regs_cnt; i++, bufp += reg_entry_size) { 1326f713d18SHari Bathini reg_entry = (struct hdat_fadump_reg_entry *)bufp; 1336f713d18SHari Bathini val = (cpu_endian ? be64_to_cpu(reg_entry->reg_val) : 1346f713d18SHari Bathini reg_entry->reg_val); 1356f713d18SHari Bathini opal_fadump_set_regval_regnum(regs, 1366f713d18SHari Bathini be32_to_cpu(reg_entry->reg_type), 1376f713d18SHari Bathini be32_to_cpu(reg_entry->reg_num), 1386f713d18SHari Bathini val); 1396f713d18SHari Bathini } 1406f713d18SHari Bathini } 1416f713d18SHari Bathini 142742a265aSHari Bathini #endif /* _POWERNV_OPAL_FADUMP_H */ 143