alder_lake_bios/Intel/AlderLake/AlderLakeChipsetPkg/CsmInt10HookSmm/VbiosWaOpRom/VbWOpRom.asm

124 lines
3.5 KiB
NASM

;;******************************************************************************
;;* Copyright (c) 1983-2014, Insyde Software Corporation. All Rights Reserved.
;;*
;;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;;* transmit, broadcast, present, recite, release, license or otherwise exploit
;;* any part of this publication in any form, by any means, without the prior
;;* written permission of Insyde Software Corporation.
;;*
;;******************************************************************************
;;
;; Abstract:
;; Hook INT10 to trigger software SMI for INTEL VBIOS workaround. (IBP:549021)
;;
.MODEL small
.586p
.code
CodeStart:
ORG 0
db 55h, 0AAh
CodeSize db ((((offset CodeEnd) - (offset CodeStart)) / 512) + 1)
ORG 3
jmp HookInt10
OldINT10SegOff dw ?, ?
INT10SmiPort dw ?
INT10SmiData dw ?
;Initialize INT10 option rom
; Input Registers:
; Regs.X.AX = COMMON_INT10_SMI;
; Regs.X.CX = ;
; Regs.X.DX = SW_SMI_PORT;
; Regs.X.DS = ;
; Regs.X.ES = ;
HookInt10 PROC PUBLIC
push eax
push ebx
push edx
mov cs:[INT10SmiData], ax
mov cs:[INT10SmiPort], dx
; Insert a WorkAroundVbios call before the real INT 10 function call.
push cs
push offset WorkAroundVbios
pop eax
mov bx,10h*4
call nChangeInt
mov dword ptr cs:OldINT10SegOff,eax
pop edx
pop ebx
pop eax
retf
HookInt10 ENDP
;-------------------------------------------------------------------------------
; nChangeInt();
; input: eax=Pro seg:offset
; bx=IntNumb*4
; output:eax=Old int seg:offset
;-------------------------------------------------------------------------------
nChangeInt PROC NEAR
push es
push 0
pop es
cli
push dword ptr es:[bx]
mov dword ptr es:[bx],eax
sti
pop eax
pop es
ret
nChangeInt ENDP
;****************************************************************************
;* TriggerSmi *
;* *
;* PURPOSE: Trigger SMI *
;* DESCRIPTION: *
;* USES: *
;* PASSED: AX - Interrupt service number *
;* EDX - New Interrupt Segment:Offset *
;* SPECIAL: NOTHING. *
;* RETURNS: EAX - Original Interrupt Segment:offset *
;****************************************************************************
TriggerSmi PROC NEAR
push dx
push ax
mov ax, cs:[INT10SmiData]
mov dx, cs:[INT10SmiPort]
out dx, al
out 0edh, al ;IO dummy for Smi trigger synchronous
pop ax
pop dx
ret
TriggerSmi ENDP
PUBLIC WorkAroundVbios
WorkAroundVbios PROC
pushf
cmp ax, 04F02h ; Check if this int 10 is for "Set VBE mode" command(AX = 04F02h). If yes, trigger workaround SMI first.
jne NoNeedOfVbWa
popf
call TriggerSmi
jmp Done
NoNeedOfVbWa:
popf
Done:
jmp dword ptr cs:[OldINT10SegOff] ; call the original INT 10 service routine in the end.
WorkAroundVbios ENDP
CodeEnd:
END