blob: 089a7bb4e78cb8b9378b64f497b653276211ca27 [file] [log] [blame]
Lawrence Tang7f21db62022-07-06 11:09:39 +01001/**
2 * Describes functions for converting memory error CPER sections from binary and JSON format
3 * into an intermediate format.
4 *
5 * Author: Lawrence.Tang@arm.com
6 **/
7#include <stdio.h>
8#include "json.h"
9#include "../edk/Cper.h"
10#include "../cper-utils.h"
11#include "cper-section-memory.h"
12
13//Converts a single memory error CPER section into JSON IR.
Lawrence Tanga0865e32022-07-06 11:59:52 +010014json_object* cper_section_platform_memory_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor)
Lawrence Tang7f21db62022-07-06 11:09:39 +010015{
16 EFI_PLATFORM_MEMORY_ERROR_DATA* memory_error = (EFI_PLATFORM_MEMORY_ERROR_DATA*)section;
17 json_object* section_ir = json_object_new_object();
18
19 //Validation bitfield.
20 json_object* validation = bitfield_to_ir(memory_error->ValidFields, 22, MEMORY_ERROR_VALID_BITFIELD_NAMES);
21 json_object_object_add(section_ir, "validationBits", validation);
22
23 //Error status.
Lawrence Tanga0865e32022-07-06 11:59:52 +010024 json_object* error_status = cper_generic_error_status_to_ir(&memory_error->ErrorStatus);
25 json_object_object_add(section_ir, "errorStatus", error_status);
26
Lawrence Tanga0865e32022-07-06 11:59:52 +010027 //Bank.
28 json_object* bank = json_object_new_object();
Lawrence Tang583cdee2022-07-11 14:31:11 +010029 if ((memory_error->ValidFields >> 5) & 0x1)
30 {
31 //Entire bank address mode.
32 json_object_object_add(bank, "value", json_object_new_uint64(memory_error->Bank));
33 }
34 else
35 {
36 //Address/group address mode.
37 json_object_object_add(bank, "address", json_object_new_uint64(memory_error->Bank & 0xFF));
38 json_object_object_add(bank, "group", json_object_new_uint64(memory_error->Bank >> 8));
39 }
Lawrence Tanga0865e32022-07-06 11:59:52 +010040 json_object_object_add(section_ir, "bank", bank);
41
42 //Memory error type.
43 json_object* memory_error_type = integer_to_readable_pair(memory_error->ErrorType, 16,
44 MEMORY_ERROR_TYPES_KEYS,
45 MEMORY_ERROR_TYPES_VALUES,
46 "Unknown (Reserved)");
47 json_object_object_add(section_ir, "memoryErrorType", memory_error_type);
48
49 //"Extended" row/column indication field + misc.
50 json_object* extended = json_object_new_object();
51 json_object_object_add(extended, "rowBit16", json_object_new_boolean(memory_error->Extended & 0b1));
52 json_object_object_add(extended, "rowBit17", json_object_new_boolean((memory_error->Extended >> 1) & 0b1));
53 json_object_object_add(extended, "chipIdentification", json_object_new_int(memory_error->Extended >> 5));
54 json_object_object_add(section_ir, "extended", extended);
55
Lawrence Tang54da4412022-07-06 13:14:58 +010056 //Miscellaneous numeric fields.
57 json_object_object_add(section_ir, "physicalAddress", json_object_new_uint64(memory_error->PhysicalAddress));
58 json_object_object_add(section_ir, "physicalAddressMask", json_object_new_uint64(memory_error->PhysicalAddressMask));
59 json_object_object_add(section_ir, "node", json_object_new_uint64(memory_error->Node));
60 json_object_object_add(section_ir, "card", json_object_new_uint64(memory_error->Card));
61 json_object_object_add(section_ir, "moduleRank", json_object_new_uint64(memory_error->ModuleRank));
62 json_object_object_add(section_ir, "device", json_object_new_uint64(memory_error->Device));
63 json_object_object_add(section_ir, "row", json_object_new_uint64(memory_error->Row));
64 json_object_object_add(section_ir, "column", json_object_new_uint64(memory_error->Column));
65 json_object_object_add(section_ir, "bitPosition", json_object_new_uint64(memory_error->BitPosition));
66 json_object_object_add(section_ir, "requestorID", json_object_new_uint64(memory_error->RequestorId));
67 json_object_object_add(section_ir, "responderID", json_object_new_uint64(memory_error->ResponderId));
68 json_object_object_add(section_ir, "targetID", json_object_new_uint64(memory_error->TargetId));
69 json_object_object_add(section_ir, "rankNumber", json_object_new_uint64(memory_error->RankNum));
70 json_object_object_add(section_ir, "cardSmbiosHandle", json_object_new_uint64(memory_error->CardHandle));
71 json_object_object_add(section_ir, "moduleSmbiosHandle", json_object_new_uint64(memory_error->ModuleHandle));
72
Lawrence Tanga0865e32022-07-06 11:59:52 +010073 return section_ir;
74}
75
76//Converts a single memory error 2 CPER section into JSON IR.
77json_object* cper_section_platform_memory2_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor)
78{
79 EFI_PLATFORM_MEMORY2_ERROR_DATA* memory_error = (EFI_PLATFORM_MEMORY2_ERROR_DATA*)section;
80 json_object* section_ir = json_object_new_object();
81
Lawrence Tang54da4412022-07-06 13:14:58 +010082 //Validation bits.
83 json_object* validation = bitfield_to_ir(memory_error->ValidFields, 22, MEMORY_ERROR_2_VALID_BITFIELD_NAMES);
84 json_object_object_add(section_ir, "validationBits", validation);
Lawrence Tanga0865e32022-07-06 11:59:52 +010085
Lawrence Tang54da4412022-07-06 13:14:58 +010086 //Error status.
87 json_object* error_status = cper_generic_error_status_to_ir(&memory_error->ErrorStatus);
88 json_object_object_add(section_ir, "errorStatus", error_status);
89
90 //Bank.
91 json_object* bank = json_object_new_object();
Lawrence Tang583cdee2022-07-11 14:31:11 +010092 if ((memory_error->ValidFields >> 5) & 0x1)
93 {
94 //Entire bank address mode.
95 json_object_object_add(bank, "value", json_object_new_uint64(memory_error->Bank));
96 }
97 else
98 {
99 //Address/group address mode.
100 json_object_object_add(bank, "address", json_object_new_uint64(memory_error->Bank & 0xFF));
101 json_object_object_add(bank, "group", json_object_new_uint64(memory_error->Bank >> 8));
102 }
Lawrence Tang54da4412022-07-06 13:14:58 +0100103 json_object_object_add(section_ir, "bank", bank);
104
105 //Memory error type.
106 json_object* memory_error_type = integer_to_readable_pair(memory_error->MemErrorType, 16,
107 MEMORY_ERROR_TYPES_KEYS,
108 MEMORY_ERROR_TYPES_VALUES,
109 "Unknown (Reserved)");
110 json_object_object_add(section_ir, "memoryErrorType", memory_error_type);
111
112 //Status.
113 json_object* status = json_object_new_object();
114 json_object_object_add(status, "value", json_object_new_int(memory_error->Status));
115 json_object_object_add(status, "state", json_object_new_string(memory_error->Status & 0b1 == 0 ? "Corrected" : "Uncorrected"));
116 json_object_object_add(section_ir, "status", status);
117
118 //Miscellaneous numeric fields.
119 json_object_object_add(section_ir, "physicalAddress", json_object_new_uint64(memory_error->PhysicalAddress));
120 json_object_object_add(section_ir, "physicalAddressMask", json_object_new_uint64(memory_error->PhysicalAddressMask));
121 json_object_object_add(section_ir, "node", json_object_new_uint64(memory_error->Node));
122 json_object_object_add(section_ir, "card", json_object_new_uint64(memory_error->Card));
123 json_object_object_add(section_ir, "module", json_object_new_uint64(memory_error->Module));
124 json_object_object_add(section_ir, "device", json_object_new_uint64(memory_error->Device));
125 json_object_object_add(section_ir, "row", json_object_new_uint64(memory_error->Row));
126 json_object_object_add(section_ir, "column", json_object_new_uint64(memory_error->Column));
127 json_object_object_add(section_ir, "rank", json_object_new_uint64(memory_error->Rank));
128 json_object_object_add(section_ir, "bitPosition", json_object_new_uint64(memory_error->BitPosition));
129 json_object_object_add(section_ir, "chipID", json_object_new_uint64(memory_error->ChipId));
130 json_object_object_add(section_ir, "requestorID", json_object_new_uint64(memory_error->RequestorId));
131 json_object_object_add(section_ir, "responderID", json_object_new_uint64(memory_error->ResponderId));
132 json_object_object_add(section_ir, "targetID", json_object_new_uint64(memory_error->TargetId));
133 json_object_object_add(section_ir, "cardSmbiosHandle", json_object_new_uint64(memory_error->CardHandle));
134 json_object_object_add(section_ir, "moduleSmbiosHandle", json_object_new_uint64(memory_error->ModuleHandle));
135
Lawrence Tanga0865e32022-07-06 11:59:52 +0100136 return section_ir;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100137}
138
139//Converts a single Memory Error IR section into CPER binary, outputting to the provided stream.
140void ir_section_memory_to_cper(json_object* section, FILE* out)
141{
142 EFI_PLATFORM_MEMORY_ERROR_DATA* section_cper =
143 (EFI_PLATFORM_MEMORY_ERROR_DATA*)calloc(1, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA));
144
145 //Validation bits.
146 section_cper->ValidFields = ir_to_bitfield(json_object_object_get(section, "validationBits"),
147 22, MEMORY_ERROR_VALID_BITFIELD_NAMES);
148
149 //Error status.
150 ir_generic_error_status_to_cper(json_object_object_get(section, "errorStatus"), &section_cper->ErrorStatus);
151
152 //Bank.
153 json_object* bank = json_object_object_get(section, "bank");
154 if ((section_cper->ValidFields >> 5) & 0x1)
155 {
156 //Bank just uses simple address.
157 section_cper->Bank = (UINT16)json_object_get_uint64(json_object_object_get(bank, "value"));
158 }
159 else
160 {
161 //Bank uses address/group style address.
162 UINT16 address = (UINT8)json_object_get_uint64(json_object_object_get(bank, "address"));
163 UINT16 group = (UINT8)json_object_get_uint64(json_object_object_get(bank, "group"));
164 section_cper->Bank = address + (group << 8);
165 }
166
167 //"Extended" field.
168 json_object* extended = json_object_object_get(section, "extended");
169 section_cper->Extended = 0;
170 section_cper->Extended |= json_object_get_boolean(json_object_object_get(extended, "rowBit16"));
171 section_cper->Extended |= json_object_get_boolean(json_object_object_get(extended, "rowBit17")) << 1;
172 section_cper->Extended |= json_object_get_int(json_object_object_get(extended, "chipIdentification")) << 5;
173
174 //Miscellaneous value fields.
175 section_cper->ErrorType = readable_pair_to_integer(json_object_object_get(section, "memoryErrorType"));
176 section_cper->PhysicalAddress = json_object_get_uint64(json_object_object_get(section, "physicalAddress"));
177 section_cper->PhysicalAddressMask = json_object_get_uint64(json_object_object_get(section, "physicalAddressMask"));
178 section_cper->Node = (UINT16)json_object_get_uint64(json_object_object_get(section, "node"));
179 section_cper->Card = (UINT16)json_object_get_uint64(json_object_object_get(section, "card"));
180 section_cper->ModuleRank = (UINT16)json_object_get_uint64(json_object_object_get(section, "moduleRank"));
181 section_cper->Device = (UINT16)json_object_get_uint64(json_object_object_get(section, "device"));
182 section_cper->Row = (UINT16)json_object_get_uint64(json_object_object_get(section, "row"));
183 section_cper->Column = (UINT16)json_object_get_uint64(json_object_object_get(section, "column"));
184 section_cper->BitPosition = (UINT16)json_object_get_uint64(json_object_object_get(section, "bitPosition"));
185 section_cper->RequestorId = json_object_get_uint64(json_object_object_get(section, "requestorID"));
186 section_cper->ResponderId = json_object_get_uint64(json_object_object_get(section, "responderID"));
187 section_cper->TargetId = json_object_get_uint64(json_object_object_get(section, "targetID"));
188 section_cper->RankNum = (UINT16)json_object_get_uint64(json_object_object_get(section, "rankNumber"));
189 section_cper->CardHandle = (UINT16)json_object_get_uint64(json_object_object_get(section, "cardSmbiosHandle"));
190 section_cper->ModuleHandle = (UINT16)json_object_get_uint64(json_object_object_get(section, "moduleSmbiosHandle"));
191
192 //Write to stream, free up resources.
193 fwrite(&section_cper, sizeof(section_cper), 1, out);
194 fflush(out);
195 free(section_cper);
196}
197
198//Converts a single Memory Error 2 IR section into CPER binary, outputting to the provided stream.
199void ir_section_memory2_to_cper(json_object* section, FILE* out)
200{
201 EFI_PLATFORM_MEMORY2_ERROR_DATA* section_cper =
202 (EFI_PLATFORM_MEMORY2_ERROR_DATA*)calloc(1, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA));
203
204 //Validation bits.
205 section_cper->ValidFields = ir_to_bitfield(json_object_object_get(section, "validationBits"),
206 22, MEMORY_ERROR_2_VALID_BITFIELD_NAMES);
207
208 //Error status.
209 ir_generic_error_status_to_cper(json_object_object_get(section, "errorStatus"), &section_cper->ErrorStatus);
210
211 //Bank.
212 json_object* bank = json_object_object_get(section, "bank");
213 if ((section_cper->ValidFields >> 5) & 0x1)
214 {
215 //Bank just uses simple address.
216 section_cper->Bank = (UINT16)json_object_get_uint64(json_object_object_get(bank, "value"));
217 }
218 else
219 {
220 //Bank uses address/group style address.
221 UINT16 address = (UINT8)json_object_get_uint64(json_object_object_get(bank, "address"));
222 UINT16 group = (UINT8)json_object_get_uint64(json_object_object_get(bank, "group"));
223 section_cper->Bank = address + (group << 8);
224 }
225
226 //Miscellaneous value fields.
227 section_cper->MemErrorType = readable_pair_to_integer(json_object_object_get(section, "memoryErrorType"));
228 section_cper->Status = (UINT8)readable_pair_to_integer(json_object_object_get(section, "status"));
229 section_cper->PhysicalAddress = json_object_get_uint64(json_object_object_get(section, "physicalAddress"));
230 section_cper->PhysicalAddressMask = json_object_get_uint64(json_object_object_get(section, "physicalAddressMask"));
231 section_cper->Node = (UINT16)json_object_get_uint64(json_object_object_get(section, "node"));
232 section_cper->Card = (UINT16)json_object_get_uint64(json_object_object_get(section, "card"));
233 section_cper->Module = (UINT32)json_object_get_uint64(json_object_object_get(section, "module"));
234 section_cper->Device = (UINT32)json_object_get_uint64(json_object_object_get(section, "device"));
235 section_cper->Row = (UINT32)json_object_get_uint64(json_object_object_get(section, "row"));
236 section_cper->Column = (UINT32)json_object_get_uint64(json_object_object_get(section, "column"));
237 section_cper->Rank = (UINT32)json_object_get_uint64(json_object_object_get(section, "rank"));
238 section_cper->BitPosition = (UINT32)json_object_get_uint64(json_object_object_get(section, "bitPosition"));
239 section_cper->ChipId = (UINT8)json_object_get_uint64(json_object_object_get(section, "chipID"));
240 section_cper->RequestorId = json_object_get_uint64(json_object_object_get(section, "requestorID"));
241 section_cper->ResponderId = json_object_get_uint64(json_object_object_get(section, "responderID"));
242 section_cper->TargetId = json_object_get_uint64(json_object_object_get(section, "targetID"));
243 section_cper->CardHandle = (UINT32)json_object_get_uint64(json_object_object_get(section, "cardSmbiosHandle"));
244 section_cper->ModuleHandle = (UINT32)json_object_get_uint64(json_object_object_get(section, "moduleSmbiosHandle"));
245
246 //Write to stream, free up resources.
247 fwrite(&section_cper, sizeof(section_cper), 1, out);
248 fflush(out);
249 free(section_cper);
Lawrence Tang7f21db62022-07-06 11:09:39 +0100250}