;	[]===========================================================[]
;
;	NOTICE: THIS PROGRAM BELONGS TO AWARD SOFTWARE INTERNATIONAL(R)
;	        INC. IT IS CONSIDERED A TRADE SECRET AND IS NOT TO BE 	
;	        DIVULGED OR USED BY PARTIES WHO HAVE NOT RECEIVED	
;	        WRITTEN AUTHORIZATION FROM THE OWNER.
;
; 	[]===========================================================[]
;

;----------------------------------------------------------------------------
;Rev  	Date	  Name	Description
;----------------------------------------------------------------------------
;R113	02/05/99  RCH	Fixed Netware v5.0 can not be installed if Cyrix M2
;			is used.
;R112	04/07/98  RCH	Enable "toggle address sequence" instead of "1+4
;			address sequence" for burst cycle of Cyrix M2 CPU
;			by setting bit 6 of CCR4(reg. 0E8H) to get up to 2% 
;       		performance increase than "1+4" mode
;R111	07/01/97  JSN	Add M2_For_ALi define. 
;R110B	05/02/97  RCH	Don't touch CCR5 bit 7 for M2, requested by Cyrix
;R110A	03/06/97  RCH	More functions change for M2 comparing with M1, also
;			patch errors reported by utility CX_TEST.EXE
;R110	02/20/97  RCH	Disable delay for ADS# and enable CPUID for M2 for MMX
;			function , requested by CYRIX
;RIR	11/29/95  KVN	Creat a CPUPOST.ASM
;R109	11/29/95  LRY	Move codes that programming Cyrix M1 reg.E8h to
;			chippost.asm 'Cyrix_Cache_Reg' for modbinable
;R108	11/16/95  KVN	Remove all POST message to E000h
;R107	10/27/95  RCH	Set public for two routines to fix M1 for PnP
;R106	10/23/95  RCH	Added AMD/5K86 CPU support
;R105	10/23/95  RCH	Show "Am5x86-P75" and "PENTIUM PRO" instead of "AMD-X5
;			and "P6"
;R104	10/13/95  DNL	Added Cyrix-DX4 CPU support
;R103	10/13/95  RCH	Show "6x86" instead of "M1"
;R102	10/11/95  RCH	Added PENTIUM P54LM A4 stepping ID (057XH) support
;R101	09/13/95  RCH	Added TI486 DX4 CPU support , the value is 81H in DIR0
;			because this CPU is same as CxDx4 , so use same CPU
;			value in CMOS
;R100	09/12/95  RCH	Added AMD-X5 CPU support(4x clock)
;R99	08/18/95  RCH	Intel cancel P55CT project, this CPU become reserve
;			Note: Please use this type for new CPU
;R98	08/05/95  RCH	Added P6 OverDrive support, the CPU ID is 161XH
;R97	07/27/95  RAY	Support Linear Burst of M1sc(5x86)
;R96	07/26/95  DNL	Modify register setting of Cx5X86 to get higher performance
;R95	07/19/95  DNL	Unlock Cyrix register again after init Cyrix register value
;R94	07/19/95  DNL	Clear CCR4 register of M1 & M1sc to get higher performance
;R93	07/11/95  LRY	Fixed Cyrix CPU CCR1 NO_LOCK bit can't be set from
;			Cyrix_Cache_Reg table,  only compress code missing
;R92	07/08/95  RCH	Let "Init_Cyrix_Reg" be empty if P6 BIOS, otherwise
;			system hang of QAplus testing.
;R91A	06/30/95  RCH	System become unstable if super pipeline is enabled
;R91	06/22/95  RCH	Enable super pipeline of M1 to get higher performance
;R90	06/20/95  DNL	Added Cyrix M1 CPU SMI function support
;R89	06/20/95  RCH	Added PENTIUM(P54CS) MP CPUID support
;R88	06/17/95  RCH	The P6 can not return correct eax after execute CPUID
;R87	06/17/95  RAY	Change Cyrix M1SC string from "M1SC" to "Cx5x86"
;			according to Cyrix's request
;R86	06/16/95  RAY	Add individual control switches to each level CPU
;R85	06/14/95  RCH	Detect partial of CPUs with CPU ID for INTEL,AMD & UMC
;R84	06/14/95  DNL	Added UMC 486SX2 CPU SMI mode support
;R82	06/12/95  RCH	Don't program register with port 22H/23H if not CYRIX
;			CPU plugged, Because the VIA/496G don't fully decode
;			port A8H/A9H.
;R81	06/12/95  DNL	Added Cyrix M1 CPU linear burst function support
;R79	06/08/95  RCH	Added INTEL P55CT support
;R78    06/08/95  RCH	Added INTEL P6 CPU support
;R76	05/23/95  RAY	Prepare CPU brand name & SMI type informations in [BP]
;RXX	05/23/95  DNL	Clean R??s for easy debugging. Original file is copied
;			as CPU.523

.XLIST
		INCLUDE BIOS.CFG

		INCLUDE COMMON.EQU
		INCLUDE POST.EQU
		INCLUDE	CPU.EQU

		INCLUDE	COMMON.MAC
		INCLUDE	POST.MAC

;R39		INCLUDE	POST.EXT
;R39		INCLUDE	MATHCOP.EXT

		EXTRN	ROM_AND_CMOS:NEAR
		EXTRN	ROM_OR_CMOS:NEAR
		extrn	POST_func_end:Near
		extrn	POST_VECT:Near
;R86ifndef	No_586_Support				;R81
;R97 IF	BIOS_SUPPORT_586				;R86
		Extrn	Enable_Linear_Burst:near	;R81
;R97 ENDIF	;BIOS_SUPPORT_586			;R86
;R86endif	;No_586_Support				;R81
		extrn	Get_Cmos:near			;RIR
		extrn	Set_Cmos:near			;RIR

.LIST
.386p
		PAGE	60,132
		TITLE	CPU - CONTROL SPECIFIC CPU FUNCTIONS

DGROUP		GROUP	FCODE
FCODE		SEGMENT	USE16 DWORD PUBLIC 'CODE'
		ASSUME	CS:DGROUP,DS:DGROUP


;Input : none
;Output: zero flag - Cyrix CPU installed
;	 not zero  - not cyrix
		public	Check_Cyrix_Cpu
Check_Cyrix_Cpu	proc	near
		xor	ax,ax
		sahf
		mov	ax,5
		mov	bx,2
		div	bl
		lahf
		cmp	ah,2
		ret
Check_Cyrix_Cpu	endp

		public	Init_Cyrix_Reg
Init_Cyrix_Reg	proc	near

ifndef	P6_BIOS_ONLY				;R92

;R82 - start
;R86ifndef	CPU_586_ONLY
IF	BIOS_SUPPORT_486			;R86
	;Get CPU type
		mov	al,CMOS_AWARD_2 NMI_OFF
		call	Get_Cmos
		and	al,CPU_TYPE_MASK
		cmp	al,TYPE_U5
		je	Not_Cy
		cmp	al,TYPE_U486SX2
		je	Not_Cy
		cmp	al,TYPE_U486DX
		je	Not_Cy
		cmp	al,TYPE_U486DX2
		je	Not_Cy
ENDIF	;BIOS_SUPPORT_486			;R86
;R86endif;	CPU_586_ONLY
;R82 - end

		call	Check_Cyrix_Cpu
		jnz	Not_Cy			;R91
;R91		jnz	short Not_Cy

;Unlock Cyrix registers before programming
		Call	UNlock_Cyrix
;R81		mov	al,0C3h
;R81		out	22h,al
;R81		in	al,23h
;R81		or	al,10h
;R81		out	23h,al

		mov	eax,cr0
		or	eax,40000000h	;disable cache filling
		mov	cr0,eax
		invd			;flush cache

		mov	ax,cs
		mov	ds,ax
		extrn	Cyrix_Cache_Reg:near
		extrn	NO_OF_CYRIX_REG:ABS
		mov	si,offset Cyrix_Cache_Reg
		mov	cx,NO_OF_CYRIX_REG
		or	cx,cx
		jz	short No_Cy_Reg
Write_Cyrix:
		lodsw
		out	22h,al
		xchg	ah,al
		out	23h,al
		NEWIODELAY
		loop	short Write_Cyrix


		call	M2_SpecialRegCtrl	;program special reg. for M2;R110A

;R110A;R110 - start
;R110A;Set bit 7 of CCR4 to enable CPUID instruction and disable delay for ADS#
;R110A;if M2 CPU plugged
;R110A		mov	al,0feH			;DIR1 register
;R110A		out	22h,al
;R110A		in	al,23h			;read DIR1 value
;R110A		cmp	al,51h
;R110A		jb	short Not_M2Cpu
;R110A		cmp	al,5fh
;R110A		ja	short Not_M2Cpu
;R110A
;R110A		mov	cl,0E8H			;CCR4 register
;R110A		call	Get_Cyrix
;R110A		or	al,80h			;enable CPUID
;R110A		call	Set_Cyrix
;R110A
;R110A		mov	cl,0C2H			;CCR2 register
;R110A		call	Get_Cyrix
;R110A		and	al,NOT 02H		;disable wait state for ADS#
;R110A		call	Set_Cyrix
;R110A
;R110ANot_M2Cpu:
;R110A;R110 - end

No_Cy_Reg:
		Call	UNlock_Cyrix		;R95
;R86ifndef	CPU_586_ONLY
IF	BIOS_SUPPORT_486			;R86
		mov	al,CMOS_AWARD_2
		call	Get_Cmos
		and	al,CPU_TYPE_MASK	;R93

		cmp	al,TYPE_CX486S
		je	short @F
		cmp	al,TYPE_CX486S2
		je	short @F
		cmp	al,TYPE_M7
		je	short @F
		cmp	al,TYPE_M7_2
		je	short @F
		cmp	al,TYPE_CYRIX_DX4	;R104
		je	short @F		;R104	
		cmp	al,TYPE_M9
;R94		je	short @F
;R94 - start
		jne	short Not_Cyrix_486

;R96		mov	cl,0E8h
;R96		xor	al,al		;Set I/O recovery time
;R96		Call	Set_Cyrix

;R97 - starts
		call	Enable_Linear_Burst
		jc	short No_5x86_Linear_Burst
		call	Enable_Cyrix_Linear_Burst
No_5x86_Linear_Burst:
;R97 - ends

;R96 - start
		mov	si,offset High_Register
		mov	bl,No_of_Value
		or	bl,bl
		jz	short No_Cyrix_Reg
Wrt_Cyrix:
		lodsw
		mov	cl,al
		Call	Get_Cyrix
		and	al,ah
		mov	dl,al
		lodsb
		or	al,dl
		Call	Set_Cyrix
		dec	bl
		jnz	short Wrt_Cyrix
No_Cyrix_Reg:
;R96 - end
		jmp	short @F
Not_Cyrix_486:
;R94 - end

		mov	ax,0C1C1h
		out	22h,al
		in	al,23h
		and	al,Not 10h		;Clear NO_LOCK bit
		xchg	ah,al
		out	22h,al
		xchg	ah,al
		out	23h,al
@@:
ENDIF	;BIOS_SUPPORT_486			;R86
;R86endif;	CPU_586_ONLY

;R81 - start
;R86ifndef	No_586_Support
IF	BIOS_SUPPORT_586			;R86
		mov	al,CMOS_AWARD_2
		call	Get_Cmos
		and	al,CPU_TYPE_MASK
		cmp	al,TYPE_M1
		jne	short Not_Cyrix_586

;R90 - start
		mov	cl,0C1h
		Call	Get_Cyrix
		or	al,80h			;enable SM3 bit
		Call	Set_Cyrix
;R90 - end

;R91 - start
;R91A		mov	cl,030h
;R91A		Call	Get_Cyrix
;R91A           or      al, 20h		;enable super pipeline
;R91A		Call	Set_Cyrix
;R91 - end

;R94 - start
;R109		mov	cl,0E8h
;R109		xor	al,al		;Set I/O recovery time
;R109		Call	Set_Cyrix
;R94 - end

		Call	Enable_Linear_Burst
		jc	short Not_Cyrix_586

		call	Enable_Cyrix_Linear_Burst	;R97

;R97		mov	cl,0c3h
;R97		Call	Get_Cyrix
;R97		or	al,04h		; set M1 LINBRST bit of CCR3
;R97		Call	Set_Cyrix


Not_Cyrix_586:
ENDIF	;BIOS_SUPPORT_586			;R86
;R86endif	;No_586_Support
;R81 - end

		extrn	Ct_Init_Cyrix:near
		call	Ct_Init_Cyrix

		Call	Lock_Cyrix		;R81
Not_Cy:
endif;	P6_BIOS_ONLY				;R92
		ret
Init_Cyrix_Reg	endp

;R110A - start
M2_SpcRegTbl:		;index	AND 	OR value
;	Note : Don't enable CPUID instruction for M2, otherwise Netware v5.0;R113
;	       installation will be failed.				    ;R113
;R113		db	0e8h,	03fh,	0C0h	;enable CPUID(bit 7)	 ;R112
		db	0e8h,	03fh,	040h	;disable CPUID		 ;R113
						;enable toggle mode(bit6);R112
;R112		db	0e8h,	07fh,	80h	;enable CPUID
 ifndef	M2_For_ALi				;R111
		db	0c2h,	0fdh,	00h	;disable WS for ADS#
 else	;M2_For_ALi				;R111
		db	0c2h,	0ffh,	00h	;R111
 endif	;M2_For_ALi				;R111
;R110B		db	0e9h,	07fh,	80h	;(CCR5)enable FAST I/O
		db	0e3h,	0fdh,	00h	;(RCR7)reserve bit
		db	0

M2_SpecialRegCtrl	proc	near
;Set bit 7 of CCR4 to enable CPUID instruction and disable delay for ADS#
;if M2 CPU plugged
		mov	al,0feH			;DIR1 register
		out	22h,al
		in	al,23h			;read DIR1 value
		cmp	al,51h
		jb	short Not_M2Cpu
		cmp	al,5fh
		ja	short Not_M2Cpu

		mov	si,offset M2_SpcRegTbl
NextM2Reg:
		mov	cl,cs:[si]		;load index
		or	cl,cl			;end of table ?
		jz	short Not_M2Cpu

		call	Get_Cyrix
		and	al,cs:[si+1]
		or	al,cs:[si+2]
		call	Set_Cyrix

		add	si,3			;next register
		jmp	short NextM2Reg


Not_M2Cpu:
		ret
M2_SpecialRegCtrl	endp
;R110A - end

;R97 - starts
Enable_Cyrix_Linear_Burst	Proc	Near

		mov	cl,0c3h
		Call	Get_Cyrix
		or	al,04h		; set M1 LINBRST bit of CCR3
		Call	Set_Cyrix
		ret

Enable_Cyrix_Linear_Burst	Endp
;R97 - ends

;R81 - start
		Public	UNLock_Cyrix			;R107
UNlock_Cyrix:
		mov	cl,0C3h
		Call	Get_Cyrix
		or	al,10h
		Call	Set_Cyrix
		ret

		Public	Lock_Cyrix			;R107
Lock_Cyrix:
		mov	cl,0C3h
		Call	Get_Cyrix
		and	al,not 10h
		Call	Set_Cyrix
		ret

		Public	Get_Cyrix
Get_Cyrix:
		mov	al,cl
		out	22h,al
		NEWIODELAY
		in	al,23h
		NEWIODELAY
		ret

		Public	Set_Cyrix
Set_Cyrix:
		xchg	cl,al		;get index
		out	22h,al
		NEWIODELAY
		xchg	cl,al		;get data
		out	23h,al
		NEWIODELAY
		ret
;R81 - end

;R96 - start
High_Register:
		db	20h		;PCR0
		db	01111000b	;Mask
ifdef	PCI_BUS
		db	10000000b	;LSSER (7)  = 1, LOOP_EN (2) = 0
					;BTB_EN (1) = 0, RSTK_EN (0) = 0
else	;PCI_BUS
		db	00000000b	;LSSER (7)  = 0, LOOP_EN (2) = 0
					;BTB_EN (1) = 0, RSTK_EN (0) = 0
endif	;PCI_BUS
		db	0C2h		;CCR2
		db	10111111b	;Mask
		db	00000000b	;BWRT (6) = 0
		db	0E8h		;CCR4
		db	11100000b	;Mask
		db	00011000b	;IORT (2-0)  = 0, MEM_BYP (3) = 1
					;DATE_EN (4) = 1
No_of_Value	EQU	( $ - High_Register ) / 3
;R96 - end

;Register tables for IBM CPUs initialization
IBMCACHEON	EQU	80H
IBMREG		STRUC
 Ibm_Ecx	dw	?	;register index
 Ibm_Edx	dd	?	;value b63-b32
 Ibm_Eax	dd	?	;value b31-b00
IBMREG		ENDS
		public	IbmCpu_Reg
		public	IbmCpu_End
IbmCpu_Reg	label	near
;R86ifdef	IBM_CPU_SUPPORT
IF	BIOS_SUPPORT_IBM_CPU			;R86
		IBMREG	<1004h,0h,20000000h>	;for 486SLC2 only
		IBMREG	<1002h,0h,00000000h>

IbmCpu_Common	label	near
		IBMREG	<1001h,30h,800083FFh> 	;for 386SLC & 486SLC2
		IBMREG	<1000h,00h,1402h> 	;for 386SLC & 486SLC2
ENDIF	;BIOS_SUPPORT_IBM_CPU			;R86
;R86endif;	IBM_CPU_SUPPORT
IbmCpu_End	label	near

;RIR - start
;Codes move to CPUPOST.ASM
;RIR - end

FCODE		ENDS

		END
