Highlights for this release: - Dynamic EFI object creation (lists instead of static arrays) - EFI selftest improvements - Minor fixes -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJaJxZhAAoJECszeR4D/txgtX4P/iTp602iM+2m4WP0P2K/L72b EsPAL4W/QXMBZBnq9MowQl7Ia3JU6bS1g2EDlbAvoQgbhmbTBfA6VxJmQj/AuOn0 waxjyfBw/YL4010YAfmExdVy8Qj0k/SEXcxOiHYZJzmW1o3PXvLuLnetUNJ0Uip9 GJQPcGjSaXY1VM7oAwpOVMWkbpaIIfgw9yrAc2Cw6KN8iHmaf6rPFBdWARGB7w9m znFtq0FpNQSLEEoyJVYAlqyRRsj+1wS3ExGnsL2no74njAgzKSWmdN7qFjkO7WC1 w+CnZLiUv5MaboYK2uORW2qBQzRylyEXWCkqIaZL+EWElVqPRz7/VSDLUJxnZLbl vhDTRUB/kVwdrmB8lP21Rruk1EjCIyYDcGQ+nwhlDes/NJztfNlyOEm47N8LNyt6 obRxOVC8nIjf4YptHB4CRgccGQAE7VqS/DqstV1plC1Ms+puG6SQvuPwlCkKX9XP qkZnirgzrUfGjmFMM3owoelA40jXWV4vv90HjQvwmaOftjPY3IJ+X0rgqUGbuOmn /R8OCW6PV0FIOx1k5/waZlqDnfFkChm56Rhxqf9LqEro37YTUjapXEgBn7a+132x /icaOySkFx0hy+cvPNQ5aXyNLQPDPS++Af9e/hcMewh4Zn5FrJqkJrmtLDZzGJIG LC5DWr8o9vwT41UftPb0 =uyBA -----END PGP SIGNATURE----- Merge tag 'signed-efi-next' of git://github.com/agraf/u-boot Patch queue for efi - 2017-12-05 Highlights for this release: - Dynamic EFI object creation (lists instead of static arrays) - EFI selftest improvements - Minor fixesmaster
commit
9188c4315c
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,89 @@ |
||||
/*
|
||||
* EFI watchdog |
||||
* |
||||
* Copyright (c) 2017 Heinrich Schuchardt |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <efi_loader.h> |
||||
|
||||
/* Conversion factor from seconds to multiples of 100ns */ |
||||
#define EFI_SECONDS_TO_100NS 10000000ULL |
||||
|
||||
static struct efi_event *watchdog_timer_event; |
||||
|
||||
/*
|
||||
* Reset the system when the watchdog event is notified. |
||||
* |
||||
* @event: the watchdog event |
||||
* @context: not used |
||||
*/ |
||||
static void EFIAPI efi_watchdog_timer_notify(struct efi_event *event, |
||||
void *context) |
||||
{ |
||||
EFI_ENTRY("%p, %p", event, context); |
||||
|
||||
printf("\nEFI: Watchdog timeout\n"); |
||||
EFI_CALL_VOID(efi_runtime_services.reset_system(EFI_RESET_COLD, |
||||
EFI_SUCCESS, 0, NULL)); |
||||
|
||||
EFI_EXIT(EFI_UNSUPPORTED); |
||||
} |
||||
|
||||
/*
|
||||
* Reset the watchdog timer. |
||||
* |
||||
* This function is used by the SetWatchdogTimer service. |
||||
* |
||||
* @timeout: seconds before reset by watchdog |
||||
* @return: status code |
||||
*/ |
||||
efi_status_t efi_set_watchdog(unsigned long timeout) |
||||
{ |
||||
efi_status_t r; |
||||
|
||||
if (timeout) |
||||
/* Reset watchdog */ |
||||
r = efi_set_timer(watchdog_timer_event, EFI_TIMER_RELATIVE, |
||||
EFI_SECONDS_TO_100NS * timeout); |
||||
else |
||||
/* Deactivate watchdog */ |
||||
r = efi_set_timer(watchdog_timer_event, EFI_TIMER_STOP, 0); |
||||
return r; |
||||
} |
||||
|
||||
/*
|
||||
* Initialize the EFI watchdog. |
||||
* |
||||
* This function is called by efi_init_obj_list() |
||||
*/ |
||||
int efi_watchdog_register(void) |
||||
{ |
||||
efi_status_t r; |
||||
|
||||
/*
|
||||
* Create a timer event. |
||||
*/ |
||||
r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, |
||||
efi_watchdog_timer_notify, NULL, |
||||
&watchdog_timer_event); |
||||
if (r != EFI_SUCCESS) { |
||||
printf("ERROR: Failed to register watchdog event\n"); |
||||
return r; |
||||
} |
||||
/*
|
||||
* The UEFI standard requires that the watchdog timer is set to five |
||||
* minutes when invoking an EFI boot option. |
||||
* |
||||
* Unified Extensible Firmware Interface (UEFI), version 2.7 Errata A |
||||
* 7.5. Miscellaneous Boot Services - EFI_BOOT_SERVICES.SetWatchdogTimer |
||||
*/ |
||||
r = efi_set_watchdog(300); |
||||
if (r != EFI_SUCCESS) { |
||||
printf("ERROR: Failed to set watchdog timer\n"); |
||||
return r; |
||||
} |
||||
return 0; |
||||
} |
@ -0,0 +1,390 @@ |
||||
/*
|
||||
* efi_selftest_devicepath |
||||
* |
||||
* Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
* |
||||
* This unit test checks the following protocol services: |
||||
* DevicePathToText |
||||
*/ |
||||
|
||||
#include <efi_selftest.h> |
||||
|
||||
static struct efi_boot_services *boottime; |
||||
|
||||
static efi_handle_t handle1; |
||||
static efi_handle_t handle2; |
||||
static efi_handle_t handle3; |
||||
|
||||
struct interface { |
||||
void (EFIAPI * inc)(void); |
||||
} interface; |
||||
|
||||
static efi_guid_t guid_device_path = DEVICE_PATH_GUID; |
||||
|
||||
static efi_guid_t guid_device_path_to_text_protocol = |
||||
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID; |
||||
|
||||
static efi_guid_t guid_protocol = |
||||
EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d, |
||||
0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xbb, 0x7d); |
||||
|
||||
static efi_guid_t guid_vendor1 = |
||||
EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d, |
||||
0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xbb, 0xb1); |
||||
|
||||
static efi_guid_t guid_vendor2 = |
||||
EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d, |
||||
0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xbb, 0xa2); |
||||
|
||||
static efi_guid_t guid_vendor3 = |
||||
EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d, |
||||
0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xbb, 0xc3); |
||||
|
||||
static u8 *dp1; |
||||
static u8 *dp2; |
||||
static u8 *dp3; |
||||
|
||||
struct efi_device_path_to_text_protocol *device_path_to_text; |
||||
|
||||
/*
|
||||
* Setup unit test. |
||||
* |
||||
* Create three handles. Install a new protocol on two of them and |
||||
* provice device paths. |
||||
* |
||||
* handle1 |
||||
* guid interface |
||||
* handle2 |
||||
* guid interface |
||||
* handle3 |
||||
* |
||||
* @handle: handle of the loaded image |
||||
* @systable: system table |
||||
*/ |
||||
static int setup(const efi_handle_t img_handle, |
||||
const struct efi_system_table *systable) |
||||
{ |
||||
struct efi_device_path_vendor vendor_node; |
||||
struct efi_device_path end_node; |
||||
efi_status_t ret; |
||||
|
||||
boottime = systable->boottime; |
||||
|
||||
ret = boottime->locate_protocol(&guid_device_path_to_text_protocol, |
||||
NULL, (void **)&device_path_to_text); |
||||
if (ret != EFI_SUCCESS) { |
||||
device_path_to_text = NULL; |
||||
efi_st_error( |
||||
"Device path to text protocol is not available.\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = boottime->allocate_pool(EFI_LOADER_DATA, |
||||
sizeof(struct efi_device_path_vendor) + |
||||
sizeof(struct efi_device_path), |
||||
(void **)&dp1); |
||||
if (ret != EFI_SUCCESS) |
||||
goto out_of_memory; |
||||
|
||||
ret = boottime->allocate_pool(EFI_LOADER_DATA, 2 * |
||||
sizeof(struct efi_device_path_vendor) + |
||||
sizeof(struct efi_device_path), |
||||
(void **)&dp2); |
||||
if (ret != EFI_SUCCESS) |
||||
goto out_of_memory; |
||||
|
||||
ret = boottime->allocate_pool(EFI_LOADER_DATA, 3 * |
||||
sizeof(struct efi_device_path_vendor) + |
||||
sizeof(struct efi_device_path), |
||||
(void **)&dp3); |
||||
if (ret != EFI_SUCCESS) |
||||
goto out_of_memory; |
||||
|
||||
vendor_node.dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE; |
||||
vendor_node.dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR; |
||||
vendor_node.dp.length = sizeof(struct efi_device_path_vendor); |
||||
|
||||
boottime->copy_mem(&vendor_node.guid, &guid_vendor1, |
||||
sizeof(efi_guid_t)); |
||||
boottime->copy_mem(dp1, &vendor_node, |
||||
sizeof(struct efi_device_path_vendor)); |
||||
boottime->copy_mem(dp2, &vendor_node, |
||||
sizeof(struct efi_device_path_vendor)); |
||||
boottime->copy_mem(dp3, &vendor_node, |
||||
sizeof(struct efi_device_path_vendor)); |
||||
|
||||
boottime->copy_mem(&vendor_node.guid, &guid_vendor2, |
||||
sizeof(efi_guid_t)); |
||||
boottime->copy_mem(dp2 + sizeof(struct efi_device_path_vendor), |
||||
&vendor_node, sizeof(struct efi_device_path_vendor)); |
||||
boottime->copy_mem(dp3 + sizeof(struct efi_device_path_vendor), |
||||
&vendor_node, sizeof(struct efi_device_path_vendor)); |
||||
|
||||
boottime->copy_mem(&vendor_node.guid, &guid_vendor3, |
||||
sizeof(efi_guid_t)); |
||||
boottime->copy_mem(dp3 + 2 * sizeof(struct efi_device_path_vendor), |
||||
&vendor_node, sizeof(struct efi_device_path_vendor)); |
||||
|
||||
end_node.type = DEVICE_PATH_TYPE_END; |
||||
end_node.sub_type = DEVICE_PATH_SUB_TYPE_END; |
||||
end_node.length = sizeof(struct efi_device_path); |
||||
boottime->copy_mem(dp1 + sizeof(struct efi_device_path_vendor), |
||||
&end_node, sizeof(struct efi_device_path)); |
||||
boottime->copy_mem(dp2 + 2 * sizeof(struct efi_device_path_vendor), |
||||
&end_node, sizeof(struct efi_device_path)); |
||||
boottime->copy_mem(dp3 + 3 * sizeof(struct efi_device_path_vendor), |
||||
&end_node, sizeof(struct efi_device_path)); |
||||
|
||||
ret = boottime->install_protocol_interface(&handle1, |
||||
&guid_device_path, |
||||
EFI_NATIVE_INTERFACE, |
||||
dp1); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("InstallProtocolInterface failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = boottime->install_protocol_interface(&handle1, |
||||
&guid_protocol, |
||||
EFI_NATIVE_INTERFACE, |
||||
&interface); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("InstallProtocolInterface failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = boottime->install_protocol_interface(&handle2, |
||||
&guid_device_path, |
||||
EFI_NATIVE_INTERFACE, |
||||
dp2); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("InstallProtocolInterface failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = boottime->install_protocol_interface(&handle2, |
||||
&guid_protocol, |
||||
EFI_NATIVE_INTERFACE, |
||||
&interface); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("InstallProtocolInterface failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = boottime->install_protocol_interface(&handle3, |
||||
&guid_device_path, |
||||
EFI_NATIVE_INTERFACE, |
||||
dp3); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("InstallProtocolInterface failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
return EFI_ST_SUCCESS; |
||||
|
||||
out_of_memory: |
||||
efi_st_error("Out of memory\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
/*
|
||||
* Tear down unit test. |
||||
* |
||||
*/ |
||||
static int teardown(void) |
||||
{ |
||||
efi_status_t ret; |
||||
|
||||
ret = boottime->uninstall_protocol_interface(&handle1, |
||||
&guid_device_path, |
||||
dp1); |
||||
if (ret != EFI_SUCCESS) |
||||
efi_st_todo("UninstallProtocolInterface failed\n"); |
||||
ret = boottime->uninstall_protocol_interface(&handle1, |
||||
&guid_protocol, |
||||
&interface); |
||||
if (ret != EFI_SUCCESS) |
||||
efi_st_todo("UninstallProtocolInterface failed\n"); |
||||
ret = boottime->uninstall_protocol_interface(&handle2, |
||||
&guid_device_path, |
||||
dp2); |
||||
if (ret != EFI_SUCCESS) |
||||
efi_st_todo("UninstallProtocolInterface failed\n"); |
||||
ret = boottime->uninstall_protocol_interface(&handle2, |
||||
&guid_protocol, |
||||
&interface); |
||||
if (ret != EFI_SUCCESS) |
||||
efi_st_todo("UninstallProtocolInterface failed\n"); |
||||
ret = boottime->uninstall_protocol_interface(&handle3, |
||||
&guid_device_path, |
||||
dp3); |
||||
if (ret != EFI_SUCCESS) |
||||
efi_st_todo("UninstallProtocolInterface failed\n"); |
||||
if (dp1) { |
||||
ret = boottime->free_pool(dp1); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("FreePool failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
} |
||||
if (dp2) { |
||||
ret = boottime->free_pool(dp2); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("FreePool failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
} |
||||
if (dp3) { |
||||
ret = boottime->free_pool(dp3); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("FreePool failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
} |
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
/*
|
||||
* Execute unit test. |
||||
* |
||||
*/ |
||||
static int execute(void) |
||||
{ |
||||
struct efi_device_path *remaining_dp; |
||||
void *handle; |
||||
/*
|
||||
* This device path node ends with the letter 't' of 'u-boot'. |
||||
* The following '.bin' does not belong to the node but is |
||||
* helps to test the correct truncation. |
||||
*/ |
||||
struct { |
||||
struct efi_device_path dp; |
||||
u16 text[12]; |
||||
} __packed dp_node = { |
||||
{ DEVICE_PATH_TYPE_MEDIA_DEVICE, |
||||
DEVICE_PATH_SUB_TYPE_FILE_PATH, |
||||
sizeof(struct efi_device_path) + 12}, |
||||
L"u-boot.bin", |
||||
}; |
||||
u16 *string; |
||||
efi_status_t ret; |
||||
efi_uintn_t i, no_handles; |
||||
efi_handle_t *handles; |
||||
struct efi_device_path *dp; |
||||
|
||||
/* Display all available device paths */ |
||||
ret = boottime->locate_handle_buffer(BY_PROTOCOL, |
||||
&guid_device_path, |
||||
NULL, &no_handles, &handles); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("Cannot retrieve device path protocols.\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
efi_st_printf("Installed device path protocols:\n"); |
||||
for (i = 0; i < no_handles; ++i) { |
||||
ret = boottime->open_protocol(handles[i], &guid_device_path, |
||||
(void **)&dp, NULL, NULL, |
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("Cannot open device path protocol.\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
string = device_path_to_text->convert_device_path_to_text( |
||||
dp, true, false); |
||||
if (!string) { |
||||
efi_st_error("ConvertDevicePathToText failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
efi_st_printf("%ps\n", string); |
||||
ret = boottime->free_pool(string); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("FreePool failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = boottime->close_protocol(handles[i], &guid_device_path, |
||||
NULL, NULL); |
||||
if (ret != EFI_SUCCESS) |
||||
efi_st_todo("Cannot close device path protocol.\n"); |
||||
} |
||||
ret = boottime->free_pool(handles); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("FreePool failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
efi_st_printf("\n"); |
||||
|
||||
/* Test ConvertDevicePathToText */ |
||||
string = device_path_to_text->convert_device_path_to_text( |
||||
(struct efi_device_path *)dp2, true, false); |
||||
if (!string) { |
||||
efi_st_error("ConvertDevicePathToText failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
efi_st_printf("dp2: %ps\n", string); |
||||
if (efi_st_strcmp_16_8( |
||||
string, |
||||
"/VenHw(dbca4c98-6cb0-694d-0872-819c650cbbb1)/VenHw(dbca4c98-6cb0-694d-0872-819c650cbba2)") |
||||
) { |
||||
efi_st_error("Incorrect text from ConvertDevicePathToText\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = boottime->free_pool(string); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("FreePool failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
/* Test ConvertDeviceNodeToText */ |
||||
string = device_path_to_text->convert_device_node_to_text( |
||||
(struct efi_device_path *)&dp_node, true, false); |
||||
if (!string) { |
||||
efi_st_error("ConvertDeviceNodeToText failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
efi_st_printf("dp_node: %ps\n", string); |
||||
ret = boottime->free_pool(string); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("FreePool failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (efi_st_strcmp_16_8(string, "u-boot")) { |
||||
efi_st_error( |
||||
"Incorrect conversion by ConvertDeviceNodeToText\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
/* Test LocateDevicePath */ |
||||
remaining_dp = (struct efi_device_path *)dp3; |
||||
ret = boottime->locate_device_path(&guid_protocol, &remaining_dp, |
||||
&handle); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("LocateDevicePath failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (handle != handle2) { |
||||
efi_st_error("LocateDevicePath returned wrong handle\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
string = device_path_to_text->convert_device_path_to_text(remaining_dp, |
||||
true, false); |
||||
if (!string) { |
||||
efi_st_error("ConvertDevicePathToText failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
efi_st_printf("remaining device path: %ps\n", string); |
||||
if (efi_st_strcmp_16_8(string, |
||||
"/VenHw(dbca4c98-6cb0-694d-0872-819c650cbbc3)") |
||||
) { |
||||
efi_st_error("LocateDevicePath: wrong remaining device path\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
EFI_UNIT_TEST(devicepath) = { |
||||
.name = "device path", |
||||
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, |
||||
.setup = setup, |
||||
.execute = execute, |
||||
.teardown = teardown, |
||||
}; |
@ -0,0 +1,95 @@ |
||||
/*
|
||||
* efi_selftest_gop |
||||
* |
||||
* Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
* |
||||
* Test the graphical output protocol. |
||||
*/ |
||||
|
||||
#include <efi_selftest.h> |
||||
|
||||
static struct efi_boot_services *boottime; |
||||
static efi_guid_t efi_gop_guid = EFI_GOP_GUID; |
||||
static struct efi_gop *gop; |
||||
|
||||
/*
|
||||
* 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 handle, |
||||
const struct efi_system_table *systable) |
||||
{ |
||||
efi_status_t ret; |
||||
|
||||
boottime = systable->boottime; |
||||
|
||||
ret = boottime->locate_protocol(&efi_gop_guid, NULL, (void **)&gop); |
||||
if (ret != EFI_SUCCESS) { |
||||
gop = NULL; |
||||
efi_st_printf("Graphical output protocol is not available.\n"); |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
/*
|
||||
* Tear down unit test. |
||||
* |
||||
* @return: EFI_ST_SUCCESS for success |
||||
*/ |
||||
static int teardown(void) |
||||
{ |
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
/*
|
||||
* Execute unit test. |
||||
* |
||||
* @return: EFI_ST_SUCCESS for success |
||||
*/ |
||||
static int execute(void) |
||||
{ |
||||
efi_status_t ret; |
||||
u32 i, max_mode; |
||||
efi_uintn_t size; |
||||
struct efi_gop_mode_info *info; |
||||
|
||||
if (!gop) |
||||
return EFI_ST_SUCCESS; |
||||
|
||||
if (!gop->mode) { |
||||
efi_st_error("EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE missing\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
max_mode = gop->mode->max_mode; |
||||
if (!max_mode) { |
||||
efi_st_error("No graphical mode available\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
efi_st_printf("Number of available modes: %u\n", max_mode); |
||||
|
||||
for (i = 0; i < max_mode; ++i) { |
||||
ret = gop->query_mode(gop, i, &size, &info); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_printf("Could not query mode %u\n", i); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
efi_st_printf("Mode %u: %u x %u\n", |
||||
i, info->width, info->height); |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
EFI_UNIT_TEST(gop) = { |
||||
.name = "graphical output", |
||||
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, |
||||
.setup = setup, |
||||
.execute = execute, |
||||
.teardown = teardown, |
||||
}; |
@ -0,0 +1,354 @@ |
||||
/*
|
||||
* efi_selftest_manageprotocols |
||||
* |
||||
* Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
* |
||||
* This unit test checks the following protocol services: |
||||
* InstallProtocolInterface, UninstallProtocolInterface, |
||||
* InstallMultipleProtocolsInterfaces, UninstallMultipleProtocolsInterfaces, |
||||
* HandleProtocol, ProtocolsPerHandle, |
||||
* LocateHandle, LocateHandleBuffer. |
||||
*/ |
||||
|
||||
#include <efi_selftest.h> |
||||
|
||||
/*
|
||||
* The test currently does not actually call the interface function. |
||||
* So this is just a dummy structure. |
||||
*/ |
||||
struct interface { |
||||
void (EFIAPI * inc)(void); |
||||
}; |
||||
|
||||
static struct efi_boot_services *boottime; |
||||
static efi_guid_t guid1 = |
||||
EFI_GUID(0x2e7ca819, 0x21d3, 0x0a3a, |
||||
0xf7, 0x91, 0x82, 0x1f, 0x7a, 0x83, 0x67, 0xaf); |
||||
static efi_guid_t guid2 = |
||||
EFI_GUID(0xf909f2bb, 0x90a8, 0x0d77, |
||||
0x94, 0x0c, 0x3e, 0xa8, 0xea, 0x38, 0xd6, 0x6f); |
||||
static efi_guid_t guid3 = |
||||
EFI_GUID(0x06d641a3, 0xf4e7, 0xe0c9, |
||||
0xe7, 0x8d, 0x41, 0x2d, 0x72, 0xa6, 0xb1, 0x24); |
||||
static efi_handle_t handle1; |
||||
static efi_handle_t handle2; |
||||
static struct interface interface1; |
||||
static struct interface interface2; |
||||
static struct interface interface3; |
||||
static struct interface interface4; |
||||
|
||||
/*
|
||||
* Find a handle in an array. |
||||
* |
||||
* @handle: handle to find |
||||
* @count: number of entries in the array |
||||
* @buffer: array to search |
||||
*/ |
||||
efi_status_t find_in_buffer(efi_handle_t handle, size_t count, |
||||
efi_handle_t *buffer) |
||||
{ |
||||
size_t i; |
||||
|
||||
for (i = 0; i < count; ++i) { |
||||
if (buffer[i] == handle) |
||||
return EFI_SUCCESS; |
||||
} |
||||
return EFI_NOT_FOUND; |
||||
} |
||||
|
||||
/*
|
||||
* Setup unit test. |
||||
* |
||||
* Create two handles and install two out of three protocol interfaces on each |
||||
* of them: |
||||
* |
||||
* handle1 |
||||
* guid1 interface1 |
||||
* guid3 interface3 |
||||
* handle2 |
||||
* guid1 interface4 |
||||
* guid2 interface2 |
||||
* |
||||
* @handle: handle of the loaded image |
||||
* @systable: system table |
||||
*/ |
||||
static int setup(const efi_handle_t img_handle, |
||||
const struct efi_system_table *systable) |
||||
{ |
||||
efi_status_t ret; |
||||
efi_handle_t handle; |
||||
|
||||
boottime = systable->boottime; |
||||
|
||||
ret = boottime->install_protocol_interface(&handle1, &guid3, |
||||
EFI_NATIVE_INTERFACE, |
||||
&interface3); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("InstallProtocolInterface failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (!handle1) { |
||||
efi_st_error("InstallProtocolInterface failed to create handle\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
handle = handle1; |
||||
ret = boottime->install_protocol_interface(&handle1, &guid1, |
||||
EFI_NATIVE_INTERFACE, |
||||
&interface1); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("InstallProtocolInterface failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (handle != handle1) { |
||||
efi_st_error("InstallProtocolInterface failed to use handle\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = boottime->install_multiple_protocol_interfaces(&handle2, |
||||
&guid1, &interface4, &guid2, &interface2, NULL); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("InstallMultipleProtocolInterfaces failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (!handle2 || handle1 == handle2) { |
||||
efi_st_error("InstallMultipleProtocolInterfaces failed to create handle\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
/*
|
||||
* Tear down unit test. |
||||
* |
||||
*/ |
||||
static int teardown(void) |
||||
{ |
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
/*
|
||||
* Execute unit test. |
||||
* |
||||
*/ |
||||
static int execute(void) |
||||
{ |
||||
struct interface *interface; |
||||
efi_status_t ret; |
||||
efi_handle_t *buffer; |
||||
size_t buffer_size; |
||||
efi_uintn_t count = 0; |
||||
efi_guid_t **prot_buffer; |
||||
efi_uintn_t prot_count; |
||||
|
||||
/*
|
||||
* Test HandleProtocol |
||||
*/ |
||||
ret = boottime->handle_protocol(handle1, &guid3, (void **)&interface); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("HandleProtocol failed to retrieve interface\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (interface != &interface3) { |
||||
efi_st_error("HandleProtocol returned wrong interface\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = boottime->handle_protocol(handle1, &guid2, (void **)&interface); |
||||
if (ret == EFI_SUCCESS) { |
||||
efi_st_error("HandleProtocol returned not installed interface\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
/*
|
||||
* Test LocateHandleBuffer with AllHandles |
||||
*/ |
||||
ret = boottime->locate_handle_buffer(ALL_HANDLES, NULL, NULL, |
||||
&count, &buffer); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("LocateHandleBuffer with AllHandles failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
buffer_size = count; |
||||
ret = find_in_buffer(handle1, count, buffer); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("LocateHandleBuffer failed to locate new handle\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = find_in_buffer(handle2, count, buffer); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("LocateHandleBuffer failed to locate new handle\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
boottime->set_mem(buffer, sizeof(efi_handle_t) * buffer_size, 0); |
||||
|
||||
/*
|
||||
* Test error handling in UninstallMultipleProtocols |
||||
* |
||||
* Try to uninstall more protocols than there are installed. |
||||
*/ |
||||
ret = boottime->uninstall_multiple_protocol_interfaces( |
||||
handle2, |
||||
&guid1, &interface4, |
||||
&guid2, &interface2, |
||||
&guid3, &interface3, |
||||
NULL); |
||||
if (ret == EFI_SUCCESS) { |
||||
efi_st_todo("UninstallMultipleProtocolInterfaces did not catch error\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
/*
|
||||
* Test LocateHandleBuffer with ByProtocol |
||||
*/ |
||||
count = buffer_size; |
||||
ret = boottime->locate_handle_buffer(BY_PROTOCOL, &guid1, NULL, |
||||
&count, &buffer); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("LocateHandleBuffer failed to locate new handles\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (count != 2) { |
||||
efi_st_error("LocateHandleBuffer failed to locate new handles\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = find_in_buffer(handle1, count, buffer); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("LocateHandleBuffer failed to locate new handle\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = find_in_buffer(handle2, count, buffer); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("LocateHandleBuffer failed to locate new handle\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
boottime->set_mem(buffer, sizeof(efi_handle_t) * buffer_size, 0); |
||||
|
||||
/*
|
||||
* Test LocateHandle with ByProtocol |
||||
*/ |
||||
count = buffer_size * sizeof(efi_handle_t); |
||||
ret = boottime->locate_handle(BY_PROTOCOL, &guid1, NULL, |
||||
&count, buffer); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("LocateHandle with ByProtocol failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (count / sizeof(efi_handle_t) != 2) { |
||||
efi_st_error("LocateHandle failed to locate new handles\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
buffer_size = count; |
||||
ret = find_in_buffer(handle1, count, buffer); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("LocateHandle failed to locate new handles\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = find_in_buffer(handle2, count, buffer); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("LocateHandle failed to locate new handles\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
boottime->set_mem(buffer, sizeof(efi_handle_t) * buffer_size, 0); |
||||
|
||||
/*
|
||||
* Test LocateProtocol |
||||
*/ |
||||
ret = boottime->locate_protocol(&guid1, NULL, (void **)&interface); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("LocateProtocol failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (interface != &interface1 && interface != &interface4) { |
||||
efi_st_error("LocateProtocol failed to locate protocol\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
/*
|
||||
* Test UninstallMultipleProtocols |
||||
*/ |
||||
ret = boottime->uninstall_multiple_protocol_interfaces( |
||||
handle2, |
||||
&guid1, &interface4, |
||||
&guid2, &interface2, |
||||
NULL); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_todo("UninstallMultipleProtocolInterfaces failed\n"); |
||||
/* This test is known to fail due to missing implementation */ |
||||
} |
||||
/*
|
||||
* Check that the protocols are really uninstalled. |
||||
*/ |
||||
count = buffer_size; |
||||
ret = boottime->locate_handle_buffer(BY_PROTOCOL, &guid1, NULL, |
||||
&count, &buffer); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("LocateHandleBuffer failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (count != 1) { |
||||
efi_st_todo("UninstallMultipleProtocolInterfaces failed to uninstall protocols\n"); |
||||
/* This test is known to fail due to missing implementation */ |
||||
} |
||||
ret = find_in_buffer(handle1, count, buffer); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("Failed to locate new handle\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
boottime->set_mem(buffer, sizeof(efi_handle_t) * buffer_size, 0); |
||||
|
||||
/*
|
||||
* Test ProtocolsPerHandle |
||||
*/ |
||||
ret = boottime->protocols_per_handle(handle1, |
||||
&prot_buffer, &prot_count); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("Failed to get protocols per handle\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (prot_count != 2) { |
||||
efi_st_error("Failed to get protocols per handle\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (efi_st_memcmp(prot_buffer[0], &guid1, 16) && |
||||
efi_st_memcmp(prot_buffer[1], &guid1, 16)) { |
||||
efi_st_error("Failed to get protocols per handle\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (efi_st_memcmp(prot_buffer[0], &guid3, 16) && |
||||
efi_st_memcmp(prot_buffer[1], &guid3, 16)) { |
||||
efi_st_error("Failed to get protocols per handle\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
/*
|
||||
* Uninstall remaining protocols |
||||
*/ |
||||
ret = boottime->uninstall_protocol_interface(handle1, &guid1, |
||||
&interface1); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_todo("UninstallProtocolInterface failed\n"); |
||||
/* This test is known to fail due to missing implementation */ |
||||
} |
||||
ret = boottime->handle_protocol(handle1, &guid1, (void **)&interface); |
||||
if (ret == EFI_SUCCESS) { |
||||
efi_st_todo("UninstallProtocolInterface failed\n"); |
||||
/* This test is known to fail due to missing implementation */ |
||||
} |
||||
ret = boottime->uninstall_protocol_interface(handle1, &guid3, |
||||
&interface1); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_todo("UninstallProtocolInterface failed\n"); |
||||
/* This test is known to fail due to missing implementation */ |
||||
} |
||||
|
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
EFI_UNIT_TEST(protserv) = { |
||||
.name = "manage protocols", |
||||
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, |
||||
.setup = setup, |
||||
.execute = execute, |
||||
.teardown = teardown, |
||||
}; |
@ -0,0 +1,53 @@ |
||||
/*
|
||||
* efi_selftest_textoutput |
||||
* |
||||
* Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
* |
||||
* Test the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL. |
||||
* |
||||
* The following services are tested: |
||||
* OutputString, TestString, SetAttribute. |
||||
*/ |
||||
|
||||
#include <efi_selftest.h> |
||||
|
||||
/*
|
||||
* Execute unit test. |
||||
* |
||||
* @return: EFI_ST_SUCCESS for success |
||||
*/ |
||||
static int execute(void) |
||||
{ |
||||
size_t foreground; |
||||
size_t background; |
||||
size_t attrib; |
||||
efi_status_t ret; |
||||
|
||||
/* SetAttribute */ |
||||
efi_st_printf("\nColor palette\n"); |
||||
for (foreground = 0; foreground < 0x10; ++foreground) { |
||||
for (background = 0; background < 0x80; background += 0x10) { |
||||
attrib = foreground | background; |
||||
con_out->set_attribute(con_out, attrib); |
||||
efi_st_printf("%p", (void *)attrib); |
||||
} |
||||
con_out->set_attribute(con_out, 0); |
||||
efi_st_printf("\n"); |
||||
} |
||||
/* TestString */ |
||||
ret = con_out->test_string(con_out, |
||||
L" !\"#$%&'()*+,-./0-9:;<=>?@A-Z[\\]^_`a-z{|}~\n"); |
||||
if (ret != EFI_ST_SUCCESS) { |
||||
efi_st_error("TestString failed for ANSI characters\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
EFI_UNIT_TEST(textoutput) = { |
||||
.name = "text output", |
||||
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, |
||||
.execute = execute, |
||||
}; |
@ -0,0 +1,231 @@ |
||||
/*
|
||||
* efi_selftest_watchdog |
||||
* |
||||
* Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
* |
||||
* The 'watchdog timer' unit test checks that the watchdog timer |
||||
* will not cause a system restart during the timeout period after |
||||
* a timer reset. |
||||
* |
||||
* The 'watchdog reboot' unit test checks that the watchdog timer |
||||
* actually reboots the system after a timeout. The test is only |
||||
* executed on explicit request. Use the following commands: |
||||
* |
||||
* setenv efi_selftest watchdog reboot |
||||
* bootefi selftest |
||||
*/ |
||||
|
||||
#include <efi_selftest.h> |
||||
|
||||
/*
|
||||
* This is the communication structure for the notification function. |
||||
*/ |
||||
struct notify_context { |
||||
/* Status code returned when resetting watchdog */ |
||||
efi_status_t status; |
||||
/* Number of invocations of the notification function */ |
||||
unsigned int timer_ticks; |
||||
}; |
||||
|
||||
static struct efi_event *event_notify; |
||||
static struct efi_event *event_wait; |
||||
static struct efi_boot_services *boottime; |
||||
static struct notify_context notification_context; |
||||
static bool watchdog_reset; |
||||
|
||||
/*
|
||||
* Notification function, increments the notfication count if parameter |
||||
* context is provided. |
||||
* |
||||
* @event notified event |
||||
* @context pointer to the timeout |
||||
*/ |
||||
static void EFIAPI notify(struct efi_event *event, void *context) |
||||
{ |
||||
struct notify_context *notify_context = context; |
||||
efi_status_t ret = EFI_SUCCESS; |
||||
|
||||
if (!notify_context) |
||||
return; |
||||
|
||||
/* Reset watchdog timer to one second */ |
||||
ret = boottime->set_watchdog_timer(1, 0, 0, NULL); |
||||
if (ret != EFI_SUCCESS) |
||||
notify_context->status = ret; |
||||
/* Count number of calls */ |
||||
notify_context->timer_ticks++; |
||||
} |
||||
|
||||
/*
|
||||
* Setup unit test. |
||||
* |
||||
* Create two timer events. |
||||
* One with EVT_NOTIFY_SIGNAL, the other with EVT_NOTIFY_WAIT. |
||||
* |
||||
* @handle: handle of the loaded image |
||||
* @systable: system table |
||||
* @return: EFI_ST_SUCCESS for success |
||||
*/ |
||||
static int setup(const efi_handle_t handle, |
||||
const struct efi_system_table *systable) |
||||
{ |
||||
efi_status_t ret; |
||||
|
||||
boottime = systable->boottime; |
||||
|
||||
notification_context.status = EFI_SUCCESS; |
||||
notification_context.timer_ticks = 0; |
||||
ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, |
||||
TPL_CALLBACK, notify, |
||||
(void *)¬ification_context, |
||||
&event_notify); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("could not create event\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_WAIT, |
||||
TPL_CALLBACK, notify, NULL, &event_wait); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("could not create event\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
/*
|
||||
* Execute the test resetting the watchdog in a timely manner. No reboot occurs. |
||||
* |
||||
* @handle: handle of the loaded image |
||||
* @systable: system table |
||||
* @return: EFI_ST_SUCCESS for success |
||||
*/ |
||||
static int setup_timer(const efi_handle_t handle, |
||||
const struct efi_system_table *systable) |
||||
{ |
||||
watchdog_reset = true; |
||||
return setup(handle, systable); |
||||
} |
||||
|
||||
/*
|
||||
* Execute the test without resetting the watchdog. A system reboot occurs. |
||||
* |
||||
* @handle: handle of the loaded image |
||||
* @systable: system table |
||||
* @return: EFI_ST_SUCCESS for success |
||||
*/ |
||||
static int setup_reboot(const efi_handle_t handle, |
||||
const struct efi_system_table *systable) |
||||
{ |
||||
watchdog_reset = false; |
||||
return setup(handle, systable); |
||||
} |
||||
|
||||
/*
|
||||
* Tear down unit test. |
||||
* |
||||
* Close the events created in setup. |
||||
* |
||||
* @return: EFI_ST_SUCCESS for success |
||||
*/ |
||||
static int teardown(void) |
||||
{ |
||||
efi_status_t ret; |
||||
|
||||
/* Set the watchdog timer to the five minute default value */ |
||||
ret = boottime->set_watchdog_timer(300, 0, 0, NULL); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("Setting watchdog timer failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (event_notify) { |
||||
ret = boottime->close_event(event_notify); |
||||
event_notify = NULL; |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("Could not close event\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
} |
||||
if (event_wait) { |
||||
ret = boottime->close_event(event_wait); |
||||
event_wait = NULL; |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("Could not close event\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
} |
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
/*
|
||||
* Execute unit test. |
||||
* |
||||
* Run a 600 ms periodic timer that resets the watchdog to one second |
||||
* on every timer tick. |
||||
* |
||||
* Run a 1350 ms single shot timer and check that the 600ms timer has |
||||
* been called 2 times. |
||||
* |
||||
* @return: EFI_ST_SUCCESS for success |
||||
*/ |
||||
static int execute(void) |
||||
{ |
||||
size_t index; |
||||
efi_status_t ret; |
||||
|
||||
/* Set the watchdog timeout to one second */ |
||||
ret = boottime->set_watchdog_timer(1, 0, 0, NULL); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("Setting watchdog timer failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (watchdog_reset) { |
||||
/* Set 600 ms timer */ |
||||
ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC, |
||||
6000000); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("Could not set timer\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
} |
||||
/* Set 1350 ms timer */ |
||||
ret = boottime->set_timer(event_wait, EFI_TIMER_RELATIVE, 13500000); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("Could not set timer\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
|
||||
ret = boottime->wait_for_event(1, &event_wait, &index); |
||||
if (ret != EFI_SUCCESS) { |
||||
efi_st_error("Could not wait for event\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (notification_context.status != EFI_SUCCESS) { |
||||
efi_st_error("Setting watchdog timer failed\n"); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
if (notification_context.timer_ticks != 2) { |
||||
efi_st_error("The timer was called %u times, expected 2.\n", |
||||
notification_context.timer_ticks); |
||||
return EFI_ST_FAILURE; |
||||
} |
||||
return EFI_ST_SUCCESS; |
||||
} |
||||
|
||||
EFI_UNIT_TEST(watchdog1) = { |
||||
.name = "watchdog timer", |
||||
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, |
||||
.setup = setup_timer, |
||||
.execute = execute, |
||||
.teardown = teardown, |
||||
}; |
||||
|
||||
EFI_UNIT_TEST(watchdog2) = { |
||||
.name = "watchdog reboot", |
||||
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, |
||||
.setup = setup_reboot, |
||||
.execute = execute, |
||||
.teardown = teardown, |
||||
.on_request = true, |
||||
}; |
Loading…
Reference in new issue