Factor out CPUID code in mdrandom(), invoke it once, then save the result. I'll use it to switch behavior depending on HV or not.
efiboot is not tested. Comments?
>From 104cb04bbbd0f7e40758938cc3103b2370a2285c Mon Sep 17 00:00:00 2001 From: Masao Uebayashi <[email protected]> Date: Thu, 10 Mar 2016 21:03:07 +0900 Subject: [PATCH 1/3] Factor out CPUID instruction in amd64 boot code --- sys/arch/amd64/stand/boot/Makefile | 1 + sys/arch/amd64/stand/boot/srt0.S | 1 + sys/arch/amd64/stand/cdboot/Makefile | 1 + sys/arch/amd64/stand/cdboot/srt0.S | 2 + sys/arch/amd64/stand/libsa/cpuid.S | 69 ++++++++++++++++++++++++++++++++ sys/arch/amd64/stand/libsa/libsa.h | 7 ++++ sys/arch/amd64/stand/libsa/random_i386.S | 22 +--------- sys/arch/amd64/stand/pxeboot/Makefile | 1 + sys/arch/amd64/stand/pxeboot/srt0.S | 2 + 9 files changed, 86 insertions(+), 20 deletions(-) create mode 100644 sys/arch/amd64/stand/libsa/cpuid.S diff --git a/sys/arch/amd64/stand/boot/Makefile b/sys/arch/amd64/stand/boot/Makefile index 359ea31..5811646 100644 --- a/sys/arch/amd64/stand/boot/Makefile +++ b/sys/arch/amd64/stand/boot/Makefile @@ -26,6 +26,7 @@ SRCS+= boot.c bootarg.c cmd.c vars.c .PATH: ${SADIR}/libsa SRCS+= gidt.S random_i386.S +SRCS+= cpuid.S SRCS+= cmd_i386.c dev_i386.c exec_i386.c gateA20.c machdep.c SRCS+= bioscons.c biosdev.c diskprobe.c memprobe.c time.c .if ${SOFTRAID:L} == "yes" diff --git a/sys/arch/amd64/stand/boot/srt0.S b/sys/arch/amd64/stand/boot/srt0.S index 9e1ede6..c2a5b2a 100644 --- a/sys/arch/amd64/stand/boot/srt0.S +++ b/sys/arch/amd64/stand/boot/srt0.S @@ -87,6 +87,7 @@ _start: rep; stosb call _ASM_LABEL(pmm_init) + call _C_LABEL(initcpuid) call _C_LABEL(boot) jmp _C_LABEL(_rtt) diff --git a/sys/arch/amd64/stand/cdboot/Makefile b/sys/arch/amd64/stand/cdboot/Makefile index 23a261f..04ba1e9 100644 --- a/sys/arch/amd64/stand/cdboot/Makefile +++ b/sys/arch/amd64/stand/cdboot/Makefile @@ -19,6 +19,7 @@ BINMODE=644 SRCS+= machdep.c dev_i386.c exec_i386.c cmd_i386.c SRCS+= gidt.S random_i386.S biosdev.c bioscons.c gateA20.c \ memprobe.c diskprobe.c time.c +SRCS+= cpuid.S SRCS+= softraid.c .PATH: ${S}/stand/boot diff --git a/sys/arch/amd64/stand/cdboot/srt0.S b/sys/arch/amd64/stand/cdboot/srt0.S index 82ff009..abe40d4 100644 --- a/sys/arch/amd64/stand/cdboot/srt0.S +++ b/sys/arch/amd64/stand/cdboot/srt0.S @@ -177,6 +177,8 @@ relocated: movl %eax, _C_LABEL(bios_bootdev) movl %eax, _C_LABEL(bios_cddev) + call _C_LABEL(initcpuid) + /* * Now call "main()". * diff --git a/sys/arch/amd64/stand/libsa/cpuid.S b/sys/arch/amd64/stand/libsa/cpuid.S new file mode 100644 index 0000000..c3ca1ac --- /dev/null +++ b/sys/arch/amd64/stand/libsa/cpuid.S @@ -0,0 +1,69 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2016 Masao Uebayashi <[email protected]> + * Copyright (c) 2013 Joel Sing <[email protected]> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <machine/param.h> +#include <machine/asm.h> +#include <machine/psl.h> +#include <machine/specialreg.h> + + .data + + .globl _C_LABEL(cpu_id) + .globl _C_LABEL(cpu_feature) + .globl _C_LABEL(cpu_ebxfeature) + .globl _C_LABEL(cpu_ecxfeature) + +_C_LABEL(cpu_id): .long 0 +_C_LABEL(cpu_feature): .long 0 +_C_LABEL(cpu_ebxfeature): .long 0 +_C_LABEL(cpu_ecxfeature): .long 0 + + .text + +ENTRY(initcpuid) + pushal + + // See if we have CPU identification. + pushfl + popl %eax + movl %eax, %ecx + orl $PSL_ID, %eax + pushl %eax + popfl + pushfl + popl %eax + pushl %ecx + popfl + andl $PSL_ID, %eax + jz done + + // CPUID leaf = 1, subleaf = 0 + movl $1, %eax + movl $0, %ecx + cpuid + + movl %eax, _C_LABEL(cpu_id) + movl %ebx, _C_LABEL(cpu_ebxfeature) + movl %ecx, _C_LABEL(cpu_ecxfeature) + movl %edx, _C_LABEL(cpu_feature) + +done: + popal + ret +END(initcpuid) diff --git a/sys/arch/amd64/stand/libsa/libsa.h b/sys/arch/amd64/stand/libsa/libsa.h index fc65c6f..1934078 100644 --- a/sys/arch/amd64/stand/libsa/libsa.h +++ b/sys/arch/amd64/stand/libsa/libsa.h @@ -77,3 +77,10 @@ extern u_int32_t bios_cksumlen; #define MACHINE_CMD cmd_machine /* we have i386-specific commands */ #define CHECK_SKIP_CONF check_skip_conf /* we can skip boot.conf with Ctrl */ + +/* cpuid.S */ +void initcpuid(void); +extern u_int32_t cpu_id; +extern u_int32_t cpu_feature; +extern u_int32_t cpu_ebxfeature; +extern u_int32_t cpu_ecxfeature; diff --git a/sys/arch/amd64/stand/libsa/random_i386.S b/sys/arch/amd64/stand/libsa/random_i386.S index 5e28b40..9d09379 100644 --- a/sys/arch/amd64/stand/libsa/random_i386.S +++ b/sys/arch/amd64/stand/libsa/random_i386.S @@ -28,34 +28,16 @@ ENTRY(mdrandom) pushal - // See if we have CPU identification. - pushfl - popl %eax - movl %eax, %ecx - orl $PSL_ID, %eax - pushl %eax - popfl - pushfl - popl %eax - pushl %ecx - popfl - andl $PSL_ID, %eax - jz done - - // CPUID leaf = 1, subleaf = 0 - movl $1, %eax - movl $0, %ecx - cpuid - movl %edx, %eax - movl 36(%esp), %ebx movl 40(%esp), %edx xorl %edi, %edi + movl _C_LABEL(cpu_ecxfeature), %ecx andl $CPUIDECX_RDRAND, %ecx // See if we have rdrand. jnz userand movl %edx, %ecx + movl _C_LABEL(cpu_feature), %eax andl $CPUID_TSC, %eax // See if we have rdtsc. jnz usetsc diff --git a/sys/arch/amd64/stand/pxeboot/Makefile b/sys/arch/amd64/stand/pxeboot/Makefile index ddf2880..468c7f0 100644 --- a/sys/arch/amd64/stand/pxeboot/Makefile +++ b/sys/arch/amd64/stand/pxeboot/Makefile @@ -20,6 +20,7 @@ BINMODE=644 SRCS+= machdep.c exec_i386.c cmd_i386.c SRCS+= gidt.S random_i386.S biosdev.c bioscons.c gateA20.c \ memprobe.c diskprobe.c time.c ## biosprobe.c +SRCS+= cpuid.S SRCS+= pxe.c pxe_call.S pxe_net.c pxe_udp.c SRCS+= softraid.c diff --git a/sys/arch/amd64/stand/pxeboot/srt0.S b/sys/arch/amd64/stand/pxeboot/srt0.S index 9c9226d..ee79225 100644 --- a/sys/arch/amd64/stand/pxeboot/srt0.S +++ b/sys/arch/amd64/stand/pxeboot/srt0.S @@ -172,6 +172,8 @@ relocated: movl $pxe_progname, %eax movl %eax, progname + call _C_LABEL(initcpuid) + /* * Now call "main()". * -- 2.7.0
>From c3072b7c101bd76d9c76b57bd317ce1829ebb153 Mon Sep 17 00:00:00 2001 From: Masao Uebayashi <[email protected]> Date: Thu, 17 Mar 2016 14:48:20 +0900 Subject: [PATCH 2/3] Implement CPUID in i386 boot loaders too --- sys/arch/i386/stand/boot/Makefile | 1 + sys/arch/i386/stand/boot/srt0.S | 1 + sys/arch/i386/stand/cdboot/Makefile | 1 + sys/arch/i386/stand/cdboot/srt0.S | 2 ++ sys/arch/i386/stand/libsa/cpuid.S | 69 ++++++++++++++++++++++++++++++++++++ sys/arch/i386/stand/libsa/libsa.h | 7 ++++ sys/arch/i386/stand/pxeboot/Makefile | 1 + sys/arch/i386/stand/pxeboot/srt0.S | 2 ++ 8 files changed, 84 insertions(+) create mode 100644 sys/arch/i386/stand/libsa/cpuid.S diff --git a/sys/arch/i386/stand/boot/Makefile b/sys/arch/i386/stand/boot/Makefile index 4339b82..c01c160 100644 --- a/sys/arch/i386/stand/boot/Makefile +++ b/sys/arch/i386/stand/boot/Makefile @@ -29,6 +29,7 @@ SRCS+= boot.c bootarg.c cmd.c vars.c .PATH: ${SADIR}/libsa SRCS+= debug_i386.S SRCS+= gidt.S random_i386.S +SRCS+= cpuid.S SRCS+= apmprobe.c debug.c pciprobe.c ps2probe.c SRCS+= cmd_i386.c dev_i386.c exec_i386.c gateA20.c machdep.c SRCS+= bioscons.c biosdev.c diskprobe.c memprobe.c time.c diff --git a/sys/arch/i386/stand/boot/srt0.S b/sys/arch/i386/stand/boot/srt0.S index 868b326..07f4240 100644 --- a/sys/arch/i386/stand/boot/srt0.S +++ b/sys/arch/i386/stand/boot/srt0.S @@ -87,6 +87,7 @@ _start: rep; stosb call _ASM_LABEL(pmm_init) + call _C_LABEL(initcpuid) call _C_LABEL(boot) jmp _C_LABEL(_rtt) diff --git a/sys/arch/i386/stand/cdboot/Makefile b/sys/arch/i386/stand/cdboot/Makefile index 6306887..a533af4 100644 --- a/sys/arch/i386/stand/cdboot/Makefile +++ b/sys/arch/i386/stand/cdboot/Makefile @@ -18,6 +18,7 @@ CLEANFILES+= crt0.o ${PROG}.whole .PATH: ${SADIR}/libsa SRCS+= debug_i386.S gidt.S random_i386.S +SRCS+= cpuid.S SRCS+= cmd_i386.c dev_i386.c exec_i386.c gateA20.c machdep.c SRCS+= apmprobe.c bioscons.c biosdev.c debug.c diskprobe.c memprobe.c \ pciprobe.c ps2probe.c time.c diff --git a/sys/arch/i386/stand/cdboot/srt0.S b/sys/arch/i386/stand/cdboot/srt0.S index 5a721e2..b9b1a19 100644 --- a/sys/arch/i386/stand/cdboot/srt0.S +++ b/sys/arch/i386/stand/cdboot/srt0.S @@ -177,6 +177,8 @@ relocated: movl %eax, _C_LABEL(bios_bootdev) movl %eax, _C_LABEL(bios_cddev) + call _C_LABEL(initcpuid) + /* * Now call "main()". * diff --git a/sys/arch/i386/stand/libsa/cpuid.S b/sys/arch/i386/stand/libsa/cpuid.S new file mode 100644 index 0000000..c3ca1ac --- /dev/null +++ b/sys/arch/i386/stand/libsa/cpuid.S @@ -0,0 +1,69 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2016 Masao Uebayashi <[email protected]> + * Copyright (c) 2013 Joel Sing <[email protected]> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <machine/param.h> +#include <machine/asm.h> +#include <machine/psl.h> +#include <machine/specialreg.h> + + .data + + .globl _C_LABEL(cpu_id) + .globl _C_LABEL(cpu_feature) + .globl _C_LABEL(cpu_ebxfeature) + .globl _C_LABEL(cpu_ecxfeature) + +_C_LABEL(cpu_id): .long 0 +_C_LABEL(cpu_feature): .long 0 +_C_LABEL(cpu_ebxfeature): .long 0 +_C_LABEL(cpu_ecxfeature): .long 0 + + .text + +ENTRY(initcpuid) + pushal + + // See if we have CPU identification. + pushfl + popl %eax + movl %eax, %ecx + orl $PSL_ID, %eax + pushl %eax + popfl + pushfl + popl %eax + pushl %ecx + popfl + andl $PSL_ID, %eax + jz done + + // CPUID leaf = 1, subleaf = 0 + movl $1, %eax + movl $0, %ecx + cpuid + + movl %eax, _C_LABEL(cpu_id) + movl %ebx, _C_LABEL(cpu_ebxfeature) + movl %ecx, _C_LABEL(cpu_ecxfeature) + movl %edx, _C_LABEL(cpu_feature) + +done: + popal + ret +END(initcpuid) diff --git a/sys/arch/i386/stand/libsa/libsa.h b/sys/arch/i386/stand/libsa/libsa.h index 76bf1e0..9539376 100644 --- a/sys/arch/i386/stand/libsa/libsa.h +++ b/sys/arch/i386/stand/libsa/libsa.h @@ -81,3 +81,10 @@ extern u_int32_t bios_cksumlen; #define MACHINE_CMD cmd_machine /* we have i386-specific commands */ #define CHECK_SKIP_CONF check_skip_conf /* we can skip boot.conf with Ctrl */ + +/* cpuid.S */ +void initcpuid(void); +extern u_int32_t cpu_id; +extern u_int32_t cpu_feature; +extern u_int32_t cpu_ebxfeature; +extern u_int32_t cpu_ecxfeature; diff --git a/sys/arch/i386/stand/pxeboot/Makefile b/sys/arch/i386/stand/pxeboot/Makefile index 9227246..f26e020 100644 --- a/sys/arch/i386/stand/pxeboot/Makefile +++ b/sys/arch/i386/stand/pxeboot/Makefile @@ -21,6 +21,7 @@ SRCS+= debug_i386.S gidt.S random_i386.S SRCS+= cmd_i386.c exec_i386.c gateA20.c machdep.c SRCS+= apmprobe.c bioscons.c biosdev.c debug.c diskprobe.c memprobe.c \ pciprobe.c ps2probe.c time.c +SRCS+= cpuid.S SRCS+= pxe_call.S pxe.c pxe_net.c pxe_udp.c SRCS+= softraid.c diff --git a/sys/arch/i386/stand/pxeboot/srt0.S b/sys/arch/i386/stand/pxeboot/srt0.S index 16a0313..a62ee6a 100644 --- a/sys/arch/i386/stand/pxeboot/srt0.S +++ b/sys/arch/i386/stand/pxeboot/srt0.S @@ -172,6 +172,8 @@ relocated: movl $pxe_progname, %eax movl %eax, progname + call _C_LABEL(initcpuid) + /* * Now call "main()". * -- 2.7.0
