| // SPDX-License-Identifier: GPL-2.0-or-later | |
| /* | |
| * efi_selftest_debug_support | |
| * | |
| * Copyright (c) 2025 Ying-Chun Liu, Linaro Ltd. <paul.liu@linaro.org> | |
| * | |
| * Test the EFI_DEBUG_SUPPORT | |
| */ | |
| #include <efi_loader.h> | |
| #include <efi_selftest.h> | |
| #include <linux/sizes.h> | |
| /** | |
| * efi_st_debug_support_execute() - execute test | |
| * | |
| * Test EFI_DEBUG_SUPPORT tables. | |
| * | |
| * Return: status code | |
| */ | |
| static int efi_st_debug_support_execute(void) | |
| { | |
| struct efi_debug_image_info_table_header *efi_st_debug_info_table_header = NULL; | |
| efi_guid_t efi_debug_image_info_table_guid = EFI_DEBUG_IMAGE_INFO_TABLE_GUID; | |
| struct efi_mem_desc *memory_map; | |
| efi_uintn_t map_size = 0; | |
| efi_uintn_t map_key; | |
| efi_uintn_t desc_size; | |
| u32 desc_version; | |
| efi_status_t ret; | |
| /* get EFI_DEBUG_IMAGE_INFO_TABLE */ | |
| efi_st_debug_info_table_header = efi_st_get_config_table(&efi_debug_image_info_table_guid); | |
| if (!efi_st_debug_info_table_header) { | |
| efi_st_error("Missing EFI_DEBUG_IMAGE_INFO_TABLE\n"); | |
| return EFI_ST_FAILURE; | |
| } | |
| /* Load memory map */ | |
| ret = st_boottime->get_memory_map(&map_size, NULL, &map_key, &desc_size, | |
| &desc_version); | |
| if (ret != EFI_BUFFER_TOO_SMALL) { | |
| efi_st_error | |
| ("GetMemoryMap did not return EFI_BUFFER_TOO_SMALL\n"); | |
| return EFI_ST_FAILURE; | |
| } | |
| /* Allocate extra space for newly allocated memory */ | |
| map_size += sizeof(struct efi_mem_desc); | |
| ret = st_boottime->allocate_pool(EFI_BOOT_SERVICES_DATA, map_size, | |
| (void **)&memory_map); | |
| if (ret != EFI_SUCCESS) { | |
| efi_st_error("AllocatePool failed\n"); | |
| return EFI_ST_FAILURE; | |
| } | |
| ret = st_boottime->get_memory_map(&map_size, memory_map, &map_key, | |
| &desc_size, &desc_version); | |
| if (ret != EFI_SUCCESS) { | |
| efi_st_error("GetMemoryMap failed\n"); | |
| return EFI_ST_FAILURE; | |
| } | |
| /* Find the system table pointer */ | |
| for (efi_uintn_t i = 0; map_size; ++i, map_size -= desc_size) { | |
| struct efi_mem_desc *entry = &memory_map[i]; | |
| u64 end; | |
| if (entry->type != EFI_RUNTIME_SERVICES_DATA) | |
| continue; | |
| end = entry->physical_start + | |
| (entry->num_pages << EFI_PAGE_SHIFT); | |
| for (u64 pos = ALIGN(entry->physical_start, SZ_4M); | |
| pos <= end; pos += SZ_4M) { | |
| struct efi_system_table_pointer *systab_pointer = | |
| (void *)(uintptr_t)pos; | |
| /* check for overflow */ | |
| if (pos < entry->physical_start) | |
| break; | |
| if (systab_pointer->signature == | |
| EFI_SYSTEM_TABLE_SIGNATURE) { | |
| if (systab_pointer->efi_system_table_base != | |
| (uintptr_t)st_systable) { | |
| efi_st_error("Wrong system table address\n"); | |
| ret = EFI_ST_FAILURE; | |
| goto out; | |
| } | |
| ret = EFI_ST_SUCCESS; | |
| goto out; | |
| } | |
| } | |
| } | |
| efi_st_error("System table pointer not found\n"); | |
| ret = EFI_ST_FAILURE; | |
| out: | |
| st_boottime->free_pool(memory_map); | |
| return ret; | |
| } | |
| EFI_UNIT_TEST(debug_support) = { | |
| .name = "debug_support", | |
| .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, | |
| .execute = efi_st_debug_support_execute, | |
| }; |