11.7Smlelstv/* $NetBSD: i386-asm.S,v 1.7 2019/05/21 05:29:21 mlelstv Exp $ */ 21.1Sad 31.1Sad/*- 41.1Sad * Copyright (c) 1998, 2000, 2004, 2006, 2007 The NetBSD Foundation, Inc. 51.1Sad * All rights reserved. 61.1Sad * 71.1Sad * Redistribution and use in source and binary forms, with or without 81.1Sad * modification, are permitted provided that the following conditions 91.1Sad * are met: 101.1Sad * 1. Redistributions of source code must retain the above copyright 111.1Sad * notice, this list of conditions and the following disclaimer. 121.1Sad * 2. Redistributions in binary form must reproduce the above copyright 131.1Sad * notice, this list of conditions and the following disclaimer in the 141.1Sad * documentation and/or other materials provided with the distribution. 151.1Sad * 161.1Sad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 171.1Sad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 181.1Sad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 191.1Sad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 201.1Sad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 211.1Sad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 221.1Sad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 231.1Sad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 241.1Sad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 251.1Sad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 261.1Sad * POSSIBILITY OF SUCH DAMAGE. 271.1Sad */ 281.1Sad 291.1Sad#include <machine/asm.h> 301.1Sad#include <machine/cputypes.h> 311.1Sad#include <machine/psl.h> 321.1Sad 331.5Smlelstv/* From sys/arch/x86/include/cpufunc.h */ 341.5Smlelstv#define OPTERON_MSR_PASSCODE 0x9c5a203aU 351.5Smlelstv 361.1Sad .text 371.1Sad 381.1SadENTRY(x86_cpuid2) 391.1Sad pushl %ebx 401.1Sad pushl %edi 411.1Sad movl 12(%esp), %eax 421.1Sad movl 16(%esp), %ecx 431.1Sad movl 20(%esp), %edi 441.1Sad cpuid 451.1Sad movl %eax, 0(%edi) 461.1Sad movl %ebx, 4(%edi) 471.1Sad movl %ecx, 8(%edi) 481.1Sad movl %edx, 12(%edi) 491.1Sad popl %edi 501.1Sad popl %ebx 511.1Sad ret 521.1SadEND(x86_cpuid2) 531.1Sad 541.3SdslENTRY(x86_xgetbv) 551.4Stnn xorl %ecx, %ecx 561.3Sdsl xgetbv 571.3Sdsl ret 581.3SdslEND(x86_xgetbv) 591.3Sdsl 601.1SadENTRY(x86_identify) 611.1Sad /* Try to toggle alignment check flag; does not exist on 386. */ 621.1Sad pushfl 631.1Sad popl %eax 641.1Sad movl %eax,%ecx 651.1Sad orl $PSL_AC,%eax 661.1Sad pushl %eax 671.1Sad popfl 681.1Sad pushfl 691.1Sad popl %eax 701.1Sad xorl %ecx,%eax 711.1Sad andl $PSL_AC,%eax 721.1Sad pushl %ecx 731.1Sad popfl 741.1Sad testl %eax,%eax 751.1Sad jnz try486 761.1Sad 771.1Sad /* 781.1Sad * Try the test of a NexGen CPU -- ZF will not change on a DIV 791.1Sad * instruction on a NexGen, it will on an i386. Documented in 801.1Sad * Nx586 Processor Recognition Application Note, NexGen, Inc. 811.1Sad */ 821.1Sad movl $0x5555,%eax 831.1Sad xorl %edx,%edx 841.1Sad movl $2,%ecx 851.1Sad divl %ecx 861.1Sad jnz is386 871.1Sad 881.1Sadisnx586: 891.1Sad /* 901.1Sad * Don't try cpuid, as Nx586s reportedly don't support the 911.1Sad * PSL_ID bit. 921.1Sad */ 931.2Sdsl movl $CPU_NX586,%eax 941.2Sdsl ret 951.1Sadis386: 961.2Sdsl movl $CPU_386,%eax 971.2Sdsl ret 981.1Sad 991.1Sadtry486: /* Try to toggle identification flag; does not exist on early 486s. */ 1001.1Sad pushfl 1011.1Sad popl %eax 1021.1Sad movl %eax,%ecx 1031.1Sad xorl $PSL_ID,%eax 1041.1Sad pushl %eax 1051.1Sad popfl 1061.1Sad pushfl 1071.1Sad popl %eax 1081.1Sad xorl %ecx,%eax 1091.1Sad andl $PSL_ID,%eax 1101.1Sad pushl %ecx 1111.1Sad popfl 1121.1Sad 1131.1Sad testl %eax,%eax 1141.2Sdsl jz is486 1151.2Sdsl 1161.2Sdsl /* Later cpu, caller will use cpuid instruction */ 1171.2Sdsl movl $-1,%eax 1181.2Sdsl ret 1191.2Sdsl 1201.2Sdslis486: 1211.1Sad /* 1221.1Sad * Check Cyrix CPU 1231.1Sad * Cyrix CPUs do not change the undefined flags following 1241.1Sad * execution of the divide instruction which divides 5 by 2. 1251.1Sad * 1261.1Sad * Note: CPUID is enabled on M2, so it passes another way. 1271.1Sad */ 1281.1Sad pushfl 1291.1Sad movl $0x5555, %eax 1301.1Sad xorl %edx, %edx 1311.1Sad movl $2, %ecx 1321.1Sad clc 1331.1Sad divl %ecx 1341.1Sad jnc trycyrix486 1351.1Sad popfl 1361.2Sdsl movl $CPU_486,%eax 1371.2Sdsl ret 1381.2Sdsl 1391.1Sadtrycyrix486: 1401.2Sdsl popfl 1411.1Sad /* 1421.1Sad * Check for Cyrix 486 CPU by seeing if the flags change during a 1431.1Sad * divide. This is documented in the Cx486SLC/e SMM Programmer's 1441.1Sad * Guide. 1451.1Sad */ 1461.1Sad xorl %edx,%edx 1471.1Sad cmpl %edx,%edx # set flags to known state 1481.2Sdsl pushl %ebx 1491.1Sad pushfl 1501.1Sad popl %ecx # store flags in ecx 1511.1Sad movl $-1,%eax 1521.1Sad movl $4,%ebx 1531.1Sad divl %ebx # do a long division 1541.1Sad pushfl 1551.1Sad popl %eax 1561.2Sdsl popl %ebx 1571.1Sad xorl %ecx,%eax # are the flags different? 1581.1Sad testl $0x8d5,%eax # only check C|PF|AF|Z|N|V 1591.2Sdsl je is486dlc # yes => must be Cyrix 6x86 CPU 1601.2Sdsl movl $CPU_6x86,%eax 1611.2Sdsl ret 1621.2Sdsl 1631.2Sdslis486dlc: 1641.2Sdsl movl $CPU_486DLC,%eax 1651.1Sad ret 1661.5Smlelstv 167