From 9ac8e292fdaf091046eb0c038a4d83faaf9168e2 Mon Sep 17 00:00:00 2001 From: Victor Sun Date: Wed, 9 Jun 2021 10:07:09 +0800 Subject: [PATCH] HV: add efi memory map parsing function When hypervisor boot from efi environment, the efi memory layout should be considered as main memory map reference for hypervisor use. This patch add function that parses the efi memory descriptor entries info from efi memory map pointer and stores the info into a static hv_memdesc[] array. Tracked-On: #5626 Signed-off-by: Victor Sun Reviewed-by: Jason Chen CJ --- hypervisor/Makefile | 1 + hypervisor/common/efi_mmap.c | 71 ++++++++++++++++++++++++++++ hypervisor/include/common/efi_mmap.h | 18 +++++++ hypervisor/include/lib/efi.h | 9 ++++ 4 files changed, 99 insertions(+) create mode 100644 hypervisor/common/efi_mmap.c create mode 100644 hypervisor/include/common/efi_mmap.h diff --git a/hypervisor/Makefile b/hypervisor/Makefile index 5acaa9177..71119c3b6 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -237,6 +237,7 @@ HW_C_SRCS += common/irq.c HW_C_SRCS += common/softirq.c HW_C_SRCS += common/schedule.c HW_C_SRCS += common/event.c +HW_C_SRCS += common/efi_mmap.c ifeq ($(CONFIG_SCHED_NOOP),y) HW_C_SRCS += common/sched_noop.c endif diff --git a/hypervisor/common/efi_mmap.c b/hypervisor/common/efi_mmap.c new file mode 100644 index 000000000..bf30d0e70 --- /dev/null +++ b/hypervisor/common/efi_mmap.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2021 Intel Corporation. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +static uint16_t hv_memdesc_nr; +static struct efi_memory_desc hv_memdesc[MAX_EFI_MMAP_ENTRIES]; + +static void sort_efi_mmap_entries(void) +{ + uint32_t i,j; + struct efi_memory_desc tmp_memdesc; + + /* Bubble sort */ + for (i = 0U; i < (hv_memdesc_nr - 1U); i++) { + for (j = 0U; j < (hv_memdesc_nr - i - 1U); j++) { + if (hv_memdesc[j].phys_addr > hv_memdesc[j + 1U].phys_addr) { + tmp_memdesc = hv_memdesc[j]; + hv_memdesc[j] = hv_memdesc[j + 1U]; + hv_memdesc[j + 1U] = tmp_memdesc; + } + } + } +} + +void init_efi_mmap_entries(struct efi_info *uefi_info) +{ + void *efi_memmap = (void *)((uint64_t)uefi_info->memmap | ((uint64_t)uefi_info->memmap_hi << 32U)); + struct efi_memory_desc *efi_memdesc = (struct efi_memory_desc *)efi_memmap; + uint32_t entry = 0U; + + while ((void *)efi_memdesc < (efi_memmap + uefi_info->memmap_size)) { + if (entry >= MAX_EFI_MMAP_ENTRIES) { + pr_err("Too many efi memmap entries, entries up %d are ignored.", MAX_EFI_MMAP_ENTRIES); + break; + } + + hv_memdesc[entry] = *efi_memdesc; + + /* Per UEFI spec, EFI_MEMORY_DESCRIPTOR array element returned in MemoryMap. + * The size is returned to allow for future expansion of the EFI_MEMORY_DESCRIPTOR + * in response to hardware innovation. The structure of the EFI_MEMORY_DESCRIPTOR + * may be extended in the future but it will remain backwards compatible with the + * current definition. Thus OS software must use the DescriptorSize to find the + * start of each EFI_MEMORY_DESCRIPTOR in the MemoryMap array. + */ + efi_memdesc = (struct efi_memory_desc *)((void *)efi_memdesc + uefi_info->memdesc_size); + entry ++; + } + + hv_memdesc_nr = entry; + + sort_efi_mmap_entries(); +} + +uint32_t get_efi_mmap_entries_count(void) +{ + return hv_memdesc_nr; +} + +const struct efi_memory_desc *get_efi_mmap_entry(void) +{ + return hv_memdesc; +} diff --git a/hypervisor/include/common/efi_mmap.h b/hypervisor/include/common/efi_mmap.h new file mode 100644 index 000000000..615192bba --- /dev/null +++ b/hypervisor/include/common/efi_mmap.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2021 Intel Corporation. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EFI_MMAP_H +#define EFI_MMAP_H +#include + +#define MAX_EFI_MMAP_ENTRIES 256U + +void init_efi_mmap_entries(struct efi_info *uefi_info); + +uint32_t get_efi_mmap_entries_count(void); +const struct efi_memory_desc *get_efi_mmap_entry(void); + +#endif diff --git a/hypervisor/include/lib/efi.h b/hypervisor/include/lib/efi.h index b420b2ad6..6fe0f478f 100644 --- a/hypervisor/include/lib/efi.h +++ b/hypervisor/include/lib/efi.h @@ -7,6 +7,15 @@ #ifndef EFI_H #define EFI_H +struct efi_memory_desc { + uint32_t type; + uint32_t pad; + uint64_t phys_addr; + uint64_t virt_addr; + uint64_t num_pages; + uint64_t attribute; +}; + struct efi_info { uint32_t loader_signature; /* 0x1c0 */ uint32_t systab; /* 0x1c4 */