0001
0002
0003
0004
0005
0006
0007
0008 #ifndef _POWERNV_OPAL_FADUMP_H
0009 #define _POWERNV_OPAL_FADUMP_H
0010
0011 #include <asm/reg.h>
0012
0013
0014
0015
0016
0017
0018 #define OPAL_FADUMP_MIN_BOOT_MEM (0x30000000UL)
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #define OPAL_FADUMP_VERSION 0x1
0029
0030
0031
0032
0033
0034
0035
0036 struct opal_fadump_mem_struct {
0037 u8 version;
0038 u8 reserved[3];
0039 __be16 region_cnt;
0040 __be16 registered_regions;
0041 __be64 fadumphdr_addr;
0042 struct opal_mpipl_region rgn[FADUMP_MAX_MEM_REGS];
0043 } __packed;
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 #define HDAT_FADUMP_CPU_DATA_VER 1
0054
0055 #define HDAT_FADUMP_CORE_INACTIVE (0x0F)
0056
0057
0058 struct hdat_fadump_thread_hdr {
0059 __be32 pir;
0060
0061 u8 core_state;
0062 u8 reserved[3];
0063
0064 __be32 offset;
0065 __be32 ecnt;
0066 __be32 esize;
0067 __be32 eactsz;
0068 } __packed;
0069
0070
0071 #define HDAT_FADUMP_REG_TYPE_GPR 0x01
0072 #define HDAT_FADUMP_REG_TYPE_SPR 0x02
0073
0074
0075 #define HDAT_FADUMP_REG_ID_NIP 0x7D0
0076 #define HDAT_FADUMP_REG_ID_MSR 0x7D1
0077 #define HDAT_FADUMP_REG_ID_CCR 0x7D2
0078
0079
0080 struct hdat_fadump_reg_entry {
0081 __be32 reg_type;
0082 __be32 reg_num;
0083 __be64 reg_val;
0084 } __packed;
0085
0086 static inline void opal_fadump_set_regval_regnum(struct pt_regs *regs,
0087 u32 reg_type, u32 reg_num,
0088 u64 reg_val)
0089 {
0090 if (reg_type == HDAT_FADUMP_REG_TYPE_GPR) {
0091 if (reg_num < 32)
0092 regs->gpr[reg_num] = reg_val;
0093 return;
0094 }
0095
0096 switch (reg_num) {
0097 case SPRN_CTR:
0098 regs->ctr = reg_val;
0099 break;
0100 case SPRN_LR:
0101 regs->link = reg_val;
0102 break;
0103 case SPRN_XER:
0104 regs->xer = reg_val;
0105 break;
0106 case SPRN_DAR:
0107 regs->dar = reg_val;
0108 break;
0109 case SPRN_DSISR:
0110 regs->dsisr = reg_val;
0111 break;
0112 case HDAT_FADUMP_REG_ID_NIP:
0113 regs->nip = reg_val;
0114 break;
0115 case HDAT_FADUMP_REG_ID_MSR:
0116 regs->msr = reg_val;
0117 break;
0118 case HDAT_FADUMP_REG_ID_CCR:
0119 regs->ccr = reg_val;
0120 break;
0121 }
0122 }
0123
0124 static inline void opal_fadump_read_regs(char *bufp, unsigned int regs_cnt,
0125 unsigned int reg_entry_size,
0126 bool cpu_endian,
0127 struct pt_regs *regs)
0128 {
0129 struct hdat_fadump_reg_entry *reg_entry;
0130 u64 val;
0131 int i;
0132
0133 memset(regs, 0, sizeof(struct pt_regs));
0134
0135 for (i = 0; i < regs_cnt; i++, bufp += reg_entry_size) {
0136 reg_entry = (struct hdat_fadump_reg_entry *)bufp;
0137 val = (cpu_endian ? be64_to_cpu(reg_entry->reg_val) :
0138 (u64)(reg_entry->reg_val));
0139 opal_fadump_set_regval_regnum(regs,
0140 be32_to_cpu(reg_entry->reg_type),
0141 be32_to_cpu(reg_entry->reg_num),
0142 val);
0143 }
0144 }
0145
0146 #endif