From 69da0243f5dad7a5df562a4be0588da97cb0baef Mon Sep 17 00:00:00 2001 From: Victor Sun Date: Mon, 17 Feb 2020 10:48:16 +0800 Subject: [PATCH] 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 Acked-by: Eddie Dong --- hypervisor/arch/x86/boot/cpu_primary.S | 2 ++ hypervisor/boot/guest/direct_boot.c | 7 +++++++ hypervisor/boot/include/boot.h | 2 ++ hypervisor/boot/multiboot2.c | 28 ++++++++++++++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/hypervisor/arch/x86/boot/cpu_primary.S b/hypervisor/arch/x86/boot/cpu_primary.S index f325e3a25..eacadda2e 100644 --- a/hypervisor/arch/x86/boot/cpu_primary.S +++ b/hypervisor/arch/x86/boot/cpu_primary.S @@ -61,6 +61,8 @@ info_req_tag_start: .short 0 .long info_req_tag_end - info_req_tag_start .long MULTIBOOT2_TAG_TYPE_MMAP + .long MULTIBOOT2_TAG_TYPE_MODULE + .long MULTIBOOT2_TAG_TYPE_ACPI_NEW info_req_tag_end: .align MULTIBOOT2_TAG_ALIGN diff --git a/hypervisor/boot/guest/direct_boot.c b/hypervisor/boot/guest/direct_boot.c index d54636fd0..3fc4fadb6 100644 --- a/hypervisor/boot/guest/direct_boot.c +++ b/hypervisor/boot/guest/direct_boot.c @@ -9,6 +9,7 @@ #include #include #include +#include #include /* 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) { +#ifdef CONFIG_MULTIBOOT2 + struct acrn_multiboot_info *mbi = get_multiboot_info(); + + return mbi->mi_acpi_rsdp; +#else return NULL; +#endif } static void init_direct_boot_irq(void) diff --git a/hypervisor/boot/include/boot.h b/hypervisor/boot/include/boot.h index ab7233ef9..0c079464d 100644 --- a/hypervisor/boot/include/boot.h +++ b/hypervisor/boot/include/boot.h @@ -30,6 +30,8 @@ struct acrn_multiboot_info { uint32_t mi_mmap_entries; struct multiboot_mmap mi_mmap_entry[E820_MAX_ENTRIES]; + + void *mi_acpi_rsdp; }; /* boot_regs store the multiboot info magic and address */ diff --git a/hypervisor/boot/multiboot2.c b/hypervisor/boot/multiboot2.c index 2b1bbf3c6..5daf1d352 100644 --- a/hypervisor/boot/multiboot2.c +++ b/hypervisor/boot/multiboot2.c @@ -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; } +/** + * @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 */ @@ -40,6 +57,7 @@ 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; + uint32_t mod_idx = 0U; /* The start part of multiboot2 info: total mbi size (4 bytes), reserved (4 bytes) */ 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: mb2_mmap_to_mbi(mbi, (struct multiboot2_tag_mmap *)mb2_tag); 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: if (mb2_tag->type <= MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR) { pr_warn("unhandled multiboot2 tag type: %d", mb2_tag->type);