* Licensed under the BSD-3-Clause License (the "License").
* You may not use this file except in compliance with the License.
*/
+#include <uk/libid.h>
#include <kvm/efi.h>
#include <uk/arch/paging.h>
#include <uk/plat/common/bootinfo.h>
#else /* !CONFIG_HAVE_PAGING */
static enum uk_efi_alloc_type uk_efi_alloc_type = UK_EFI_ALLOCATE_MAX_ADDRESS;
#endif /* !CONFIG_HAVE_PAGING */
+#if CONFIG_LIBUKDEBUG_PRINTD
+#include <stdio.h>
+#endif /* CONFIG_LIBUKDEBUG_PRINTD */
static struct uk_efi_runtime_services *uk_efi_rs;
static struct uk_efi_boot_services *uk_efi_bs;
return i + 1;
}
-static void _uk_efi_crash(void)
+static void uk_efi_do_crash(void)
{
const char reset_data[] = "UK EFI SYSTEM CRASH";
sizeof(reset_data), (void *)reset_data);
}
-#ifdef CONFIG_KVM_BOOT_PROTO_EFI_STUB_DEBUG
-#define UK_EFI_MAX_CRASH_STR_LEN 256
+#if CONFIG_LIBUKDEBUG_PRINTD
+#define UK_EFI_MAX_FMT_STR_LEN 256
+
+static void uk_efi_printf(const char *str, ...)
+{
+ char fmt_str[UK_EFI_MAX_FMT_STR_LEN];
+ char str_tmp[UK_EFI_MAX_FMT_STR_LEN];
+ __s16 str16[UK_EFI_MAX_FMT_STR_LEN];
+ va_list ap;
+
+ sprintf(fmt_str, "dbg: [%s] <%s @ %4u> %s\r", uk_libname_self(),
+ STRINGIFY(__BASENAME__), __LINE__, str);
+
+ va_start(ap, str);
+ vsprintf(str_tmp, fmt_str, ap);
+ va_end(ap);
+
+ ascii_to_utf16(str_tmp, (char *)str16, UK_EFI_MAX_FMT_STR_LEN - 1);
+ uk_efi_st->con_out->output_string(uk_efi_st->con_out, str16);
+}
+
+#define uk_efi_pr_debug uk_efi_printf
/* UEFI for proper \n, we must also use CRLF */
-#define uk_efi_crash(str) \
- do { \
- __s16 str16[UK_EFI_MAX_CRASH_STR_LEN]; \
- \
- ascii_to_utf16("[uk_efi]: "str"\r", (char *)str16, \
- UK_EFI_MAX_CRASH_STR_LEN - 1); \
- uk_efi_st->con_out->output_string(uk_efi_st->con_out, \
- str16); \
- _uk_efi_crash(); \
+#define UK_EFI_CRASH(...) \
+ do { \
+ uk_efi_printf(__VA_ARGS__); \
+ uk_efi_do_crash(); \
} while (0)
#else
-#define uk_efi_crash(str) _uk_efi_crash()
-#endif
+#define uk_efi_pr_debug(...)
+#define UK_EFI_CRASH(str) uk_efi_do_crash()
+#endif /* CONFIG_LIBUKDEBUG_PRINTD */
static void uk_efi_cls(void)
{
status = uk_efi_bs->get_memory_map(map_sz, *map, &uk_efi_map_key,
desc_sz, &desc_ver);
if (unlikely(status != UK_EFI_BUFFER_TOO_SMALL))
- uk_efi_crash("Failed to call initial dummy get_memory_map\n");
+ UK_EFI_CRASH("Failed to call initial dummy get_memory_map\n");
/* Make sure the actual allocated buffer is bigger */
*map_sz += *desc_sz * UK_EFI_SURPLUS_MEM_DESC_COUNT;
DIV_ROUND_UP(*map_sz, PAGE_SIZE),
(uk_efi_paddr_t *)map);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to allocate memory for map\n");
+ UK_EFI_CRASH("Failed to allocate memory for map\n");
/* Now we call it for real */
status = uk_efi_bs->get_memory_map(map_sz, *map, &uk_efi_map_key,
desc_sz, &desc_ver);
- if unlikely((status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to get memory map\n");
+ if (unlikely(status != UK_EFI_SUCCESS))
+ UK_EFI_CRASH("Failed to get memory map\n");
}
/* Runtime Services memory regions in the Memory Attribute Table have a higher
*rt_mrds_count * sizeof(**rt_mrds),
(void **)rt_mrds);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to allocate memory for Memory Sub-region Descriptors\n");
+ UK_EFI_CRASH("Failed to allocate memory for Memory Sub-region Descriptors\n");
/* Convert the EFI Runtime Services Memory descriptors to
* ukplat_memregion_desc's
#if defined(__X86_64__)
rc = ukplat_memregion_list_insert_legacy_hi_mem(&bi->mrds);
if (unlikely(rc < 0))
- uk_efi_crash("Failed to insert legacy high memory region\n");
+ UK_EFI_CRASH("Failed to insert legacy high memory region\n");
#endif
/* Fetch the Runtime Services memory regions from the MAT */
for (i = 0; i < rt_mrds_count; i++) {
rc = ukplat_memregion_list_insert(&bi->mrds, &rt_mrds[i]);
if (unlikely(rc < 0))
- uk_efi_crash("Failed to insert rt_mrd\n");
+ UK_EFI_CRASH("Failed to insert rt_mrd\n");
}
/* We no longer need the list of Runtime Services memory regions */
status = uk_efi_bs->free_pool(rt_mrds);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to free rt_mrds\n");
+ UK_EFI_CRASH("Failed to free rt_mrds\n");
/* Get memory map through GetMemoryMap */
uk_efi_get_mmap(&map_start, &map_sz, &desc_sz);
rc = ukplat_memregion_list_insert(&bi->mrds, &mrd);
if (unlikely(rc < 0))
- uk_efi_crash("Failed to insert mrd\n");
+ UK_EFI_CRASH("Failed to insert mrd\n");
}
ukplat_memregion_list_coalesce(&bi->mrds);
#if defined(__X86_64__)
rc = ukplat_memregion_alloc_sipi_vect();
if (unlikely(rc))
- uk_efi_crash("Failed to insert SIPI vector region\n");
+ UK_EFI_CRASH("Failed to insert SIPI vector region\n");
#endif
}
UK_EFI_LOADED_IMAGE_PROTOCOL_GUID,
(void **)&uk_img_hndl);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to handle loaded image protocol\n");
+ UK_EFI_CRASH("Failed to handle loaded image protocol\n");
return uk_img_hndl;
}
UK_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID,
&sfs_proto);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to handle Simple Filesystem Protocol\n");
+ UK_EFI_CRASH("Failed to handle Simple Filesystem Protocol\n");
/* For each block device that supports FAT12/16/32 firmware
* automatically creates handles for it. So now we basically open
*/
status = sfs_proto->open_volume(sfs_proto, &volume);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to open Volume\n");
+ UK_EFI_CRASH("Failed to open Volume\n");
/* UEFI only knows UTF-16 */
len16 = ascii_to_utf16(file_name, (char *)file_name16,
UK_EFI_MAXPATHLEN - 1);
if (unlikely(len16 > UK_EFI_MAXPATHLEN))
- uk_efi_crash("File path too long\n");
+ UK_EFI_CRASH("File path too long\n");
status = volume->open(volume, &file_hndl, file_name16,
UK_EFI_FILE_MODE_READ,
UK_EFI_FILE_READ_ONLY | UK_EFI_FILE_HIDDEN);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to open file\n");
+ UK_EFI_CRASH("Failed to open file\n");
/* Just like GetMemoryMap, we first need to do a dummy call */
file_info_len = 0;
status = file_hndl->get_info(file_hndl, UK_EFI_FILE_INFO_ID_GUID,
&file_info_len, file_info);
if (unlikely(status != UK_EFI_BUFFER_TOO_SMALL))
- uk_efi_crash("Dummy call to get_info failed\n");
+ UK_EFI_CRASH("Dummy call to get_info failed\n");
status = uk_efi_bs->allocate_pool(UK_EFI_LOADER_DATA, file_info_len,
(void **)&file_info);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to allocate memory for file_info\n");
+ UK_EFI_CRASH("Failed to allocate memory for file_info\n");
status = file_hndl->get_info(file_hndl, UK_EFI_FILE_INFO_ID_GUID,
&file_info_len, file_info);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to get file_info\n");
+ UK_EFI_CRASH("Failed to get file_info\n");
*len = file_info->file_size;
*buf = (char *)uk_efi_alloc_max_paddr;
DIV_ROUND_UP(*len, PAGE_SIZE),
(uk_efi_paddr_t *)buf);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to allocate memory for file contents\n");
+ UK_EFI_CRASH("Failed to allocate memory for file contents\n");
status = file_hndl->read(file_hndl, len, *buf);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to read file\n");
+ UK_EFI_CRASH("Failed to read file\n");
status = uk_efi_bs->free_pool(file_info);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to free file_info\n");
+ UK_EFI_CRASH("Failed to free file_info\n");
(*buf)[*len] = '\0';
}
DIV_ROUND_UP(len, PAGE_SIZE),
(uk_efi_paddr_t *)&cmdl);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to allocate memory for cmdl\n");
+ UK_EFI_CRASH("Failed to allocate memory for cmdl\n");
/* Update actual size */
len = utf16_to_ascii(uk_img_hndl->load_options, cmdl, len - 1);
if (unlikely(len == __SZ_MAX))
- uk_efi_crash("Conversion from UTF-16 to ASCII of cmdl "
+ UK_EFI_CRASH("Conversion from UTF-16 to ASCII of cmdl "
"overflowed. This shouldn't be possible\n");
} else if (sizeof(EFI_STUB_CMDLINE_FNAME) > 1) {
uk_efi_read_file(uk_img_hndl->device_handle,
mrd.flags = UKPLAT_MEMRF_READ | UKPLAT_MEMRF_MAP;
rc = ukplat_memregion_list_insert(&bi->mrds, &mrd);
if (unlikely(rc < 0))
- uk_efi_crash("Failed to insert cmdl mrd\n");
+ UK_EFI_CRASH("Failed to insert cmdl mrd\n");
bi->cmdline = (__u64)cmdl;
bi->cmdline_len = len;
mrd.flags = UKPLAT_MEMRF_READ | UKPLAT_MEMRF_MAP;
rc = ukplat_memregion_list_insert(&bi->mrds, &mrd);
if (unlikely(rc < 0))
- uk_efi_crash("Failed to insert initrd mrd\n");
+ UK_EFI_CRASH("Failed to insert initrd mrd\n");
}
static void uk_efi_setup_bootinfo_dtb(struct ukplat_bootinfo *bi)
mrd.flags = UKPLAT_MEMRF_READ | UKPLAT_MEMRF_MAP;
rc = ukplat_memregion_list_insert(&bi->mrds, &mrd);
if (unlikely(rc < 0))
- uk_efi_crash("Failed to insert dtb mrd\n");
+ UK_EFI_CRASH("Failed to insert dtb mrd\n");
bi->dtb = (__u64)dtb;
}
bi = ukplat_bootinfo_get();
if (unlikely(!bi))
- uk_efi_crash("Failed to get bootinfo\n");
+ UK_EFI_CRASH("Failed to get bootinfo\n");
memcpy(bi->bootloader, bl, sizeof(bl));
memcpy(bi->bootprotocol, bp, sizeof(bp));
if (status == UK_EFI_UNSUPPORTED || status == UK_EFI_NOT_FOUND)
return;
else if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to get MemoryOverwriteRequestControl variable\n");
+ UK_EFI_CRASH("Failed to get MemoryOverwriteRequestControl variable\n");
status = uk_efi_rs->set_variable((__s16 *)var_name,
MEMORY_ONLY_RESET_CONTROL_GUID,
UK_EFI_VARIABLE_RUNTIME_ACCESS,
sizeof(enable), &enable);
if (unlikely(status != UK_EFI_SUCCESS))
- uk_efi_crash("Failed to enable reset attack mitigation\n");
+ UK_EFI_CRASH("Failed to enable reset attack mitigation\n");
#endif
}