]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - drivers/bios_emulator/besys.c
tpm: Add Kconfig options for TPMs
[karo-tx-uboot.git] / drivers / bios_emulator / besys.c
1 /****************************************************************************
2 *
3 *                        BIOS emulator and interface
4 *                      to Realmode X86 Emulator Library
5 *
6 *  ========================================================================
7 *
8 *   Copyright (C) 2007 Freescale Semiconductor, Inc.
9 *   Jason Jin<Jason.jin@freescale.com>
10 *
11 *   Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved.
12 *
13 *   This file may be distributed and/or modified under the terms of the
14 *   GNU General Public License version 2.0 as published by the Free
15 *   Software Foundation and appearing in the file LICENSE.GPL included
16 *   in the packaging of this file.
17 *
18 *   Licensees holding a valid Commercial License for this product from
19 *   SciTech Software, Inc. may use this file in accordance with the
20 *   Commercial License Agreement provided with the Software.
21 *
22 *   This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
23 *   THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 *   PURPOSE.
25 *
26 *   See http://www.scitechsoft.com/license/ for information about
27 *   the licensing options available and how to purchase a Commercial
28 *   License Agreement.
29 *
30 *   Contact license@scitechsoft.com if any conditions of this licensing
31 *   are not clear to you, or you have questions about licensing options.
32 *
33 *  ========================================================================
34 *
35 * Language:     ANSI C
36 * Environment:  Any
37 * Developer:    Kendall Bennett
38 *
39 * Description:  This file includes BIOS emulator I/O and memory access
40 *               functions.
41 *
42 *               Jason ported this file to u-boot to run the ATI video card
43 *               BIOS in u-boot. Removed some emulate functions such as the
44 *               timer port access. Made all the VGA port except reading 0x3c3
45 *               be emulated. Seems like reading 0x3c3 should return the high
46 *               16 bit of the io port.
47 *
48 ****************************************************************************/
49
50 #define __io
51 #include <common.h>
52 #include <asm/io.h>
53 #include "biosemui.h"
54
55 /*------------------------- Global Variables ------------------------------*/
56
57 #ifndef CONFIG_X86EMU_RAW_IO
58 static char *BE_biosDate = "08/14/99";
59 static u8 BE_model = 0xFC;
60 static 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 /*----------------------------- Implementation ----------------------------*/
72
73 /****************************************************************************
74 PARAMETERS:
75 addr    - Emulator memory address to convert
76
77 RETURNS:
78 Actual memory address to read or write the data
79
80 REMARKS:
81 This function converts an emulator memory address in a 32-bit range to
82 a real memory address that we wish to access. It handles splitting up the
83 memory address space appropriately to access the emulator BIOS image, video
84 memory and system BIOS etc.
85 ****************************************************************************/
86 static 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                 /* We map the real System BIOS directly on real PC's */
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                 /* Return a faked BIOS date string for non-x86 machines */
107                 debug_io("BE_memaddr - Returning BIOS date\n");
108                 return (u8 *)(BE_biosDate + addr - 0xFFFF5);
109         } else if (addr == 0xFFFFE) {
110                 /* Return system model identifier for non-x86 machines */
111                 debug_io("BE_memaddr - Returning model\n");
112                 return &BE_model;
113         } else if (addr == 0xFFFFF) {
114                 /* Return system submodel identifier for non-x86 machines */
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 PARAMETERS:
129 addr    - Emulator memory address to read
130
131 RETURNS:
132 Byte value read from emulator memory.
133
134 REMARKS:
135 Reads a byte value from the emulator memory. We have three distinct memory
136 regions that are handled differently, which this function handles.
137 ****************************************************************************/
138 u8 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 PARAMETERS:
150 addr    - Emulator memory address to read
151
152 RETURNS:
153 Word value read from emulator memory.
154
155 REMARKS:
156 Reads a word value from the emulator memory. We have three distinct memory
157 regions that are handled differently, which this function handles.
158 ****************************************************************************/
159 u16 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 PARAMETERS:
172 addr    - Emulator memory address to read
173
174 RETURNS:
175 Long value read from emulator memory.
176
177 REMARKS:
178 Reads a 32-bit value from the emulator memory. We have three distinct memory
179 regions that are handled differently, which this function handles.
180 ****************************************************************************/
181 u32 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 PARAMETERS:
194 addr    - Emulator memory address to read
195 val     - Value to store
196
197 REMARKS:
198 Writes a byte value to emulator memory. We have three distinct memory
199 regions that are handled differently, which this function handles.
200 ****************************************************************************/
201 void 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 PARAMETERS:
210 addr    - Emulator memory address to read
211 val     - Value to store
212
213 REMARKS:
214 Writes a word value to emulator memory. We have three distinct memory
215 regions that are handled differently, which this function handles.
216 ****************************************************************************/
217 void 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 PARAMETERS:
228 addr    - Emulator memory address to read
229 val     - Value to store
230
231 REMARKS:
232 Writes a 32-bit value to emulator memory. We have three distinct memory
233 regions that are handled differently, which this function handles.
234 ****************************************************************************/
235 void 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 /* For Non-Intel machines we may need to emulate some I/O port accesses that
246  * the BIOS may try to access, such as the PCI config registers.
247  */
248
249 #define IS_TIMER_PORT(port) (0x40 <= port && port <= 0x43)
250 #define IS_CMOS_PORT(port)  (0x70 <= port && port <= 0x71)
251 /*#define IS_VGA_PORT(port)   (_BE_env.emulateVGA && 0x3C0 <= port && port <= 0x3DA)*/
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 PARAMETERS:
258 port    - Port to read from
259 type    - Type of access to perform
260
261 REMARKS:
262 Performs an emulated read from the Standard VGA I/O ports. If the target
263 hardware does not support mapping the VGA I/O and memory (such as some
264 PowerPC systems), we emulate the VGA so that the BIOS will still be able to
265 set NonVGA display modes such as on ATI hardware.
266 ****************************************************************************/
267 static 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                 /* 3C0 has funky characteristics because it can act as either
275                    a data register or index register depending on the state
276                    of an internal flip flop in the hardware. Hence we have
277                    to emulate that functionality in here. */
278                 if (_BE_env.flipFlop3C0 == 0) {
279                         /* Access 3C0 as index register */
280                         val = _BE_env.emu3C0;
281                 } else {
282                         /* Access 3C0 as data register */
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 PARAMETERS:
335 port    - Port to write to
336 type    - Type of access to perform
337
338 REMARKS:
339 Performs an emulated write to one of the 8253 timer registers. For now
340 we only emulate timer 0 which is the only timer that the BIOS code appears
341 to use.
342 ****************************************************************************/
343 static void VGA_outpb (int port, u8 val)
344 {
345         switch (port) {
346         case 0x3C0:
347                 /* 3C0 has funky characteristics because it can act as either
348                    a data register or index register depending on the state
349                    of an internal flip flop in the hardware. Hence we have
350                    to emulate that functionality in here. */
351                 if (_BE_env.flipFlop3C0 == 0) {
352                         /* Access 3C0 as index register */
353                         _BE_env.emu3C0 = val;
354                 } else {
355                         /* Access 3C0 as data register */
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 PARAMETERS:
406 regOffset   - Offset into register space for non-DWORD accesses
407 value       - Value to write to register for PCI_WRITE_* operations
408 func        - Function to perform (PCIAccessRegFlags)
409
410 RETURNS:
411 Value read from configuration register for PCI_READ_* operations
412
413 REMARKS:
414 Accesses a PCI configuration space register by decoding the value currently
415 stored in the _BE_env.configAddress variable and passing it through to the
416 portable PCI_accessReg function.
417 ****************************************************************************/
418 static 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         /* Decode the configuration register values for the register we wish to
428          * access
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         /* Ignore accesses to all devices other than the one we're POSTing */
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         /* Ignore accesses to all devices other than the one we're POSTing */
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 PARAMETERS:
493 port    - Port to read from
494 type    - Type of access to perform
495
496 REMARKS:
497 Performs an emulated read from one of the PCI configuration space registers.
498 We emulate this using our PCI_accessReg function which will access the PCI
499 configuration space registers in a portable fashion.
500 ****************************************************************************/
501 static 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 PARAMETERS:
526 port    - Port to write to
527 type    - Type of access to perform
528
529 REMARKS:
530 Performs an emulated write to one of the PCI control registers.
531 ****************************************************************************/
532 static 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 PARAMETERS:
560 port    - Port to write to
561
562 RETURNS:
563 Value read from the I/O port
564
565 REMARKS:
566 Performs an emulated 8-bit read from an I/O port. We handle special cases
567 that we need to emulate in here, and fall through to reflecting the write
568 through to the real hardware if we don't need to special case it.
569 ****************************************************************************/
570 u8 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                 /*seems reading port 0x3c3 return the high 16 bit of io port*/
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 PARAMETERS:
606 port    - Port to write to
607
608 RETURNS:
609 Value read from the I/O port
610
611 REMARKS:
612 Performs an emulated 16-bit read from an I/O port. We handle special cases
613 that we need to emulate in here, and fall through to reflecting the write
614 through to the real hardware if we don't need to special case it.
615 ****************************************************************************/
616 u16 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 PARAMETERS:
639 port    - Port to write to
640
641 RETURNS:
642 Value read from the I/O port
643
644 REMARKS:
645 Performs an emulated 32-bit read from an I/O port. We handle special cases
646 that we need to emulate in here, and fall through to reflecting the write
647 through to the real hardware if we don't need to special case it.
648 ****************************************************************************/
649 u32 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 PARAMETERS:
671 port    - Port to write to
672 val     - Value to write to port
673
674 REMARKS:
675 Performs an emulated 8-bit write to an I/O port. We handle special cases
676 that we need to emulate in here, and fall through to reflecting the write
677 through to the real hardware if we don't need to special case it.
678 ****************************************************************************/
679 void 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 PARAMETERS:
706 port    - Port to write to
707 val     - Value to write to port
708
709 REMARKS:
710 Performs an emulated 16-bit write to an I/O port. We handle special cases
711 that we need to emulate in here, and fall through to reflecting the write
712 through to the real hardware if we don't need to special case it.
713 ****************************************************************************/
714 void 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 PARAMETERS:
737 port    - Port to write to
738 val     - Value to write to port
739
740 REMARKS:
741 Performs an emulated 32-bit write to an I/O port. We handle special cases
742 that we need to emulate in here, and fall through to reflecting the write
743 through to the real hardware if we don't need to special case it.
744 ****************************************************************************/
745 void 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 }