summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/QemuVideoDxe/VbeShim.asm
blob: 1d284b26412423bfdf8c65d51c0585d963833e4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
;------------------------------------------------------------------------------
; @file
; A minimal Int10h stub that allows the Windows 2008 R2 SP1 UEFI guest's buggy,
; default VGA driver to switch to 1024x768x32, on the stdvga and QXL video
; cards of QEMU.
;
; Copyright (C) 2014, Red Hat, Inc.
; Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
;
; 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:
TIMES 256 nop


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   StrUnknownFunction
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, 0x00f1
  je         KnownMode1
  DebugLog   StrUnknownMode
  jmp        Hang
KnownMode1:
  ; target (es:di) set on input
  push       cs
  pop        ds
  mov        si, VbeModeInfo
  ; source (ds:si) set now

  mov        cx, 256
  cld
  rep movsb

  pop        cx
  pop        si
  pop        ds
  pop        di
  pop        es
  jmp        Success


%define ATT_ADDRESS_REGISTER   0x03c0
%define VBE_DISPI_IOPORT_INDEX 0x01ce
%define VBE_DISPI_IOPORT_DATA  0x01d0

%define VBE_DISPI_INDEX_XRES        0x1
%define VBE_DISPI_INDEX_YRES        0x2
%define VBE_DISPI_INDEX_BPP         0x3
%define VBE_DISPI_INDEX_ENABLE      0x4
%define VBE_DISPI_INDEX_BANK        0x5
%define VBE_DISPI_INDEX_VIRT_WIDTH  0x6
%define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
%define VBE_DISPI_INDEX_X_OFFSET    0x8
%define VBE_DISPI_INDEX_Y_OFFSET    0x9

%define VBE_DISPI_ENABLED     0x01
%define VBE_DISPI_LFB_ENABLED 0x40

%macro BochsWrite 2
  push       dx
  push       ax

  mov        dx, VBE_DISPI_IOPORT_INDEX
  mov        ax, %1
  out        dx, ax

  mov        dx, VBE_DISPI_IOPORT_DATA
  mov        ax, %2
  out        dx, ax

  pop        ax
  pop        dx
%endmacro

SetMode:
  push       dx
  push       ax

  DebugLog   StrEnterSetMode

  cmp        bx, 0x40f1
  je         KnownMode2
  DebugLog   StrUnknownMode
  jmp        Hang
KnownMode2:

  ; unblank
  mov        dx, ATT_ADDRESS_REGISTER
  mov        al, 0x20
  out        dx, al

  BochsWrite VBE_DISPI_INDEX_ENABLE,        0
  BochsWrite VBE_DISPI_INDEX_BANK,          0
  BochsWrite VBE_DISPI_INDEX_X_OFFSET,      0
  BochsWrite VBE_DISPI_INDEX_Y_OFFSET,      0
  BochsWrite VBE_DISPI_INDEX_BPP,          32
  BochsWrite VBE_DISPI_INDEX_XRES,       1024
  BochsWrite VBE_DISPI_INDEX_VIRT_WIDTH, 1024
  BochsWrite VBE_DISPI_INDEX_YRES,        768
  BochsWrite VBE_DISPI_INDEX_VIRT_HEIGHT, 768
  BochsWrite VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED

  pop        ax
  pop        dx
  jmp        Success


GetMode:
  DebugLog   StrEnterGetMode
  mov        bx, 0x40f1
  jmp        Success


GetPmCapabilities:
  DebugLog   StrGetPmCapabilities
  jmp        Unsupported


ReadEdid:
  DebugLog   StrReadEdid
  jmp        Unsupported


SetModeLegacy:
  DebugLog   StrEnterSetModeLegacy

  cmp        al, 0x03
  je         KnownMode3
  cmp        al, 0x12
  je         KnownMode4
  DebugLog   StrUnknownMode
  jmp        Hang
KnownMode3:
  mov        al, 0x30
  jmp        SetModeLegacyDone
KnownMode4:
  mov        al, 0x20
SetModeLegacyDone:
  DebugLog   StrExitSuccess
  iret


Success:
  DebugLog   StrExitSuccess
  mov        ax, 0x004f
  iret


Unsupported:
  DebugLog   StrExitUnsupported
  mov        ax, 0x014f
  iret


%ifdef DEBUG
PrintStringSi:
  pusha
  push       ds ; save original
  push       cs
  pop        ds
  mov        dx, 0x0402
PrintStringSiLoop:
  lodsb
  cmp        al, 0
  je         PrintStringSiDone
  out        dx, al
  jmp        PrintStringSiLoop
PrintStringSiDone:
  pop        ds ; restore original
  popa
  ret


StrExitSuccess:
  db 'Exit', 0x0a, 0

StrExitUnsupported:
  db 'Unsupported', 0x0a, 0

StrUnknownFunction:
  db 'Unknown Function', 0x0a, 0

StrEnterGetInfo:
  db 'GetInfo', 0x0a, 0

StrEnterGetModeInfo:
  db 'GetModeInfo', 0x0a, 0

StrEnterGetMode:
  db 'GetMode', 0x0a, 0

StrEnterSetMode:
  db 'SetMode', 0x0a, 0

StrEnterSetModeLegacy:
  db 'SetModeLegacy', 0x0a, 0

StrUnknownMode:
  db 'Unknown Mode', 0x0a, 0

StrGetPmCapabilities:
  db 'GetPmCapabilities', 0x0a, 0

StrReadEdid:
  db 'ReadEdid', 0x0a, 0
%endif