HV: init module and rsdp info with multiboot2

Initialize module info and ACPI rsdp info of acrn mbi when boot from
multiboot2 protocol, with this patch SOS VM could be loaded sucessfully
with correct ACPI RSDP;

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:
Victor Sun 2020-02-17 10:48:16 +08:00 committed by wenlingz
parent b669a71931
commit 69da0243f5
4 changed files with 39 additions and 0 deletions

View File

@ -61,6 +61,8 @@ info_req_tag_start:
.short 0 .short 0
.long info_req_tag_end - info_req_tag_start .long info_req_tag_end - info_req_tag_start
.long MULTIBOOT2_TAG_TYPE_MMAP .long MULTIBOOT2_TAG_TYPE_MMAP
.long MULTIBOOT2_TAG_TYPE_MODULE
.long MULTIBOOT2_TAG_TYPE_ACPI_NEW
info_req_tag_end: info_req_tag_end:
.align MULTIBOOT2_TAG_ALIGN .align MULTIBOOT2_TAG_ALIGN

View File

@ -9,6 +9,7 @@
#include <types.h> #include <types.h>
#include <e820.h> #include <e820.h>
#include <cpu.h> #include <cpu.h>
#include <boot.h>
#include <direct_boot.h> #include <direct_boot.h>
/* AP trampoline code buffer base address. */ /* AP trampoline code buffer base address. */
@ -27,7 +28,13 @@ static uint64_t get_direct_boot_ap_trampoline(void)
static void* get_direct_boot_rsdp(void) static void* get_direct_boot_rsdp(void)
{ {
#ifdef CONFIG_MULTIBOOT2
struct acrn_multiboot_info *mbi = get_multiboot_info();
return mbi->mi_acpi_rsdp;
#else
return NULL; return NULL;
#endif
} }
static void init_direct_boot_irq(void) static void init_direct_boot_irq(void)

View File

@ -30,6 +30,8 @@ struct acrn_multiboot_info {
uint32_t mi_mmap_entries; uint32_t mi_mmap_entries;
struct multiboot_mmap mi_mmap_entry[E820_MAX_ENTRIES]; struct multiboot_mmap mi_mmap_entry[E820_MAX_ENTRIES];
void *mi_acpi_rsdp;
}; };
/* boot_regs store the multiboot info magic and address */ /* boot_regs store the multiboot info magic and address */

View File

@ -32,6 +32,23 @@ static void mb2_mmap_to_mbi(struct acrn_multiboot_info *mbi, struct multiboot2_t
mbi->mi_flags |= MULTIBOOT_INFO_HAS_MMAP; mbi->mi_flags |= MULTIBOOT_INFO_HAS_MMAP;
} }
/**
* @pre mbi != NULL && mb2_tag_mods != NULL
*/
static void mb2_mods_to_mbi(struct acrn_multiboot_info *mbi,
uint32_t mbi_mod_idx, struct multiboot2_tag_module *mb2_tag_mods)
{
if (mbi_mod_idx >= MAX_MODULE_COUNT) {
pr_err("unhandled multiboot2 module: 0x%x", mb2_tag_mods->mod_start);
} else {
mbi->mi_mods[mbi_mod_idx].mm_mod_start = mb2_tag_mods->mod_start;
mbi->mi_mods[mbi_mod_idx].mm_mod_end = mb2_tag_mods->mod_end;
mbi->mi_mods[mbi_mod_idx].mm_string = (uint32_t)(uint64_t)mb2_tag_mods->cmdline;
mbi->mi_mods_count = mbi_mod_idx + 1U;
}
mbi->mi_flags |= MULTIBOOT_INFO_HAS_MODS;
}
/** /**
* @pre mbi != NULL && mb2_info != NULL * @pre mbi != NULL && mb2_info != NULL
*/ */
@ -40,6 +57,7 @@ int32_t multiboot2_to_acrn_mbi(struct acrn_multiboot_info *mbi, void *mb2_info)
int32_t ret = 0; int32_t ret = 0;
struct multiboot2_tag *mb2_tag, *mb2_tag_end; struct multiboot2_tag *mb2_tag, *mb2_tag_end;
uint32_t mb2_info_size = *(uint32_t *)mb2_info; uint32_t mb2_info_size = *(uint32_t *)mb2_info;
uint32_t mod_idx = 0U;
/* The start part of multiboot2 info: total mbi size (4 bytes), reserved (4 bytes) */ /* 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 = (struct multiboot2_tag *)((uint8_t *)mb2_info + 8U);
@ -56,6 +74,16 @@ int32_t multiboot2_to_acrn_mbi(struct acrn_multiboot_info *mbi, void *mb2_info)
case MULTIBOOT2_TAG_TYPE_MMAP: case MULTIBOOT2_TAG_TYPE_MMAP:
mb2_mmap_to_mbi(mbi, (struct multiboot2_tag_mmap *)mb2_tag); mb2_mmap_to_mbi(mbi, (struct multiboot2_tag_mmap *)mb2_tag);
break; break;
case MULTIBOOT2_TAG_TYPE_MODULE:
mb2_mods_to_mbi(mbi, mod_idx, (struct multiboot2_tag_module *)mb2_tag);
mod_idx++;
break;
case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME:
mbi->mi_loader_name = ((struct multiboot2_tag_string *)mb2_tag)->string;
break;
case MULTIBOOT2_TAG_TYPE_ACPI_NEW:
mbi->mi_acpi_rsdp = ((struct multiboot2_tag_new_acpi *)mb2_tag)->rsdp;
break;
default: default:
if (mb2_tag->type <= MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR) { if (mb2_tag->type <= MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR) {
pr_warn("unhandled multiboot2 tag type: %d", mb2_tag->type); pr_warn("unhandled multiboot2 tag type: %d", mb2_tag->type);