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);