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 <victor.sun@intel.com>
Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
This commit is contained in:
Victor Sun 2021-06-09 10:07:09 +08:00 committed by wenlingz
parent 4e1deab3d9
commit 9ac8e292fd
4 changed files with 99 additions and 0 deletions

View File

@ -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

View File

@ -0,0 +1,71 @@
/*
* Copyright (C) 2021 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <types.h>
#include <boot.h>
#include <efi.h>
#include <efi_mmap.h>
#include <logmsg.h>
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;
}

View File

@ -0,0 +1,18 @@
/*
* Copyright (C) 2021 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef EFI_MMAP_H
#define EFI_MMAP_H
#include <types.h>
#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

View File

@ -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 */