/* * Setup unit test. * * @handle: handle of the loaded image * @systable: system table * @return: EFI_ST_SUCCESS for success */ static int setup(const efi_handle_t img_handle, const struct efi_system_table *systable) { efi_uintn_t i; boottime = systable->boottime; /* Find configuration tables */ for (i = 0; i < systable->nr_tables; ++i) { if (!efi_st_memcmp(&systable->tables[i].guid, &fdt_guid, sizeof(efi_guid_t))) fdt = systable->tables[i].table; } if (!fdt) { efi_st_error("Missing device tree\n"); return EFI_ST_FAILURE; } return EFI_ST_SUCCESS; }
/* * Execute unit test. * * A table is installed, updated, removed. The table entry and the * triggering of events is checked. * * @return: EFI_ST_SUCCESS for success */ static int execute(void) { efi_status_t ret; unsigned int counter = 0; struct efi_event *event; void *table; const unsigned int tables[2]; efi_uintn_t i; efi_uintn_t tabcnt; efi_uintn_t table_count = sys_table->nr_tables; ret = boottime->create_event_ex(0, TPL_NOTIFY, notify, (void *)&counter, &table_guid, &event); if (ret != EFI_SUCCESS) { efi_st_error("Failed to create event\n"); return EFI_ST_FAILURE; } /* Try to delete non-existent table */ ret = boottime->install_configuration_table(&table_guid, NULL); if (ret != EFI_NOT_FOUND) { efi_st_error("Failed to detect missing table\n"); return EFI_ST_FAILURE; } if (counter) { efi_st_error("Notification function was called.\n"); return EFI_ST_FAILURE; } /* Check if the event was signaled */ ret = boottime->check_event(event); if (ret == EFI_SUCCESS) { efi_st_error("Event was signaled on EFI_NOT_FOUND\n"); return EFI_ST_FAILURE; } if (counter != 1) { efi_st_error("Notification function was not called.\n"); return EFI_ST_FAILURE; } if (table_count != sys_table->nr_tables) { efi_st_error("Incorrect table count %u, expected %u\n", (unsigned int)sys_table->nr_tables, (unsigned int)table_count); return EFI_ST_FAILURE; } /* Install table */ ret = boottime->install_configuration_table(&table_guid, (void *)&tables[0]); if (ret != EFI_SUCCESS) { efi_st_error("Failed to install table\n"); return EFI_ST_FAILURE; } /* Check signaled state */ ret = boottime->check_event(event); if (ret != EFI_SUCCESS) { efi_st_error("Event was not signaled on insert\n"); return EFI_ST_FAILURE; } if (++table_count != sys_table->nr_tables) { efi_st_error("Incorrect table count %u, expected %u\n", (unsigned int)sys_table->nr_tables, (unsigned int)table_count); return EFI_ST_FAILURE; } table = NULL; for (i = 0; i < sys_table->nr_tables; ++i) { if (!efi_st_memcmp(&sys_table->tables[i].guid, &table_guid, sizeof(efi_guid_t))) table = sys_table->tables[i].table; } if (!table) { efi_st_error("Installed table not found\n"); return EFI_ST_FAILURE; } if (table != &tables[0]) { efi_st_error("Incorrect table address\n"); return EFI_ST_FAILURE; } if (check_table(sys_table) != EFI_ST_SUCCESS) { efi_st_error("Checking system table\n"); return EFI_ST_FAILURE; } /* Update table */ ret = boottime->install_configuration_table(&table_guid, (void *)&tables[1]); if (ret != EFI_SUCCESS) { efi_st_error("Failed to update table\n"); return EFI_ST_FAILURE; } /* Check signaled state */ ret = boottime->check_event(event); if (ret != EFI_SUCCESS) { efi_st_error("Event was not signaled on update\n"); return EFI_ST_FAILURE; } if (table_count != sys_table->nr_tables) { efi_st_error("Incorrect table count %u, expected %u\n", (unsigned int)sys_table->nr_tables, (unsigned int)table_count); return EFI_ST_FAILURE; } table = NULL; tabcnt = 0; for (i = 0; i < sys_table->nr_tables; ++i) { if (!efi_st_memcmp(&sys_table->tables[i].guid, &table_guid, sizeof(efi_guid_t))) { table = sys_table->tables[i].table; ++tabcnt; } } if (!table) { efi_st_error("Installed table not found\n"); return EFI_ST_FAILURE; } if (tabcnt > 1) { efi_st_error("Duplicate table GUID\n"); return EFI_ST_FAILURE; } if (table != &tables[1]) { efi_st_error("Incorrect table address\n"); return EFI_ST_FAILURE; } if (check_table(sys_table) != EFI_ST_SUCCESS) { efi_st_error("Checking system table\n"); return EFI_ST_FAILURE; } /* Delete table */ ret = boottime->install_configuration_table(&table_guid, NULL); if (ret != EFI_SUCCESS) { efi_st_error("Failed to delete table\n"); return EFI_ST_FAILURE; } /* Check signaled state */ ret = boottime->check_event(event); if (ret != EFI_SUCCESS) { efi_st_error("Event was not signaled on delete\n"); return EFI_ST_FAILURE; } if (--table_count != sys_table->nr_tables) { efi_st_error("Incorrect table count %u, expected %u\n", (unsigned int)sys_table->nr_tables, (unsigned int)table_count); return EFI_ST_FAILURE; } table = NULL; for (i = 0; i < sys_table->nr_tables; ++i) { if (!efi_st_memcmp(&sys_table->tables[i].guid, &table_guid, sizeof(efi_guid_t))) { table = sys_table->tables[i].table; } } if (table) { efi_st_error("Wrong table deleted\n"); return EFI_ST_FAILURE; } ret = boottime->close_event(event); if (ret != EFI_SUCCESS) { efi_st_error("Failed to close event\n"); return EFI_ST_FAILURE; } if (check_table(sys_table) != EFI_ST_SUCCESS) { efi_st_error("Checking system table\n"); return EFI_ST_FAILURE; } return EFI_ST_SUCCESS; }