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

📄 gxmcpuid.asm

📁 X86 GX1 BOOTLOAD代码 ,支持WINCE操作系统!
💻 ASM
字号:
;**************************************************************************
;*
;*  CPUCPUID.ASM
;* 
;*  Copyright (c) 1999 National Semiconductor Corporation.
;*  All Rights Reserved. 
;* 
;*  Function: 
;*    CPU ID routines. 
;* 
;*  $Revision:: 1   $
;*
;**************************************************************************

;;.MODEL TINY
.486P

	INCLUDE MACROS.INC			; Macros
	INCLUDE DEF.INC				; Definitions
	INCLUDE PORT80.INC

_TEXT SEGMENT PUBLIC use16 'CODE'

	EXTERN	Delay_100_mSec:NEAR
	EXTERN	CpuRegWrite:NEAR
	EXTERN	CpuRegRead:NEAR

;**************************************************************************
;*
;*	CPUTest
;*
;*	Test CPU ID instruction
;*
;*	Entry:
;*	  BX = return address
;*
;*	Exit:
;*
;*	Destroys:
;*	  EAX, EBX, ECX, EDX, (PORT80 destroys AL)
;*
;**************************************************************************
cpuTest PROC
	mov	gs, bx

	; Normally, you would check to see if you can toggle bit 21
	; in EFLAGS.  If you can, GxmID is supported.  If you can't, it isn't
	; We are going to assume that GxmID is supported.
	;


	PORT80	POST_CPU_ID

	; MAPEN MUST ALREADY BE ENABLED
	; Enable the GxmID Instruction to be processed
	mov	al, CPU_CCR4
	out	CPU_INDEX, al		
	in	al, CPU_DATA		; Read CCR4 register
	or	al, 80h			; Turn on GxmID
	out	CPU_DATA, al		; Write new modified version back

	;
	; Check GxmID with EAX = 0000 0000h
	;
	xor	eax, eax		; Make sure EAX is clear
	xor	dx, dx			; Make sure DX is clear
	xor	cx, cx			; Make sure CX is clear	

	DB	00Fh, 0A2h		; Issue GxmID opcode
;
; 1st try "CyrixInstead"
;
	cmp	ebx, 69727943h		; ASCII for "Cyri"
	jne	cpuNSC			; try NSC

	cmp	ecx, 64616574h		; ASCII for "tead"
	jne	cpuNSC			; try NSC

	cmp	edx, 736E4978h		; ASCII for "xIns"
	je	IDGood
;
; check for newer CPU which have ID of "Geode by NSC"
;
cpuNSC:
	cmp	ebx, 'doeG'		; ASCII for "Geod"
	jne	cpuFail

	cmp	ecx, 'CSN '		; ASCII for " NSC"
	jne	cpuFail

	cmp	edx, 'yb e'		; ASCII for "e by"
	jne	cpuFail

IDGood:
	;
	; Check GxmID with EAX = 0000 0001h
	;
	mov	eax, 00000001h		; Function 1

	DB	00Fh, 0A2h		; GxmID opcode

	mov	ecx, eax
	PORT80	POST_CPU_STEPPING	; post_28h
	cmp	ecx, CPU_ID		; Stepping ID correct?
	Jne	cpuFail

	PORT80	POST_CPU_FLAGS		; post_2ah
	cmp	edx, CPU_MXI		; Standard feature flags
	jne	cpuFail

	jmp	cpuDone			; Gxm Passed GxmID Check

cpuFail:
	PORT80	POST_CPU_ID_FAIL	; post_2fh
	hlt

cpuDone:
	PORT80	POST_CPU_ID_GOOD	; post_2eh

	mov	bx, gs
	jmp	bx

cpuTest ENDP

;**************************************************************************
;*
;*	CPU_Revision
;*	Description:  Pentium and newer CPU's support the CPU
;*	ID instruction (0FA2H).  This instruction uses the contents
;*	of EAX to determine which subfunction to execute.  The
;*	standard subfunctions are:
;*
;*	EAX = 0:  Return Manufacturer Information
;*	EAX = 1:  Return Processor Stepping/Model Information
;*
;*	The CPU ID instruction can be executed at any time.  To
;*	determine if a CPU supports CPU ID, the code checks to
;*	see if bit 21 of the EFLAGS register is changeable.
;*
;*	All current processors except Cyrix 6x86 power on with
;*	CPU ID instruction enabled.  In the Cyrix 6x86, the CPU ID
;*	instruction must be enabled before it can be used.
;*
;*	Each manufacturer supplies an application note that
;*	describes the return values, which typically come
;*	back in EAX, EBX, ECX and EDX.  These application notes
;*	are listed here:
;*
;*	Entry:
;*	Exit:
;*	Destroys:
;*
;**************************************************************************
CPU_Revision PROC near public
	pushfd				; Push EFLAGS
	pop	eax			; Store EFLAGS In EAX
	mov	ebx, eax		; Save Copy Of EFLAGS For Testing Later
	xor	eax, 0200000H		; Flip Bit 21
	push	eax			; Copy "Modified" EFLAGS To Stack
	popfd				; Save "Modified" EAX To EFLAGS
	pushfd				; Push "Modified" EFLAGS Back Onto Stack
	pop	eax			; Get EFLAGS Back Into EAX
	cmp	eax, ebx		; Did Bit 21 Change ??
	mov	eax, NOT SUCCESS	; Assume CPU ID Is supported
	je	NotSupported		; Nope, CPU ID Instruction Not Supported

	mov	eax, 1
	CPU_ID_OPCODE

	;
	; In CPU ID Function #1, EAX Returns The Following:
	;
	; Bits 31:12  Reserved
	; Bits 11:8   Instruction Family (4 = 486, 5 = Pentium, etc.)
	; Bits  7:4   Model # (Vendor-defined model designator)
	; Bits  3:0   Stepping # (Vendor-defined stepping number)
	;

	and	eax, 0F00H		; Check Instruction Family and Model ID
	shr	eax, 8			; Move Major Revision Into Low Byte

NotSupported:
	ret

CPU_Revision ENDP

;**************************************************************************
;*
;*	CPU_ID_SUPPORT
;*
;*	Check To See If CPU Supports CPU ID Instruction
;*
;*	(In All CPU's, Bit 21 In EFLAGS Is Changeable If
;*	And Only If CPU ID Instruction Is Supported)
;*
;*	Entry:
;*	Exit:
;*	Destroys
;*
;**************************************************************************
CPU_ID_Support PROC near public
	pushfd				; Push EFLAGS
	pop	eax			; Store EFLAGS In EAX
	mov	ebx, eax		; Save Copy Of EFLAGS For Testing Later
	xor	eax, 0200000H		; Flip Bit 21
	push	eax			; Copy "Modified" EFLAGS To Stack
	popfd				; Save "Modified" EAX To EFLAGS
	pushfd				; Push "Modified" EFLAGS Back Onto Stack
	pop	eax			; Get EFLAGS Back Into EAX
	cmp	eax, ebx		; Did Bit 21 Change ??
	mov	eax, NOT SUCCESS	; Assume CPU ID Is supported
	je	NotSupported		; Nope, CPU ID Instruction Not Supported

	xor	eax, eax
	CPU_ID_OPCODE

	cmp	ebx, Cyrix_EBX		; Check For Cyrix EBX
	jne	NotSupported

	cmp	ecx, Cyrix_ECX		; Check For Cyrix ECX
	jne	NotSupported

	cmp	edx, Cyrix_EDX		; Check For Cyrix EDX
	jne	NotSupported

	mov	eax, SUCCESS		; Return True (Non-Zero)

NotSupported:
	ret

CPU_ID_Support ENDP

;**************************************************************************
;*
;*	GetCPUSpeed
;*
;*	Calculate CPU Speed Using RTSC (Read Time Stamp Counter)
;*	Instruction.
;*
;*	Entry:
;*	Exit:
;*	Destroys
;*
;**************************************************************************
GetCPUSpeed proc near public

DoItAgain:
	pushf
	cli

	RDTSC_OPCODE

	mov	esi, edx
	mov	edi, eax

	call	Delay_100_mSec

	RDTSC_OPCODE

	popf

	;
	; The Following Is Impossible Unless The Counter
	; Is Stuck
	;
	cmp	eax, edi
	je	CounterBroke

	cmp	esi, edx
	jne	DoItAgain

	;
	; Calculate The Total Counts (Start - Final)
	;
	sub	eax, edi

	;
	; Multiply By 10 The Old Fashioned Way
	; To Get Counts/Second
	;
	mov	ebx, eax
	shl	eax, 3
	add	eax, ebx
	add	eax, ebx

	;//
	;// Divide By A Million To Get MHz
	;//
	xor	edx, edx
	mov	ebx, 1000000
	div	ebx

	ret

CounterBroke:
	Xor	eax, eax
	ret

GetCPUSpeed endp



;**************************************************************************
;*
;*	GetPCISpeed
;*
;*	Returns PCI Frequency, 
;*
;*	Entry:
;*
;*	Exit: AX = pci speed in mhz 
;*
;*	Destroys: None
;*
;**************************************************************************
PCIFreqTable1:
	db	4,6,4,6,7,8,7,5
PCIFreqTable2:
	db	4,10,4,6,9,5,7,8

GetPCISpeed proc near public
	push	esi
	push	ebx
	push	ecx
	push	edx
	push	eax
;
; get Clk Multiplier
;

	mov	al, CPU_DIR0
	out	CPU_INDEX, al
	in	al, CPU_DATA
	and	al, 0Fh
	mov	dl, al

	mov	al, CPU_DIR1			; get cpu revision
	out	CPU_INDEX, al
	in	al, CPU_DATA

	lea	si, PCIFreqTable1
	cmp 	al, 50h				; which table to use
	jb	incsi2
	lea	si, PCIFreqTable2		; walk Clock Multiplier Table

incsi2:	
	cmp	dl, 0
	je	SavePCIFreq
	inc	si
	dec	dl
	jmp	incsi2

SavePCIFreq:
	xor	bx, bx
	mov	bl, byte ptr cs:[si]
	push	bx


	call	GetCPUSpeed		; returns cpu speed in AX
	push	ax


	pop 	ax			; cpuspeed
	pop	bx			; PCI

	xor	dx, dx
	div	bx

PCIFreqDone:
	mov	dx, ax


	pop	eax
	mov	ax, dx
	pop	edx
	pop	ecx
	pop	ebx
	pop	esi

	ret
GetPCISpeed endp

_TEXT ENDS

END

⌨️ 快捷键说明

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