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..260f156f3 --- /dev/null +++ b/hypervisor/common/efi_mmap.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2021 Intel Corporation. All rights reserved. + * + * 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 abi_efi_info *efi_info) +{ + struct efi_memory_desc *efi_memdesc = (struct efi_memory_desc *)efi_info->memmap; + uint32_t entry = 0U; + + while ((void *)efi_memdesc < (efi_info->memmap + efi_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 + efi_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..590ed6266 --- /dev/null +++ b/hypervisor/include/common/efi_mmap.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2021 Intel Corporation. All rights reserved. + * + * 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 abi_efi_info *efi_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 ab35da076..2b9d757c2 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 efi_loader_signature; /* 0x1c0 */ uint32_t efi_systab; /* 0x1c4 */