diff --git a/hypervisor/Makefile b/hypervisor/Makefile index dd71b8365..941c110fb 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -216,6 +216,7 @@ endif ifeq ($(CONFIG_PLATFORM_UEFI),y) C_SRCS += bsp/uefi/uefi.c C_SRCS += bsp/uefi/cmdline.c +C_SRCS += boot/uefi/uefi_boot.c TEMPLATE_ACPI_INFO_HEADER := bsp/include/uefi/platform_acpi_info.h else ifeq ($(CONFIG_PLATFORM_SBL),y) diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c index 757565599..fbac84a3f 100644 --- a/hypervisor/arch/x86/guest/vcpu.c +++ b/hypervisor/arch/x86/guest/vcpu.c @@ -9,8 +9,6 @@ #include #include -vm_sw_loader_t vm_sw_loader; - inline uint64_t vcpu_get_gpreg(const struct acrn_vcpu *vcpu, uint32_t reg) { const struct run_context *ctx = diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index e1aa43122..d19348c06 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -9,6 +9,9 @@ #include #include #include +#include + +vm_sw_loader_t vm_sw_loader; /* Local variables */ @@ -101,6 +104,8 @@ int32_t create_vm(struct vm_description *vm_desc, struct acrn_vm **rtn_vm) #ifndef CONFIG_EFI_STUB status = init_vm_boot_info(vm); +#else + status = efi_boot_init(); #endif if (status == 0) { init_iommu_vm0_domain(vm); diff --git a/hypervisor/boot/dmar_parse.c b/hypervisor/boot/dmar_parse.c index 2f38c5d31..71323d7b3 100644 --- a/hypervisor/boot/dmar_parse.c +++ b/hypervisor/boot/dmar_parse.c @@ -291,7 +291,7 @@ handle_one_drhd(struct acpi_dmar_hardware_unit *acpi_drhd, return 0; } -int32_t parse_dmar_table(void) +static int32_t parse_dmar_table(void) { int32_t i; struct acpi_dmar_hardware_unit *acpi_drhd; diff --git a/hypervisor/boot/uefi/uefi_boot.c b/hypervisor/boot/uefi/uefi_boot.c new file mode 100644 index 000000000..93f864c20 --- /dev/null +++ b/hypervisor/boot/uefi/uefi_boot.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#ifdef CONFIG_EFI_STUB + +static void efi_spurious_handler(int32_t vector) +{ + if (get_cpu_id() == BOOT_CPU_ID) { + struct acrn_vcpu *vcpu = per_cpu(vcpu, BOOT_CPU_ID); + + if (vcpu != NULL) { + vlapic_set_intr(vcpu, vector, 0); + } else { + pr_err("%s vcpu or vlapic is not ready, interrupt lost\n", __func__); + } + } +} + +static int32_t uefi_sw_loader(struct acrn_vm *vm) +{ + int32_t ret = 0; + struct acrn_vcpu *vcpu = get_primary_vcpu(vm); + struct acrn_vcpu_regs *vcpu_regs = &boot_context; + const struct efi_context *efi_ctx = get_efi_ctx(); + const struct lapic_regs *uefi_lapic_regs = get_efi_lapic_regs(); + + pr_dbg("Loading guest to run-time location"); + + vlapic_restore(vcpu_vlapic(vcpu), uefi_lapic_regs); + + /* For UEFI platform, the bsp init regs come from two places: + * 1. saved in efi_boot: gpregs, rip + * 2. saved when HV started: other registers + * We copy the info saved in efi_boot to boot_context and + * init bsp with boot_context. + */ + memcpy_s(&(vcpu_regs->gprs), sizeof(struct acrn_gp_regs), + &(efi_ctx->vcpu_regs.gprs), sizeof(struct acrn_gp_regs)); + + vcpu_regs->rip = efi_ctx->vcpu_regs.rip; + set_vcpu_regs(vcpu, vcpu_regs); + + /* defer irq enabling till vlapic is ready */ + CPU_IRQ_ENABLE(); + + return ret; +} + +int32_t efi_boot_init(void) +{ + vm_sw_loader = uefi_sw_loader; + spurious_handler = (spurious_handler_t)efi_spurious_handler; + + return 0; +} +#endif diff --git a/hypervisor/bsp/include/bsp_extern.h b/hypervisor/bsp/include/bsp_extern.h index f7ffd679f..2c0f08469 100644 --- a/hypervisor/bsp/include/bsp_extern.h +++ b/hypervisor/bsp/include/bsp_extern.h @@ -40,4 +40,12 @@ void init_bsp(void); void acpi_fixup(void); #endif +#ifdef CONFIG_EFI_STUB + +void *get_rsdp_from_uefi(void); +void *get_ap_trampoline_buf(void); +const struct efi_context *get_efi_ctx(void); +const struct lapic_regs *get_efi_lapic_regs(void); +#endif + #endif /* BSP_EXTERN_H */ diff --git a/hypervisor/bsp/uefi/uefi.c b/hypervisor/bsp/uefi/uefi.c index 2c3217e83..e69843243 100644 --- a/hypervisor/bsp/uefi/uefi.c +++ b/hypervisor/bsp/uefi/uefi.c @@ -10,63 +10,41 @@ #include #ifdef CONFIG_EFI_STUB -static void efi_init(void); -struct efi_context* efi_ctx = NULL; -struct lapic_regs uefi_lapic_regs; +static struct efi_context *efi_ctx = NULL; +static struct lapic_regs uefi_lapic_regs; static int32_t efi_initialized; -void efi_spurious_handler(int32_t vector) +static void efi_init(void) { - struct acrn_vcpu* vcpu; + struct multiboot_info *mbi = NULL; - if (get_cpu_id() != 0) - return; + if (boot_regs[0] != MULTIBOOT_INFO_MAGIC) { + pr_err("no multiboot info found"); + } else { - vcpu = per_cpu(vcpu, 0); - if (vcpu != NULL) { - vlapic_set_intr(vcpu, vector, 0); - } else - pr_err("%s vcpu or vlapic is not ready, interrupt lost\n", - __func__); + mbi = (struct multiboot_info *) hpa2hva(((uint64_t)(uint32_t)boot_regs[1])); + if ((mbi->mi_flags & MULTIBOOT_INFO_HAS_DRIVES) == 0U) { + pr_err("no multiboot drivers for uefi found"); + } else { - return; -} + efi_ctx = (struct efi_context *)hpa2hva((uint64_t)mbi->mi_drives_addr); + if (efi_ctx == NULL) { + pr_err("no uefi context found"); + } else { -int32_t uefi_sw_loader(struct acrn_vm *vm) -{ - int32_t ret = 0; - struct acrn_vcpu *vcpu = get_primary_vcpu(vm); - struct acrn_vcpu_regs *vcpu_regs = &boot_context; - - ASSERT(vm != NULL, "Incorrect argument"); - - pr_dbg("Loading guest to run-time location"); - - vlapic_restore(vcpu_vlapic(vcpu), &uefi_lapic_regs); - - /* For UEFI platform, the bsp init regs come from two places: - * 1. saved in efi_boot: gpregs, rip - * 2. saved when HV started: other registers - * We copy the info saved in efi_boot to boot_context and - * init bsp with boot_context. - */ - memcpy_s(&(vcpu_regs->gprs), sizeof(struct acrn_gp_regs), - &(efi_ctx->vcpu_regs.gprs), sizeof(struct acrn_gp_regs)); - - vcpu_regs->rip = efi_ctx->vcpu_regs.rip; - set_vcpu_regs(vcpu, vcpu_regs); - - /* defer irq enabling till vlapic is ready */ - CPU_IRQ_ENABLE(); - - return ret; + save_lapic(&uefi_lapic_regs); + efi_initialized = 1; + } + } + } } void *get_rsdp_from_uefi(void) { - if (!efi_initialized) + if (!efi_initialized) { efi_init(); + } return hpa2hva((uint64_t)efi_ctx->rsdp); } @@ -76,30 +54,16 @@ void *get_ap_trampoline_buf(void) return efi_ctx->ap_trampoline_buf; } -static void efi_init(void) +const struct efi_context *get_efi_ctx(void) { - struct multiboot_info *mbi = NULL; - - if (boot_regs[0] != MULTIBOOT_INFO_MAGIC) - ASSERT(0, "no multiboot info found"); - - mbi = (struct multiboot_info *) - hpa2hva(((uint64_t)(uint32_t)boot_regs[1])); - - if (!(mbi->mi_flags & MULTIBOOT_INFO_HAS_DRIVES)) - ASSERT(0, "no multiboot drivers for uefi found"); - - efi_ctx = (struct efi_context *)hpa2hva((uint64_t)mbi->mi_drives_addr); - ASSERT(efi_ctx != NULL, "no uefi context found"); - - vm_sw_loader = uefi_sw_loader; - - spurious_handler = (spurious_handler_t)efi_spurious_handler; - - save_lapic(&uefi_lapic_regs); - - efi_initialized = 1; + return efi_ctx; } + +const struct lapic_regs *get_efi_lapic_regs(void) +{ + return &uefi_lapic_regs; +} + #endif void init_bsp(void) diff --git a/hypervisor/include/arch/x86/guest/vm0_boot.h b/hypervisor/include/arch/x86/guest/vm0_boot.h index 27ef6e60e..e41ec0ba4 100644 --- a/hypervisor/include/arch/x86/guest/vm0_boot.h +++ b/hypervisor/include/arch/x86/guest/vm0_boot.h @@ -14,8 +14,7 @@ struct efi_context { void *ap_trampoline_buf; } __packed; -void *get_rsdp_from_uefi(void); -void *get_ap_trampoline_buf(void); +int32_t efi_boot_init(void); #endif #endif /* VM0_BOOT_H */