📄 cpu586.asm
字号:
call F000_Get_Cmos
test al,SMICPU shr 8
pop ax
ret
;[]==========================================================[]
;Input : DL = Value for CMOS_AWARD_2 (03DH)
; DH = Value for CMOS_OVERRIDE (03FH)
;[]==========================================================[]
Set_CPU_Type_Bits:
mov al,CMOS_AWARD_2 NMI_OFF
mov ah,dl
call F000_Set_Cmos
mov ah,CMOS_OVERRIDE NMI_OFF
mov al,ah
call F000_Get_Cmos
and al,NOT (CLOCK_MODE+((SMICPU+WBCPU) SHR 8))
or al,dh
xchg ah,al
call F000_Set_Cmos
ret
;[]------------------------------------------------------------------------[]
;[]------------------------------------------------------------------------[]
public Intel_To_AMD
Intel_To_AMD proc near
ret
Intel_To_AMD endp
;[]------------------------------------------------------------------------[]
;Procedur : Prepare_CPU_Info
;
;Input : None
;
;Output : None
;
;Description : - This routine is called after the BIOS has issued
; the CPUID instruction & all the CPUs are identified.
;
; - There are 2 variables in the stack area namely
; CPU_BRAND[bp] & CPU_SMI_TYPE[bp]
; This routine will place appropriate values into
; these 2 [BP] variables
; The BIOS engineers can easily reference to them
; for their own programming
;
; - please refer to BSETUP.INC for the definitions
; of CPU_BRAND[bp] & CPU_SMI_TYPE[bp]
;
;Note : BIOS engineers should use instruction "test" to
; check SMI type & "cmp" for CPU brand
;
; e.g.
; cmp CPU_BRAND[bp], CPU_BRAND_CYRIX
; test CPU_SMI_TYPE[bp], SMI_TYPE_CYRIX
;
;[]------------------------------------------------------------------------[]
Public Prepare_CPU_Info
Prepare_CPU_Info Proc Near
mov al,CMOS_AWARD_2 NMI_OFF
call F000_Get_Cmos
and al,CPU_TYPE_MASK
movzx si,al
xor ah, ah
shr ax, 1
add si, ax
mov dx,word ptr cs:CPU_Info_Tbl[si]
mov word ptr CPU_BRAND[bp],dx
mov al, byte ptr cs:CPU_Info_Tbl[si+2]
mov byte ptr CPU_LEVEL[bp], al
mov al,OVERRIDE NMI_OFF
call F000_Get_Cmos
test al,((SMICPU) shr 8) ;SMI CPU?
jnz Set_SMI_OK ;Yes
mov byte ptr CPU_SMI_TYPE[bp],SMI_NONE
Set_SMI_OK:
ret
Prepare_CPU_Info Endp
ALIGN 4
CPU_Info_Tbl:
db CPU_BRAND_INTEL ,SMI_NONE ,LEVEL_386 ;TYPE_386DX
db CPU_BRAND_INTEL ,SMI_NONE ,LEVEL_386 ;TYPE_386SX
db CPU_BRAND_INTEL ,SMI_NONE ,LEVEL_386 ;TYPE_386SL
db CPU_BRAND_INTEL ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_486DX
db CPU_BRAND_INTEL ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_486SX
db CPU_BRAND_INTEL ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_486DX2
db CPU_BRAND_CYRIX ,SMI_NONE ,LEVEL_386 ;TYPE_486SLC
db CPU_BRAND_CYRIX ,SMI_TYPE_CYRIX ,LEVEL_386 ;TYPE_486DLC
db CPU_BRAND_IBM ,SMI_TYPE_IBM ,LEVEL_386 ;TYPE_IBM386SLC
db CPU_BRAND_IBM ,SMI_TYPE_IBM ,LEVEL_386 ;TYPE_IBM486SLC2
db CPU_BRAND_INTEL ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_P24T
db CPU_BRAND_CYRIX ,SMI_TYPE_CYRIX ,LEVEL_486 ;TYPE_CX486S
db CPU_BRAND_CYRIX ,SMI_TYPE_CYRIX ,LEVEL_486 ;TYPE_CX486S2
db CPU_BRAND_INTEL ,SMI_TYPE_INTEL ,LEVEL_586 ;TYPE_586
db CPU_BRAND_INTEL ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_486DXS
db CPU_BRAND_INTEL ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_486SXS
db CPU_BRAND_INTEL ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_486DX2S
db CPU_BRAND_IBM ,SMI_TYPE_IBM ,LEVEL_386 ;TYPE_IBM486DLC3
db CPU_BRAND_CYRIX ,SMI_TYPE_CYRIX ,LEVEL_486 ;TYPE_M7
db CPU_BRAND_CYRIX ,SMI_TYPE_CYRIX ,LEVEL_486 ;TYPE_M7_2
db CPU_BRAND_CYRIX ,SMI_NONE ,LEVEL_386 ;TYPE_CX486SLC2
db CPU_BRAND_INTEL ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_P24C
db CPU_BRAND_TI ,SMI_TYPE_CYRIX ,LEVEL_486 ;TYPE_TI486SXL
db CPU_BRAND_TI ,SMI_TYPE_CYRIX ,LEVEL_486 ;TYPE_TI486SXL2
db CPU_BRAND_UMC ,SMI_TYPE_OLD_AMD,LEVEL_486 ;TYPE_U5
db CPU_BRAND_AMD ,SMI_NONE ,LEVEL_486 ;TYPE_AMD486
db CPU_BRAND_INTEL ,SMI_TYPE_INTEL ,LEVEL_586 ;TYPE_P54C
db CPU_BRAND_TI ,SMI_TYPE_CYRIX ,LEVEL_486 ;TYPE_TI486SXLC
db CPU_BRAND_TI ,SMI_TYPE_CYRIX ,LEVEL_486 ;TYPE_TI486SXLC2
db CPU_BRAND_AMD ,SMI_NONE ,LEVEL_486 ;TYPE_AMD486DX2
db CPU_BRAND_INTEL ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_P24D
db CPU_BRAND_AMD ,SMI_NONE ,LEVEL_486 ;TYPE_AMD486DX4
db CPU_BRAND_CYRIX ,SMI_TYPE_CYRIX ,LEVEL_586 ;TYPE_M1
db CPU_BRAND_AMD ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_AMD486PLUS
db CPU_BRAND_AMD ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_AMD486DX4PLUS
db CPU_BRAND_UMC ,SMI_TYPE_OLD_AMD,LEVEL_486 ;TYPE_U486SX2
db CPU_BRAND_UMC ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_U486DX
db CPU_BRAND_UMC ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_U486DX2
ifndef CPU_Support_Above_GXM
db CPU_BRAND_CYRIX ,SMI_TYPE_CYRIX ,LEVEL_486 ;TYPE_M9
else ;CPU_Support_Above_GXM
db CPU_BRAND_CYRIX ,SMI_TYPE_CYRIX ,LEVEL_586
endif ;CPU_Support_Above_GXM
db CPU_BRAND_CYRIX ,SMI_TYPE_CYRIX ,LEVEL_486 ;TYPE_CYRIX_DX4
db CPU_BRAND_INTEL ,SMI_TYPE_INTEL ,LEVEL_686 ;TYPE_P6
db CPU_BRAND_AMD ,SMI_TYPE_INTEL ,LEVEL_486 ;TYPE_X5
db CPU_BRAND_AMD ,SMI_TYPE_INTEL ,LEVEL_586 ;TYPE_AMD5K86
db CPU_BRAND_CYRIX ,SMI_TYPE_CYRIX ,LEVEL_586 ;TYPE_CYRIX_GXM
;[]==============================================================[]
;
;CpuClk_Int08:
;
; Temporary interrupt service routine for caculating CPU clock
;
;Saves: NONE
;
;Entry: NONE
;Exit: NONE
;
;[]==============================================================[]
ALIGN 4
CpuClk_Int08 PROC NEAR
push edx
db 0fh,31h ;ReaD Time Stamp Counter
cmp dword ptr ds:[4fch],-1 ;high 32 bit value
je First_Int
cmp byte ptr ds:[4f0h],0aaH ;second INT ?
je Finish_Int
mov edi,dword ptr ds:[4fch] ;high 32 bit value
mov esi,dword ptr ds:[4f8h] ;low 32 bit value
sub edx,edi ;high 32-bit value
sub eax,esi ;low 32-bit value
jnc No_Dec_High32
dec edx
No_Dec_High32:
mov dword ptr ds:[4fch],edx ;high 32 bit value
mov dword ptr ds:[4f8h],eax ;low 32 bit value
mov byte ptr ds:[4f0h],0aaH;mark for second INT
jmp Finish_Int
First_Int:
mov dword ptr ds:[4fch],edx ;high 32 bit value
mov dword ptr ds:[4f8h],eax ;low 32 bit value
Finish_Int:
pop edx
NEWIODELAY
mov al,END_OF_INT ; eoi command
out a8259,al ; tell controller
NEWIODELAY
iret
CpuClk_Int08 ENDP
;-----------------------------------------------------------------
;Input : None
;Output : carry set - this CPU don't have instruction RDTSC
; carry clear - this CPU have instruction RDTSC and
; BX : CPU clock detected (0-65535Mhz) return
;Destroy: use 0:4f8H - 0:4ffH as temporary memory
;-----------------------------------------------------------------
;
New_CpuClk_Detection proc near
;use RDTSC to check CPU clock if 586 level CPU
cli
cmp byte ptr CPU_LEVEL[bp], LEVEL_686
je Yes_Rdtsc
cmp byte ptr CPU_LEVEL[bp], LEVEL_586
stc ;assume CPU no counter
jne No_Rdtsc
Yes_Rdtsc:
xor edx,edx
xor eax,eax ;input value = 1
mov ds,ax
push dword ptr ds:[4*6] ;save int 06h vector
mov word ptr ds:[4*6],offset Temp_Int06
mov word ptr ds:[4*6+2], cs
db 0fh,31h ;ReaD Time Stamp Counter
pop dword ptr ds:[4*6] ;restore int 06h vector
or eax,edx ;counter changed ?
stc ;assume CPU no counter
jz No_Rdtsc ;no , this CPU don't have
;counter
mov ax,G_RAM ; seg_0
mov ds,ax
assume ds:G_RAM
mov byte ptr ds:[4f8h],0 ;init flag
mov dword ptr ds:[4f8h],0 ;init low dword value
mov dword ptr ds:[4fch],-1 ;init high dword value
;
; Move INT 08h vector to a temporary routine
;
mov dx,word ptr [int08] ; save vector
mov bx,word ptr [int08+2]
mov word ptr [int08],offset CpuClk_Int08; tmr isr entry
mov word ptr [int08+2],cs ; code segment
;
; Enable just the timer interrupt
;
mov al,0ffh ; mask all interrupts on controller 2
out B8259+1,al ; tell controller
NEWIODELAY
dec al ; mask all except timer (IRQ 8)
out A8259+1,al ; tell controller
;
; Set up timer 0
;
mov al,36h ; setup timer counter 0
out 43h,al ; select counter 0
NEWIODELAY
xor ax,ax ; INT every 1/18 seconds
out 40h,al ; write lsb
NEWIODELAY
out 40h,al ; write msb
;
; Wait for interrupts
;
xor ax,ax ; clear interrupt flag
sti ; enable interrupt
Wait_Irq0:
cmp byte ptr ds:[4f0h],0aaH ;second INT occured ?
jne Wait_Irq0
cli ; disable interrupts
;
; Turn off all of the interrupts
;
mov al,0ffh ; mask all interrupts
out A8259+1,al ; tell controller
NEWIODELAY
;
; Restore INT 08h vector
;
mov word ptr [int08],dx ; restore old vector
mov word ptr [int08+2],bx
;Now , the content of 0:[4f8h] contain counter value
mov bx,1
mov eax,dword ptr ds:[4f8h]
mov ecx,55100 ;factor to calculate
Next_Div:
sub eax,ecx
jc Finish_Div
inc bx
jmp Next_Div
Finish_Div:
clc
No_Rdtsc:
ret
New_CpuClk_Detection endp
;Table for CPU clock over 255Mhz
CPU_Over255MHz:
db 400-256, 400-256-2, CPU66 ;66x6
db 373-256, 373-256-2, CPU83 ;83x4.5
db 366-256, 366-256-2, CPU66 ;66x5.5
db 350-256, 350-256-2, CPU100 ;100x3.5
db 333-256, 333-256-2, CPU66 ;66x5
db 300-256, 300-256-2, CPU66 ;66x4.5
DB 290-256, 290-256-2, CPU83 ;83X3.5
db 266-256, 266-256-2, CPU66 ;66x4
db 0 ;end of table
;Clock table for P5-class CPUs
NewCPU_Int_Clock_Tbl:
ifdef CLOCK_TBL_FOR_ICWORK
db 250, 246, CPU66 ;83*3
ifndef NO_CPU_240MHZ_SUPPORT
db 240, 236, CPU60 ;60x4
endif; NO_CPU_240MHZ_SUPPORT
db 233, 228, CPU66 ;66x3.5
db 225, 223, CPU75 ;75x3
db 210, 205, CPU60 ;60x3.5
db 200, 194, CPU66 ;66x3
db 188, 185, CPU66 ;75*2.5
db 180, 176, CPU60 ;60x3
db 166, 163, CPU66 ;66x2.5
db 150, 147, CPU60 ;60x2.5
db 133, 128, CPU66 ;66x2 ;here special
db 125, 124, CPU50 ;50x2.5
db 120, 118, CPU60 ;60x2 ;here special
db 117, 115, CPU66 ;66x1.75
db 110, 109, CPU50 ;55x2
db 105, 103, CPU60 ;60x1.75
db 100, 98, CPU66 ;66x1.5 ;here special
else; CLOCK_TBL_FOR_ICWORK
ifdef CLOCK_TBL_FOR_ICS
db 250, 248, CPU66 ;83*3
ifndef NO_CPU_240MHZ_SUPPORT
db 240, 238, CPU60 ;60x4
endif; NO_CPU_240MHZ_SUPPORT
ifdef Lower_233Mhz_FOR_ICS
db 233, 223, CPU66 ;66x3.5
else; Lower_233Mhz_FOR_ICS
db 233, 230, CPU66 ;66x3.5
endif; Lower_233Mhz_FOR_ICS
ifndef NO_CPU_225MHZ_SUPPORT_FOR_ICS
db 225, 223, CPU75 ;75x3
endif; NO_CPU_225MHZ_SUPPORT_FOR_ICS
ifndef NO_CPU_210MHZ_SUPPORT_FOR_ICS
db 210, 208, CPU60 ;60x3.5
endif; NO_CPU_210MHZ_SUPPORT_FOR_ICS
db 200, 186, CPU66 ;66x3
db 193, 181, CPU50 ;55*3.5
ifndef NO_CPU_188MHZ_SUPPORT_FOR_ICS
db 188, 174, CPU66 ;75*2.5
endif; NO_CPU_188MHZ_SUPPORT_FOR_ICS
db 180, 170, CPU60 ;60x3
ifndef NO_CPU_175MHZ_SUPPORT_FOR_ICS
db 175, 164, CPU50 ;50x3.5
endif; NO_CPU_175MHZ_SUPPORT_FOR_ICS
db 166, 154, CPU66 ;66x2.5
db 150, 138, CPU60 ;60x2.5
db 133, 123, CPU66 ;66x2
ifndef NO_CPU_125MHZ_SUPPORT_FOR_ICS
db 125, 115, CPU50 ;50x2.5
endif; NO_CPU_125MHZ_SUPPORT_FOR_ICS
db 120, 110, CPU60 ;60x2
db 117, 106, CPU66 ;66x1.75
db 110, 101, CPU50 ;55x2
ifndef NO_CPU_105MHZ_SUPPORT_FOR_ICS
db 105, 96, CPU60 ;60x1.75
endif; NO_CPU_105MHZ_SUPPORT_FOR_ICS
ifndef Higher_100Mhz_FOR_ICS
db 100, 89, CPU66 ;66x1.5
else; Higher_100Mhz_FOR_ICS
db 100, 93, CPU66 ;66x1.5
endif; Higher_100Mhz_FOR_ICS
else; CLOCK_TBL_FOR_ICS
db 250, 248, CPU66 ;83*3
ifndef NO_CPU_240MHZ_SUPPORT
ifdef Higher_240MHz_Tbl
db 240, 240, CPU60 ;60x4
else; Higher_240MHz_Tbl
db 240, 238, CPU60 ;60x4
endif; Higher_240MHz_Tbl
endif; NO_CPU_240MHZ_SUPPORT
db 233, 230, CPU66 ;66x3.5
db 225, 223, CPU75 ;75x3
db 210, 208, CPU60 ;60x3.5
db 200, 195, CPU66 ;66x3
ifndef No_55MHz
db 193, 190, CPU50 ;55*3.5
endif ;No_55MHz
db 190, 189, CPU95
db 188, 185, CPU66 ;75*2.5
db 180, 179, CPU60 ;60x3
db 175, 174, CPU50 ;50x3.5
db 166, 165, CPU66 ;66x2.5
db 150, 149, CPU60 ;60x2.5
db 133, 132, CPU66 ;66x2
db 125, 124, CPU50 ;50x2.5
db 120, 119, CPU60 ;60x2
db 117, 115, CPU66 ;66x1.75
ifndef No_55MHz
db 110, 109, CPU50 ;55x2
endif ;No_55MHz
ifndef No_105MHz
db 105, 103, CPU60 ;60x1.75
endif; No_105MHz
db 100, 99, CPU66 ;66x1.5
endif; CLOCK_TBL_FOR_ICS
endif; CLOCK_TBL_FOR_ICWORK
db 90, 88, CPU60 ;60x1.5
db 90, 86, CPU50 ;50x1.75
ifndef No_55MHz
db 83, 82, CPU50 ;55x1.5
endif ;No_55MHz
db 75, 70, CPU50 ;50x1.5
db 66, 65, CPU66 ;66x1
db 60, 59, CPU66 ;60x1
db 50, 49, CPU66 ;50x1
db 0 ;end of table
;Clock detection for 386,486 & 586 CPUs
ALIGN 16
Public MOV_SHAD_OFF
MOV_SHAD_OFF EQU 00000H
Public MOV_SHAD_SEG
MOV_SHAD_SEG EQU 5000h
Public Measure_CPU_Speed
Measure_CPU_Speed proc near
;--------------------------------------
;Copy code into RAM for speed detection
;--------------------------------------
push 0f000h
pop ds
;Use new algorithm for CPU clock detection if CPU have RDTSC instruction
;(0fh,31h)
call New_CpuClk_Detection ;use new method to check
jc Cpu_NoRdtsc ; CPU clock ?
;carry set, use old method
mov al,bl ;AL = Actual CPU clock found
mov dh,bl ;AL = Actual CPU clock found
mov CPU_INT_CLOCK[bp],bx ;actual internal CPU clock
call Get_M2_Clock_Tbl ;M2 Present ?
jc CpuSpeedEnd
call Get_AMD_Model8_Clock_Tbl ;AMD Model 8 Present ?
jc CpuSpeedEnd
ifdef Special_CPU_Clock_Table
mov si, offset Ct_Int_Clock_Tbl
else ;Special_CPU_Clock_Table
mov si,offset NewCPU_Int_Clock_Tbl ;new table for PENTIUM
endif ;Special_CPU_Clock_Table
cmp word ptr CPU_INT_CLOCK[bp],255 ;over 255Mhz ?
jbe Not_Over255Mhz
mov si,offset CPU_Over255MHz
Not_Over255Mhz:
jmp R_Off_Clk
Cpu_NoRdtsc:
;--------------------------------------------------
;Set KB high speed for test & save results(push bx)
;--------------------------------------------------
ifdef TOGGLE_8042_FOR_CPU_CLK_DETECT
mov al,1 ;Set low speed for test
call F000_Out_8042_Pin
endif; TOGGLE_8042_FOR_CPU_CLK_DETECT
in al,PORT61
IODELAY
push ax ;save PORT61 value
;execute the CPU detection code in DRAM
call far ptr S_CPU
;return register values after calling S_CPU are
; BH - CPU host clock
; DL - CPU clock mode (x1, x2 ,x3 or x4)
mov al,bh
mul dl
mov si,ax
pop ax ;restore PORT61 value
out PORT61,al
IODELAY
ifdef TOGGLE_8042_FOR_CPU_CLK_DETECT
;Save KB high speed result
push dx
push bx
;-------------------------
;Set KB low speed for test
;-------------------------
xor al,al ;Set high speed for test
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -