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#include <common.h>
51#include "biosemui.h"
52
53
54
55#ifndef __i386__
56static char *BE_biosDate = "08/14/99";
57static u8 BE_model = 0xFC;
58static u8 BE_submodel = 0x00;
59#endif
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76static u8 *BE_memaddr(u32 addr)
77{
78 if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
79 return (u8*)(_BE_env.biosmem_base + addr - 0xC0000);
80 } else if (addr > _BE_env.biosmem_limit && addr < 0xD0000) {
81 DB(printf("BE_memaddr: address %#lx may be invalid!\n", addr);)
82 return M.mem_base;
83 } else if (addr >= 0xA0000 && addr <= 0xBFFFF) {
84 return (u8*)(_BE_env.busmem_base + addr - 0xA0000);
85 }
86#ifdef __i386__
87 else if (addr >= 0xD0000 && addr <= 0xFFFFF) {
88
89 DB(printf("BE_memaddr: System BIOS address %#lx\n", addr);)
90 return _BE_env.busmem_base + addr - 0xA0000;
91 }
92#else
93 else if (addr >= 0xFFFF5 && addr < 0xFFFFE) {
94
95 DB(printf("BE_memaddr - Returning BIOS date\n");)
96 return (u8 *)(BE_biosDate + addr - 0xFFFF5);
97 } else if (addr == 0xFFFFE) {
98
99 DB(printf("BE_memaddr - Returning model\n");)
100 return &BE_model;
101 } else if (addr == 0xFFFFF) {
102
103 DB(printf("BE_memaddr - Returning submodel\n");)
104 return &BE_submodel;
105 }
106#endif
107 else if (addr > M.mem_size - 1) {
108 HALT_SYS();
109 return M.mem_base;
110 }
111
112 return M.mem_base + addr;
113}
114
115
116
117
118
119
120
121
122
123
124
125
126u8 X86API BE_rdb(u32 addr)
127{
128 if (_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)
129 return 0;
130 else {
131 u8 val = readb_le(BE_memaddr(addr));
132 return val;
133 }
134}
135
136
137
138
139
140
141
142
143
144
145
146
147u16 X86API BE_rdw(u32 addr)
148{
149 if (_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)
150 return 0;
151 else {
152 u8 *base = BE_memaddr(addr);
153 u16 val = readw_le(base);
154 return val;
155 }
156}
157
158
159
160
161
162
163
164
165
166
167
168
169u32 X86API BE_rdl(u32 addr)
170{
171 if (_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)
172 return 0;
173 else {
174 u8 *base = BE_memaddr(addr);
175 u32 val = readl_le(base);
176 return val;
177 }
178}
179
180
181
182
183
184
185
186
187
188
189void X86API BE_wrb(u32 addr, u8 val)
190{
191 if (!(_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)) {
192 writeb_le(BE_memaddr(addr), val);
193 }
194}
195
196
197
198
199
200
201
202
203
204
205void X86API BE_wrw(u32 addr, u16 val)
206{
207 if (!(_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)) {
208 u8 *base = BE_memaddr(addr);
209 writew_le(base, val);
210
211 }
212}
213
214
215
216
217
218
219
220
221
222
223void X86API BE_wrl(u32 addr, u32 val)
224{
225 if (!(_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)) {
226 u8 *base = BE_memaddr(addr);
227 writel_le(base, val);
228 }
229}
230
231#if defined(DEBUG) || !defined(__i386__)
232
233
234
235
236
237#define IS_TIMER_PORT(port) (0x40 <= port && port <= 0x43)
238#define IS_CMOS_PORT(port) (0x70 <= port && port <= 0x71)
239
240#define IS_VGA_PORT(port) (0x3C0 <= port && port <= 0x3DA)
241#define IS_PCI_PORT(port) (0xCF8 <= port && port <= 0xCFF)
242#define IS_SPKR_PORT(port) (port == 0x61)
243
244
245
246
247
248
249
250
251
252
253
254
255static u8 VGA_inpb (const int port)
256{
257 u8 val = 0xff;
258
259 switch (port) {
260 case 0x3C0:
261
262
263
264
265 if (_BE_env.flipFlop3C0 == 0) {
266
267 val = _BE_env.emu3C0;
268 } else {
269
270 if (_BE_env.emu3C0 < ATT_C)
271 val = _BE_env.emu3C1[_BE_env.emu3C0];
272 }
273 _BE_env.flipFlop3C0 ^= 1;
274 break;
275 case 0x3C1:
276 if (_BE_env.emu3C0 < ATT_C)
277 return _BE_env.emu3C1[_BE_env.emu3C0];
278 break;
279 case 0x3CC:
280 return _BE_env.emu3C2;
281 case 0x3C4:
282 return _BE_env.emu3C4;
283 case 0x3C5:
284 if (_BE_env.emu3C4 < ATT_C)
285 return _BE_env.emu3C5[_BE_env.emu3C4];
286 break;
287 case 0x3C6:
288 return _BE_env.emu3C6;
289 case 0x3C7:
290 return _BE_env.emu3C7;
291 case 0x3C8:
292 return _BE_env.emu3C8;
293 case 0x3C9:
294 if (_BE_env.emu3C7 < PAL_C)
295 return _BE_env.emu3C9[_BE_env.emu3C7++];
296 break;
297 case 0x3CE:
298 return _BE_env.emu3CE;
299 case 0x3CF:
300 if (_BE_env.emu3CE < GRA_C)
301 return _BE_env.emu3CF[_BE_env.emu3CE];
302 break;
303 case 0x3D4:
304 if (_BE_env.emu3C2 & 0x1)
305 return _BE_env.emu3D4;
306 break;
307 case 0x3D5:
308 if ((_BE_env.emu3C2 & 0x1) && (_BE_env.emu3D4 < CRT_C))
309 return _BE_env.emu3D5[_BE_env.emu3D4];
310 break;
311 case 0x3DA:
312 _BE_env.flipFlop3C0 = 0;
313 val = _BE_env.emu3DA;
314 _BE_env.emu3DA ^= 0x9;
315 break;
316 }
317 return val;
318}
319
320
321
322
323
324
325
326
327
328
329
330static void VGA_outpb (int port, u8 val)
331{
332 switch (port) {
333 case 0x3C0:
334
335
336
337
338 if (_BE_env.flipFlop3C0 == 0) {
339
340 _BE_env.emu3C0 = val;
341 } else {
342
343 if (_BE_env.emu3C0 < ATT_C)
344 _BE_env.emu3C1[_BE_env.emu3C0] = val;
345 }
346 _BE_env.flipFlop3C0 ^= 1;
347 break;
348 case 0x3C2:
349 _BE_env.emu3C2 = val;
350 break;
351 case 0x3C4:
352 _BE_env.emu3C4 = val;
353 break;
354 case 0x3C5:
355 if (_BE_env.emu3C4 < ATT_C)
356 _BE_env.emu3C5[_BE_env.emu3C4] = val;
357 break;
358 case 0x3C6:
359 _BE_env.emu3C6 = val;
360 break;
361 case 0x3C7:
362 _BE_env.emu3C7 = (int) val *3;
363
364 break;
365 case 0x3C8:
366 _BE_env.emu3C8 = (int) val *3;
367
368 break;
369 case 0x3C9:
370 if (_BE_env.emu3C8 < PAL_C)
371 _BE_env.emu3C9[_BE_env.emu3C8++] = val;
372 break;
373 case 0x3CE:
374 _BE_env.emu3CE = val;
375 break;
376 case 0x3CF:
377 if (_BE_env.emu3CE < GRA_C)
378 _BE_env.emu3CF[_BE_env.emu3CE] = val;
379 break;
380 case 0x3D4:
381 if (_BE_env.emu3C2 & 0x1)
382 _BE_env.emu3D4 = val;
383 break;
384 case 0x3D5:
385 if ((_BE_env.emu3C2 & 0x1) && (_BE_env.emu3D4 < CRT_C))
386 _BE_env.emu3D5[_BE_env.emu3D4] = val;
387 break;
388 }
389}
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405static u32 BE_accessReg(int regOffset, u32 value, int func)
406{
407#ifdef __KERNEL__
408 int function, device, bus;
409 u8 val8;
410 u16 val16;
411 u32 val32;
412
413
414
415
416
417 regOffset += (_BE_env.configAddress & 0xFF);
418 function = (_BE_env.configAddress >> 8) & 0x7;
419 device = (_BE_env.configAddress >> 11) & 0x1F;
420 bus = (_BE_env.configAddress >> 16) & 0xFF;
421
422
423 if ((function == _BE_env.vgaInfo.function) &&
424 (device == _BE_env.vgaInfo.device) &&
425 (bus == _BE_env.vgaInfo.bus)) {
426 switch (func) {
427 case REG_READ_BYTE:
428 pci_read_config_byte(_BE_env.vgaInfo.pcidev, regOffset,
429 &val8);
430 return val8;
431 case REG_READ_WORD:
432 pci_read_config_word(_BE_env.vgaInfo.pcidev, regOffset,
433 &val16);
434 return val16;
435 case REG_READ_DWORD:
436 pci_read_config_dword(_BE_env.vgaInfo.pcidev, regOffset,
437 &val32);
438 return val32;
439 case REG_WRITE_BYTE:
440 pci_write_config_byte(_BE_env.vgaInfo.pcidev, regOffset,
441 value);
442
443 return 0;
444 case REG_WRITE_WORD:
445 pci_write_config_word(_BE_env.vgaInfo.pcidev, regOffset,
446 value);
447
448 return 0;
449 case REG_WRITE_DWORD:
450 pci_write_config_dword(_BE_env.vgaInfo.pcidev,
451 regOffset, value);
452
453 return 0;
454 }
455 }
456 return 0;
457#else
458 PCIDeviceInfo pciInfo;
459
460 pciInfo.mech1 = 1;
461 pciInfo.slot.i = 0;
462 pciInfo.slot.p.Function = (_BE_env.configAddress >> 8) & 0x7;
463 pciInfo.slot.p.Device = (_BE_env.configAddress >> 11) & 0x1F;
464 pciInfo.slot.p.Bus = (_BE_env.configAddress >> 16) & 0xFF;
465 pciInfo.slot.p.Enable = 1;
466
467
468 if ((pciInfo.slot.p.Function ==
469 _BE_env.vgaInfo.pciInfo->slot.p.Function)
470 && (pciInfo.slot.p.Device == _BE_env.vgaInfo.pciInfo->slot.p.Device)
471 && (pciInfo.slot.p.Bus == _BE_env.vgaInfo.pciInfo->slot.p.Bus))
472 return PCI_accessReg((_BE_env.configAddress & 0xFF) + regOffset,
473 value, func, &pciInfo);
474 return 0;
475#endif
476}
477
478
479
480
481
482
483
484
485
486
487
488static u32 PCI_inp(int port, int type)
489{
490 switch (type) {
491 case REG_READ_BYTE:
492 if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
493 && port <= 0xCFF)
494 return BE_accessReg(port - 0xCFC, 0, REG_READ_BYTE);
495 break;
496 case REG_READ_WORD:
497 if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
498 && port <= 0xCFF)
499 return BE_accessReg(port - 0xCFC, 0, REG_READ_WORD);
500 break;
501 case REG_READ_DWORD:
502 if (port == 0xCF8)
503 return _BE_env.configAddress;
504 else if ((_BE_env.configAddress & 0x80000000) && port == 0xCFC)
505 return BE_accessReg(0, 0, REG_READ_DWORD);
506 break;
507 }
508 return 0;
509}
510
511
512
513
514
515
516
517
518
519static void PCI_outp(int port, u32 val, int type)
520{
521 switch (type) {
522 case REG_WRITE_BYTE:
523 if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
524 && port <= 0xCFF)
525 BE_accessReg(port - 0xCFC, val, REG_WRITE_BYTE);
526 break;
527 case REG_WRITE_WORD:
528 if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
529 && port <= 0xCFF)
530 BE_accessReg(port - 0xCFC, val, REG_WRITE_WORD);
531 break;
532 case REG_WRITE_DWORD:
533 if (port == 0xCF8)
534 {
535 _BE_env.configAddress = val & 0x80FFFFFC;
536 }
537 else if ((_BE_env.configAddress & 0x80000000) && port == 0xCFC)
538 BE_accessReg(0, val, REG_WRITE_DWORD);
539 break;
540 }
541}
542
543#endif
544
545
546
547
548
549
550
551
552
553
554
555
556
557u8 X86API BE_inb(X86EMU_pioAddr port)
558{
559 u8 val = 0;
560
561#if defined(DEBUG) || !defined(__i386__)
562 if (IS_VGA_PORT(port)){
563
564 if(port == 0x3c3)
565 val = LOG_inpb(port);
566 else
567 val = VGA_inpb(port);
568 }
569 else if (IS_TIMER_PORT(port))
570 DB(printf("Can not interept TIMER port now!\n");)
571 else if (IS_SPKR_PORT(port))
572 DB(printf("Can not interept SPEAKER port now!\n");)
573 else if (IS_CMOS_PORT(port))
574 DB(printf("Can not interept CMOS port now!\n");)
575 else if (IS_PCI_PORT(port))
576 val = PCI_inp(port, REG_READ_BYTE);
577 else if (port < 0x100) {
578 DB(printf("WARN: INVALID inb.%04X -> %02X\n", (u16) port, val);)
579 val = LOG_inpb(port);
580 } else
581#endif
582 val = LOG_inpb(port);
583 return val;
584}
585
586
587
588
589
590
591
592
593
594
595
596
597
598u16 X86API BE_inw(X86EMU_pioAddr port)
599{
600 u16 val = 0;
601
602#if defined(DEBUG) || !defined(__i386__)
603 if (IS_PCI_PORT(port))
604 val = PCI_inp(port, REG_READ_WORD);
605 else if (port < 0x100) {
606 DB(printf("WARN: Maybe INVALID inw.%04X -> %04X\n", (u16) port, val);)
607 val = LOG_inpw(port);
608 } else
609#endif
610 val = LOG_inpw(port);
611 return val;
612}
613
614
615
616
617
618
619
620
621
622
623
624
625
626u32 X86API BE_inl(X86EMU_pioAddr port)
627{
628 u32 val = 0;
629
630#if defined(DEBUG) || !defined(__i386__)
631 if (IS_PCI_PORT(port))
632 val = PCI_inp(port, REG_READ_DWORD);
633 else if (port < 0x100) {
634 val = LOG_inpd(port);
635 } else
636#endif
637 val = LOG_inpd(port);
638 return val;
639}
640
641
642
643
644
645
646
647
648
649
650
651void X86API BE_outb(X86EMU_pioAddr port, u8 val)
652{
653#if defined(DEBUG) || !defined(__i386__)
654 if (IS_VGA_PORT(port))
655 VGA_outpb(port, val);
656 else if (IS_TIMER_PORT(port))
657 DB(printf("Can not interept TIMER port now!\n");)
658 else if (IS_SPKR_PORT(port))
659 DB(printf("Can not interept SPEAKER port now!\n");)
660 else if (IS_CMOS_PORT(port))
661 DB(printf("Can not interept CMOS port now!\n");)
662 else if (IS_PCI_PORT(port))
663 PCI_outp(port, val, REG_WRITE_BYTE);
664 else if (port < 0x100) {
665 DB(printf("WARN:Maybe INVALID outb.%04X <- %02X\n", (u16) port, val);)
666 LOG_outpb(port, val);
667 } else
668#endif
669 LOG_outpb(port, val);
670}
671
672
673
674
675
676
677
678
679
680
681
682void X86API BE_outw(X86EMU_pioAddr port, u16 val)
683{
684#if defined(DEBUG) || !defined(__i386__)
685 if (IS_VGA_PORT(port)) {
686 VGA_outpb(port, val);
687 VGA_outpb(port + 1, val >> 8);
688 } else if (IS_PCI_PORT(port))
689 PCI_outp(port, val, REG_WRITE_WORD);
690 else if (port < 0x100) {
691 DB(printf("WARN: MAybe INVALID outw.%04X <- %04X\n", (u16) port,
692 val);)
693 LOG_outpw(port, val);
694 } else
695#endif
696 LOG_outpw(port, val);
697}
698
699
700
701
702
703
704
705
706
707
708
709void X86API BE_outl(X86EMU_pioAddr port, u32 val)
710{
711#if defined(DEBUG) || !defined(__i386__)
712 if (IS_PCI_PORT(port))
713 PCI_outp(port, val, REG_WRITE_DWORD);
714 else if (port < 0x100) {
715 DB(printf("WARN: INVALID outl.%04X <- %08X\n", (u16) port,val);)
716 LOG_outpd(port, val);
717 } else
718#endif
719 LOG_outpd(port, val);
720}
721