Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 1 | /** |
Ed Tanous | fedd457 | 2024-07-12 13:56:00 -0700 | [diff] [blame] | 2 | * Describes utility functions for parsing CPER into JSON IR. |
| 3 | * |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 4 | * Author: Lawrence.Tang@arm.com |
| 5 | **/ |
| 6 | |
| 7 | #include <stdio.h> |
Lawrence Tang | 5202bbb | 2022-08-12 14:54:36 +0100 | [diff] [blame] | 8 | #include <json.h> |
Thu Nguyen | e42fb48 | 2024-10-15 14:43:11 +0000 | [diff] [blame] | 9 | #include <libcper/Cper.h> |
| 10 | #include <libcper/cper-utils.h> |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 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. |
Ed Tanous | b35d957 | 2024-06-18 13:17:22 -0700 | [diff] [blame] | 134 | json_object *integer_to_readable_pair(UINT64 value, int len, const int keys[], |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 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++) { |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 144 | if ((UINT64)keys[i] == value) { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 145 | name = values[i]; |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 146 | } |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 147 | } |
Lawrence Tang | 3c43f74 | 2022-07-05 11:37:17 +0100 | [diff] [blame] | 148 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 149 | json_object_object_add(result, "name", json_object_new_string(name)); |
| 150 | return result; |
Lawrence Tang | 3c43f74 | 2022-07-05 11:37:17 +0100 | [diff] [blame] | 151 | } |
| 152 | |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 153 | //Converts a single integer value to an object containing a value, readable name and description if possible. |
Ed Tanous | b35d957 | 2024-06-18 13:17:22 -0700 | [diff] [blame] | 154 | json_object *integer_to_readable_pair_with_desc(int value, int len, |
| 155 | const int keys[], |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 156 | const char *values[], |
| 157 | const char *descriptions[], |
| 158 | const char *default_value) |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 159 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 160 | json_object *result = json_object_new_object(); |
| 161 | json_object_object_add(result, "value", json_object_new_int(value)); |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 162 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 163 | //Search for human readable name, add. |
| 164 | const char *name = default_value; |
| 165 | for (int i = 0; i < len; i++) { |
| 166 | if (keys[i] == value) { |
| 167 | name = values[i]; |
| 168 | json_object_object_add( |
| 169 | result, "description", |
| 170 | json_object_new_string(descriptions[i])); |
| 171 | } |
| 172 | } |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 173 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 174 | json_object_object_add(result, "name", json_object_new_string(name)); |
| 175 | return result; |
Lawrence Tang | 7f21db6 | 2022-07-06 11:09:39 +0100 | [diff] [blame] | 176 | } |
| 177 | |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 178 | //Returns a single UINT64 value from the given readable pair object. |
| 179 | //Assumes the integer value is held in the "value" field. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 180 | UINT64 readable_pair_to_integer(json_object *pair) |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 181 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 182 | return json_object_get_uint64(json_object_object_get(pair, "value")); |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 183 | } |
| 184 | |
Lawrence Tang | 794312c | 2022-07-05 14:46:10 +0100 | [diff] [blame] | 185 | //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] | 186 | json_object *bitfield_to_ir(UINT64 bitfield, int num_fields, |
| 187 | const char *names[]) |
Lawrence Tang | 794312c | 2022-07-05 14:46:10 +0100 | [diff] [blame] | 188 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 189 | json_object *result = json_object_new_object(); |
| 190 | for (int i = 0; i < num_fields; i++) { |
| 191 | json_object_object_add(result, names[i], |
| 192 | json_object_new_boolean((bitfield >> i) & |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 193 | 0x1)); |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 194 | } |
Lawrence Tang | 794312c | 2022-07-05 14:46:10 +0100 | [diff] [blame] | 195 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 196 | return result; |
Lawrence Tang | 794312c | 2022-07-05 14:46:10 +0100 | [diff] [blame] | 197 | } |
| 198 | |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 199 | //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] | 200 | 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] | 201 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 202 | UINT64 result = 0x0; |
| 203 | for (int i = 0; i < num_fields; i++) { |
| 204 | if (json_object_get_boolean( |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 205 | json_object_object_get(ir, names[i]))) { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 206 | result |= (0x1 << i); |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 207 | } |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 208 | } |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 209 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 210 | return result; |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 211 | } |
| 212 | |
Lawrence Tang | e18aaee | 2022-07-07 09:01:30 +0100 | [diff] [blame] | 213 | //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] | 214 | json_object *uint64_array_to_ir_array(UINT64 *array, int len) |
Lawrence Tang | e18aaee | 2022-07-07 09:01:30 +0100 | [diff] [blame] | 215 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 216 | json_object *array_ir = json_object_new_array(); |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 217 | for (int i = 0; i < len; i++) { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 218 | json_object_array_add(array_ir, |
| 219 | json_object_new_uint64(array[i])); |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 220 | } |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 221 | return array_ir; |
Lawrence Tang | e18aaee | 2022-07-07 09:01:30 +0100 | [diff] [blame] | 222 | } |
Lawrence Tang | 794312c | 2022-07-05 14:46:10 +0100 | [diff] [blame] | 223 | |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 224 | //Converts a single UINT16 revision number into JSON IR representation. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 225 | json_object *revision_to_ir(UINT16 revision) |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 226 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 227 | json_object *revision_info = json_object_new_object(); |
| 228 | json_object_object_add(revision_info, "major", |
| 229 | json_object_new_int(revision >> 8)); |
| 230 | json_object_object_add(revision_info, "minor", |
| 231 | json_object_new_int(revision & 0xFF)); |
| 232 | return revision_info; |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 233 | } |
| 234 | |
| 235 | //Returns the appropriate string for the given integer severity. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 236 | const char *severity_to_string(UINT32 severity) |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 237 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 238 | return severity < 4 ? CPER_SEVERITY_TYPES[severity] : "Unknown"; |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 239 | } |
| 240 | |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 241 | //Converts a single EFI timestamp to string, at the given output. |
| 242 | //Output must be at least TIMESTAMP_LENGTH bytes long. |
Ed Tanous | 13f099f | 2024-11-20 11:10:30 -0800 | [diff] [blame] | 243 | void timestamp_to_string(char *out, int out_len, |
| 244 | EFI_ERROR_TIME_STAMP *timestamp) |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 245 | { |
Ed Tanous | 13f099f | 2024-11-20 11:10:30 -0800 | [diff] [blame] | 246 | int written = snprintf( |
| 247 | out, out_len, |
| 248 | "%02hhu%02hhu-%02hhu-%02hhuT%02hhu:%02hhu:%02hhu+00:00", |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 249 | bcd_to_int(timestamp->Century) % |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 250 | 100, //Cannot go to three digits. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 251 | bcd_to_int(timestamp->Year) % 100, //Cannot go to three digits. |
| 252 | bcd_to_int(timestamp->Month), bcd_to_int(timestamp->Day), |
| 253 | bcd_to_int(timestamp->Hours), bcd_to_int(timestamp->Minutes), |
| 254 | bcd_to_int(timestamp->Seconds)); |
Ed Tanous | 13f099f | 2024-11-20 11:10:30 -0800 | [diff] [blame] | 255 | |
| 256 | if (written < 0 || written >= out_len) { |
| 257 | printf("Timestamp buffer of insufficient size\n"); |
| 258 | } |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 259 | } |
| 260 | |
| 261 | //Converts a single timestamp string to an EFI timestamp. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 262 | void string_to_timestamp(EFI_ERROR_TIME_STAMP *out, const char *timestamp) |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 263 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 264 | //Ignore invalid timestamps. |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 265 | if (timestamp == NULL) { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 266 | return; |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 267 | } |
Lawrence Tang | 0cb3379 | 2022-07-13 13:51:39 +0100 | [diff] [blame] | 268 | |
Aushim Nagarkatti | de7dd06 | 2024-11-04 15:23:39 -0800 | [diff] [blame] | 269 | sscanf(timestamp, "%2hhu%2hhu-%hhu-%hhuT%hhu:%hhu:%hhu+00:00", |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 270 | &out->Century, &out->Year, &out->Month, &out->Day, &out->Hours, |
| 271 | &out->Minutes, &out->Seconds); |
Lawrence Tang | aacf0e2 | 2022-07-20 13:28:52 +0100 | [diff] [blame] | 272 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 273 | //Convert back to BCD. |
| 274 | out->Century = int_to_bcd(out->Century); |
| 275 | out->Year = int_to_bcd(out->Year); |
| 276 | out->Month = int_to_bcd(out->Month); |
| 277 | out->Day = int_to_bcd(out->Day); |
| 278 | out->Hours = int_to_bcd(out->Hours); |
| 279 | out->Minutes = int_to_bcd(out->Minutes); |
| 280 | out->Seconds = int_to_bcd(out->Seconds); |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 281 | } |
| 282 | |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 283 | //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] | 284 | void guid_to_string(char *out, EFI_GUID *guid) |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 285 | { |
Karthik Rajagopalan | 7623a6e | 2024-09-20 19:24:35 -0700 | [diff] [blame] | 286 | sprintf(out, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 287 | guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], |
| 288 | guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], |
| 289 | guid->Data4[5], guid->Data4[6], guid->Data4[7]); |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 290 | } |
| 291 | |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 292 | //Helper function to convert a string into an EDK EFI GUID. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 293 | void string_to_guid(EFI_GUID *out, const char *guid) |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 294 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 295 | //Ignore invalid GUIDs. |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 296 | if (guid == NULL) { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 297 | return; |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 298 | } |
Lawrence Tang | 0cb3379 | 2022-07-13 13:51:39 +0100 | [diff] [blame] | 299 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 300 | sscanf(guid, |
Karthik Rajagopalan | 7623a6e | 2024-09-20 19:24:35 -0700 | [diff] [blame] | 301 | "%08x-%04hx-%04hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 302 | &out->Data1, &out->Data2, &out->Data3, out->Data4, |
| 303 | out->Data4 + 1, out->Data4 + 2, out->Data4 + 3, out->Data4 + 4, |
| 304 | out->Data4 + 5, out->Data4 + 6, out->Data4 + 7); |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame] | 305 | } |
| 306 | |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 307 | //Returns one if two EFI GUIDs are equal, zero otherwise. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 308 | int guid_equal(EFI_GUID *a, EFI_GUID *b) |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 309 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 310 | //Check top base 3 components. |
| 311 | if (a->Data1 != b->Data1 || a->Data2 != b->Data2 || |
| 312 | a->Data3 != b->Data3) { |
| 313 | return 0; |
| 314 | } |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 315 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 316 | //Check Data4 array for equality. |
| 317 | for (int i = 0; i < 8; i++) { |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 318 | if (a->Data4[i] != b->Data4[i]) { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 319 | return 0; |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 320 | } |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 321 | } |
Lawrence Tang | 1b0b00e | 2022-07-05 10:33:10 +0100 | [diff] [blame] | 322 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 323 | return 1; |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 324 | } |