📄 cpu586.asm
字号:
call F000_Set_Cyrix
mov al, bh
mov cl, 0d0h ;ARR4 A31-A24
call F000_Set_Cyrix
mov cl, 0e0h
mov al, 1 ;Set ARR4 noncacheable region
call F000_Set_Cyrix
pop bx ;get must noncacheable address ( MB )
mov ax, si ;Get last Cacheable size
sub bx, ax ;if noncacheable address =
;Cacheable size
mov ax, bx ;ax is must noncacheable address
mov ch, 0 ;ch is D2 value
jz Value_Ok3 ;go set D2 value
mov ch, 0fh ;value for 32MB
mov si, 01000000b ;maxmum is 32MB
Chk_MemSize3:
shr si, 1 ;next memory size
dec ch ;next register value
cmp bx, si ;if must noncacheable address
;=> Cacheable size
jae Value_Ok3 ;go to check is it on the times value
jmp Chk_MemSize3;check next vlaue
Value_Ok3:
push ax ;save must noncacheable address
push dx ;save surplus value
div si ;onboard memory size DIV
;noncacheable memory size
or dx, dx ;if on the value
pop dx ;restore surplus value
pop ax ;restore onboard memory size
jnz Chk_MemSize3 ;go to set it
mov cl, 0D2h ;ARR4
call F000_Get_Cyrix
and al, 11110000b ;set REGION BLOCK value
or al, ch
call F000_Set_Cyrix
Value_ok:
;R06 - starts
;----------------------------------------------
;If DIR1 >= 08H
;Set WL(Weak_Locking) bit of M2 CPU RCRx Reg
;----------------------------------------------
mov al,0FFh ;DIR1 of M2 CPU
out 22h,al
in al,23h
cmp al,08h ; > 08h
jb short _NoSetWLBit
;R06A mov cl, 0E0h ;RCR4 - RCR7
;R06A _Loop_RCRx:
;R06A call F000_Get_Cyrix
;R06A or al, 00000100b ;Set WL Bit
;R06A call F000_Set_Cyrix
;R06A inc cl
;R06A cmp cl, 0E4h
;R06A jne short _Loop_RCRx
;R06A _NoSetWLBit:
;R06A - starts
;---------------------------------------------------------
;Since we are using a subtraction algorithm, i.e.
; (e.g. 24Mb total memory -->
; AAR7 0-23M cacheable, AAR6 24M-31M non-cacheable)
; to calculating the cacheable region
;
;Thus we only have to program the WL bit of RCR7(AAR7)
;---------------------------------------------------------
mov cl, 0E3h ;RCR7
call F000_Get_Cyrix
or al, 00000100b ;Set WL Bit
call F000_Set_Cyrix
_NoSetWLBit:
;R06A - ends
;----------------------------------------------
;R06 - ends
F000_call lock_Cyrix ;lock cyrix CPU register access
pop esi
Not_M1Cpu:
ret
Set_Cpu_MtRR endp
Public Enable_M1_FarHit
Enable_M1_FarHit proc near
call Check_M1_Cpu
jne Not_M1_Cpu
F000_call UNlock_Cyrix
ifdef HIGH_6X86_L2_HIT_RATE
;Enable WT_ALLOC of CCR5 to improve L2 cache hit rate for CCT386.EXE
;For 256Kb cache it improve hit rate from 26% upto 62% for 6x86 CPUs
ifdef Disable_WT_ALLOC_When_Cyrix_100 ;R02 - start
extrn Ct_Quatify_100Mhz:Near
call Ct_Quatify_100Mhz ;If 100MHz Host CLK ?
jnc short Not_100Mhz ; Not, Jmp
jmp short Skip_WT_ALLOC
Not_100Mhz:
endif; Disable_WT_ALLOC_When_Cyrix_100 ;R02 - end
ifdef Disable_WT_ALLOC_When_Cyrix_PR266
mov cl,0FEh ; DIR0 of M2 CPU
call F000_Get_Cyrix
; AL = 51 : 'x 2'
; AL = 52 : 'x 2.5'
; AL = 53 : 'x 3'
cmp al,52h
jnz Not_Cyrix_PR266
cmp byte ptr CPU_INT_CLOCK[bp],208 ;208Mhze(PR266) ?
jnz Not_Cyrix_PR266
jmp Skip_WT_ALLOC
Not_Cyrix_PR266:
endif; Disable_WT_ALLOC_When_Cyrix_PR266
ifdef Disable_WT_ALLOC_When_Cyrix_83_x3
mov cl,0FEh ; DIR0 of M2 CPU
call F000_Get_Cyrix
; AL = 51 : 'x 2'
; AL = 52 : 'x 2.5'
; AL = 53 : 'x 3'
cmp al,53h
jnz Not_MII_333
cmp byte ptr CPU_INT_CLOCK[bp],250 ;250Mhze(MII333) ?
jnz Not_MII_333
jmp Skip_WT_ALLOC
Not_MII_333:
endif; Disable_WT_ALLOC_When_Cyrix_83_x3
mov cl,0E9H ;CCR5
call F000_Get_Cyrix
or al,01H ;enable WT_ALLOC
call F000_Set_Cyrix
Skip_WT_ALLOC:
endif; HIGH_6X86_L2_HIT_RATE
;set bit 6 of index 30H
mov cl,30H
call F000_Get_Cyrix
or al,40H
call F000_Set_Cyrix
;enable far hit
mov ebx,28h
db 0fh,26h,0cbh ;mov tr1,ebx
db 0fh,24h,0d0h ;mov eax,tr2
and al,NOT 02H ;enable far hits
db 0fh,26h,0d0h ;mov tr2,eax
;clear bit 6 of index 30H
mov cl,30H
call F000_Get_Cyrix
and al,NOT 40H
call F000_Set_Cyrix
F000_call lock_Cyrix
Not_M1_Cpu:
ret
Enable_M1_FarHit endp
public F000_Set_Cyrix
F000_Set_Cyrix Proc Near
F000_Call Set_Cyrix
ret
F000_Set_Cyrix Endp
F000_Get_Cyrix Proc Near
F000_Call Get_Cyrix
ret
F000_Get_Cyrix Endp
;[]========================================================================[]
;Name : Prg_K5_Write_Allocate
;
;Function : To enable the AMD K5 CPU's write allocation function
;
;Input : dword ptr EXT_MEM_SIZE[bp] in terms of 1K
;
;Output : None
;[]========================================================================[]
Public Prg_K5_Write_Allocate
Prg_K5_Write_Allocate Proc Near
ifndef No_K5_Write_Allocation
pushad
call Check_K586_Cpu ;AMD 5k86 CPU ?
jne No_Write_Alloc
call Read_CpuID ;read CPU ID in AX
mov ah, al
and ah, 0F0h ;Model = 0x ?
jz No_Write_Alloc ;yes, skip
cmp ah, 030h ;Model = 0x, 1x, 2x ?
ja No_Write_Alloc ;no, skip
and al, 0Fh ;AL = stepping
cmp al, 4 ;stepping >= 4
jb No_Write_Alloc ;no, skip
;----------------------------------------------------------
;MSR 85h b15-b0 : Top of memory address
; b16 : Fixed Range Enable, i.e. from A0000-FFFFF
; b17 : Programmable Range Enable
; b18 : Top-Of-Memory Enable
;----------------------------------------------------------
F000_call Ct_MemHole_Status ;get hole status in AX
mov si, ax ;temporary save to SI
mov ecx, 85h
RDMSR
mov ecx, EXT_MEM_SIZE[bp]
shr ecx, 6 ;convert to 64K byte unit
add cx, 10h ;add 1M of base memory
mov ax, cx
and eax, not 00070000h ;always disable Fixed Range
or eax, 00050000h ;enable Top-Of-Mem range
; & Fix Range
or si, si ;memory hole enabled?
jz @F ;disabled !
or eax, 00020000h ;enable Programmable Range
@@:
mov ecx, 85h
WRMSR
;program the Programmable Range for 15M-16M as Non-WA
or si, si ;memory hole enabled?
jz @F ;disabled !
mov ecx, 86h
RDMSR
mov eax,00FF00F0h ;15M-16M as Non-cacheable
mov ecx, 86h
WRMSR
@@:
;program bit 4 or MSR 83 to enable write allocate
;bit 31 is for bus pipeline but undocumented.
mov ecx, 83h
RDMSR
or eax, 80000010h ;enable write allocate
;disable bus pipeline
WRMSR
No_Write_Alloc:
popad
endif ;No_K5_Write_Allocation
ret
Prg_K5_Write_Allocate Endp
ECODE ENDS
XGROUP GROUP XCODE
XCODE SEGMENT USE16 PARA PUBLIC 'XCODE'
ASSUME CS:XGROUP,ES:XGROUP
DIVID MACRO
mov ax,di
div bx
endm
PORT61 EQU 61H
PORT8254 EQU 42H
DATA8254 EQU 43H
COUNT EQU 3EH
align 16
;Function : Measure CPU clock without RDTSC instruction
;Input : none
;Output : CX - duration time of one CPU clock
;Note : This routine will be executed in base memory.
;
XMeasureNoRDTSCCpuClck proc far
cli
mov al,0fch ;disable counter 2
out PORT61,al
SIODELAY
mov al,0b4h ;program counter 2
out DATA8254,al
IODELAY
xor al,al
out PORT8254,al
IODELAY
out PORT8254,al
IODELAY
mov di,7aaah ;dividend
mov bx,5555h ;divisor
xor dx,dx
mov cx,COUNT ;count
mov al,0fdh ;enable counter
out PORT61,al
SIODELAY
ALIGN 16
Divid_33:
DIVID ;divide 1
DIVID ;divide 2
DIVID ;divide 3
DIVID ;divide 4
DIVID ;divide 5
DIVID ;divide 6
DIVID ;divide 7
DIVID ;divide 8
DIVID ;divide 9
DIVID ;divide 10
DIVID ;divide 11
DIVID ;divide 12
DIVID ;divide 13
DIVID ;divide 14
DIVID ;divide 15
DIVID ;divide 16
DIVID ;divide 17
DIVID ;divide 18
DIVID ;divide 19
DIVID ;divide 20
DIVID ;divide 21
DIVID ;divide 22
DIVID ;divide 23
DIVID ;divide 24
DIVID ;divide 25
DIVID ;divide 26
DIVID ;divide 27
DIVID ;divide 28
DIVID ;divide 29
DIVID ;divide 30
DIVID ;divide 31
DIVID ;divide 32
DIVID ;divide 33
dec cx
jz Finish
jmp Divid_33
Finish:
mov al,0fch ;stop counter 2
out 61h,al
SIODELAY
in al,PORT8254 ;read counter 2 low byte
IODELAY
mov ah,al
in al,PORT8254 ;read counter 2 high byte
IODELAY
xchg ah,al
mov si,ax ;store result
xor dx,dx
mov cx,COUNT ;count
mov al,0fdh ;enable counter
out PORT61,al
SIODELAY
ALIGN 16
Divid_1:
DIVID ;divide 1
dec cx
jz short Finish1
jmp short Divid_1
Finish1:
mov al,0fch ;stop counter 2
out 61h,al
SIODELAY
in al,PORT8254 ;read counter 2 low byte
IODELAY
mov ah,al
in al,PORT8254 ;read counter 2 high byte
IODELAY
xchg ah,al
mov cx,ax
sub cx,si ;result 2 - result 1
ret
XMeasureNoRDTSCCpuClck endp
ENDIF ;COMPILE_FOR_E0
IFE COMPILE_FOR_E0
extrn F000_call_proc:near
extrn Ct_MemHole_Status:Near
extrn F000_Shadow_W:Near
extrn F000_Shadow_R:Near
extrn Skip_K6_Write_Allocate:Near
extrn F000_GetItem_Value:near
extrn F000_Display_Char:Near
extrn F000_Display_String:Near
extrn DISPLAY_CS_STRING:Near
extrn SYSCFG_CPU_CLOCK1:Near
extrn fProc_Disp_Word_Int3:far
extrn fProc_Disp_Byte_Int2:far
extrn X_Display_Char:near
extrn X_Display_CS_String:near
extrn X_GetItem_Value:near
extrn M2CpuID_Item:near
extrn UNLock_Cyrix:near
extrn Lock_Cyrix:near
extrn Get_Cyrix:near
extrn Set_Cyrix:near
.LIST
EGROUP GROUP ECODE
ECODE SEGMENT USE16 PARA PUBLIC 'ECODE'
ASSUME CS:EGROUP,DS:G_RAM,ES:EGROUP
;Function : return cache size in AL for display
;Input : DL - CPU register value to indicate cache size
; 40H - No L2 cache
; 41H - 128K
; 42H - 256K
; 43H - 512K
; 44H - 1Mb
; 45H - 2Mb
;Output : AL - cache size for BIOS to display
; AL - 0 = 0K, 1=16K , 2=32K , 3=64K , 4=128K , 5=256K
; 6 =512K, 7=1024K ,etc...
Public Convert_P6L2_Cache
Convert_P6L2_Cache proc near
ret
Convert_P6L2_Cache endp
;=============================================================================
;FUNC: CPU_DISPLAY
;
;DESC: Returns the length and description string for the CPU.
;
;IN: NONE
;OUT: CS:SI String pointer
;
;SAVES: DX
;=============================================================================
PUBLIC CPU_DISPLAY
CPU_DISPLAY PROC Near
mov al,FIXED_DISK_STEP[bp]
and al,CPU_TYPE_MASK
cmp al,NUM_OF_CPU_TYPE
mov si,offset Unknown_Str
ja @F
movzx si,al
mov si,word ptr cs:CPU_TYPE_STRS[si]
@@:
ifndef K7_CPU_SUPPORT
cmp si,offset Cpu_P6_Str ;is P6 CPU ?
jne Not_P6Cpu
Not_P6Cpu:
endif; K7_CPU_SUPPORT
Cpu_Str_Ok:
;display IDT/C6 string instead of Pentium if it is C6
cmp si,offset Cpu_586_Str ;assume Pentium CPU
jne Not_IdtC6
call Check_RiseCpu ;is Rise mP6 CPU ?
jne NotRiseCpu
;R01 mov si,offset RiseMp6_Str ;display mP6 instead of Pentium
call Read_CpuID ;read CPUID
and al, 0F0H ;get model
;R01 - start
;"Family 6" for 06xx CPUID
cmp ah, 06H ;Rise family 6 CPU(06xx) ?
jne short NotFamily6 ;no
mov si, offset RiseFM6_Str ;display family 6 CPU name
jmp short GoCpuDisaplay
NotFamily6:
;"mP6(tm)" for 050x & 051x CPU
mov si,offset RiseMp6_Str ;display mP6 instead of Pentium
cmp al, 00H ;050x ?
je short GoCpuDisaplay
cmp al, 10H ;051x ?
je short GoCpuDisaplay
;"mP6(tm) II" for 0580x
mov si,offset RiseMp6_2_Str ;display "mP6 II"
cmp al, 080H ;MP6-II(058x) ?
je short GoCpuDisaplay
;"Family 5" for others CPUID
mov si, offset RiseFM5_Str ;display family 5 CPU name
jmp short GoCpuDisaplay
;R01 - end
;R01 cmp al, 080H ;MP6-II ?
;R01 jne short NotRiseCpu ;Not mP6-II
;R01 mov si,offset RiseMp6_2_Str ;display "mP6 II"
NotRiseCpu:
call Check_IdtCpu ;is IDT C6 CPU ?
jne Not_IdtC6
mov si,offset IdtC6_Str ;display C6 instead of Pentium
jmp GoCpuDisaplay
Not_IdtC6:
call Check_Tillamook
jne Not_Tillamook
mov si,offset Tillamook_Str
jmp GoCpuDisaplay
Not_Tillamook:
;if CPU type is AMD K6, then return with K6 string
call Check_K6_CPU ;K6 ?
jne Is_Not_K6 ;no !
call TreatK6String
jmp GoCpuDisaplay
Is_Not_K6:
call Check_M1_Cpu ;check if 6x86 CPU
jne Not_Cy6x86Cpu
mov al,0feH
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -