mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-04-29 12:14:13 +00:00
Initialize and sanitize a acrn specific multiboot info struct with current supported multiboot1 in very early boot stage, which would bring below benifits: - don't need to do hpa2hva convention every time when refering boot_regs; - panic early if failed to sanitize multiboot info, so that don't need to check multiboot info pointer/flags and panic in later boot process; - keep most code unchanged when introduce multiboot2 support in future; Tracked-On: #4419 Signed-off-by: Victor Sun <victor.sun@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
80 lines
2.4 KiB
C
80 lines
2.4 KiB
C
/*
|
|
* Copyright (C) 2020 Intel Corporation. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <types.h>
|
|
#include <errno.h>
|
|
#include <pgtable.h>
|
|
#include <boot.h>
|
|
#include <rtl.h>
|
|
#include <logmsg.h>
|
|
|
|
static struct acrn_multiboot_info acrn_mbi = { 0U };
|
|
|
|
int32_t sanitize_multiboot_info(void)
|
|
{
|
|
int32_t ret = 0;
|
|
|
|
if (boot_from_multiboot1()) {
|
|
struct multiboot_info *mbi = (struct multiboot_info *)(hpa2hva_early((uint64_t)boot_regs[1]));
|
|
|
|
pr_info("Multiboot1 detected.");
|
|
acrn_mbi.mi_flags = mbi->mi_flags;
|
|
acrn_mbi.mi_drives_addr = mbi->mi_drives_addr;
|
|
acrn_mbi.mi_drives_length = mbi->mi_drives_length;
|
|
acrn_mbi.mi_cmdline = (char *)hpa2hva_early((uint64_t)mbi->mi_cmdline);
|
|
acrn_mbi.mi_loader_name = (char *)hpa2hva_early((uint64_t)mbi->mi_loader_name);
|
|
|
|
acrn_mbi.mi_mmap_entries = mbi->mi_mmap_length / sizeof(struct multiboot_mmap);
|
|
if ((acrn_mbi.mi_mmap_entries != 0U) && (mbi->mi_mmap_addr != 0U)) {
|
|
if (acrn_mbi.mi_mmap_entries > E820_MAX_ENTRIES) {
|
|
pr_err("Too many E820 entries %d\n", acrn_mbi.mi_mmap_entries);
|
|
acrn_mbi.mi_mmap_entries = E820_MAX_ENTRIES;
|
|
}
|
|
(void)memcpy_s((void *)(&acrn_mbi.mi_mmap_entry[0]),
|
|
(acrn_mbi.mi_mmap_entries * sizeof(struct multiboot_mmap)),
|
|
(const void *)hpa2hva_early((uint64_t)mbi->mi_mmap_addr),
|
|
(acrn_mbi.mi_mmap_entries * sizeof(struct multiboot_mmap)));
|
|
} else {
|
|
acrn_mbi.mi_flags &= ~MULTIBOOT_INFO_HAS_MMAP;
|
|
}
|
|
|
|
acrn_mbi.mi_mods_count = mbi->mi_mods_count;
|
|
if ((mbi->mi_mods_count != 0U) && (mbi->mi_mods_addr != 0U)) {
|
|
if (mbi->mi_mods_count > MAX_MODULE_COUNT) {
|
|
pr_err("Too many multiboot modules %d\n", mbi->mi_mods_count);
|
|
acrn_mbi.mi_mods_count = MAX_MODULE_COUNT;
|
|
}
|
|
(void)memcpy_s((void *)(&acrn_mbi.mi_mods[0]),
|
|
(acrn_mbi.mi_mods_count * sizeof(struct multiboot_module)),
|
|
(const void *)hpa2hva_early((uint64_t)mbi->mi_mods_addr),
|
|
(acrn_mbi.mi_mods_count * sizeof(struct multiboot_module)));
|
|
} else {
|
|
acrn_mbi.mi_flags &= ~MULTIBOOT_INFO_HAS_MODS;
|
|
}
|
|
|
|
} else {
|
|
pr_err("no multiboot info found!");
|
|
ret = -ENODEV;
|
|
}
|
|
|
|
if ((acrn_mbi.mi_flags & MULTIBOOT_INFO_HAS_MMAP) == 0U) {
|
|
pr_err("no multiboot memory map info found!");
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* @post retval != NULL
|
|
* @post retval->mi_flags & MULTIBOOT_INFO_HAS_MMAP != 0U
|
|
* @post (retval->mi_mmap_entries > 0U) && (retval->mi_mmap_entries <= E820_MAX_ENTRIES)
|
|
*/
|
|
struct acrn_multiboot_info *get_multiboot_info(void)
|
|
{
|
|
return &acrn_mbi;
|
|
}
|