VirtualBox

source: kStuff/hacks/os2ldr/pcibios_workaround1.asm

Last change on this file was 45, checked in by bird, 13 years ago

os2ldr: Hack around broken PCI BIOS in recent AMI UEFI firmwares.

File size: 6.4 KB
RevLine 
[45]1; $Id: $
2;; @file
3; Workaround for borked PCI BIOSes in recent UEFI BIOSES.
4;
5
6;
7; Copyright (C) Knut St. Osmundsen
8; All rights reserved.
9;
10
11
12;
13; SMP OS2LDR constants.
14;
15%define ADDR_CallPciBios 0x2a73
16%define ADDR_fpfnDevHlp 0x2496
17%define ADDR_fpPciBiosServiceVector 0x24ac
18%define OS2LDR_DATA_SEG 0x0108
19
20%define PATCH_ORG 0c600h ; End of OS2LDR stack + lots.
21 ORG PATCH_ORG
22 BITS 16
23
24;
25; A patch header that can be processed by my patch utility.
26;
27patch_header:
28 db 'bird' ; signature
29 dw PATCH_ORG ; the ORG of this patch
30
31patch_sizes:
32 db 'size'
33 dw 2 ; two sizes to patch
34 dw 07a21h, 0baa2h, 0000h ; <offset>, <orignal value>, <delta>
35 dw 07ce0h, 079f8h, 0000h ; <offset>, <orignal value>, <delta>
36
37patch_jmps:
38 db 'jmps'
39 dw 1 ; one patch jmp
40%if 1
41 ; CallPciBios
42 dw ADDR_CallPciBios
43 dw CallPciBiosWrapper
44 dw 6h ; length of the following instructions
45CallPciBiosLeadIn:
46 push ebp
47 mov [024a8h], ss
48 jmp ADDR_CallPciBios + 6h
49%endif
50 db 'end',0
51
52;
53; OS/2 constants.
54;
55%define VMDHA_FIXED (1 << 1)
56%define VMDHA_USEHIGHMEM (1 << 11)
57%define DevHlp_VMAlloc 0x57
58%define DevHlp_GetDOSVar 0x24
59struc DosTable2
60 .d2_Entries resb 1
61 .d2_ErrMap24 resd 1
62 .d2_MsgMap24 resd 1
63 .d2_Err_Table_24 resd 1
64 .d2_CDSAddr resd 1
65 .d2_GDT_RDR1 resd 1
66 .d2_InterruptLevel resd 1
67 .d2__cInDos resd 1
68 .d2_zero_1 resd 1
69 .d2_zero_2 resd 1
70 .d2_FlatCS resd 1
71 .d2_FlatDS resd 1
72 .d2__TKSSBase resd 1
73 .d2_intSwitchStack resd 1
74 .d2_privateStack resd 1
75 .d2_PhysDiskTablePtr resd 1
76 .d2_forceEMHandler resd 1
77 .d2_ReserveVM resd 1
78 .d2_pgpPageDir resd 1
79 .d2_unknown resd 1
80endstruc
81
82;
83; Globals
84;
85gdt_lock:
86 dd 0
87gdtr_saved:
88 dd 0, 0
89gdtr_copy:
90 dd 0, 0
91gdtr_inited:
92 db 0
93 db 0
94flat_ds:
95 dw 178h
96
97
98db 'padding', 0
99db 'padding', 0
100db 'padding', 0
101db 'padding', 0
102db 'padding', 0
103db 'padding', 0
104
105;;
106; Function which wrapps up the CallPciBios.
107;
108CallPciBiosWrapper:
109 push fs
110 push ds
111 pop fs ; load whatever DATA segment we're working with.
112
113 ; Take the lock.
114 push eax
115.retry:
116 mov al, 1
117 xchg [fs:gdt_lock], al
118 cmp al, 0
119 je .locked
120 pause
121 jmp .retry
122.locked:
123 pop eax
124
125 ; Save the GDTR.
126 db 066h
127 sgdt [fs:gdtr_saved]
128
129 ; Lazy init detour.
130 cmp byte [fs:gdtr_inited], 0
131 je .set_up_gdt
132
133 ; Update the GDT copy.
134.update_gdt:
135 push ecx
136 push edi
137 push esi
138 push es
139 push ds
140
141 mov cx, [fs:flat_ds]
142 mov ds, cx
143 mov es, cx
144
145 movzx ecx, word [fs:gdtr_saved]
146 inc ecx
147 cmp ecx, 0f000h
148 jbe .small_gdt
149 mov ecx, 0f000h
150.small_gdt:
151 mov esi, [fs:gdtr_saved + 2]
152 mov edi, [fs:gdtr_copy + 2]
153 cld
154 db 067h
155 rep movsb
156
157 pop ds
158 pop es
159 pop esi
160 pop edi
161 pop ecx
162
163 ; Load the GDT copy.
164 pushf
165 cli
166 db 066h
167 lgdt [fs:gdtr_copy]
168 popf
169
170 ; Call what remains of CallPciBios instructions.
171 call CallPciBiosLeadIn
172
173 ; Restore the OS/2 GDTR and release the lock.
174 pushf
175 push eax
176 cli
177
178 db 066h
179 lgdt [fs:gdtr_saved]
180
181 xor al, al
182 xchg [fs:gdt_lock], al
183
184 pop eax
185 popf
186
187 pop fs
188 ret
189
190 ;
191 ; Set up the 'copy' GDT.
192 ;
193.set_up_gdt:
194 push es
195 push ds
196 push gs
197 pushad
198
199 ; Figure out what the 32-bit DS selector value is.
200 mov eax, 9 ; Undocumented, dostable.
201 xor ecx, ecx
202 mov dl, DevHlp_GetDOSVar
203 call far [fs:ADDR_fpfnDevHlp]
204 jc near .failed
205 mov es, ax
206 movzx cx, byte [es:bx] ; table length
207 shl cx, 2
208 inc cx
209 add bx, cx ; es:bx points to DosTable2.
210 mov ax, [es:bx + DosTable2.d2_FlatDS]
211 mov [fs:flat_ds], ax
212
213 ; Allocate a 64KB GDT.
214 mov ecx, 10000h ; Size = 64KB
215 mov edi, 0ffffffffh ; PhysAddr = -1
216 mov eax, VMDHA_FIXED | VMDHA_USEHIGHMEM
217 mov dl, DevHlp_VMAlloc
218 call far [fs:ADDR_fpfnDevHlp]
219 jc .failed
220 mov [fs:gdtr_copy+2], eax
221 mov word [fs:gdtr_copy], 0ffffh
222
223 ; Clear it.
224 cld
225 mov ax, [fs:flat_ds] ; load flag gd
226 mov ds, ax
227 mov es, ax
228 mov edi, [fs:gdtr_copy + 2]
229 xor eax, eax
230 mov ecx, 10000h
231 db 067h
232 rep stosb
233
234 ; Set up the 0f000h selector as a copy of the other ROM selector.
235 mov si, [fs:ADDR_fpPciBiosServiceVector + 2]
236 and esi, 0000fff8h
237 add esi, [fs:gdtr_saved + 2] ; = source gdt entry
238 mov edi, [fs:gdtr_copy + 2]
239 add edi, dword 0f000h ; = destination gdt entry - ?dword for yasm bug? saw '66 81 c7 00 10 00 10 add edi, 010001000h'
240 mov ecx, 8h ; gdt entry size
241 db 067h
242 rep movsb
243
244 ; Indicated that we've completed the GDT init.
245 inc word [fs:gdtr_inited]
246
247.done:
248 popad
249 pop gs
250 pop ds
251 pop es
252 jmp .update_gdt
253.failed:
254 int3
255 jmp .done
256
257
258db 'Padding', 0
259db 'Padding', 0
260db 'Padding', 0
261db 'Padding', 0
262db 'Padding', 0
263db 'Padding', 0
264
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette