mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-04-29 12:14:13 +00:00
HV: init and sanitize acrn multiboot info
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>
This commit is contained in:
parent
520a0222d3
commit
19ffaa50dc
@ -193,6 +193,7 @@ endif
|
|||||||
BOOT_S_SRCS += arch/x86/boot/cpu_primary.S
|
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/cpu_save_boot_ctx.S
|
||||||
BOOT_S_SRCS += arch/x86/boot/trampoline.S
|
BOOT_S_SRCS += arch/x86/boot/trampoline.S
|
||||||
|
BOOT_C_SRCS += boot/multiboot.c
|
||||||
BOOT_C_SRCS += boot/reloc.c
|
BOOT_C_SRCS += boot/reloc.c
|
||||||
|
|
||||||
# hardware management component
|
# hardware management component
|
||||||
|
@ -116,6 +116,10 @@ void init_pcpu_pre(bool is_bsp)
|
|||||||
panic("hardware not support!");
|
panic("hardware not support!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sanitize_multiboot_info() != 0) {
|
||||||
|
panic("Multiboot info error!");
|
||||||
|
}
|
||||||
|
|
||||||
init_pcpu_model_name();
|
init_pcpu_model_name();
|
||||||
|
|
||||||
load_pcpu_state_data();
|
load_pcpu_state_data();
|
||||||
|
@ -114,54 +114,34 @@ void init_e820(void)
|
|||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint64_t top_addr_space = CONFIG_PLATFORM_RAM_SIZE + PLATFORM_LO_MMIO_SIZE;
|
uint64_t top_addr_space = CONFIG_PLATFORM_RAM_SIZE + PLATFORM_LO_MMIO_SIZE;
|
||||||
|
|
||||||
if (boot_regs[0] == MULTIBOOT_INFO_MAGIC) {
|
struct acrn_multiboot_info *mbi = get_multiboot_info();
|
||||||
/*
|
struct multiboot_mmap *mmap = mbi->mi_mmap_entry;
|
||||||
* Before installing new PML4 table in enable_paging(), HPA->HVA is always 1:1 mapping
|
|
||||||
* and hpa2hva() can't be used to do the conversion. Here we simply treat boot_reg[1] as HPA.
|
|
||||||
*/
|
|
||||||
uint64_t hpa = (uint64_t)boot_regs[1];
|
|
||||||
struct multiboot_info *mbi = (struct multiboot_info *)hpa;
|
|
||||||
|
|
||||||
pr_info("Multiboot info detected\n");
|
hv_e820_entries_nr = mbi->mi_mmap_entries;
|
||||||
if ((mbi->mi_flags & MULTIBOOT_INFO_HAS_MMAP) != 0U) {
|
|
||||||
/* HPA->HVA is always 1:1 mapping at this moment */
|
|
||||||
hpa = (uint64_t)mbi->mi_mmap_addr;
|
|
||||||
struct multiboot_mmap *mmap = (struct multiboot_mmap *)hpa;
|
|
||||||
|
|
||||||
hv_e820_entries_nr = mbi->mi_mmap_length / sizeof(struct multiboot_mmap);
|
dev_dbg(DBG_LEVEL_E820, "mmap addr 0x%x entries %d\n",
|
||||||
if (hv_e820_entries_nr > E820_MAX_ENTRIES) {
|
mbi->mi_mmap_entry, hv_e820_entries_nr);
|
||||||
pr_err("Too many E820 entries %d\n", hv_e820_entries_nr);
|
|
||||||
hv_e820_entries_nr = E820_MAX_ENTRIES;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_dbg(DBG_LEVEL_E820, "mmap length 0x%x addr 0x%x entries %d\n",
|
|
||||||
mbi->mi_mmap_length, mbi->mi_mmap_addr, hv_e820_entries_nr);
|
|
||||||
|
|
||||||
for (i = 0U; i < hv_e820_entries_nr; i++) {
|
for (i = 0U; i < hv_e820_entries_nr; i++) {
|
||||||
if (mmap[i].baseaddr >= top_addr_space) {
|
if (mmap[i].baseaddr >= top_addr_space) {
|
||||||
mmap[i].length = 0UL;
|
mmap[i].length = 0UL;
|
||||||
} else {
|
|
||||||
if ((mmap[i].baseaddr + mmap[i].length) > top_addr_space) {
|
|
||||||
mmap[i].length = top_addr_space - mmap[i].baseaddr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hv_e820[i].baseaddr = mmap[i].baseaddr;
|
|
||||||
hv_e820[i].length = mmap[i].length;
|
|
||||||
hv_e820[i].type = mmap[i].type;
|
|
||||||
|
|
||||||
dev_dbg(DBG_LEVEL_E820, "mmap table: %d type: 0x%x\n", i, mmap[i].type);
|
|
||||||
dev_dbg(DBG_LEVEL_E820, "Base: 0x%016lx length: 0x%016lx",
|
|
||||||
mmap[i].baseaddr, mmap[i].length);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
panic("no memory map found from multiboot info");
|
if ((mmap[i].baseaddr + mmap[i].length) > top_addr_space) {
|
||||||
|
mmap[i].length = top_addr_space - mmap[i].baseaddr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obtain_mem_range_info();
|
hv_e820[i].baseaddr = mmap[i].baseaddr;
|
||||||
} else {
|
hv_e820[i].length = mmap[i].length;
|
||||||
panic("no multiboot info found");
|
hv_e820[i].type = mmap[i].type;
|
||||||
|
|
||||||
|
dev_dbg(DBG_LEVEL_E820, "mmap table: %d type: 0x%x\n", i, mmap[i].type);
|
||||||
|
dev_dbg(DBG_LEVEL_E820, "Base: 0x%016lx length: 0x%016lx",
|
||||||
|
mmap[i].baseaddr, mmap[i].length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obtain_mem_range_info();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_e820_entries_count(void)
|
uint32_t get_e820_entries_count(void)
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include <logmsg.h>
|
#include <logmsg.h>
|
||||||
#include <seed.h>
|
#include <seed.h>
|
||||||
#include <ld_sym.h>
|
#include <ld_sym.h>
|
||||||
#include <vboot.h>
|
#include <boot.h>
|
||||||
|
|
||||||
/* Push sp magic to top of stack for call trace */
|
/* Push sp magic to top of stack for call trace */
|
||||||
#define SWITCH_TO(rsp, to) \
|
#define SWITCH_TO(rsp, to) \
|
||||||
|
@ -41,17 +41,12 @@ static uint32_t parse_seed_arg(void)
|
|||||||
{
|
{
|
||||||
char *cmd_src = NULL;
|
char *cmd_src = NULL;
|
||||||
char *arg, *arg_end;
|
char *arg, *arg_end;
|
||||||
struct multiboot_info *mbi = NULL;
|
struct acrn_multiboot_info *mbi = get_multiboot_info();
|
||||||
uint32_t i = SEED_ARG_NUM - 1U;
|
uint32_t i = SEED_ARG_NUM - 1U;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
|
|
||||||
if (boot_regs[0U] == MULTIBOOT_INFO_MAGIC) {
|
if ((mbi->mi_flags & MULTIBOOT_INFO_HAS_CMDLINE) != 0U) {
|
||||||
mbi = (struct multiboot_info *)hpa2hva((uint64_t)boot_regs[1U]);
|
cmd_src = mbi->mi_cmdline;
|
||||||
if (mbi != NULL) {
|
|
||||||
if ((mbi->mi_flags & MULTIBOOT_INFO_HAS_CMDLINE) != 0U) {
|
|
||||||
cmd_src = (char *)hpa2hva((uint64_t)mbi->mi_cmdline);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd_src != NULL) {
|
if (cmd_src != NULL) {
|
||||||
|
@ -16,7 +16,7 @@ void parse_hv_cmdline(void)
|
|||||||
const char *start = NULL;
|
const char *start = NULL;
|
||||||
const char *end = NULL;
|
const char *end = NULL;
|
||||||
|
|
||||||
if ((boot_regs[0] == MULTIBOOT_INFO_MAGIC) && (boot_regs[1] != 0U)) {
|
if (boot_from_multiboot1()) {
|
||||||
struct multiboot_info *mbi = (struct multiboot_info *)(hpa2hva_early((uint64_t)boot_regs[1]));
|
struct multiboot_info *mbi = (struct multiboot_info *)(hpa2hva_early((uint64_t)boot_regs[1]));
|
||||||
|
|
||||||
if ((mbi->mi_flags & MULTIBOOT_INFO_HAS_CMDLINE) != 0U) {
|
if ((mbi->mi_flags & MULTIBOOT_INFO_HAS_CMDLINE) != 0U) {
|
||||||
|
@ -24,11 +24,10 @@ static struct lapic_regs depri_boot_lapic_regs;
|
|||||||
static void init_depri_boot(void)
|
static void init_depri_boot(void)
|
||||||
{
|
{
|
||||||
static bool depri_initialized = false;
|
static bool depri_initialized = false;
|
||||||
struct multiboot_info *mbi = NULL;
|
struct acrn_multiboot_info *mbi = get_multiboot_info();
|
||||||
|
|
||||||
if (!depri_initialized) {
|
if (!depri_initialized) {
|
||||||
mbi = (struct multiboot_info *) hpa2hva(((uint64_t)(uint32_t)boot_regs[1]));
|
if ((mbi->mi_flags & MULTIBOOT_INFO_HAS_DRIVES) == 0U) {
|
||||||
if ((mbi == NULL) || ((mbi->mi_flags & MULTIBOOT_INFO_HAS_DRIVES) == 0U)) {
|
|
||||||
pr_err("no multiboot drivers for depri_boot found");
|
pr_err("no multiboot drivers for depri_boot found");
|
||||||
} else {
|
} else {
|
||||||
(void)memcpy_s(&depri_boot_ctx, sizeof(struct depri_boot_context),
|
(void)memcpy_s(&depri_boot_ctx, sizeof(struct depri_boot_context),
|
||||||
|
@ -151,7 +151,7 @@ static int32_t init_vm_kernel_info(struct acrn_vm *vm, const struct multiboot_mo
|
|||||||
/**
|
/**
|
||||||
* @pre vm != NULL && mbi != NULL
|
* @pre vm != NULL && mbi != NULL
|
||||||
*/
|
*/
|
||||||
static void init_vm_bootargs_info(struct acrn_vm *vm, const struct multiboot_info *mbi)
|
static void init_vm_bootargs_info(struct acrn_vm *vm, const struct acrn_multiboot_info *mbi)
|
||||||
{
|
{
|
||||||
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
|
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
|
||||||
char *bootargs = vm_config->os_config.bootargs;
|
char *bootargs = vm_config->os_config.bootargs;
|
||||||
@ -162,12 +162,12 @@ static void init_vm_bootargs_info(struct acrn_vm *vm, const struct multiboot_inf
|
|||||||
} else {
|
} else {
|
||||||
/* vm_config->load_order == SOS_VM */
|
/* vm_config->load_order == SOS_VM */
|
||||||
if (((mbi->mi_flags & MULTIBOOT_INFO_HAS_CMDLINE) != 0U)
|
if (((mbi->mi_flags & MULTIBOOT_INFO_HAS_CMDLINE) != 0U)
|
||||||
&& (*(char *)hpa2hva(mbi->mi_cmdline) != 0)) {
|
&& (*(mbi->mi_cmdline) != '\0')) {
|
||||||
/*
|
/*
|
||||||
* If there is cmdline from mbi->mi_cmdline, merge it with
|
* If there is cmdline from mbi->mi_cmdline, merge it with
|
||||||
* vm_config->os_config.bootargs
|
* vm_config->os_config.bootargs
|
||||||
*/
|
*/
|
||||||
merge_cmdline(vm, hpa2hva((uint64_t)mbi->mi_cmdline), bootargs);
|
merge_cmdline(vm, mbi->mi_cmdline, bootargs);
|
||||||
|
|
||||||
vm->sw.bootargs_info.src_addr = kernel_cmdline;
|
vm->sw.bootargs_info.src_addr = kernel_cmdline;
|
||||||
vm->sw.bootargs_info.size = strnlen_s(kernel_cmdline, MAX_BOOTARGS_SIZE);
|
vm->sw.bootargs_info.size = strnlen_s(kernel_cmdline, MAX_BOOTARGS_SIZE);
|
||||||
@ -210,10 +210,10 @@ static uint32_t get_mod_idx_by_tag(const struct multiboot_module *mods, uint32_t
|
|||||||
|
|
||||||
/* @pre vm != NULL && mbi != NULL
|
/* @pre vm != NULL && mbi != NULL
|
||||||
*/
|
*/
|
||||||
static int32_t init_vm_sw_load(struct acrn_vm *vm, const struct multiboot_info *mbi)
|
static int32_t init_vm_sw_load(struct acrn_vm *vm, const struct acrn_multiboot_info *mbi)
|
||||||
{
|
{
|
||||||
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
|
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
|
||||||
struct multiboot_module *mods = (struct multiboot_module *)hpa2hva((uint64_t)mbi->mi_mods_addr);
|
struct multiboot_module *mods = (struct multiboot_module *)(&mbi->mi_mods[0]);
|
||||||
uint32_t mod_idx;
|
uint32_t mod_idx;
|
||||||
int32_t ret = -EINVAL;
|
int32_t ret = -EINVAL;
|
||||||
|
|
||||||
@ -245,25 +245,17 @@ static int32_t init_vm_sw_load(struct acrn_vm *vm, const struct multiboot_info *
|
|||||||
*/
|
*/
|
||||||
static int32_t init_general_vm_boot_info(struct acrn_vm *vm)
|
static int32_t init_general_vm_boot_info(struct acrn_vm *vm)
|
||||||
{
|
{
|
||||||
struct multiboot_info *mbi = NULL;
|
struct acrn_multiboot_info *mbi = get_multiboot_info();
|
||||||
int32_t ret = -EINVAL;
|
int32_t ret = -EINVAL;
|
||||||
|
|
||||||
if (boot_regs[0] != MULTIBOOT_INFO_MAGIC) {
|
stac();
|
||||||
panic("no multiboot info found");
|
if ((mbi->mi_flags & MULTIBOOT_INFO_HAS_MODS) == 0U) {
|
||||||
|
panic("no multiboot module info found");
|
||||||
} else {
|
} else {
|
||||||
mbi = (struct multiboot_info *)hpa2hva((uint64_t)boot_regs[1]);
|
ret = init_vm_sw_load(vm, mbi);
|
||||||
|
|
||||||
if (mbi != NULL) {
|
|
||||||
stac();
|
|
||||||
dev_dbg(DBG_LEVEL_BOOT, "Multiboot detected, flag=0x%x", mbi->mi_flags);
|
|
||||||
if ((mbi->mi_flags & MULTIBOOT_INFO_HAS_MODS) == 0U) {
|
|
||||||
panic("no multiboot module info found");
|
|
||||||
} else {
|
|
||||||
ret = init_vm_sw_load(vm, mbi);
|
|
||||||
}
|
|
||||||
clac();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
clac();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,7 @@ static enum vboot_mode sos_boot_mode;
|
|||||||
*/
|
*/
|
||||||
void init_vboot(void)
|
void init_vboot(void)
|
||||||
{
|
{
|
||||||
|
struct acrn_multiboot_info *mbi = get_multiboot_info();
|
||||||
struct multiboot_info *mbi;
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
const struct vboot_bootloader_map vboot_bootloader_maps[BOOTLOADER_NUM] = {
|
const struct vboot_bootloader_map vboot_bootloader_maps[BOOTLOADER_NUM] = {
|
||||||
@ -43,23 +42,18 @@ void init_vboot(void)
|
|||||||
{"PXELINUX", DIRECT_BOOT_MODE},
|
{"PXELINUX", DIRECT_BOOT_MODE},
|
||||||
};
|
};
|
||||||
|
|
||||||
mbi = (struct multiboot_info *)hpa2hva((uint64_t)boot_regs[1]);
|
for (i = 0U; i < BOOTLOADER_NUM; i++) {
|
||||||
if (mbi == NULL) {
|
if (strncmp(mbi->mi_loader_name, vboot_bootloader_maps[i].bootloader_name,
|
||||||
panic("No multiboot info");
|
strnlen_s(vboot_bootloader_maps[i].bootloader_name, BOOTLOADER_NAME_SIZE)) == 0) {
|
||||||
} else {
|
/* Only support two vboot mode */
|
||||||
for (i = 0U; i < BOOTLOADER_NUM; i++) {
|
if (vboot_bootloader_maps[i].mode == DEPRI_BOOT_MODE) {
|
||||||
if (strncmp(hpa2hva(mbi->mi_loader_name), vboot_bootloader_maps[i].bootloader_name,
|
vboot_ops = get_deprivilege_boot_ops();
|
||||||
strnlen_s(vboot_bootloader_maps[i].bootloader_name, BOOTLOADER_NAME_SIZE)) == 0) {
|
sos_boot_mode = DEPRI_BOOT_MODE;
|
||||||
/* Only support two vboot mode */
|
} else {
|
||||||
if (vboot_bootloader_maps[i].mode == DEPRI_BOOT_MODE) {
|
vboot_ops = get_direct_boot_ops();
|
||||||
vboot_ops = get_deprivilege_boot_ops();
|
sos_boot_mode = DIRECT_BOOT_MODE;
|
||||||
sos_boot_mode = DEPRI_BOOT_MODE;
|
|
||||||
} else {
|
|
||||||
vboot_ops = get_direct_boot_ops();
|
|
||||||
sos_boot_mode = DIRECT_BOOT_MODE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,10 +8,37 @@
|
|||||||
#define BOOT_H_
|
#define BOOT_H_
|
||||||
|
|
||||||
#include <multiboot.h>
|
#include <multiboot.h>
|
||||||
|
#include <e820.h>
|
||||||
|
|
||||||
#define MAX_BOOTARGS_SIZE 2048U
|
#define MAX_BOOTARGS_SIZE 2048U
|
||||||
|
#define MAX_MODULE_COUNT 4U
|
||||||
|
|
||||||
|
struct acrn_multiboot_info {
|
||||||
|
uint32_t mi_flags; /* the flags is back-compatible with multiboot1 */
|
||||||
|
|
||||||
|
char *mi_cmdline;
|
||||||
|
char *mi_loader_name;
|
||||||
|
|
||||||
|
uint32_t mi_mods_count;
|
||||||
|
struct multiboot_module mi_mods[MAX_MODULE_COUNT];
|
||||||
|
|
||||||
|
uint32_t mi_drives_length;
|
||||||
|
uint32_t mi_drives_addr;
|
||||||
|
|
||||||
|
uint32_t mi_mmap_entries;
|
||||||
|
struct multiboot_mmap mi_mmap_entry[E820_MAX_ENTRIES];
|
||||||
|
};
|
||||||
|
|
||||||
/* boot_regs store the multiboot info magic and address */
|
/* boot_regs store the multiboot info magic and address */
|
||||||
extern uint32_t boot_regs[2];
|
extern uint32_t boot_regs[2];
|
||||||
|
|
||||||
|
static inline bool boot_from_multiboot1(void)
|
||||||
|
{
|
||||||
|
return ((boot_regs[0] == MULTIBOOT_INFO_MAGIC) && (boot_regs[1] != 0U));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct acrn_multiboot_info *get_multiboot_info(void);
|
||||||
|
int32_t sanitize_multiboot_info(void);
|
||||||
|
void parse_hv_cmdline(void);
|
||||||
|
|
||||||
#endif /* BOOT_H_ */
|
#endif /* BOOT_H_ */
|
||||||
|
@ -26,6 +26,5 @@ uint64_t get_ap_trampoline_buf(void);
|
|||||||
void *get_rsdp_ptr(void);
|
void *get_rsdp_ptr(void);
|
||||||
|
|
||||||
enum vboot_mode get_sos_boot_mode(void);
|
enum vboot_mode get_sos_boot_mode(void);
|
||||||
void parse_hv_cmdline(void);
|
|
||||||
|
|
||||||
#endif /* end of include guard: VBOOT_H */
|
#endif /* end of include guard: VBOOT_H */
|
||||||
|
79
hypervisor/boot/multiboot.c
Normal file
79
hypervisor/boot/multiboot.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user