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