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#define __io
45#include <common.h>
46#include <asm/io.h>
47#include "biosemui.h"
48
49
50
51
52
53
54
55
56
57
58static void X86API undefined_intr(int intno)
59{
60 if (BE_rdw(intno * 4 + 2) == BIOS_SEG) {
61 DB(printf("biosEmu: undefined interrupt %xh called!\n", intno);)
62 } else
63 X86EMU_prepareForInt(intno);
64}
65
66
67
68
69
70
71
72
73
74
75static void X86API int42(int intno)
76{
77 if (M.x86.R_AH == 0x12 && M.x86.R_BL == 0x32) {
78 if (M.x86.R_AL == 0) {
79
80 PM_outpb(0x3c2, PM_inpb(0x3cc) | (u8) 0x02);
81 return;
82 } else if (M.x86.R_AL == 1) {
83
84 PM_outpb(0x3c2, PM_inpb(0x3cc) & (u8) ~ 0x02);
85 return;
86 }
87#ifdef CONFIG_X86EMU_DEBUG
88 else {
89 printf("int42: unknown function AH=0x12, BL=0x32, AL=%#02x\n",
90 M.x86.R_AL);
91 }
92#endif
93 }
94#ifdef CONFIG_X86EMU_DEBUG
95 else {
96 printf("int42: unknown function AH=%#02x, AL=%#02x, BL=%#02x\n",
97 M.x86.R_AH, M.x86.R_AL, M.x86.R_BL);
98 }
99#endif
100}
101
102
103
104
105
106
107
108
109
110
111
112
113static void X86API int10(int intno)
114{
115 if (BE_rdw(intno * 4 + 2) == BIOS_SEG)
116 int42(intno);
117 else
118 X86EMU_prepareForInt(intno);
119}
120
121
122
123#define SUCCESSFUL 0x00
124#define FUNC_NOT_SUPPORT 0x81
125#define BAD_VENDOR_ID 0x83
126#define DEVICE_NOT_FOUND 0x86
127#define BAD_REGISTER_NUMBER 0x87
128#define SET_FAILED 0x88
129#define BUFFER_TOO_SMALL 0x89
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145static void X86API int1A(int unused)
146{
147 u16 pciSlot;
148
149#ifdef __KERNEL__
150 u8 interface, subclass, baseclass;
151
152
153 pciSlot = ((int)_BE_env.vgaInfo.bus << 8) |
154 ((int)_BE_env.vgaInfo.device << 3) | (int)_BE_env.vgaInfo.function;
155#else
156
157 if (!_BE_env.vgaInfo.pciInfo)
158 return;
159
160 pciSlot = (u16) (_BE_env.vgaInfo.pciInfo->slot.i >> 8);
161#endif
162 switch (M.x86.R_AX) {
163 case 0xB101:
164 M.x86.R_AL = 0x00;
165 M.x86.R_EDX = 0x20494350;
166 M.x86.R_BX = 0x0210;
167 M.x86.R_CL = 0;
168 CLEAR_FLAG(F_CF);
169 break;
170 case 0xB102:
171 M.x86.R_AH = DEVICE_NOT_FOUND;
172#ifdef __KERNEL__
173 if (M.x86.R_DX == _BE_env.vgaInfo.VendorID &&
174 M.x86.R_CX == _BE_env.vgaInfo.DeviceID && M.x86.R_SI == 0) {
175#else
176 if (M.x86.R_DX == _BE_env.vgaInfo.pciInfo->VendorID &&
177 M.x86.R_CX == _BE_env.vgaInfo.pciInfo->DeviceID &&
178 M.x86.R_SI == 0) {
179#endif
180 M.x86.R_AH = SUCCESSFUL;
181 M.x86.R_BX = pciSlot;
182 }
183 CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
184 break;
185 case 0xB103:
186 M.x86.R_AH = DEVICE_NOT_FOUND;
187#ifdef __KERNEL__
188#ifdef CONFIG_DM_PCI
189 dm_pci_read_config8(_BE_env.vgaInfo.pcidev, PCI_CLASS_PROG,
190 &interface);
191 dm_pci_read_config8(_BE_env.vgaInfo.pcidev, PCI_CLASS_DEVICE,
192 &subclass);
193 dm_pci_read_config8(_BE_env.vgaInfo.pcidev,
194 PCI_CLASS_DEVICE + 1, &baseclass);
195#else
196 pci_read_config_byte(_BE_env.vgaInfo.pcidev, PCI_CLASS_PROG,
197 &interface);
198 pci_read_config_byte(_BE_env.vgaInfo.pcidev, PCI_CLASS_DEVICE,
199 &subclass);
200 pci_read_config_byte(_BE_env.vgaInfo.pcidev,
201 PCI_CLASS_DEVICE + 1, &baseclass);
202#endif
203 if (M.x86.R_CL == interface && M.x86.R_CH == subclass
204 && (u8) (M.x86.R_ECX >> 16) == baseclass) {
205#else
206 if (M.x86.R_CL == _BE_env.vgaInfo.pciInfo->Interface &&
207 M.x86.R_CH == _BE_env.vgaInfo.pciInfo->SubClass &&
208 (u8) (M.x86.R_ECX >> 16) ==
209 _BE_env.vgaInfo.pciInfo->BaseClass) {
210#endif
211 M.x86.R_AH = SUCCESSFUL;
212 M.x86.R_BX = pciSlot;
213 }
214 CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
215 break;
216 case 0xB108:
217 M.x86.R_AH = BAD_REGISTER_NUMBER;
218 if (M.x86.R_BX == pciSlot) {
219 M.x86.R_AH = SUCCESSFUL;
220#ifdef __KERNEL__
221# ifdef CONFIG_DM_PCI
222 dm_pci_read_config8(_BE_env.vgaInfo.pcidev, M.x86.R_DI,
223 &M.x86.R_CL);
224# else
225 pci_read_config_byte(_BE_env.vgaInfo.pcidev, M.x86.R_DI,
226 &M.x86.R_CL);
227# endif
228#else
229 M.x86.R_CL =
230 (u8) PCI_accessReg(M.x86.R_DI, 0, PCI_READ_BYTE,
231 _BE_env.vgaInfo.pciInfo);
232#endif
233 }
234 CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
235 break;
236 case 0xB109:
237 M.x86.R_AH = BAD_REGISTER_NUMBER;
238 if (M.x86.R_BX == pciSlot) {
239 M.x86.R_AH = SUCCESSFUL;
240#ifdef __KERNEL__
241# ifdef CONFIG_DM_PCI
242 dm_pci_read_config16(_BE_env.vgaInfo.pcidev, M.x86.R_DI,
243 &M.x86.R_CX);
244# else
245 pci_read_config_word(_BE_env.vgaInfo.pcidev, M.x86.R_DI,
246 &M.x86.R_CX);
247# endif
248#else
249 M.x86.R_CX =
250 (u16) PCI_accessReg(M.x86.R_DI, 0, PCI_READ_WORD,
251 _BE_env.vgaInfo.pciInfo);
252#endif
253 }
254 CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
255 break;
256 case 0xB10A:
257 M.x86.R_AH = BAD_REGISTER_NUMBER;
258 if (M.x86.R_BX == pciSlot) {
259 M.x86.R_AH = SUCCESSFUL;
260#ifdef __KERNEL__
261# ifdef CONFIG_DM_PCI
262 dm_pci_read_config32(_BE_env.vgaInfo.pcidev,
263 M.x86.R_DI, &M.x86.R_ECX);
264# else
265 pci_read_config_dword(_BE_env.vgaInfo.pcidev,
266 M.x86.R_DI, &M.x86.R_ECX);
267# endif
268#else
269 M.x86.R_ECX =
270 (u32) PCI_accessReg(M.x86.R_DI, 0, PCI_READ_DWORD,
271 _BE_env.vgaInfo.pciInfo);
272#endif
273 }
274 CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
275 break;
276 case 0xB10B:
277 M.x86.R_AH = BAD_REGISTER_NUMBER;
278 if (M.x86.R_BX == pciSlot) {
279 M.x86.R_AH = SUCCESSFUL;
280#ifdef __KERNEL__
281# ifdef CONFIG_DM_PCI
282 dm_pci_write_config8(_BE_env.vgaInfo.pcidev,
283 M.x86.R_DI, M.x86.R_CL);
284# else
285 pci_write_config_byte(_BE_env.vgaInfo.pcidev,
286 M.x86.R_DI, M.x86.R_CL);
287# endif
288#else
289 PCI_accessReg(M.x86.R_DI, M.x86.R_CL, PCI_WRITE_BYTE,
290 _BE_env.vgaInfo.pciInfo);
291#endif
292 }
293 CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
294 break;
295 case 0xB10C:
296 M.x86.R_AH = BAD_REGISTER_NUMBER;
297 if (M.x86.R_BX == pciSlot) {
298 M.x86.R_AH = SUCCESSFUL;
299#ifdef __KERNEL__
300# ifdef CONFIG_DM_PCI
301 dm_pci_write_config32(_BE_env.vgaInfo.pcidev,
302 M.x86.R_DI, M.x86.R_CX);
303# else
304 pci_write_config_word(_BE_env.vgaInfo.pcidev,
305 M.x86.R_DI, M.x86.R_CX);
306# endif
307#else
308 PCI_accessReg(M.x86.R_DI, M.x86.R_CX, PCI_WRITE_WORD,
309 _BE_env.vgaInfo.pciInfo);
310#endif
311 }
312 CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
313 break;
314 case 0xB10D:
315 M.x86.R_AH = BAD_REGISTER_NUMBER;
316 if (M.x86.R_BX == pciSlot) {
317 M.x86.R_AH = SUCCESSFUL;
318#ifdef __KERNEL__
319# ifdef CONFIG_DM_PCI
320 dm_pci_write_config32(_BE_env.vgaInfo.pcidev,
321 M.x86.R_DI, M.x86.R_ECX);
322# else
323 pci_write_config_dword(_BE_env.vgaInfo.pcidev,
324 M.x86.R_DI, M.x86.R_ECX);
325# endif
326#else
327 PCI_accessReg(M.x86.R_DI, M.x86.R_ECX, PCI_WRITE_DWORD,
328 _BE_env.vgaInfo.pciInfo);
329#endif
330 }
331 CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
332 break;
333 default:
334 printf("biosEmu/bios.int1a: unknown function AX=%#04x\n",
335 M.x86.R_AX);
336 }
337}
338
339
340
341
342
343
344
345
346
347#define BE_constLE_32(v) ((((((v)&0xff00)>>8)|(((v)&0xff)<<8))<<16)|(((((v)&0xff000000)>>8)|(((v)&0x00ff0000)<<8))>>16))
348
349void _BE_bios_init(u32 * intrTab)
350{
351 int i;
352 X86EMU_intrFuncs bios_intr_tab[256];
353
354 for (i = 0; i < 256; ++i) {
355 intrTab[i] = BE_constLE_32(BIOS_SEG << 16);
356 bios_intr_tab[i] = undefined_intr;
357 }
358 bios_intr_tab[0x10] = int10;
359 bios_intr_tab[0x1A] = int1A;
360 bios_intr_tab[0x42] = int42;
361 bios_intr_tab[0x6D] = int10;
362 X86EMU_setupIntrFuncs(bios_intr_tab);
363}
364