mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-24 14:33:38 +00:00
HV: init mmap info with multiboot2
Initialize mmap info of acrn mbi when boot from multiboot2 protocol, with this patch acrn hv could boot from multiboot2; Tracked-On: #4419 Signed-off-by: Victor Sun <victor.sun@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
d008b72fdd
commit
b669a71931
@ -197,6 +197,9 @@ BOOT_S_SRCS += arch/x86/boot/cpu_primary.S
|
||||
BOOT_S_SRCS += arch/x86/boot/cpu_save_boot_ctx.S
|
||||
BOOT_S_SRCS += arch/x86/boot/trampoline.S
|
||||
BOOT_C_SRCS += boot/multiboot.c
|
||||
ifeq ($(CONFIG_MULTIBOOT2),y)
|
||||
BOOT_C_SRCS += boot/multiboot2.c
|
||||
endif
|
||||
BOOT_C_SRCS += boot/reloc.c
|
||||
|
||||
# hardware management component
|
||||
|
@ -8,6 +8,9 @@
|
||||
#define BOOT_H_
|
||||
|
||||
#include <multiboot.h>
|
||||
#ifdef CONFIG_MULTIBOOT2
|
||||
#include <multiboot2.h>
|
||||
#endif
|
||||
#include <e820.h>
|
||||
|
||||
#define MAX_BOOTARGS_SIZE 2048U
|
||||
@ -37,6 +40,15 @@ static inline bool boot_from_multiboot1(void)
|
||||
return ((boot_regs[0] == MULTIBOOT_INFO_MAGIC) && (boot_regs[1] != 0U));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MULTIBOOT2
|
||||
static inline bool boot_from_multiboot2(void)
|
||||
{
|
||||
return ((boot_regs[0] == MULTIBOOT2_INFO_MAGIC) && (boot_regs[1] != 0U));
|
||||
}
|
||||
|
||||
int32_t multiboot2_to_acrn_mbi(struct acrn_multiboot_info *mbi, void *mb2_info);
|
||||
#endif
|
||||
|
||||
struct acrn_multiboot_info *get_multiboot_info(void);
|
||||
int32_t sanitize_multiboot_info(void);
|
||||
void parse_hv_cmdline(void);
|
||||
|
@ -54,7 +54,10 @@ int32_t sanitize_multiboot_info(void)
|
||||
} else {
|
||||
acrn_mbi.mi_flags &= ~MULTIBOOT_INFO_HAS_MODS;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MULTIBOOT2
|
||||
} else if (boot_from_multiboot2()) {
|
||||
ret = multiboot2_to_acrn_mbi(&acrn_mbi, hpa2hva_early((uint64_t)boot_regs[1]));
|
||||
#endif
|
||||
} else {
|
||||
pr_err("no multiboot info found!");
|
||||
ret = -ENODEV;
|
||||
|
80
hypervisor/boot/multiboot2.c
Normal file
80
hypervisor/boot/multiboot2.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <errno.h>
|
||||
#include <boot.h>
|
||||
#include <pgtable.h>
|
||||
#include <util.h>
|
||||
#include <logmsg.h>
|
||||
|
||||
/**
|
||||
* @pre mbi != NULL && mb2_tag_mmap != NULL
|
||||
*/
|
||||
static void mb2_mmap_to_mbi(struct acrn_multiboot_info *mbi, struct multiboot2_tag_mmap *mb2_tag_mmap)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
/* multiboot2 mmap tag header occupied 16 bytes */
|
||||
mbi->mi_mmap_entries = (mb2_tag_mmap->size - 16U) / sizeof(struct multiboot2_mmap_entry);
|
||||
if (mbi->mi_mmap_entries > E820_MAX_ENTRIES) {
|
||||
pr_err("Too many E820 entries %d\n", mbi->mi_mmap_entries);
|
||||
mbi->mi_mmap_entries = E820_MAX_ENTRIES;
|
||||
}
|
||||
for (i = 0U; i < mbi->mi_mmap_entries; i++) {
|
||||
mbi->mi_mmap_entry[i].baseaddr = mb2_tag_mmap->entries[i].addr;
|
||||
mbi->mi_mmap_entry[i].length = mb2_tag_mmap->entries[i].len;
|
||||
mbi->mi_mmap_entry[i].type = mb2_tag_mmap->entries[i].type;
|
||||
}
|
||||
mbi->mi_flags |= MULTIBOOT_INFO_HAS_MMAP;
|
||||
}
|
||||
|
||||
/**
|
||||
* @pre mbi != NULL && mb2_info != NULL
|
||||
*/
|
||||
int32_t multiboot2_to_acrn_mbi(struct acrn_multiboot_info *mbi, void *mb2_info)
|
||||
{
|
||||
int32_t ret = 0;
|
||||
struct multiboot2_tag *mb2_tag, *mb2_tag_end;
|
||||
uint32_t mb2_info_size = *(uint32_t *)mb2_info;
|
||||
|
||||
/* The start part of multiboot2 info: total mbi size (4 bytes), reserved (4 bytes) */
|
||||
mb2_tag = (struct multiboot2_tag *)((uint8_t *)mb2_info + 8U);
|
||||
mb2_tag_end = (struct multiboot2_tag *)((uint8_t *)mb2_info + mb2_info_size);
|
||||
|
||||
while ((mb2_tag->type != MULTIBOOT2_TAG_TYPE_END) && (mb2_tag < mb2_tag_end)) {
|
||||
if (mb2_tag->size == 0U) {
|
||||
pr_err("the multiboot2 tag size should not be 0!");
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (mb2_tag->type) {
|
||||
case MULTIBOOT2_TAG_TYPE_MMAP:
|
||||
mb2_mmap_to_mbi(mbi, (struct multiboot2_tag_mmap *)mb2_tag);
|
||||
break;
|
||||
default:
|
||||
if (mb2_tag->type <= MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR) {
|
||||
pr_warn("unhandled multiboot2 tag type: %d", mb2_tag->type);
|
||||
} else {
|
||||
pr_err("unknown multiboot2 tag type: %d", mb2_tag->type);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ret != 0) {
|
||||
pr_err("multiboot2 info format error!");
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* tag->size is not including padding whearas each tag
|
||||
* start at 8-bytes aligned address.
|
||||
*/
|
||||
mb2_tag = (struct multiboot2_tag *)((uint8_t *)mb2_tag
|
||||
+ ((mb2_tag->size + (MULTIBOOT2_INFO_ALIGN - 1U)) & ~(MULTIBOOT2_INFO_ALIGN - 1U)));
|
||||
}
|
||||
return ret;
|
||||
}
|
Loading…
Reference in New Issue
Block a user