⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpumodel.s

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 S
字号:
/*  cpuModel.S * *  This file contains all assembly code for the Intel Cpu identification. *  It is based on linux cpu detection code. * *  Intel also provides public similar code in the book *  called : *	 *	Pentium Processor Family *		Developer Family *	Volume  3 :	Architecture and Programming Manual * * At the following place : *	 *	Chapter 5 :	Feature determination *	Chapter 25:	CPUID instruction	 * *  COPYRIGHT (c) 1998 valette@crf.canon.fr * *  The license and distribution terms for this file may be *  found in the file LICENSE in this distribution or at *  http://www.rtems.com/license/LICENSE. * *  $Id: cpuModel.S,v 1.4.2.1 2003/09/04 18:45:43 joel Exp $ */#include <asm.h>#include <rtems/score/registers.h>BEGIN_CODE	PUBLIC(checkCPUtypeSetCr0); /*  * check Processor type: 386, 486, 6x86(L) or CPUID capable processor  */SYM (checkCPUtypeSetCr0):	/*	 *  Assume 386 for now 	 */	movl $3, SYM (x86) 	/*	 * Start using the EFLAGS AC bit determination method described in	 * the book mentioned above page 5.1. If this bit can be set we	 * have a 486 or above.	 */	pushfl				/* save EFLAGS			*/		pushfl				/* Get EFLAGS in EAX		*/	popl eax		movl eax,ecx			/* save original EFLAGS in ECX	*/	xorl $EFLAGS_ALIGN_CHECK,eax	/* flip AC bit in EAX		*/	pushl eax			/* set EAX as EFLAGS		*/	popfl				pushfl				/* Get new EFLAGS in EAX	*/	popl eax		xorl ecx,eax			/* check if AC bit changed	*/	andl $EFLAGS_ALIGN_CHECK,eax		je is386			/* If not : we have a 386	*/	/*	 *  Assume 486 for now 	 */	movl $4,SYM (x86)	movl ecx,eax			/* Restore orig EFLAGS in EAX	*/	xorl $EFLAGS_ID,eax		/* flip  ID flag		*/	pushl eax			/* set EAX as EFLAGS		*/	popfl					pushfl				/* Get new EFLAGS in EAX	*/	popl eax					xorl ecx,eax			/* check if ID bit changed	*/	andl $EFLAGS_ID,eax	/* 	 * if we are on a straight 486DX,	 * SX, or 487SX we can't change it	 * OTOH 6x86MXs and MIIs check OK 	 * Also if we are on a Cyrix 6x86(L)	 */	je is486xisnew:		/*	 * restore original EFLAGS	 */	popfl	incl SYM(have_cpuid)	/* we have CPUID instruction */	/* use it to get :		 *	processor type,	 *	processor model,	 *	processor mask,	 * by using it with EAX = 1	 */	movl $1, eax			cpuid				movb al, cl		/* save reg for future use */		andb $0x0f,ah		/* mask processor family   */	movb ah,SYM (x86)	/* put result in x86 var   */		andb $0xf0, al		/* get model		   */	shrb $4, al	movb al,SYM (x86_model) /* store it in x86_model   */		andb $0x0f, cl		/* get mask revision	   */	movb cl,SYM (x86_mask)  /* store it in x86_mask	   */		movl edx,SYM(x86_capability)	/* store feature flags in x86_capability */		/* get vendor info by using CPUID with EXA = 0 */	xorl eax, eax			cpuid	/*	 * store results contained in ebx, edx, ecx in	 * x86_vendor_id variable.	 */	movl ebx,SYM(x86_vendor_id)		movl edx,SYM(x86_vendor_id)+4		movl ecx,SYM(x86_vendor_id)+8		movl cr0,eax		/* 486+ */	andl $(CR0_PAGING | CR0_PROTECTION_ENABLE | CR0_EXTENSION_TYPE), eax	orl $(CR0_ALIGMENT_MASK | CR0_WRITE_PROTECT | CR0_NUMERIC_ERROR | CR0_MONITOR_COPROC),eax	jmp 2f/* Now we test if we have a Cyrix 6x86(L). We didn't test before to avoid * clobbering the new BX chipset used with the Pentium II, which has a register * at the same addresses as those used to access the Cyrix special configuration * registers (CCRs). */	/*	 * A Cyrix/IBM 6x86(L) preserves flags after dividing 5 by 2	 * (and it _must_ be 5 divided by 2) while other CPUs change	 * them in undefined ways. We need to know this since we may	 * need to enable the CPUID instruction at least.	 * We couldn't use this test before since the PPro and PII behave	 * like Cyrix chips in this respect.	 */is486x:	xor ax,ax	sahf	movb $5,al	movb $2,bl	div bl	lahf	cmpb $2,ah	jne ncyrix	/*	 * N.B. The pattern of accesses to 0x22 and 0x23 is *essential*	 *      so do not try to "optimize" it! For the same reason we	 *	do all this with interrupts off.	 */#define setCx86(reg, val) \	movb reg,al;	\	outb al,$0x22;	\	movb val,al;	\	outb al,$0x23#define getCx86(reg) \	movb reg,al;	\	outb al,$0x22;	\	inb $0x23,al	cli	getCx86($0xc3)		/*  get CCR3 */	movb al,cl		/* Save old value */	movb al,bl	andb $0x0f,bl		/* Enable access to all config registers */	orb $0x10,bl		/* by setting bit 4 */	setCx86($0xc3,bl)	getCx86($0xe8)		/* now we can get CCR4 */	orb $0x80,al		/* and set bit 7 (CPUIDEN) */	movb al,bl		/* to enable CPUID execution */	setCx86($0xe8,bl)        getCx86($0xfe)          /* DIR0 : let's check this is a 6x86(L) */        andb $0xf0,al		/* should be 3xh */	cmpb $0x30,al			jne n6x86        getCx86($0xe9)          /* CCR5 : we reset the SLOP bit */        andb $0xfd,al		/* so that udelay calculation */        movb al,bl		/* is correct on 6x86(L) CPUs */        setCx86($0xe9,bl)	setCx86($0xc3,cl)	/* Restore old CCR3 */	sti	jmp isnew		/* We enabled CPUID now */n6x86:	setCx86($0xc3,cl)	/* Restore old CCR3 */	stincyrix:				/* restore original EFLAGS */	popfl	movl cr0,eax		/* 486 */	andl $(CR0_PAGING | CR0_EXTENSION_TYPE | CR0_PROTECTION_ENABLE),eax	/* Save PG,PE,ET */	orl $(CR0_ALIGMENT_MASK | CR0_WRITE_PROTECT | CR0_NUMERIC_ERROR | CR0_MONITOR_COPROC),eax	/* set AM, WP, NE and MP */	jmp 2fis386:				/* restore original EFLAGS */	popfl	movl cr0,eax		/* 386 */	andl $(CR0_PAGING | CR0_EXTENSION_TYPE | CR0_PROTECTION_ENABLE),eax	/* Save PG,PE,ET */	orl $CR0_MONITOR_COPROC,eax		/* set MP */2:	movl eax,cr0	call check_x87	ret	/* * We depend on ET to be correct. This checks for 287/387. */check_x87:	movb $0,SYM(hard_math)	clts	fninit	fstsw ax	cmpb $0,al	je 1f	movl cr0,eax		/* no coprocessor: have to set bits */	xorl $4,eax		/* set EM */	movl eax,cr0	ret	.align 161:	movb $1,SYM(hard_math)	.byte 0xDB,0xE4		/* fsetpm for 287, ignored by 387 */	retEND_CODE	BEGIN_DATA	PUBLIC(x86)	PUBLIC(have_cpuid)	PUBLIC(x86_model)	PUBLIC(x86_mask)	PUBLIC(x86_capability)	PUBLIC(x86_vendor_id)	PUBLIC(hard_math)SYM(x86):		.byte 0SYM(have_cpuid):		.long 0SYM(x86_model):		.byte 0SYM(x86_mask):		.byte 0SYM(x86_capability):		.long 0		SYM(x86_vendor_id):		.zero 13SYM(hard_math):		.byte 0END_DATA	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -