📄 gpmmp.inc
字号:
; 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
; (CH) cpu vendor # ;
; 00 Intel ;
; 01 Cyrix ;
; 02 AMD ;
; 03 IBM ;
; 04 TI ;
; 05 UMC ;
; (CL) cpu # ;
; >= 16 IBM-CYRIX cpu (all in decimal) ;
; 12-31 AMD-PLUS cpu (all in decimal) ;
; 0ffh means UNKNOWN CPU ;
; STACK PRESENT ;
; Output: (CY) 00 successful ;
; (CY) 01 error ;
; Register destroyed : (EAX),(EDX),(SI),(EDI) ;
;---------------------------------------------------------------;
setup_smi_handler_for_multiple_cpu proc near
xor si,si ; smram init request
call common_smi_init_for_multiple_cpu; do smram initialisation for all secondary cpu
ret
setup_smi_handler_for_multiple_cpu endp
;---------------------------------------------------------------;
; RELOCATE_SMBASE_FOR_MULTIPLE_CPU ;
;---------------------------------------------------------------;
; Input : (DS) SMRAM segment (not accessible) ;
; (ES) SMRAM segment (not accessible) ;
; (BL) bit 0 set for 32KB SMRAM ;
; bit 0 clear for 64KB or greater SMRAM ;
; bit 1 set for smbase requires relocation ;
; bit 1 clear for smbase relocation not reqd.;
; 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
; (CH) cpu vendor # ;
; 00 Intel ;
; 01 Cyrix ;
; 02 AMD ;
; 03 IBM ;
; 04 TI ;
; 05 UMC ;
; (CL) cpu # ;
; >= 16 IBM-CYRIX cpu (all in decimal) ;
; 12-31 AMD-PLUS cpu (all in decimal) ;
; 0ffh means UNKNOWN CPU ;
; STACK PRESENT ;
; Output: (CY) 00 successful ;
; (CY) 01 error ;
; Register destroyed : (EAX),(EDX),(SI),(EDI) ;
;---------------------------------------------------------------;
relocate_smbase_for_multiple_cpu proc near
mov si,0ffh ; smbase relocation request
call common_smi_init_for_multiple_cpu; do smbase relocation for all secondary cpu
ret
relocate_smbase_for_multiple_cpu endp
;---------------------------------------------------------------;
; COMMON_SMI_INIT_FOR_MULTIPLE_CPU ;
;---------------------------------------------------------------;
; Input : (DS) SMRAM segment ;
; (ES) SMRAM segment ;
; (SI) 00h/0ffh for smram init/smbase relocation ;
; (BL) bit 0 set for 32KB SMRAM ;
; bit 0 clear for 64KB or greater SMRAM ;
; bit 1 set for smbase requires relocation ;
; bit 1 clear for smbase relocation not reqd.;
; 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
; (CH) cpu vendor # ;
; 00 Intel ;
; 01 Cyrix ;
; 02 AMD ;
; 03 IBM ;
; 04 TI ;
; 05 UMC ;
; (CL) cpu # ;
; >= 16 IBM-CYRIX cpu (all in decimal) ;
; 12-31 AMD-PLUS cpu (all in decimal) ;
; 0ffh means UNKNOWN CPU ;
; STACK PRESENT ;
; Output: (CY) 00 successful ;
; (CY) 01 error ;
; Register destroyed : (EAX),(EDX),(SI),(EDI) ;
;---------------------------------------------------------------;
common_smi_init_for_multiple_cpu proc near
test bl,dual_cpu_present ; dual/multiple cpu present ?
jz short common_init_multiple_cpu_01; no...EXIT...(CY) = 00
test bl,irq_power_management ; IRQ based power management active ?
jnz short common_init_multiple_cpu_01; yes...EXIT...(CY) = 00
or si,si ; smram init ?
jnz short common_init_multiple_cpu_05; no...smbase relocation
push si ;
call get_mapped_smi_seg_and_size ; CHIPSET HOOK HOOK HOOK...(edi) = SMI area size
pop si ;
movzx eax,bh ;
and al,00001111b ; (eax) = # of secondary CPU present
inc al ; include boot strap processor (BSP)
shl eax,15 ; 32KB SMI space needed for each CPU
cmp edi,eax ; is enough SMI space available ?
jc short common_init_multiple_cpu_01; error...not enough SMI space available
;-----------------------------------------------;
mov ds:bsp_code_seg_cseg,ds ; set BSP code segment in BSP SMRAM space
mov word ptr ds:current_processor_bit_cseg,boot_strap_processor_bit
mov word ptr ds:processor_in_smi_info_cseg,0000h; clear processor in SMI
;-----------------------------------------------;
common_init_multiple_cpu_05:
mov dx,ds ; (dx) = segment for BSP processor
sub dx,800h ; (dx) = segment for 1st secondary processor (non-BSP)
mov ax,0000000000000010b ; bit position for 1st secondary processor
call multiple_cpu_common ; init/smbase relocation for current cpu
jc short common_init_multiple_cpu_01; error...during SMRAM copy/compare
add dx,1000h ; (dx) = segment for next secondary processor
;-----------------------------------------------;
movzx di,bh ;
and di,0000000000001111b ; (di) = # of secondary cpu present
common_init_multiple_cpu_03:
dec di ; decrement # of secondary cpu
jz short common_init_multiple_cpu_02; all secondary cpu done
shl ax,1 ; bit position for next secondary cpu
call multiple_cpu_common ; init/smbase relocation for current cpu
jc short common_init_multiple_cpu_01; error...during SMRAM copy/compare
add dx,800h ; (dx) = segment for next secondary cpu
jmp short common_init_multiple_cpu_03
common_init_multiple_cpu_02:
clc ; (cy) = 00 for no error
common_init_multiple_cpu_01:
ret
common_smi_init_for_multiple_cpu endp
;---------------------------------------------------------------;
; MULTIPLE_CPU_COMMON ;
;---------------------------------------------------------------;
; Input : (DS) boot strap processor (BSP) SMI code segment;
; (ES) boot strap processor (BSP) SMI code segment;
; (CS) dual/multiple CPU SMI code source segment ;
; (AX) current processor bit ;
; (DX) dual/multiple processor SMI code segment ;
; (SI) 00h/0ffh for smram init/smbase relocation ;
; STACK PRESENT ;
; Output: (CY) 00 for no error ;
; (CY) 01 for miscompare ;
; Register destroyed : upper 16 bit of (EAX) ;
;---------------------------------------------------------------;
multiple_cpu_common proc near
or si,si ; smram init ?
jnz short multiple_cpu_common_01 ; no...smbase relocation
call copy_compare_multiple_cpu_smram ; copy SMRAM code to 1st secondary processor and initialise
ret
multiple_cpu_common_01:
call relocate_smbase_individual_cpu ; relocate smbase for individual cpu
ret
multiple_cpu_common endp
;---------------------------------------------------------------;
; COPY_COMPARE_MULTIPLE_CPU_SMRAM ;
;---------------------------------------------------------------;
; Input : (DS) boot strap processor (BSP) SMI code segment;
; (ES) boot strap processor (BSP) SMI code segment;
; (CS) dual/multiple CPU SMI code source segment ;
; (AX) current processor bit ;
; (DX) dual/multiple processor SMI code segment ;
; STACK PRESENT ;
; Output: (CY) 00 for no error ;
; (CY) 01 for miscompare ;
; Register destroyed : NONE ;
;---------------------------------------------------------------;
copy_compare_multiple_cpu_smram proc near
pusha ;
push es ;
mov es,dx ; (es) = SMI code destination segment for current processor
mov si,offset cgroup:non_bsp_smi_code_begin ; (cs:si) = SMI code start
mov cx,offset cgroup:non_bsp_smi_code_end
call copy_compare_cpu_smram ;
mov es:bsp_code_seg_cseg,ds ; fill in BSP code segment in local processor area
mov es:current_processor_bit_cseg,ax; fill in info about processor #
pop es ;
popa ;
ret
copy_compare_multiple_cpu_smram endp
;---------------------------------------------------------------;
; RELOCATE_SMBASE_INDIVIDUAL_CPU ;
;---------------------------------------------------------------;
; Input : (DS) boot strap processor (BSP) SMI code segment;
; (ES) boot strap processor (BSP) SMI code segment;
; (CS) dual/multiple CPU SMI code source segment ;
; (AX) current processor bit ;
; (DX) dual/multiple processor SMI code segment ;
; STACK PRESENT ;
; Output: (CY) 00 for no error ;
; (CY) 01 for miscompare ;
; Register destroyed : upper 16 bit of (EAX) ;
;---------------------------------------------------------------;
relocate_smbase_individual_cpu proc near
pusha ;
push es ;
mov cx,3000h ;
mov es,cx ; (es) = default SMRAM segment
push ds ;
call get_bsp_default_smram_save_info ;
rep movsd ; save BSP default SMRAM code
pop ds ;
mov si,offset cgroup:non_bsp_relocation_code_begin ; (cs:si) = SMI code start
mov cx,offset cgroup:non_bsp_relocation_code_end
call copy_compare_cpu_smram ;
jc short rel_smbase_ind_cpu_00 ; error in copy/compare
mov es:smi_code_seg_intel_amd_plus_cseg,dx; set SMI code segment for current processor
mov byte ptr es:processor_in_smi_info_cseg,11111111b; set current processor in SMI
call send_apic_smi_ipi ; send SMI IPI for current processor for reloaction
jc short rel_smbase_ind_cpu_02 ; error in sending SMI IPI
xor cx,cx ; wait in 64K loop for current processor in SMI for smbase relocation
rel_smbase_ind_cpu_01:
test byte ptr es:processor_in_smi_info_cseg,11111111b; is current processor still in SMI ?
loopnz rel_smbase_ind_cpu_01 ; wait for current processor out of SMI
jz short rel_smbase_ind_cpu_02 ; no...(cy) = 00
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -