Index: head/stand/defs.mk =================================================================== --- head/stand/defs.mk +++ head/stand/defs.mk @@ -189,14 +189,15 @@ ${SYSDIR}/teken/sequences > teken_state.h .if !defined(NO_OBJ) -_ILINKS=machine +_ILINKS=include/machine .if ${MACHINE} != ${MACHINE_CPUARCH} && ${MACHINE} != "arm64" -_ILINKS+=${MACHINE_CPUARCH} +_ILINKS+=include/${MACHINE_CPUARCH} .endif .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" -_ILINKS+=x86 +_ILINKS+=include/x86 .endif -CLEANFILES+=${_ILINKS} +CFLAGS+= -Iinclude +CLEANDIRS+= include beforedepend: ${_ILINKS} beforebuild: ${_ILINKS} @@ -211,8 +212,8 @@ .NOPATH: ${_ILINKS} -${_ILINKS}: - @case ${.TARGET} in \ +${_ILINKS}: .NOMETA + @case ${.TARGET:T} in \ machine) \ if [ ${DO32:U0} -eq 0 ]; then \ path=${SYSDIR}/${MACHINE}/include ; \ @@ -222,8 +223,11 @@ *) \ path=${SYSDIR}/${.TARGET:T}/include ;; \ esac ; \ + case ${.TARGET} in \ + */*) mkdir -p ${.TARGET:H};; \ + esac ; \ path=`(cd $$path && /bin/pwd)` ; \ - ${ECHO} ${.TARGET:T} "->" $$path ; \ - ln -fhs $$path ${.TARGET:T} + ${ECHO} ${.TARGET} "->" $$path ; \ + ln -fhs $$path ${.TARGET} .endif # !NO_OBJ .endif # __BOOT_DEFS_MK__ Index: head/stand/ficl/amd64/sysdep.c =================================================================== --- head/stand/ficl/amd64/sysdep.c +++ head/stand/ficl/amd64/sysdep.c @@ -17,6 +17,8 @@ #endif #include "ficl.h" +#include "../x86/sysdep.c" + /* ******************* FreeBSD P O R T B E G I N S H E R E ******************** Michael Smith */ Index: head/stand/ficl/i386/sysdep.c =================================================================== --- head/stand/ficl/i386/sysdep.c +++ head/stand/ficl/i386/sysdep.c @@ -14,12 +14,11 @@ #include #else #include -#ifdef __i386__ -#include #endif -#endif #include "ficl.h" +#include "../x86/sysdep.c" + /* ******************* FreeBSD P O R T B E G I N S H E R E ******************** Michael Smith */ @@ -80,53 +79,6 @@ free(p); } -#ifndef TESTMAIN -/* - * outb ( port# c -- ) - * Store a byte to I/O port number port# - */ -void -ficlOutb(FICL_VM *pVM) -{ - u_char c; - uint32_t port; - - port=stackPopUNS(pVM->pStack); - c=(u_char)stackPopINT(pVM->pStack); - outb(port,c); -} - -/* - * inb ( port# -- c ) - * Fetch a byte from I/O port number port# - */ -void -ficlInb(FICL_VM *pVM) -{ - u_char c; - uint32_t port; - - port=stackPopUNS(pVM->pStack); - c=inb(port); - stackPushINT(pVM->pStack,c); -} - -/* - * Glue function to add the appropriate forth words to access x86 special cpu - * functionality. - */ -static void ficlCompileCpufunc(FICL_SYSTEM *pSys) -{ - FICL_DICT *dp = pSys->dp; - assert (dp); - - dictAppendWord(dp, "outb", ficlOutb, FW_DEFAULT); - dictAppendWord(dp, "inb", ficlInb, FW_DEFAULT); -} - -FICL_COMPILE_SET(ficlCompileCpufunc); - -#endif /* ** Stub function for dictionary access control - does nothing Index: head/stand/ficl/loader.c =================================================================== --- head/stand/ficl/loader.c +++ head/stand/ficl/loader.c @@ -287,6 +287,32 @@ return; } +#ifndef TESTMAIN + +/* isvirtualized? - Return whether the loader runs under a + * hypervisor. + * + * isvirtualized? ( -- flag ) + */ +static void +ficlIsvirtualizedQ(FICL_VM *pVM) +{ + FICL_INT flag; + const char *hv; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 0, 1); +#endif + + hv = (archsw.arch_hypervisor != NULL) + ? (*archsw.arch_hypervisor)() + : NULL; + flag = (hv != NULL) ? FICL_TRUE : FICL_FALSE; + stackPushINT(pVM->pStack, flag); +} + +#endif /* ndef TESTMAIN */ + void ficlCcall(FICL_VM *pVM) { @@ -840,7 +866,10 @@ dictAppendWord(dp, "ccall", ficlCcall, FW_DEFAULT); dictAppendWord(dp, "uuid-from-string", ficlUuidFromString, FW_DEFAULT); dictAppendWord(dp, "uuid-to-string", ficlUuidToString, FW_DEFAULT); - +#ifndef TESTMAIN + dictAppendWord(dp, "isvirtualized?",ficlIsvirtualizedQ, FW_DEFAULT); +#endif + SET_FOREACH(fnpp, Xficl_compile_set) (*fnpp)(pSys); Index: head/stand/ficl/x86/sysdep.c =================================================================== --- head/stand/ficl/x86/sysdep.c +++ head/stand/ficl/x86/sysdep.c @@ -0,0 +1,51 @@ +/* $FreeBSD$ */ + +#ifndef TESTMAIN +#include + +/* + * outb ( port# c -- ) + * Store a byte to I/O port number port# + */ +void +ficlOutb(FICL_VM *pVM) +{ + u_char c; + uint32_t port; + + port=stackPopUNS(pVM->pStack); + c=(u_char)stackPopINT(pVM->pStack); + outb(port,c); +} + +/* + * inb ( port# -- c ) + * Fetch a byte from I/O port number port# + */ +void +ficlInb(FICL_VM *pVM) +{ + u_char c; + uint32_t port; + + port=stackPopUNS(pVM->pStack); + c=inb(port); + stackPushINT(pVM->pStack,c); +} + +/* + * Glue function to add the appropriate forth words to access x86 special cpu + * functionality. + */ +static void ficlCompileCpufunc(FICL_SYSTEM *pSys) +{ + FICL_DICT *dp = pSys->dp; + assert (dp); + + dictAppendWord(dp, "outb", ficlOutb, FW_DEFAULT); + dictAppendWord(dp, "inb", ficlInb, FW_DEFAULT); +} + +FICL_COMPILE_SET(ficlCompileCpufunc); + +#endif Index: head/stand/i386/loader/main.c =================================================================== --- head/stand/i386/loader/main.c +++ head/stand/i386/loader/main.c @@ -167,6 +167,7 @@ archsw.arch_readin = i386_readin; archsw.arch_isainb = isa_inb; archsw.arch_isaoutb = isa_outb; + archsw.arch_hypervisor = x86_hypervisor; #ifdef LOADER_ZFS_SUPPORT archsw.arch_zfs_probe = i386_zfs_probe; Index: head/stand/libsa/Makefile =================================================================== --- head/stand/libsa/Makefile +++ head/stand/libsa/Makefile @@ -71,6 +71,11 @@ SRCS+= udivmoddi4.c udivmodsi4.c udivdi3.c udivsi3.c umoddi3.c umodsi3.c SRCS+= ashldi3.c ashrdi3.c lshrdi3.c +.if ${MACHINE_CPUARCH:Namd64:Ni386} == "" +.PATH: ${SASRC}/x86 +SRCS+= hypervisor.c +.endif + .if ${MACHINE_CPUARCH} == "powerpc" SRCS+= syncicache.c .endif Index: head/stand/libsa/stand.h =================================================================== --- head/stand/libsa/stand.h +++ head/stand/libsa/stand.h @@ -434,6 +434,8 @@ void Free(void *, const char *, int); extern void mallocstats(void); +const char *x86_hypervisor(void); + #ifdef DEBUG_MALLOC #define malloc(x) Malloc(x, __FILE__, __LINE__) #define memalign(x, y) Memalign(x, y, __FILE__, __LINE__) Index: head/stand/libsa/x86/hypervisor.c =================================================================== --- head/stand/libsa/x86/hypervisor.c +++ head/stand/libsa/x86/hypervisor.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2013-2019 Juniper Networks, Inc. + * All rights reserved. + * + * 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 +#include +#include + +const char * +x86_hypervisor(void) +{ + static union { + struct { + u_int high; + char name[13]; + } hv; + u_int regs[4]; + } u; + + /* Return NULL when no hypervisor is present. */ + do_cpuid(1, u.regs); + if ((u.regs[2] & CPUID2_HV) == 0) + return (NULL); + /* Return the hypervisor's identification. */ + do_cpuid(0x40000000, u.regs); + return (u.hv.name); +}