📄 gpminit.inc
字号:
pop es ;
pop ds ;
popad ;
ret
;-----------------------------------------------;
init_smram_64:
and bl,not smbase_reloc_reqd ; clear bit 1...smbase relocation not required
call close_smram ; CHIPSET HOOK HOOK HOOK...close SMRAM space
call global_smi_enable ; CHIPSET HOOK HOOK HOOK...set for SMI generation
jmp short init_smram_08 ;
init_smram_local endp
;---------------------------------------------------------------;
;*****************************************************************;
;*****************************************************************;
;** **;
;** (C)Copyright 1985-1996, American Megatrends Inc. **;
;** **;
;** All Rights Reserved. **;
;** **;
;** 6145-F, Northbelt Parkway, Norcross, **;
;** **;
;** Georgia - 30071, USA. Phone-(770)-246-8600. **;
;** **;
;*****************************************************************;
;*****************************************************************;
;---------------------------------------------------------------;
; SUBROUTINES USED BY SMRAM INIT ROUTINE ;
;---------------------------------------------------------------;
; GET_DUAL_CPU_INFO ;
;---------------------------------------------------------------;
; Input : (CH) cpu vendor # ;
; (CL) cpu # ;
; (BH) bit 3 bit 2 ;
; 0 0 ... INTEL type SMI ;
; 0 1 ... CYRIX type SMI ;
; 1 0 ... AMD type SMI ;
; 1 1 ... reserved ;
; bit 6 set for SMI capable CPU ;
; bit 6 clear for non-SMI CPU ;
; STACK PRESENT ;
; Output: (BH) bit 4 set for dual/multiple CPU present ;
; bit 4 clear for single CPU ;
; (BL) bit 3-0...no. of secondary CPU present ;
; Register destroyed : (BX) ;
;---------------------------------------------------------------;
get_dual_cpu_info proc near
and bx,(not dual_cpu_present)*256 + 11110000b; clear bit 4 of (bh) for dual/multiple CPU not present
; clear bit 3 thru 0 of (bl) for no dual/multiple CPU present
call get_no_of_sec_cpu_local ; (al) = # of dual/multiple CPU present
jc short get_dual_cpu_info_00 ; no dual/multiple CPU present
and al,00001111b ; consider bits 3 thru 0
or bl,al ; set # of secondary CPU present
or bh,dual_cpu_present ; set dual/multiple CPU present
get_dual_cpu_info_00:
ret
get_dual_cpu_info endp
;---------------------------------------------------------------;
; DETERMINE_SMRAM_SIZE ;
;---------------------------------------------------------------;
; Input : (CH) cpu vendor # ;
; (CL) cpu # ;
; (BL) bit 3 bit 2 ;
; 0 0 ... INTEL type SMI ;
; 0 1 ... CYRIX type SMI ;
; 1 0 ... AMD type SMI ;
; 1 1 ... reserved ;
; bit 4 set for dual/multiple CPU present ;
; bit 4 clear for single CPU ;
; bit 5 set for IRQ based power management ;
; bit 5 clear for SMI based power management ;
; bit 6 set for SMI capable CPU ;
; bit 6 clear for non-SMI CPU ;
; (BH) bit 3-0...no. of secondary CPU present ;
; bit 7-4...IRQ level for IRQ power management
; (EDI) 00010000h or other values for 64KB ;
; or greater SMRAM ;
; 00008000h for 32KB SMRAM ;
; STACK PRESENT ;
; Output: (CY) 01 SMI can not be supported for current ;
; CPU and SMRAM size ;
; (CY) 00 SMI can be supported for current CPU and;
; SMRAM size & ;
; (BL) bit 0 set for 32KB SMRAM ;
; bit 0 clear for 64KB or greater SMRAM
; Register destroyed : (BL) ;
;---------------------------------------------------------------;
determine_smram_size proc near
and bl,not smram_size_32kb ; bit 0 clear for 64KB or greater SMRAM
cmp edi,8000h ; is 32KB SMRAM ?
ja short det_smram_size_01 ; no...64KB or greater SMRAM
IF IRQ_HANDLING_SUPPORT
test bl,irq_power_management ; IRQ based power management ?
jnz short det_smram_size_02 ; yes...
ENDIF
test bl,smi_type_amd ; AMD type SMI ?
jnz short det_smram_size_00 ; yes...can not support 32KB SMRAM for AMD non-PLUS/IBM/UMC CPU...EXIT
test bl,smi_type_cyrix ; CYRIX type SMI ?
jnz short det_smram_size_02 ; yes...can support 32KB SMRAM
test bl,dual_cpu_present ; dual/multiple CPU present ?
jnz short det_smram_size_00 ; yes...can not support 32KB SMRAM for AMD non-PLUS/IBM/UMC CPU...EXIT
det_smram_size_02:
or bl,smram_size_32kb ; set (bl) bit 0 for 32KB SMRAM
det_smram_size_01:
clc ; (cy) = 00 for no error
ret
det_smram_size_00:
stc ; (cy) = 01 for smi can not be supported for current CPU & SMRAM size
ret
determine_smram_size endp
;---------------------------------------------------------------;
; CLEAR_SMRAM ;
;---------------------------------------------------------------;
; Input : (ES) segment where SMI code will be copied to ;
; (BL) bit 0 set for 32KB SMRAM ;
; bit 0 clear for 64KB or greater SMRAM ;
; bit 3 bit 2 ;
; 0 0 ... INTEL type SMI ;
; 0 1 ... CYRIX type SMI ;
; 1 0 ... AMD type SMI ;
; 1 1 ... reserved ;
; bit 4 set for dual/multiple CPU present ;
; bit 4 clear for single CPU ;
; bit 5 set for IRQ based power management ;
; bit 5 clear for SMI based power management ;
; bit 6 set for SMI capable CPU ;
; bit 6 clear for non-SMI CPU ;
; (BH) bit 3-0...no. of secondary CPU present ;
; bit 7-4...IRQ level for IRQ power management
; STACK PRESENT ;
; Output: NONE ;
; Register destroyed : (EAX),(DI) ;
;---------------------------------------------------------------;
clear_smram proc near
push cx ;
call get_size_and_offset ; get size and offset of SMRAM area
xor eax,eax ;
rep stosd ; clear the SMRAM
pop cx ;
ret
clear_smram endp
;---------------------------------------------------------------;
; GET_SIZE_AND_OFFSET ;
;---------------------------------------------------------------;
; Input : (BL) bit 0 set for 32KB SMRAM ;
; bit 0 clear for 64KB or greater SMRAM ;
; bit 3 bit 2 ;
; 0 0 ... INTEL type SMI ;
; 0 1 ... CYRIX type SMI ;
; 1 0 ... AMD type SMI ;
; 1 1 ... reserved ;
; bit 4 set for dual/multiple CPU present ;
; bit 4 clear for single CPU ;
; bit 5 set for IRQ based power management ;
; bit 5 clear for SMI based power management ;
; bit 6 set for SMI capable CPU ;
; bit 6 clear for non-SMI CPU ;
; (BH) bit 3-0...no. of secondary CPU present ;
; bit 7-4...IRQ level for IRQ power management
; STACK PRESENT ;
; Output: (CX) size of SMRAM area in DWORDs ;
; (DI) offset for start of SMRAM area ;
; Register destroyed : (CX),(DI) ;
;---------------------------------------------------------------;
get_size_and_offset proc near
xor di,di ; offset for 64KB SMRAM
mov cx,4000h ; 16KB dwords for 64KB SMRAM
test bl,smram_size_32kb ; is SMRAM size 32KB ?
jz short get_size_offset_00 ; no...64KB or greater
mov di,8000h ; offset for 32KB SMRAM
mov ch,20h ; 8KB dwords for 32KB SMRAM
get_size_offset_00:
ret
get_size_and_offset endp
;---------------------------------------------------------------;
; COPY_COMPARE_SMRAM ;
;---------------------------------------------------------------;
; Input : (DS) segment where SMI code will be copied to ;
; (ES) segment where SMI code will be copied to ;
; (CS) SMI code source segment ;
; STACK PRESENT ;
; Output: (CY) 00 for no error ;
; (CY) 01 for miscompare ;
; Register destroyed : (SI),(DI) ;
;---------------------------------------------------------------;
copy_compare_smram proc near
push cx ;
mov si,offset cgroup:smi_code_begin ; (cs:si) = SMI code start
;;; mov cx,offset cgroup:smi_code_end ;
mov cx,cseg_data_area_begin ;
call copy_compare_cpu_smram ;
pop cx ;
ret
copy_compare_smram endp
;---------------------------------------------------------------;
; COPY_COMPARE_CPU_SMRAM ;
;---------------------------------------------------------------;
; Input : (ES) segment where SMI code will be copied to ;
; (CS) SMI code source segment ;
; (SI) SMI code start offset ;
; (CX) SMI code end offset ;
; STACK PRESENT ;
; Output: (CY) 00 for no error ;
; (CY) 01 for miscompare ;
; Register destroyed : (CX),(SI),(DI) ;
;---------------------------------------------------------------;
copy_compare_cpu_smram proc near
push ds ;
push cs ;
pop ds ; (ds) = SMI code source segment
mov di,orgbase ; offset in SMRAM area for SMI code
sub cx,si ; (cx) = SIZE of SMI code in bytes
add cx,3 ; adjust to calculate # of dwords
shr cx,2 ; (cx) = # of dwords to be copied
call copy_compare ;
pop ds ;
ret
copy_compare_cpu_smram endp
;---------------------------------------------------------------;
; COPY_COMPARE_DEFAULT_SMRAM ;
;---------------------------------------------------------------;
; Input : (DS) SMRAM segment ;
; (ES) SMRAM segment ;
; (BL) bit 0 set for 32KB SMRAM ;
; bit 0 clear for 64KB or greater SMRAM ;
; bit 3 bit 2 ;
; 0 0 ... INTEL type SMI ;
; 0 1 ... CYRIX type SMI ;
; 1 0 ... AMD type SMI ;
; 1 1 ... reserved ;
; bit 4 set for dual/multiple CPU present ;
; bit 4 clear for single CPU ;
; bit 5 set for IRQ based power management ;
; bit 5 clear for SMI based power management ;
; bit 6 set for SMI capable CPU ;
; bit 6 clear for non-SMI CPU ;
; (BH) bit 3-0...no. of secondary CPU present ;
; bit 7-4...IRQ level for IRQ power management
; STACK PRESENT ;
; Output: (CY) 00 for no error ;
; (CY) 01 for miscompare ;
; Register destroyed : (SI),(DI) ;
;---------------------------------------------------------------;
copy_compare_default_smram proc near
push cx ;
push es ;
mov cx,3000h ;
mov es,cx ; (es) = default SMRAM segment
call get_size_and_offset ; get size and offset of SMRAM area
mov si,di ;
call copy_compare ;
pop es ;
pop cx ;
ret
copy_compare_default_smram endp
;---------------------------------------------------------------;
; COPY_COMPARE ;
;---------------------------------------------------------------;
; Input : (DS:SI) source ;
; (ES:DI) destination ;
; (CX) count of DWORDs to copy ;
; STACK PRESENT ;
; Output: (CY) 00 for no error ;
; (CY) 01 for miscompare ;
; Register destroyed : (CX),(SI),(DI) ;
;---------------------------------------------------------------;
copy_compare proc near
push cx ;
push si ;
push di ;
rep movsd ; copy SMI code in SMRAM area
pop di ;
pop si ;
pop cx ;
repe cmpsd
clc ; (cy) = 00 for no error
jz short copy_compare_00 ; compare successful
stc ; (cy) = 01 for compare error
copy_compare_00:
ret
copy_compare endp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -