mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-04-30 04:33:58 +00:00
In the current design, hypervisor only detects two kinds of multiboot compiliant firwares (UEFI loader and non-UEFI loader), It can't detect other multiboot compliant firware (such GRUB loader) and can't detect UEFI loader explicitly since loader name is not supported by UEFI loader (efi stub). In the logical partition scenario on KBL NUC i7, one multiboot compliant firware is used to boot hypervisor and load guest OS image, and firware runtime service shall be disable to avoid interference. So GRUB can be selected as a candidate to enable logical partition scenario on KBL NUC i7. Update firware detection and operations selecting logic to detect more multiboot compiliant firware (such as GRUB and UEFI loader) explicitly, different operations is selected according to the boot load name through a static mapping table between boot load name and firmware operations. GRUB loader can use the SBL operations to handle multiboot information parsing and vm booting since these multiboot compiliant firmware (SBL/ABL/GRUB) which boots hypervisor (binary format), provides multiboot information and the start address of guest OS image(binary format) in the same way, and only runs on boot time. From MISRA C view, viarble array is not allowed, so define the static array for above mapping table; From security view, it is better use strncmp insteads of strcmp. TODO: In future, need to redesign boot moudle to suport different boot loader, different VM boot, and different guest OS. V2-->V3: Update firmware detection logic to handle GRUB loader which is need to provided multiboot information to the hypervisor (such as the address of guest OS image); V3-->V4: Update firmware detection and operations selecting logic to enable GRUB loader support in hypervisor; V4-->V5: Separte UEFI loader name supporting in a separate patch, and update commit comment to make patch clearer. V5-->V6: Update "Tracked-On" Tracked-On: #2944 Signed-off-by: Xiangyang Wu <xiangyang.wu@linux.intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
76 lines
1.8 KiB
C
76 lines
1.8 KiB
C
/*
|
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <multiboot.h>
|
|
#include <vm.h>
|
|
#include <types.h>
|
|
#include <pgtable.h>
|
|
#include <firmware.h>
|
|
#include <firmware_sbl.h>
|
|
#include <firmware_uefi.h>
|
|
#include "platform_acpi_info.h"
|
|
|
|
static struct firmware_operations *firmware_ops;
|
|
|
|
/**
|
|
* @pre: this function is called during detect mode which is very early stage,
|
|
* other exported interfaces should not be called beforehand.
|
|
*/
|
|
void init_firmware_operations(void)
|
|
{
|
|
|
|
struct multiboot_info *mbi;
|
|
uint32_t i;
|
|
|
|
const struct firmware_candidates fw_candidates[NUM_FIRMWARE_SUPPORTING] = {
|
|
{"Slim BootLoader", 15U, sbl_get_firmware_operations},
|
|
{"Intel IOTG/TSD ABL", 18U, sbl_get_firmware_operations},
|
|
{"ACRN UEFI loader", 16U, uefi_get_firmware_operations},
|
|
{"GRUB", 4U, sbl_get_firmware_operations},
|
|
};
|
|
|
|
mbi = (struct multiboot_info *)hpa2hva((uint64_t)boot_regs[1]);
|
|
for (i = 0U; i < NUM_FIRMWARE_SUPPORTING; i++) {
|
|
if (strncmp(hpa2hva(mbi->mi_loader_name), fw_candidates[i].name, fw_candidates[i].name_sz) == 0) {
|
|
firmware_ops = fw_candidates[i].ops();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* @pre: firmware_ops->init != NULL */
|
|
void init_firmware(void)
|
|
{
|
|
#ifndef CONFIG_CONSTANT_ACPI
|
|
acpi_fixup();
|
|
#endif
|
|
firmware_ops->init();
|
|
}
|
|
|
|
/* @pre: firmware_ops->get_ap_trampoline != NULL */
|
|
uint64_t firmware_get_ap_trampoline(void)
|
|
{
|
|
return firmware_ops->get_ap_trampoline();
|
|
}
|
|
|
|
/* @pre: firmware_ops->get_rsdp != NULL */
|
|
void *firmware_get_rsdp(void)
|
|
{
|
|
return firmware_ops->get_rsdp();
|
|
}
|
|
|
|
/* @pre: firmware_ops->init_irq != NULL */
|
|
void firmware_init_irq(void)
|
|
{
|
|
return firmware_ops->init_irq();
|
|
}
|
|
|
|
/* @pre: firmware_ops->init_vm_boot_info != NULL */
|
|
int32_t firmware_init_vm_boot_info(struct acrn_vm *vm)
|
|
{
|
|
return firmware_ops->init_vm_boot_info(vm);
|
|
}
|