opal-fadump.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * Firmware-Assisted Dump support on POWER platform (OPAL).
  4. *
  5. * Copyright 2019, Hari Bathini, IBM Corporation.
  6. */
  7. #ifndef _POWERNV_OPAL_FADUMP_H
  8. #define _POWERNV_OPAL_FADUMP_H
  9. #include <asm/reg.h>
  10. /*
  11. * With kernel & initrd loaded at 512MB (with 256MB size), enforce a minimum
  12. * boot memory size of 768MB to ensure f/w loading kernel and initrd doesn't
  13. * mess with crash'ed kernel's memory during MPIPL.
  14. */
  15. #define OPAL_FADUMP_MIN_BOOT_MEM (0x30000000UL)
  16. /*
  17. * OPAL FADump metadata structure format version
  18. *
  19. * OPAL FADump kernel metadata structure stores kernel metadata needed to
  20. * register-for/process crash dump. Format version is used to keep a tab on
  21. * the changes in the structure format. The changes, if any, to the format
  22. * are expected to be minimal and backward compatible.
  23. */
  24. #define OPAL_FADUMP_VERSION 0x1
  25. /*
  26. * OPAL FADump kernel metadata
  27. *
  28. * The address of this structure will be registered with f/w for retrieving
  29. * in the capture kernel to process the crash dump.
  30. */
  31. struct opal_fadump_mem_struct {
  32. u8 version;
  33. u8 reserved[3];
  34. __be16 region_cnt; /* number of regions */
  35. __be16 registered_regions; /* Regions registered for MPIPL */
  36. __be64 fadumphdr_addr;
  37. struct opal_mpipl_region rgn[FADUMP_MAX_MEM_REGS];
  38. } __packed;
  39. /*
  40. * CPU state data
  41. *
  42. * CPU state data information is provided by f/w. The format for this data
  43. * is defined in the HDAT spec. Version is used to keep a tab on the changes
  44. * in this CPU state data format. Changes to this format are unlikely, but
  45. * if there are any changes, please refer to latest HDAT specification.
  46. */
  47. #define HDAT_FADUMP_CPU_DATA_VER 1
  48. #define HDAT_FADUMP_CORE_INACTIVE (0x0F)
  49. /* HDAT thread header for register entries */
  50. struct hdat_fadump_thread_hdr {
  51. __be32 pir;
  52. /* 0x00 - 0x0F - The corresponding stop state of the core */
  53. u8 core_state;
  54. u8 reserved[3];
  55. __be32 offset; /* Offset to Register Entries array */
  56. __be32 ecnt; /* Number of entries */
  57. __be32 esize; /* Alloc size of each array entry in bytes */
  58. __be32 eactsz; /* Actual size of each array entry in bytes */
  59. } __packed;
  60. /* Register types populated by f/w */
  61. #define HDAT_FADUMP_REG_TYPE_GPR 0x01
  62. #define HDAT_FADUMP_REG_TYPE_SPR 0x02
  63. /* ID numbers used by f/w while populating certain registers */
  64. #define HDAT_FADUMP_REG_ID_NIP 0x7D0
  65. #define HDAT_FADUMP_REG_ID_MSR 0x7D1
  66. #define HDAT_FADUMP_REG_ID_CCR 0x7D2
  67. /* HDAT register entry. */
  68. struct hdat_fadump_reg_entry {
  69. __be32 reg_type;
  70. __be32 reg_num;
  71. __be64 reg_val;
  72. } __packed;
  73. static inline void opal_fadump_set_regval_regnum(struct pt_regs *regs,
  74. u32 reg_type, u32 reg_num,
  75. u64 reg_val)
  76. {
  77. if (reg_type == HDAT_FADUMP_REG_TYPE_GPR) {
  78. if (reg_num < 32)
  79. regs->gpr[reg_num] = reg_val;
  80. return;
  81. }
  82. switch (reg_num) {
  83. case SPRN_CTR:
  84. regs->ctr = reg_val;
  85. break;
  86. case SPRN_LR:
  87. regs->link = reg_val;
  88. break;
  89. case SPRN_XER:
  90. regs->xer = reg_val;
  91. break;
  92. case SPRN_DAR:
  93. regs->dar = reg_val;
  94. break;
  95. case SPRN_DSISR:
  96. regs->dsisr = reg_val;
  97. break;
  98. case HDAT_FADUMP_REG_ID_NIP:
  99. regs->nip = reg_val;
  100. break;
  101. case HDAT_FADUMP_REG_ID_MSR:
  102. regs->msr = reg_val;
  103. break;
  104. case HDAT_FADUMP_REG_ID_CCR:
  105. regs->ccr = reg_val;
  106. break;
  107. }
  108. }
  109. static inline void opal_fadump_read_regs(char *bufp, unsigned int regs_cnt,
  110. unsigned int reg_entry_size,
  111. bool cpu_endian,
  112. struct pt_regs *regs)
  113. {
  114. struct hdat_fadump_reg_entry *reg_entry;
  115. u64 val;
  116. int i;
  117. memset(regs, 0, sizeof(struct pt_regs));
  118. for (i = 0; i < regs_cnt; i++, bufp += reg_entry_size) {
  119. reg_entry = (struct hdat_fadump_reg_entry *)bufp;
  120. val = (cpu_endian ? be64_to_cpu(reg_entry->reg_val) :
  121. (u64)(reg_entry->reg_val));
  122. opal_fadump_set_regval_regnum(regs,
  123. be32_to_cpu(reg_entry->reg_type),
  124. be32_to_cpu(reg_entry->reg_num),
  125. val);
  126. }
  127. }
  128. #endif /* _POWERNV_OPAL_FADUMP_H */