Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 1 | /** |
| 2 | * Describes utility functions for parsing CPER into JSON IR. |
| 3 | * |
| 4 | * Author: Lawrence.Tang@arm.com |
| 5 | **/ |
| 6 | |
| 7 | #include <stdio.h> |
| 8 | #include "json.h" |
| 9 | #include "edk/Cper.h" |
| 10 | #include "cper-utils.h" |
| 11 | |
| 12 | //The available severity types for CPER. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 13 | const char *CPER_SEVERITY_TYPES[4] = { "Recoverable", "Fatal", "Corrected", |
| 14 | "Informational" }; |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 15 | |
Lawrence Tang | a0865e3 | 2022-07-06 11:59:52 +0100 | [diff] [blame] | 16 | //Converts the given generic CPER error status to JSON IR. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 17 | json_object * |
| 18 | cper_generic_error_status_to_ir(EFI_GENERIC_ERROR_STATUS *error_status) |
Lawrence Tang | a0865e3 | 2022-07-06 11:59:52 +0100 | [diff] [blame] | 19 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 20 | json_object *error_status_ir = json_object_new_object(); |
Lawrence Tang | a0865e3 | 2022-07-06 11:59:52 +0100 | [diff] [blame] | 21 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 22 | //Error type. |
| 23 | json_object_object_add(error_status_ir, "errorType", |
| 24 | integer_to_readable_pair_with_desc( |
| 25 | error_status->Type, 18, |
| 26 | CPER_GENERIC_ERROR_TYPES_KEYS, |
| 27 | CPER_GENERIC_ERROR_TYPES_VALUES, |
| 28 | CPER_GENERIC_ERROR_TYPES_DESCRIPTIONS, |
| 29 | "Unknown (Reserved)")); |
Lawrence Tang | a0865e3 | 2022-07-06 11:59:52 +0100 | [diff] [blame] | 30 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 31 | //Boolean bit fields. |
| 32 | json_object_object_add( |
| 33 | error_status_ir, "addressSignal", |
| 34 | json_object_new_boolean(error_status->AddressSignal)); |
| 35 | json_object_object_add( |
| 36 | error_status_ir, "controlSignal", |
| 37 | json_object_new_boolean(error_status->ControlSignal)); |
| 38 | json_object_object_add( |
| 39 | error_status_ir, "dataSignal", |
| 40 | json_object_new_boolean(error_status->DataSignal)); |
| 41 | json_object_object_add( |
| 42 | error_status_ir, "detectedByResponder", |
| 43 | json_object_new_boolean(error_status->DetectedByResponder)); |
| 44 | json_object_object_add( |
| 45 | error_status_ir, "detectedByRequester", |
| 46 | json_object_new_boolean(error_status->DetectedByRequester)); |
| 47 | json_object_object_add( |
| 48 | error_status_ir, "firstError", |
| 49 | json_object_new_boolean(error_status->FirstError)); |
| 50 | json_object_object_add( |
| 51 | error_status_ir, "overflowDroppedLogs", |
| 52 | json_object_new_boolean(error_status->OverflowNotLogged)); |
| 53 | |
| 54 | return error_status_ir; |
Lawrence Tang | a0865e3 | 2022-07-06 11:59:52 +0100 | [diff] [blame] | 55 | } |
| 56 | |
Lawrence Tang | 3b7f45b | 2022-07-14 14:14:30 +0100 | [diff] [blame] | 57 | //Converts the given CPER-JSON generic error status into a CPER structure. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 58 | void ir_generic_error_status_to_cper( |
| 59 | json_object *error_status, EFI_GENERIC_ERROR_STATUS *error_status_cper) |
Lawrence Tang | 3b7f45b | 2022-07-14 14:14:30 +0100 | [diff] [blame] | 60 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 61 | error_status_cper->Type = readable_pair_to_integer( |
| 62 | json_object_object_get(error_status, "errorType")); |
| 63 | error_status_cper->AddressSignal = json_object_get_boolean( |
| 64 | json_object_object_get(error_status, "addressSignal")); |
| 65 | error_status_cper->ControlSignal = json_object_get_boolean( |
| 66 | json_object_object_get(error_status, "controlSignal")); |
| 67 | error_status_cper->DataSignal = json_object_get_boolean( |
| 68 | json_object_object_get(error_status, "dataSignal")); |
| 69 | error_status_cper->DetectedByResponder = json_object_get_boolean( |
| 70 | json_object_object_get(error_status, "detectedByResponder")); |
| 71 | error_status_cper->DetectedByRequester = json_object_get_boolean( |
| 72 | json_object_object_get(error_status, "detectedByRequester")); |
| 73 | error_status_cper->FirstError = json_object_get_boolean( |
| 74 | json_object_object_get(error_status, "firstError")); |
| 75 | error_status_cper->OverflowNotLogged = json_object_get_boolean( |
| 76 | json_object_object_get(error_status, "overflowDroppedLogs")); |
Lawrence Tang | 3b7f45b | 2022-07-14 14:14:30 +0100 | [diff] [blame] | 77 | } |
| 78 | |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 79 | //Converts a single uniform struct of UINT64s into intermediate JSON IR format, given names for each field in byte order. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 80 | json_object *uniform_struct64_to_ir(UINT64 *start, int len, const char *names[]) |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 81 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 82 | json_object *result = json_object_new_object(); |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 83 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 84 | UINT64 *cur = start; |
| 85 | for (int i = 0; i < len; i++) { |
| 86 | json_object_object_add(result, names[i], |
| 87 | json_object_new_uint64(*cur)); |
| 88 | cur++; |
| 89 | } |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 90 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 91 | return result; |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 92 | } |
| 93 | |
| 94 | //Converts a single uniform struct of UINT32s into intermediate JSON IR format, given names for each field in byte order. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 95 | json_object *uniform_struct_to_ir(UINT32 *start, int len, const char *names[]) |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 96 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 97 | json_object *result = json_object_new_object(); |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 98 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 99 | UINT32 *cur = start; |
| 100 | for (int i = 0; i < len; i++) { |
| 101 | json_object_object_add(result, names[i], |
| 102 | json_object_new_uint64(*cur)); |
| 103 | cur++; |
| 104 | } |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 105 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 106 | return result; |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 107 | } |
| 108 | |
Lawrence Tang | 71570a2 | 2022-07-14 11:45:28 +0100 | [diff] [blame] | 109 | //Converts a single object containing UINT32s into a uniform struct. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 110 | void ir_to_uniform_struct64(json_object *ir, UINT64 *start, int len, |
| 111 | const char *names[]) |
Lawrence Tang | 71570a2 | 2022-07-14 11:45:28 +0100 | [diff] [blame] | 112 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 113 | UINT64 *cur = start; |
| 114 | for (int i = 0; i < len; i++) { |
| 115 | *cur = json_object_get_uint64( |
| 116 | json_object_object_get(ir, names[i])); |
| 117 | cur++; |
| 118 | } |
Lawrence Tang | 71570a2 | 2022-07-14 11:45:28 +0100 | [diff] [blame] | 119 | } |
| 120 | |
| 121 | //Converts a single object containing UINT32s into a uniform struct. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 122 | void ir_to_uniform_struct(json_object *ir, UINT32 *start, int len, |
| 123 | const char *names[]) |
Lawrence Tang | 71570a2 | 2022-07-14 11:45:28 +0100 | [diff] [blame] | 124 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 125 | UINT32 *cur = start; |
| 126 | for (int i = 0; i < len; i++) { |
| 127 | *cur = (UINT32)json_object_get_uint64( |
| 128 | json_object_object_get(ir, names[i])); |
| 129 | cur++; |
| 130 | } |
Lawrence Tang | 71570a2 | 2022-07-14 11:45:28 +0100 | [diff] [blame] | 131 | } |
| 132 | |
Lawrence Tang | 3c43f74 | 2022-07-05 11:37:17 +0100 | [diff] [blame] | 133 | //Converts a single integer value to an object containing a value, and a readable name if possible. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 134 | json_object *integer_to_readable_pair(UINT64 value, int len, int keys[], |
| 135 | const char *values[], |
| 136 | const char *default_value) |
Lawrence Tang | 3c43f74 | 2022-07-05 11:37:17 +0100 | [diff] [blame] | 137 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 138 | json_object *result = json_object_new_object(); |
| 139 | json_object_object_add(result, "value", json_object_new_uint64(value)); |
Lawrence Tang | 3c43f74 | 2022-07-05 11:37:17 +0100 | [diff] [blame] | 140 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 141 | //Search for human readable name, add. |
| 142 | const char *name = default_value; |
| 143 | for (int i = 0; i < len; i++) { |
| 144 | if (keys[i] == value) |
| 145 | name = values[i]; |
| 146 | } |
Lawrence Tang | 3c43f74 | 2022-07-05 11:37:17 +0100 | [diff] [blame] | 147 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 148 | json_object_object_add(result, "name", json_object_new_string(name)); |
| 149 | return result; |
Lawrence Tang | 3c43f74 | 2022-07-05 11:37:17 +0100 | [diff] [blame] | 150 | } |
| 151 | |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 152 | //Converts a single integer value to an object containing a value, readable name and description if possible. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 153 | json_object *integer_to_readable_pair_with_desc(int value, int len, int keys[], |
| 154 | const char *values[], |
| 155 | const char *descriptions[], |
| 156 | const char *default_value) |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 157 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 158 | json_object *result = json_object_new_object(); |
| 159 | json_object_object_add(result, "value", json_object_new_int(value)); |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 160 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 161 | //Search for human readable name, add. |
| 162 | const char *name = default_value; |
| 163 | for (int i = 0; i < len; i++) { |
| 164 | if (keys[i] == value) { |
| 165 | name = values[i]; |
| 166 | json_object_object_add( |
| 167 | result, "description", |
| 168 | json_object_new_string(descriptions[i])); |
| 169 | } |
| 170 | } |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 171 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 172 | json_object_object_add(result, "name", json_object_new_string(name)); |
| 173 | return result; |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 174 | } |
| 175 | |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 176 | //Returns a single UINT64 value from the given readable pair object. |
| 177 | //Assumes the integer value is held in the "value" field. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 178 | UINT64 readable_pair_to_integer(json_object *pair) |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 179 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 180 | return json_object_get_uint64(json_object_object_get(pair, "value")); |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 181 | } |
| 182 | |
Lawrence Tang | 794312c | 2022-07-05 14:46:10 +0100 | [diff] [blame] | 183 | //Converts the given 64 bit bitfield to IR, assuming bit 0 starts on the left. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 184 | json_object *bitfield_to_ir(UINT64 bitfield, int num_fields, |
| 185 | const char *names[]) |
Lawrence Tang | 794312c | 2022-07-05 14:46:10 +0100 | [diff] [blame] | 186 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 187 | json_object *result = json_object_new_object(); |
| 188 | for (int i = 0; i < num_fields; i++) { |
| 189 | json_object_object_add(result, names[i], |
| 190 | json_object_new_boolean((bitfield >> i) & |
| 191 | 0b1)); |
| 192 | } |
Lawrence Tang | 794312c | 2022-07-05 14:46:10 +0100 | [diff] [blame] | 193 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 194 | return result; |
Lawrence Tang | 794312c | 2022-07-05 14:46:10 +0100 | [diff] [blame] | 195 | } |
| 196 | |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 197 | //Converts the given IR bitfield into a standard UINT64 bitfield, with fields beginning from bit 0. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 198 | UINT64 ir_to_bitfield(json_object *ir, int num_fields, const char *names[]) |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 199 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 200 | UINT64 result = 0x0; |
| 201 | for (int i = 0; i < num_fields; i++) { |
| 202 | if (json_object_get_boolean( |
| 203 | json_object_object_get(ir, names[i]))) |
| 204 | result |= (0x1 << i); |
| 205 | } |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 206 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 207 | return result; |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 208 | } |
| 209 | |
Lawrence Tang | e18aaee | 2022-07-07 09:01:30 +0100 | [diff] [blame] | 210 | //Converts the given UINT64 array into a JSON IR array, given the length. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 211 | json_object *uint64_array_to_ir_array(UINT64 *array, int len) |
Lawrence Tang | e18aaee | 2022-07-07 09:01:30 +0100 | [diff] [blame] | 212 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 213 | json_object *array_ir = json_object_new_array(); |
| 214 | for (int i = 0; i < len; i++) |
| 215 | json_object_array_add(array_ir, |
| 216 | json_object_new_uint64(array[i])); |
| 217 | return array_ir; |
Lawrence Tang | e18aaee | 2022-07-07 09:01:30 +0100 | [diff] [blame] | 218 | } |
Lawrence Tang | 794312c | 2022-07-05 14:46:10 +0100 | [diff] [blame] | 219 | |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 220 | //Converts a single UINT16 revision number into JSON IR representation. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 221 | json_object *revision_to_ir(UINT16 revision) |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 222 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 223 | json_object *revision_info = json_object_new_object(); |
| 224 | json_object_object_add(revision_info, "major", |
| 225 | json_object_new_int(revision >> 8)); |
| 226 | json_object_object_add(revision_info, "minor", |
| 227 | json_object_new_int(revision & 0xFF)); |
| 228 | return revision_info; |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 229 | } |
| 230 | |
| 231 | //Returns the appropriate string for the given integer severity. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 232 | const char *severity_to_string(UINT32 severity) |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 233 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 234 | return severity < 4 ? CPER_SEVERITY_TYPES[severity] : "Unknown"; |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 235 | } |
| 236 | |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 237 | //Converts a single EFI timestamp to string, at the given output. |
| 238 | //Output must be at least TIMESTAMP_LENGTH bytes long. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 239 | void timestamp_to_string(char *out, EFI_ERROR_TIME_STAMP *timestamp) |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 240 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 241 | sprintf(out, "%02hhu%02hhu-%02hhu-%02hhuT%02hhu:%02hhu:%02hhu.000", |
| 242 | bcd_to_int(timestamp->Century) % |
| 243 | 100, //Cannot go to three digits. |
| 244 | bcd_to_int(timestamp->Year) % 100, //Cannot go to three digits. |
| 245 | bcd_to_int(timestamp->Month), bcd_to_int(timestamp->Day), |
| 246 | bcd_to_int(timestamp->Hours), bcd_to_int(timestamp->Minutes), |
| 247 | bcd_to_int(timestamp->Seconds)); |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 248 | } |
| 249 | |
| 250 | //Converts a single timestamp string to an EFI timestamp. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 251 | void string_to_timestamp(EFI_ERROR_TIME_STAMP *out, const char *timestamp) |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 252 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 253 | //Ignore invalid timestamps. |
| 254 | if (timestamp == NULL) |
| 255 | return; |
Lawrence Tang | 0cb3379 | 2022-07-13 13:51:39 +0100 | [diff] [blame] | 256 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 257 | sscanf(timestamp, "%2hhu%2hhu-%hhu-%hhuT%hhu:%hhu:%hhu.000", |
| 258 | &out->Century, &out->Year, &out->Month, &out->Day, &out->Hours, |
| 259 | &out->Minutes, &out->Seconds); |
Lawrence Tang | aacf0e2 | 2022-07-20 13:28:52 +0100 | [diff] [blame] | 260 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 261 | //Convert back to BCD. |
| 262 | out->Century = int_to_bcd(out->Century); |
| 263 | out->Year = int_to_bcd(out->Year); |
| 264 | out->Month = int_to_bcd(out->Month); |
| 265 | out->Day = int_to_bcd(out->Day); |
| 266 | out->Hours = int_to_bcd(out->Hours); |
| 267 | out->Minutes = int_to_bcd(out->Minutes); |
| 268 | out->Seconds = int_to_bcd(out->Seconds); |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 269 | } |
| 270 | |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 271 | //Helper function to convert an EDK EFI GUID into a string for intermediate use. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 272 | void guid_to_string(char *out, EFI_GUID *guid) |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 273 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 274 | sprintf(out, "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x", |
| 275 | guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], |
| 276 | guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], |
| 277 | guid->Data4[5], guid->Data4[6], guid->Data4[7]); |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 278 | } |
| 279 | |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 280 | //Helper function to convert a string into an EDK EFI GUID. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 281 | void string_to_guid(EFI_GUID *out, const char *guid) |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 282 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 283 | //Ignore invalid GUIDs. |
| 284 | if (guid == NULL) |
| 285 | return; |
Lawrence Tang | 0cb3379 | 2022-07-13 13:51:39 +0100 | [diff] [blame] | 286 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 287 | sscanf(guid, |
| 288 | "%08x-%04hx-%04hx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", |
| 289 | &out->Data1, &out->Data2, &out->Data3, out->Data4, |
| 290 | out->Data4 + 1, out->Data4 + 2, out->Data4 + 3, out->Data4 + 4, |
| 291 | out->Data4 + 5, out->Data4 + 6, out->Data4 + 7); |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 292 | } |
| 293 | |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 294 | //Returns one if two EFI GUIDs are equal, zero otherwise. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 295 | int guid_equal(EFI_GUID *a, EFI_GUID *b) |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 296 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 297 | //Check top base 3 components. |
| 298 | if (a->Data1 != b->Data1 || a->Data2 != b->Data2 || |
| 299 | a->Data3 != b->Data3) { |
| 300 | return 0; |
| 301 | } |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 302 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 303 | //Check Data4 array for equality. |
| 304 | for (int i = 0; i < 8; i++) { |
| 305 | if (a->Data4[i] != b->Data4[i]) |
| 306 | return 0; |
| 307 | } |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 308 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 309 | return 1; |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 310 | } |