#define EFI_CUSTOM_MODE_ENABLE_GUID \
GUID_DEF(0xc076ec0c, 0x7028, 0x4399, 0xa0, 0x72, 0x71, 0xee, 0x5c, 0x44, 0x8b, 0x9f)
+#define EFI_SYSTEM_RESOURCE_TABLE_GUID \
+ GUID_DEF(0xb122a263, 0x3661, 0x4f68, 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80)
+
+/* EFI System Resource Table (ESRT) Firmware Type Definitions */
+#define ESRT_FW_TYPE_UNKNOWN 0x00000000U
+#define ESRT_FW_TYPE_SYSTEMFIRMWARE 0x00000001U
+#define ESRT_FW_TYPE_DEVICEFIRMWARE 0x00000002U
+#define ESRT_FW_TYPE_UEFIDRIVER 0x00000003U
+
+#define LAST_ATTEMPT_STATUS_SUCCESS 0x00000000U
#define EVT_TIMER 0x80000000U
#define EVT_RUNTIME 0x40000000U
} *ConfigurationTable;
} EFI_SYSTEM_TABLE;
+typedef struct {
+ EFI_GUID FwClass;
+ uint32_t FwType;
+ uint32_t FwVersion;
+ uint32_t LowestSupportedFwVersion;
+ uint32_t CapsuleFlags;
+ uint32_t LastAttemptVersion;
+ uint32_t LastAttemptStatus;
+} EFI_SYSTEM_RESOURCE_ENTRY;
+
+typedef struct {
+ uint32_t FwResourceCount;
+ uint32_t FwResourceCountMax;
+ uint64_t FwResourceVersion;
+ EFI_SYSTEM_RESOURCE_ENTRY Entries[];
+} EFI_SYSTEM_RESOURCE_TABLE;
+
extern EFI_SYSTEM_TABLE *ST;
extern EFI_BOOT_SERVICES *BS;
extern EFI_RUNTIME_SERVICES *RT;
#include "sysfail.h"
#include "util.h"
+static bool firmware_update_has_failed(void) {
+ const EFI_SYSTEM_RESOURCE_TABLE *esrt_table;
+ const EFI_SYSTEM_RESOURCE_ENTRY *esrt_entries;
+
+ esrt_table = find_configuration_table(MAKE_GUID_PTR(EFI_SYSTEM_RESOURCE_TABLE));
+ if (!esrt_table)
+ return false;
+
+ esrt_entries = esrt_table->Entries;
+
+ FOREACH_ARRAY(esrt_entry, esrt_entries, esrt_table->FwResourceCount)
+ if (esrt_entry->FwType == ESRT_FW_TYPE_SYSTEMFIRMWARE)
+ return esrt_entry->LastAttemptStatus != LAST_ATTEMPT_STATUS_SUCCESS;
+
+ return false;
+}
+
SysFailType sysfail_check(void) {
+ if (firmware_update_has_failed())
+ return SYSFAIL_FIRMWARE_UPDATE;
+
return SYSFAIL_NO_FAILURE;
}
const char16_t* sysfail_get_error_str(SysFailType fail_type) {
- return NULL;
+ switch (fail_type) {
+ case SYSFAIL_NO_FAILURE:
+ return NULL;
+ case SYSFAIL_FIRMWARE_UPDATE:
+ return u"firmware-updare-failure";
+ default:
+ assert_not_reached();
+ }
}