;------------------------------------------------------------------------------ ; @file ; A minimal Int10h stub that allows the Windows 2008 R2 SP1 UEFI guest's buggy, ; default VGA driver to switch to 1024x768x32. ; ; Copyright (C) 2020, Rebecca Cran ; Copyright (C) 2015, Nahanni Systems, Inc. ; Copyright (C) 2014, Red Hat, Inc. ; Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
; ; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ ; enable this macro for debug messages %define DEBUG %macro DebugLog 1 %ifdef DEBUG push si mov si, %1 call PrintStringSi pop si %endif %endmacro BITS 16 ORG 0 VbeInfo: TIMES 256 nop VbeModeInfo: VbeMode1: TIMES 50 nop VbeMode2: TIMES 50 nop VbeMode3: TIMES 50 nop VbeMode4: TIMES 50 nop TIMES 56 nop ; filler for 256 bytes Handler: cmp ax, 0x4f00 je GetInfo cmp ax, 0x4f01 je GetModeInfo cmp ax, 0x4f02 je SetMode cmp ax, 0x4f03 je GetMode cmp ax, 0x4f10 je GetPmCapabilities cmp ax, 0x4f15 je ReadEdid cmp ah, 0x00 je SetModeLegacy DebugLog StrUnkownFunction Hang: jmp Hang GetInfo: push es push di push ds push si push cx DebugLog StrEnterGetInfo ; target (es:di) set on input push cs pop ds mov si, VbeInfo ; source (ds:si) set now mov cx, 256 cld rep movsb pop cx pop si pop ds pop di pop es jmp Success GetModeInfo: push es push di push ds push si push cx DebugLog StrEnterGetModeInfo and cx, ~0x4000 ; clear potentially set LFB bit in mode number cmp cx, 0x013f je gKnownMode1 cmp cx, 0x0140 je gKnownMode2 cmp cx, 0x0141 je gKnownMode3 DebugLog StrUnkownMode jmp Hang gKnownMode1: DebugLog StrMode1 mov si, VbeMode1 jmp CopyModeInfo gKnownMode2: DebugLog StrMode2 mov si, VbeMode2 jmp CopyModeInfo gKnownMode3: DebugLog StrMode3 mov si, VbeMode3 jmp CopyModeInfo gKnownMode4: DebugLog StrMode4 mov si, VbeMode4 jmp CopyModeInfo CopyModeInfo: ; target (es:di) set on input push cs pop ds ;mov si, VbeModeInfo ; source (ds:si) set now ;mov cx, 256 mov cx, 50 cld rep movsb pop cx pop si pop ds pop di pop es jmp Success SetMode: push dx push ax DebugLog StrEnterSetMode and bx, ~0x4000 ; clear potentially set LFB bit in mode number cmp bx, 0x013f je KnownMode1 cmp bx, 0x0140 je KnownMode2 cmp bx, 0x0141 je KnownMode3 DebugLog StrUnkownMode jmp Hang KnownMode1: DebugLog StrMode1 jmp SetModeDone KnownMode2: DebugLog StrMode2 jmp SetModeDone KnownMode3: DebugLog StrMode3 jmp SetModeDone KnownMode4: DebugLog StrMode4 SetModeDone: mov [CurMode], bl mov [CurMode+1], bh pop ax pop dx jmp Success GetMode: DebugLog StrEnterGetMode mov bl, [CurMode] mov bh, [CurMode+1] jmp Success GetPmCapabilities: DebugLog StrGetPmCapabilities mov bx, 0x0080 jmp Success ReadEdid: push es push di push ds push si push cx DebugLog StrReadEdid ; target (es:di) set on input push cs pop ds mov si, Edid ; source (ds:si) set now mov cx, 128 cld rep movsb pop cx pop si pop ds pop di pop es jmp Success SetModeLegacy: DebugLog StrEnterSetModeLegacy cmp al, 0x03 je sKnownMode3 cmp al, 0x12 je sKnownMode4 DebugLog StrUnkownMode jmp Hang sKnownMode3: DebugLog StrLegacyMode3 mov al, 0 ; 0x30 jmp SetModeLegacyDone sKnownMode4: mov al, 0 ;0x20 SetModeLegacyDone: DebugLog StrExitSuccess iret Success: DebugLog StrExitSuccess mov ax, 0x004f iret Unsupported: DebugLog StrExitUnsupported mov ax, 0x024f iret %ifdef DEBUG PrintStringSi: pusha push ds ; save original push cs pop ds mov dx, 0x220 ; bhyve debug cons port mov ax, 0 PrintStringSiLoop: lodsb cmp al, 0 je PrintStringSiDone out dx, al jmp PrintStringSiLoop PrintStringSiDone: pop ds ; restore original popa ret StrExitSuccess: db 'vOk', 0x0d, 0x0a, 0 StrExitUnsupported: db 'vUnsupported', 0x0d, 0x0a, 0 StrUnkownFunction: db 'vUnknown Function', 0x0d, 0x0a, 0 StrEnterGetInfo: db 'vGetInfo', 0x0d, 0x0a, 0 StrEnterGetModeInfo: db 'vGetModeInfo', 0x0d, 0x0a, 0 StrEnterGetMode: db 'vGetMode', 0x0d, 0x0a, 0 StrEnterSetMode: db 'vSetMode', 0x0d, 0x0a, 0 StrEnterSetModeLegacy: db 'vSetModeLegacy', 0x0d, 0x0a, 0 StrUnkownMode: db 'vUnkown Mode', 0x0d, 0x0a, 0 StrGetPmCapabilities: db 'vGetPmCapabilities', 0x0d, 0x0a, 0 StrReadEdid: db 'vReadEdid', 0x0d, 0x0a, 0 StrLegacyMode3: db 'vLegacyMode3', 0x0d, 0x0a, 0 StrMode1: db 'mode_640x480x32', 0x0d, 0x0a, 0 StrMode2: db 'mode_800x600x32', 0x0d, 0x0a, 0 StrMode3: db 'mode_1024x768x32', 0x0d, 0x0a, 0 StrMode4: db 'mode_unused', 0x0d, 0x0a, 0 %endif CurMode: db 0x00, 0x00 ; ; EDID stores monitor information. For now, just send back an null item. ; Edid: db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00