1/* $NetBSD: i386-asm.S,v 1.7 2019/05/21 05:29:21 mlelstv Exp $ */ 2 3/*- 4 * Copyright (c) 1998, 2000, 2004, 2006, 2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <machine/asm.h> 30#include <machine/cputypes.h> 31#include <machine/psl.h> 32 33/* From sys/arch/x86/include/cpufunc.h */ 34#define OPTERON_MSR_PASSCODE 0x9c5a203aU 35 36 .text 37 38ENTRY(x86_cpuid2) 39 pushl %ebx 40 pushl %edi 41 movl 12(%esp), %eax 42 movl 16(%esp), %ecx 43 movl 20(%esp), %edi 44 cpuid 45 movl %eax, 0(%edi) 46 movl %ebx, 4(%edi) 47 movl %ecx, 8(%edi) 48 movl %edx, 12(%edi) 49 popl %edi 50 popl %ebx 51 ret 52END(x86_cpuid2) 53 54ENTRY(x86_xgetbv) 55 xorl %ecx, %ecx 56 xgetbv 57 ret 58END(x86_xgetbv) 59 60ENTRY(x86_identify) 61 /* Try to toggle alignment check flag; does not exist on 386. */ 62 pushfl 63 popl %eax 64 movl %eax,%ecx 65 orl $PSL_AC,%eax 66 pushl %eax 67 popfl 68 pushfl 69 popl %eax 70 xorl %ecx,%eax 71 andl $PSL_AC,%eax 72 pushl %ecx 73 popfl 74 testl %eax,%eax 75 jnz try486 76 77 /* 78 * Try the test of a NexGen CPU -- ZF will not change on a DIV 79 * instruction on a NexGen, it will on an i386. Documented in 80 * Nx586 Processor Recognition Application Note, NexGen, Inc. 81 */ 82 movl $0x5555,%eax 83 xorl %edx,%edx 84 movl $2,%ecx 85 divl %ecx 86 jnz is386 87 88isnx586: 89 /* 90 * Don't try cpuid, as Nx586s reportedly don't support the 91 * PSL_ID bit. 92 */ 93 movl $CPU_NX586,%eax 94 ret 95is386: 96 movl $CPU_386,%eax 97 ret 98 99try486: /* Try to toggle identification flag; does not exist on early 486s. */ 100 pushfl 101 popl %eax 102 movl %eax,%ecx 103 xorl $PSL_ID,%eax 104 pushl %eax 105 popfl 106 pushfl 107 popl %eax 108 xorl %ecx,%eax 109 andl $PSL_ID,%eax 110 pushl %ecx 111 popfl 112 113 testl %eax,%eax 114 jz is486 115 116 /* Later cpu, caller will use cpuid instruction */ 117 movl $-1,%eax 118 ret 119 120is486: 121 /* 122 * Check Cyrix CPU 123 * Cyrix CPUs do not change the undefined flags following 124 * execution of the divide instruction which divides 5 by 2. 125 * 126 * Note: CPUID is enabled on M2, so it passes another way. 127 */ 128 pushfl 129 movl $0x5555, %eax 130 xorl %edx, %edx 131 movl $2, %ecx 132 clc 133 divl %ecx 134 jnc trycyrix486 135 popfl 136 movl $CPU_486,%eax 137 ret 138 139trycyrix486: 140 popfl 141 /* 142 * Check for Cyrix 486 CPU by seeing if the flags change during a 143 * divide. This is documented in the Cx486SLC/e SMM Programmer's 144 * Guide. 145 */ 146 xorl %edx,%edx 147 cmpl %edx,%edx # set flags to known state 148 pushl %ebx 149 pushfl 150 popl %ecx # store flags in ecx 151 movl $-1,%eax 152 movl $4,%ebx 153 divl %ebx # do a long division 154 pushfl 155 popl %eax 156 popl %ebx 157 xorl %ecx,%eax # are the flags different? 158 testl $0x8d5,%eax # only check C|PF|AF|Z|N|V 159 je is486dlc # yes => must be Cyrix 6x86 CPU 160 movl $CPU_6x86,%eax 161 ret 162 163is486dlc: 164 movl $CPU_486DLC,%eax 165 ret 166 167