master
h 168 lines 5 KB
Raw
1 /*
2 * Emulation of MPIPL (Memory Preserving Initial Program Load), aka fadump
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #ifndef PNV_MPIPL_H
8 #define PNV_MPIPL_H
9
10 #include <assert.h>
11 #include <stdbool.h>
12 #include <stdint.h>
13
14 #include "exec/hwaddr.h"
15 #include "qemu/compiler.h"
16
17 typedef struct MdstTableEntry MdstTableEntry;
18 typedef struct MdrtTableEntry MdrtTableEntry;
19 typedef struct MpiplPreservedState MpiplPreservedState;
20 typedef struct MpiplRegDataHdr MpiplRegDataHdr;
21 typedef struct MpiplRegEntry MpiplRegEntry;
22 typedef struct MpiplProcDumpArea MpiplProcDumpArea;
23 typedef struct MpiplPreservedCPUState MpiplPreservedCPUState;
24
25 /*
26 * Following offsets are copied from skiboot source code.
27 * These need to be updated if this changes in a future skiboot version
28 */
29 /* Use 768 bytes for SPIRAH */
30 #define SPIRAH_OFF 0x00010000
31 #define SPIRAH_SIZE 0x300
32
33 /* Use 256 bytes for processor dump area */
34 #define PROC_DUMP_AREA_OFF (SPIRAH_OFF + SPIRAH_SIZE)
35 #define PROC_DUMP_AREA_SIZE 0x100
36
37 #define PROCIN_OFF (PROC_DUMP_AREA_OFF + PROC_DUMP_AREA_SIZE)
38 #define PROCIN_SIZE 0x800
39
40 /* Offsets of MDST and MDDT tables from skiboot base */
41 #define MDST_TABLE_OFF (PROCIN_OFF + PROCIN_SIZE)
42 #define MDST_TABLE_SIZE 0x400
43
44 #define MDDT_TABLE_OFF (MDST_TABLE_OFF + MDST_TABLE_SIZE)
45 #define MDDT_TABLE_SIZE 0x400
46 /*
47 * Offset of the dump result table MDRT. Hostboot will write to this
48 * memory after moving memory content from source to destination memory.
49 */
50 #define MDRT_TABLE_OFF 0x01c00000
51 #define MDRT_TABLE_SIZE 0x00008000
52
53 /* HRMOR_BIT copied from skiboot */
54 #define HRMOR_BIT (1ull << 63)
55
56 #define NUM_REGS_PER_CPU 66 /*(32 GPRs, 34 SPRs)*/
57
58 /*
59 * Memory Dump Source Table (MDST)
60 *
61 * Format of this table is same as Memory Dump Source Table defined in HDAT
62 */
63 struct MdstTableEntry {
64 uint64_t addr;
65 uint8_t data_region;
66 uint8_t dump_type;
67 uint16_t reserved;
68 uint32_t size;
69 } QEMU_PACKED;
70
71 /* Memory dump destination table (MDDT) has same structure as MDST */
72 typedef MdstTableEntry MddtTableEntry;
73
74 /*
75 * Memory dump result table (MDRT)
76 *
77 * List of the memory ranges that have been included in the dump. This table is
78 * filled by hostboot and passed to OPAL on second boot. OPAL/payload will use
79 * this table to extract the dump.
80 *
81 * Note: This structure differs from HDAT, but matches the structure
82 * skiboot uses
83 */
84 struct MdrtTableEntry {
85 uint64_t src_addr;
86 uint64_t dest_addr;
87 uint8_t data_region;
88 uint8_t dump_type; /* unused */
89 uint16_t reserved; /* unused */
90 uint32_t size;
91 uint64_t padding; /* unused */
92 } QEMU_PACKED;
93
94 /* Maximum length of mdst/mddt/mdrt tables */
95 #define MDST_MAX_ENTRIES (MDST_TABLE_SIZE / sizeof(MdstTableEntry))
96 #define MDDT_MAX_ENTRIES (MDDT_TABLE_SIZE / sizeof(MddtTableEntry))
97 #define MDRT_MAX_ENTRIES (MDRT_TABLE_SIZE / sizeof(MdrtTableEntry))
98
99 static_assert(MDST_MAX_ENTRIES == MDDT_MAX_ENTRIES,
100 "Maximum entries in MDDT must match MDST");
101 static_assert(MDRT_MAX_ENTRIES >= MDST_MAX_ENTRIES,
102 "MDRT should support atleast having number of entries as in MDST");
103
104 /*
105 * Processor Dump Area
106 *
107 * This contains the information needed for having processor
108 * state captured during a platform dump.
109 *
110 * As mentioned in HDAT, following the P9 specific format
111 */
112 struct MpiplProcDumpArea {
113 uint32_t thread_size; /* Size of each thread register entry */
114 #define PROC_DUMP_AREA_VERSION_P9 0x1 /* P9 format */
115 uint8_t version;
116 uint8_t reserved[11];
117 uint64_t alloc_addr; /* Destination memory to place register data */
118 uint32_t reserved2;
119 uint32_t alloc_size; /* Allocated size */
120 uint64_t dest_addr; /* Destination address */
121 uint32_t reserved3;
122 uint32_t act_size; /* Actual data size */
123 } QEMU_PACKED;
124
125 /*
126 * "Architected Register Data" in the HDAT spec
127 *
128 * Acts as a header to the register entries for a particular thread
129 */
130 struct MpiplRegDataHdr {
131 uint32_t pir; /* PIR of thread */
132 uint8_t core_state; /* Stop state of the overall core */
133 uint8_t reserved[3];
134 uint32_t off_regentries; /* Offset to Register Entries Array */
135 uint32_t num_regentries; /* Number of Register Entries in Array */
136 uint32_t alloc_size; /* Allocated size for each Register Entry */
137 uint32_t act_size; /* Actual size for each Register Entry */
138 } QEMU_PACKED;
139
140 struct MpiplRegEntry {
141 uint32_t reg_type;
142 uint32_t reg_num;
143 uint64_t reg_val;
144 } QEMU_PACKED;
145
146 struct MpiplPreservedCPUState {
147 MpiplRegDataHdr hdr;
148
149 /* Length of 'reg_entries' is hdr.num_regentries */
150 MpiplRegEntry reg_entries[NUM_REGS_PER_CPU];
151 };
152
153 /* Preserved state to be saved in PnvMachineState */
154 struct MpiplPreservedState {
155 /* skiboot_base will be valid only after OPAL sends relocated base to SBE */
156 hwaddr skiboot_base;
157 bool is_next_boot_mpipl;
158
159 MdrtTableEntry *mdrt_table;
160 uint32_t num_mdrt_entries;
161
162 MpiplProcDumpArea proc_area;
163
164 MpiplPreservedCPUState *cpu_states;
165 uint32_t num_cpu_states;
166 };
167
168 #endif