Index: sys/amd64/acpica/acpi_wakeup.c =================================================================== --- sys/amd64/acpica/acpi_wakeup.c +++ sys/amd64/acpica/acpi_wakeup.c @@ -147,7 +147,7 @@ int cpu; u_char mpbiosreason; - if (!efi_boot) { + if (firmware_type != FW_UEFI) { /* save the current value of the warm-start vector */ mpbioswarmvec = *((uint32_t *)WARMBOOT_OFF); outb(CMOS_REG, BIOS_RESET); @@ -172,7 +172,7 @@ } } - if (!efi_boot) { + if (firmware_type != FW_UEFI) { /* restore the warmstart vector */ *(uint32_t *)WARMBOOT_OFF = mpbioswarmvec; Index: sys/amd64/amd64/machdep.c =================================================================== --- sys/amd64/amd64/machdep.c +++ sys/amd64/amd64/machdep.c @@ -223,8 +223,6 @@ void (*vmm_resume_p)(void); -bool efi_boot; - static void cpu_startup(dummy) void *dummy; @@ -1167,21 +1165,20 @@ * ie: an int32_t immediately precedes smap. */ - efihdr = (struct efi_map_header *)preload_search_info(kmdp, - MODINFO_METADATA | MODINFOMD_EFI_MAP); + if (firmware_type == FW_UEFI) { + efihdr = (struct efi_map_header *)preload_search_info(kmdp, + MODINFO_METADATA | MODINFOMD_EFI_MAP); + add_efi_map_entries(efihdr, physmap, physmap_idx); + return; + } + smap = (struct bios_smap *)preload_search_info(kmdp, MODINFO_METADATA | MODINFOMD_SMAP); - if (efihdr == NULL && smap == NULL) + if (smap == NULL) panic("No BIOS smap or EFI map info from loader!"); - if (efihdr != NULL) { - add_efi_map_entries(efihdr, physmap, physmap_idx); - strlcpy(bootmethod, "UEFI", sizeof(bootmethod)); - } else { - size = *((u_int32_t *)smap - 1); - bios_add_smap_entries(smap, size, physmap, physmap_idx); - strlcpy(bootmethod, "BIOS", sizeof(bootmethod)); - } + size = *((u_int32_t *)smap - 1); + bios_add_smap_entries(smap, size, physmap, physmap_idx); } #define PAGES_PER_GB (1024 * 1024 * 1024 / PAGE_SIZE) @@ -1634,10 +1631,15 @@ kmdp = init_ops.parse_preload_data(modulep); - efi_boot = preload_search_info(kmdp, MODINFO_METADATA | - MODINFOMD_EFI_MAP) != NULL; + if (firmware_type == FW_NONE) { + if (preload_search_info(kmdp, MODINFO_METADATA | + MODINFOMD_EFI_MAP) != NULL) + firmware_type = FW_UEFI; + else + firmware_type = FW_BIOS; + } - if (!efi_boot) { + if (firmware_type != FW_UEFI) { /* Tell the bios to warmboot next time */ atomic_store_short((u_short *)0x472, 0x1234); } @@ -1793,7 +1795,7 @@ * Once bootblocks have updated, we can test directly for * efi_systbl != NULL here... */ - if (efi_boot) + if (firmware_type == FW_UEFI) vty_set_preferred(VTY_VT); TUNABLE_INT_FETCH("hw.ibrs_disable", &hw_ibrs_disable); Index: sys/amd64/amd64/mp_machdep.c =================================================================== --- sys/amd64/amd64/mp_machdep.c +++ sys/amd64/amd64/mp_machdep.c @@ -393,13 +393,13 @@ printf("AP boot address %#lx\n", boot_address); /* save the current value of the warm-start vector */ - if (!efi_boot) + if (firmware_type != FW_UEFI) mpbioswarmvec = *((u_int32_t *) WARMBOOT_OFF); outb(CMOS_REG, BIOS_RESET); mpbiosreason = inb(CMOS_DATA); /* setup a vector to our boot code */ - if (!efi_boot) { + if (firmware_type != FW_UEFI) { *((volatile u_short *)WARMBOOT_OFF) = WARMBOOT_TARGET; *((volatile u_short *)WARMBOOT_SEG) = (boot_address >> 4); } @@ -446,7 +446,7 @@ /* attempt to start the Application Processor */ if (!start_ap(apic_id, boot_address)) { /* restore the warmstart vector */ - if (!efi_boot) + if (firmware_type != FW_UEFI) *(u_int32_t *)WARMBOOT_OFF = mpbioswarmvec; panic("AP #%d (PHY# %d) failed!", cpu, apic_id); } @@ -455,7 +455,7 @@ } /* restore the warmstart vector */ - if (!efi_boot) + if (firmware_type != FW_UEFI) *(u_int32_t *)WARMBOOT_OFF = mpbioswarmvec; outb(CMOS_REG, BIOS_RESET); Index: sys/amd64/include/md_var.h =================================================================== --- sys/amd64/include/md_var.h +++ sys/amd64/include/md_var.h @@ -52,8 +52,6 @@ extern vm_paddr_t kernphys; extern vm_paddr_t KERNend; -extern bool efi_boot; - struct savefpu; struct sysentvec; Index: sys/arm64/arm64/machdep.c =================================================================== --- sys/arm64/arm64/machdep.c +++ sys/arm64/arm64/machdep.c @@ -1291,8 +1291,10 @@ /* Load the physical memory ranges */ efihdr = (struct efi_map_header *)preload_search_info(kmdp, MODINFO_METADATA | MODINFOMD_EFI_MAP); - if (efihdr != NULL) + if (efihdr != NULL) { add_efi_map_entries(efihdr); + firmware_type = FW_UEFI; + } #ifdef FDT else { /* Grab physical memory regions information from device tree. */ Index: sys/conf/files.arm64 =================================================================== --- sys/conf/files.arm64 +++ sys/conf/files.arm64 @@ -4,6 +4,7 @@ ## Kernel ## +kern/bootmethod.c standard kern/msi_if.m optional intrng kern/pic_if.m optional intrng kern/subr_devmap.c standard Index: sys/conf/files.x86 =================================================================== --- sys/conf/files.x86 +++ sys/conf/files.x86 @@ -279,6 +279,7 @@ dev/qat/qat_dh895xcc.c optional qat dev/qat/qat_hw15.c optional qat dev/qat/qat_hw17.c optional qat +kern/bootmethod.c standard libkern/x86/crc32_sse42.c standard # # x86 shared code between IA32 and AMD64 architectures Index: sys/dev/xen/efi/pvefi.c =================================================================== --- sys/dev/xen/efi/pvefi.c +++ sys/dev/xen/efi/pvefi.c @@ -43,8 +43,6 @@ #include -extern char bootmethod[16]; - static int rt_ok(void) { @@ -224,7 +222,7 @@ rt_disabled = 0; TUNABLE_INT_FETCH("efi.rt.disabled", &rt_disabled); - if (!xen_initial_domain() || strcmp("UEFI", bootmethod) != 0 || + if (!xen_initial_domain() || firmware_type != FW_UEFI || rt_disabled == 1) return (0); Index: sys/i386/i386/machdep.c =================================================================== --- sys/i386/i386/machdep.c +++ sys/i386/i386/machdep.c @@ -2350,7 +2350,7 @@ init_param1(); /* Set bootmethod to BIOS: it's the only supported on i386. */ - strlcpy(bootmethod, "BIOS", sizeof(bootmethod)); + firmware_type = FW_BIOS; /* * Make gdt memory segments. All segments cover the full 4GB Index: sys/kern/bootmethod.c =================================================================== --- /dev/null +++ sys/kern/bootmethod.c @@ -0,0 +1,62 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2021 Elliott Mitchell + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include /* for u_* for atomic.h, for systm.h */ +#include /* for MAXPATHLEN for kernel.h */ +#include +#include +#include + + +enum firmware_types firmware_type = FW_NONE; + +static char bootmethod[16]; +SYSCTL_STRING(_machdep, OID_AUTO, bootmethod, CTLFLAG_RD, bootmethod, 0, + "System firmware boot method"); + +/* + * Set the sysctl bootmethod for compatibility + */ +static void set_bootmethod(const void *unused __unused) +{ + const char *const types[] = { + [FW_NONE] = "unknown", + [FW_UEFI] = "UEFI", + [FW_BIOS] = "BIOS", + [FW_LINUXABI] = "LinuxABI", + }; + const char *val = "other"; + + if (firmware_type < nitems(types) && types[firmware_type] != NULL) + val = types[firmware_type]; + + strlcpy(bootmethod, val, sizeof(bootmethod)); +} +C_SYSINIT(set_bootmethod, SI_SUB_LAST, SI_ORDER_SECOND, set_bootmethod, NULL); Index: sys/sys/systm.h =================================================================== --- sys/sys/systm.h +++ sys/sys/systm.h @@ -70,6 +70,15 @@ extern int boothowto; /* reboot flags, from console subsystem */ extern int bootverbose; /* nonzero to print verbose messages */ +extern enum firmware_types { + FW_NONE = 0, + FW_UEFI, + FW_BIOS, + FW_LINUXABI, + FW_HYPER, + FW_LAST +} firmware_type; + extern int maxusers; /* system tune hint */ extern int ngroups_max; /* max # of supplemental groups */ extern int vm_guest; /* Running as virtual machine guest? */ Index: sys/x86/include/x86_var.h =================================================================== --- sys/x86/include/x86_var.h +++ sys/x86/include/x86_var.h @@ -95,7 +95,6 @@ extern int cpu_flush_rsb_ctxsw; extern int x86_rngds_mitg_enable; extern int cpu_amdc1e_bug; -extern char bootmethod[16]; struct pcb; struct thread; Index: sys/x86/x86/cpu_machdep.c =================================================================== --- sys/x86/x86/cpu_machdep.c +++ sys/x86/x86/cpu_machdep.c @@ -113,10 +113,6 @@ static volatile u_int cpu_reset_proxy_active; #endif -char bootmethod[16]; -SYSCTL_STRING(_machdep, OID_AUTO, bootmethod, CTLFLAG_RD, bootmethod, 0, - "System firmware boot method"); - struct msr_op_arg { u_int msr; int op; Index: sys/x86/xen/pv.c =================================================================== --- sys/x86/xen/pv.c +++ sys/x86/xen/pv.c @@ -363,11 +363,6 @@ if (envp != NULL) envp += off; xen_pvh_set_env(envp, reject_option); - - if (MD_FETCH(kmdp, MODINFOMD_EFI_MAP, void *) != NULL) - strlcpy(bootmethod, "UEFI", sizeof(bootmethod)); - else - strlcpy(bootmethod, "BIOS", sizeof(bootmethod)); } else { /* Parse the extra boot information given by Xen */ if (start_info->cmdline_paddr != 0) @@ -375,7 +370,7 @@ (char *)(start_info->cmdline_paddr + KERNBASE), ","); kmdp = NULL; - strlcpy(bootmethod, "XEN", sizeof(bootmethod)); + firmware_type = FW_HYPER; } boothowto |= boot_env_to_howto();