acrn-hypervisor/hypervisor/boot/guest/vboot_wrapper.c

98 lines
2.2 KiB
C
Raw Normal View History

/*
* 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 <acpi.h>
restruct boot and bsp dir for firmware stuff currently, ACRN hypervisor can either boot from sbl/abl or uefi, that's why we have different firmware method under bsp & boot dirs. but the fact is that we actually have two different operations based on different guest boot mode: 1. de-privilege-boot: ACRN hypervisor will boot VM0 in the same context as native(before entering hypervisor) - it means hypervisor will co-work with ACRN UEFI bootloader, restore the context env and de-privilege this env to VM0 guest. 2. direct-boot: ACRN hypervisor will directly boot different pre-launched VM(including SOS), it will setup guest env by pre-defined configuration, and prepare guest kernel image, ramdisk which fetch from multiboot modules. this patch is trying to: - rename files related with firmware, change them to guest vboot related - restruct all guest boot stuff in boot & bsp dirs into a new boot/guest dir - use de-privilege & direct boot to distinguish two different boot operations this patch is pure file movement, the rename of functions based on old assumption will be in the following patch. Changes to be committed: modified: ../efi-stub/Makefile modified: ../efi-stub/boot.c modified: Makefile modified: arch/x86/cpu.c modified: arch/x86/guest/vm.c modified: arch/x86/init.c modified: arch/x86/irq.c modified: arch/x86/trampoline.c modified: boot/acpi.c renamed: bsp/cmdline.c -> boot/cmdline.c renamed: bsp/firmware_uefi.c -> boot/guest/deprivilege_boot.c renamed: boot/uefi/uefi_boot.c -> boot/guest/deprivilege_boot_info.c renamed: bsp/firmware_sbl.c -> boot/guest/direct_boot.c renamed: boot/sbl/multiboot.c -> boot/guest/direct_boot_info.c renamed: bsp/firmware_wrapper.c -> boot/guest/vboot_wrapper.c modified: boot/include/acpi.h renamed: bsp/include/firmware_uefi.h -> boot/include/guest/deprivilege_boot.h renamed: bsp/include/firmware_sbl.h -> boot/include/guest/direct_boot.h renamed: bsp/include/firmware.h -> boot/include/guest/vboot.h modified: include/arch/x86/multiboot.h Tracked-On: #1842 Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
2019-04-30 13:56:32 +08:00
#include <vboot.h>
#include <direct_boot.h>
#include <deprivilege_boot.h>
#include <logmsg.h>
#define BOOTLOADER_NUM 4U
#define BOOTLOADER_NAME_SIZE 20U
struct vboot_bootloader_map {
const char bootloader_name[BOOTLOADER_NAME_SIZE];
enum vboot_mode mode;
};
static struct vboot_operations *vboot_ops;
static enum vboot_mode sos_boot_mode;
/**
* @pre: this function is called during detect mode which is very early stage,
* other exported interfaces should not be called beforehand.
*/
void init_vboot_operations(void)
{
HV:BSP:Update firmware detection and operations selecting logic 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>
2019-04-15 23:02:08 +08:00
struct multiboot_info *mbi;
uint32_t i;
const struct vboot_bootloader_map vboot_bootloader_maps[BOOTLOADER_NUM] = {
{"Slim BootLoader", DIRECT_BOOT_MODE},
{"Intel IOTG/TSD ABL", DIRECT_BOOT_MODE},
{"ACRN UEFI loader", DEPRI_BOOT_MODE},
{"GRUB", DIRECT_BOOT_MODE},
HV:BSP:Update firmware detection and operations selecting logic 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>
2019-04-15 23:02:08 +08:00
};
mbi = (struct multiboot_info *)hpa2hva((uint64_t)boot_regs[1]);
if (mbi == NULL) {
panic("No multiboot info");
} else {
for (i = 0U; i < BOOTLOADER_NUM; i++) {
if (strncmp(hpa2hva(mbi->mi_loader_name), vboot_bootloader_maps[i].bootloader_name,
strnlen_s(vboot_bootloader_maps[i].bootloader_name, BOOTLOADER_NAME_SIZE)) == 0) {
/* Only support two vboot mode */
if (vboot_bootloader_maps[i].mode == DEPRI_BOOT_MODE) {
vboot_ops = get_deprivilege_boot_ops();
sos_boot_mode = DEPRI_BOOT_MODE;
} else {
vboot_ops = get_direct_boot_ops();
sos_boot_mode = DIRECT_BOOT_MODE;
}
break;
}
HV:BSP:Update firmware detection and operations selecting logic 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>
2019-04-15 23:02:08 +08:00
}
}
}
/* @pre: vboot_ops->init != NULL */
void init_vboot(void)
{
#ifdef CONFIG_ACPI_PARSE_ENABLED
acpi_fixup();
#endif
vboot_ops->init();
}
/* @pre: vboot_ops != NULL */
enum vboot_mode get_sos_boot_mode(void)
{
return sos_boot_mode;
}
/* @pre: vboot_ops->get_ap_trampoline != NULL */
uint64_t get_ap_trampoline_buf(void)
{
return vboot_ops->get_ap_trampoline();
}
/* @pre: vboot_ops->get_rsdp != NULL */
void *get_rsdp_ptr(void)
{
return vboot_ops->get_rsdp();
}
/* @pre: vboot_ops->init_irq != NULL */
void init_vboot_irq(void)
{
return vboot_ops->init_irq();
}