blob: 8e29a9eafec6f1e7adf2096140da171bfe2eeec0 [file] [log] [blame]
Jason Jinece92f82007-07-06 08:34:56 +08001/****************************************************************************
2*
3* BIOS emulator and interface
4* to Realmode X86 Emulator Library
5*
6* ========================================================================
7*
Kumar Gala4c2e3da2009-07-28 21:49:52 -05008* Copyright (C) 2007 Freescale Semiconductor, Inc.
Jason Jinece92f82007-07-06 08:34:56 +08009* 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
Linus Walleijb2da8032013-04-01 22:14:14 +000050#define __io
51#include <asm/io.h>
Michal Simek78cff502007-08-16 10:46:28 +020052#include <common.h>
Jason Jinece92f82007-07-06 08:34:56 +080053#include "biosemui.h"
54
55/*------------------------- Global Variables ------------------------------*/
56
Simon Glassad6edca2014-11-14 20:56:39 -070057#ifndef CONFIG_X86EMU_RAW_IO
Jason Jinece92f82007-07-06 08:34:56 +080058static char *BE_biosDate = "08/14/99";
59static u8 BE_model = 0xFC;
60static u8 BE_submodel = 0x00;
61#endif
62
63/*----------------------------- Implementation ----------------------------*/
64
65/****************************************************************************
66PARAMETERS:
67addr - Emulator memory address to convert
68
69RETURNS:
70Actual memory address to read or write the data
71
72REMARKS:
73This function converts an emulator memory address in a 32-bit range to
74a real memory address that we wish to access. It handles splitting up the
75memory address space appropriately to access the emulator BIOS image, video
76memory and system BIOS etc.
77****************************************************************************/
78static u8 *BE_memaddr(u32 addr)
79{
80 if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
81 return (u8*)(_BE_env.biosmem_base + addr - 0xC0000);
82 } else if (addr > _BE_env.biosmem_limit && addr < 0xD0000) {
Simon Glassad6edca2014-11-14 20:56:39 -070083 DB(printf("BE_memaddr: address %#lx may be invalid!\n",
84 (ulong)addr);)
85 return (u8 *)M.mem_base;
Jason Jinece92f82007-07-06 08:34:56 +080086 } else if (addr >= 0xA0000 && addr <= 0xBFFFF) {
87 return (u8*)(_BE_env.busmem_base + addr - 0xA0000);
88 }
Simon Glassad6edca2014-11-14 20:56:39 -070089#ifdef CONFIG_X86EMU_RAW_IO
Jason Jinece92f82007-07-06 08:34:56 +080090 else if (addr >= 0xD0000 && addr <= 0xFFFFF) {
91 /* We map the real System BIOS directly on real PC's */
Simon Glassad6edca2014-11-14 20:56:39 -070092 DB(printf("BE_memaddr: System BIOS address %#lx\n",
93 (ulong)addr);)
94 return (u8 *)_BE_env.busmem_base + addr - 0xA0000;
Jason Jinece92f82007-07-06 08:34:56 +080095 }
96#else
97 else if (addr >= 0xFFFF5 && addr < 0xFFFFE) {
98 /* Return a faked BIOS date string for non-x86 machines */
99 DB(printf("BE_memaddr - Returning BIOS date\n");)
Wolfgang Denk409ecdc2007-11-18 16:36:27 +0100100 return (u8 *)(BE_biosDate + addr - 0xFFFF5);
Jason Jinece92f82007-07-06 08:34:56 +0800101 } else if (addr == 0xFFFFE) {
102 /* Return system model identifier for non-x86 machines */
103 DB(printf("BE_memaddr - Returning model\n");)
104 return &BE_model;
105 } else if (addr == 0xFFFFF) {
106 /* Return system submodel identifier for non-x86 machines */
107 DB(printf("BE_memaddr - Returning submodel\n");)
108 return &BE_submodel;
109 }
110#endif
111 else if (addr > M.mem_size - 1) {
112 HALT_SYS();
Simon Glassad6edca2014-11-14 20:56:39 -0700113 return (u8 *)M.mem_base;
Jason Jinece92f82007-07-06 08:34:56 +0800114 }
115
Simon Glassad6edca2014-11-14 20:56:39 -0700116 return (u8 *)(M.mem_base + addr);
Jason Jinece92f82007-07-06 08:34:56 +0800117}
118
119/****************************************************************************
120PARAMETERS:
121addr - Emulator memory address to read
122
123RETURNS:
124Byte value read from emulator memory.
125
126REMARKS:
127Reads a byte value from the emulator memory. We have three distinct memory
128regions that are handled differently, which this function handles.
129****************************************************************************/
130u8 X86API BE_rdb(u32 addr)
131{
132 if (_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)
133 return 0;
134 else {
135 u8 val = readb_le(BE_memaddr(addr));
136 return val;
137 }
138}
139
140/****************************************************************************
141PARAMETERS:
142addr - Emulator memory address to read
143
144RETURNS:
145Word value read from emulator memory.
146
147REMARKS:
148Reads a word value from the emulator memory. We have three distinct memory
149regions that are handled differently, which this function handles.
150****************************************************************************/
151u16 X86API BE_rdw(u32 addr)
152{
153 if (_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)
154 return 0;
155 else {
156 u8 *base = BE_memaddr(addr);
157 u16 val = readw_le(base);
158 return val;
159 }
160}
161
162/****************************************************************************
163PARAMETERS:
164addr - Emulator memory address to read
165
166RETURNS:
167Long value read from emulator memory.
168
169REMARKS:
170Reads a 32-bit value from the emulator memory. We have three distinct memory
171regions that are handled differently, which this function handles.
172****************************************************************************/
173u32 X86API BE_rdl(u32 addr)
174{
175 if (_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)
176 return 0;
177 else {
178 u8 *base = BE_memaddr(addr);
179 u32 val = readl_le(base);
180 return val;
181 }
182}
183
184/****************************************************************************
185PARAMETERS:
186addr - Emulator memory address to read
187val - Value to store
188
189REMARKS:
190Writes a byte value to emulator memory. We have three distinct memory
191regions that are handled differently, which this function handles.
192****************************************************************************/
193void X86API BE_wrb(u32 addr, u8 val)
194{
195 if (!(_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)) {
196 writeb_le(BE_memaddr(addr), val);
197 }
198}
199
200/****************************************************************************
201PARAMETERS:
202addr - Emulator memory address to read
203val - Value to store
204
205REMARKS:
206Writes a word value to emulator memory. We have three distinct memory
207regions that are handled differently, which this function handles.
208****************************************************************************/
209void X86API BE_wrw(u32 addr, u16 val)
210{
211 if (!(_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)) {
212 u8 *base = BE_memaddr(addr);
213 writew_le(base, val);
214
215 }
216}
217
218/****************************************************************************
219PARAMETERS:
220addr - Emulator memory address to read
221val - Value to store
222
223REMARKS:
224Writes a 32-bit value to emulator memory. We have three distinct memory
225regions that are handled differently, which this function handles.
226****************************************************************************/
227void X86API BE_wrl(u32 addr, u32 val)
228{
229 if (!(_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)) {
230 u8 *base = BE_memaddr(addr);
231 writel_le(base, val);
232 }
233}
234
Simon Glassad6edca2014-11-14 20:56:39 -0700235#if !defined(CONFIG_X86EMU_RAW_IO)
Jason Jinece92f82007-07-06 08:34:56 +0800236
237/* For Non-Intel machines we may need to emulate some I/O port accesses that
238 * the BIOS may try to access, such as the PCI config registers.
239 */
240
241#define IS_TIMER_PORT(port) (0x40 <= port && port <= 0x43)
242#define IS_CMOS_PORT(port) (0x70 <= port && port <= 0x71)
243/*#define IS_VGA_PORT(port) (_BE_env.emulateVGA && 0x3C0 <= port && port <= 0x3DA)*/
244#define IS_VGA_PORT(port) (0x3C0 <= port && port <= 0x3DA)
245#define IS_PCI_PORT(port) (0xCF8 <= port && port <= 0xCFF)
246#define IS_SPKR_PORT(port) (port == 0x61)
247
248/****************************************************************************
249PARAMETERS:
250port - Port to read from
251type - Type of access to perform
252
253REMARKS:
254Performs an emulated read from the Standard VGA I/O ports. If the target
255hardware does not support mapping the VGA I/O and memory (such as some
256PowerPC systems), we emulate the VGA so that the BIOS will still be able to
257set NonVGA display modes such as on ATI hardware.
258****************************************************************************/
Wolfgang Denk9c7e4b02007-08-06 02:17:36 +0200259static u8 VGA_inpb (const int port)
Jason Jinece92f82007-07-06 08:34:56 +0800260{
Wolfgang Denk9c7e4b02007-08-06 02:17:36 +0200261 u8 val = 0xff;
Jason Jinece92f82007-07-06 08:34:56 +0800262
Wolfgang Denk9c7e4b02007-08-06 02:17:36 +0200263 switch (port) {
264 case 0x3C0:
265 /* 3C0 has funky characteristics because it can act as either
266 a data register or index register depending on the state
267 of an internal flip flop in the hardware. Hence we have
268 to emulate that functionality in here. */
269 if (_BE_env.flipFlop3C0 == 0) {
270 /* Access 3C0 as index register */
271 val = _BE_env.emu3C0;
272 } else {
273 /* Access 3C0 as data register */
274 if (_BE_env.emu3C0 < ATT_C)
275 val = _BE_env.emu3C1[_BE_env.emu3C0];
276 }
277 _BE_env.flipFlop3C0 ^= 1;
278 break;
279 case 0x3C1:
280 if (_BE_env.emu3C0 < ATT_C)
281 return _BE_env.emu3C1[_BE_env.emu3C0];
282 break;
283 case 0x3CC:
284 return _BE_env.emu3C2;
285 case 0x3C4:
286 return _BE_env.emu3C4;
287 case 0x3C5:
288 if (_BE_env.emu3C4 < ATT_C)
289 return _BE_env.emu3C5[_BE_env.emu3C4];
290 break;
291 case 0x3C6:
292 return _BE_env.emu3C6;
293 case 0x3C7:
294 return _BE_env.emu3C7;
295 case 0x3C8:
296 return _BE_env.emu3C8;
297 case 0x3C9:
298 if (_BE_env.emu3C7 < PAL_C)
299 return _BE_env.emu3C9[_BE_env.emu3C7++];
300 break;
301 case 0x3CE:
302 return _BE_env.emu3CE;
303 case 0x3CF:
304 if (_BE_env.emu3CE < GRA_C)
305 return _BE_env.emu3CF[_BE_env.emu3CE];
306 break;
307 case 0x3D4:
308 if (_BE_env.emu3C2 & 0x1)
309 return _BE_env.emu3D4;
310 break;
311 case 0x3D5:
312 if ((_BE_env.emu3C2 & 0x1) && (_BE_env.emu3D4 < CRT_C))
313 return _BE_env.emu3D5[_BE_env.emu3D4];
314 break;
315 case 0x3DA:
316 _BE_env.flipFlop3C0 = 0;
317 val = _BE_env.emu3DA;
318 _BE_env.emu3DA ^= 0x9;
319 break;
320 }
321 return val;
Jason Jinece92f82007-07-06 08:34:56 +0800322}
323
324/****************************************************************************
325PARAMETERS:
326port - Port to write to
327type - Type of access to perform
328
329REMARKS:
330Performs an emulated write to one of the 8253 timer registers. For now
331we only emulate timer 0 which is the only timer that the BIOS code appears
332to use.
333****************************************************************************/
Wolfgang Denk9c7e4b02007-08-06 02:17:36 +0200334static void VGA_outpb (int port, u8 val)
Jason Jinece92f82007-07-06 08:34:56 +0800335{
Wolfgang Denk9c7e4b02007-08-06 02:17:36 +0200336 switch (port) {
337 case 0x3C0:
338 /* 3C0 has funky characteristics because it can act as either
339 a data register or index register depending on the state
340 of an internal flip flop in the hardware. Hence we have
341 to emulate that functionality in here. */
342 if (_BE_env.flipFlop3C0 == 0) {
343 /* Access 3C0 as index register */
344 _BE_env.emu3C0 = val;
345 } else {
346 /* Access 3C0 as data register */
347 if (_BE_env.emu3C0 < ATT_C)
348 _BE_env.emu3C1[_BE_env.emu3C0] = val;
349 }
350 _BE_env.flipFlop3C0 ^= 1;
351 break;
352 case 0x3C2:
353 _BE_env.emu3C2 = val;
354 break;
355 case 0x3C4:
356 _BE_env.emu3C4 = val;
357 break;
358 case 0x3C5:
359 if (_BE_env.emu3C4 < ATT_C)
360 _BE_env.emu3C5[_BE_env.emu3C4] = val;
361 break;
362 case 0x3C6:
363 _BE_env.emu3C6 = val;
364 break;
365 case 0x3C7:
366 _BE_env.emu3C7 = (int) val *3;
367
368 break;
369 case 0x3C8:
370 _BE_env.emu3C8 = (int) val *3;
371
372 break;
373 case 0x3C9:
374 if (_BE_env.emu3C8 < PAL_C)
375 _BE_env.emu3C9[_BE_env.emu3C8++] = val;
376 break;
377 case 0x3CE:
378 _BE_env.emu3CE = val;
379 break;
380 case 0x3CF:
381 if (_BE_env.emu3CE < GRA_C)
382 _BE_env.emu3CF[_BE_env.emu3CE] = val;
383 break;
384 case 0x3D4:
385 if (_BE_env.emu3C2 & 0x1)
386 _BE_env.emu3D4 = val;
387 break;
388 case 0x3D5:
389 if ((_BE_env.emu3C2 & 0x1) && (_BE_env.emu3D4 < CRT_C))
390 _BE_env.emu3D5[_BE_env.emu3D4] = val;
391 break;
392 }
Jason Jinece92f82007-07-06 08:34:56 +0800393}
394
395/****************************************************************************
396PARAMETERS:
397regOffset - Offset into register space for non-DWORD accesses
398value - Value to write to register for PCI_WRITE_* operations
399func - Function to perform (PCIAccessRegFlags)
400
401RETURNS:
402Value read from configuration register for PCI_READ_* operations
403
404REMARKS:
405Accesses a PCI configuration space register by decoding the value currently
406stored in the _BE_env.configAddress variable and passing it through to the
407portable PCI_accessReg function.
408****************************************************************************/
409static u32 BE_accessReg(int regOffset, u32 value, int func)
410{
411#ifdef __KERNEL__
412 int function, device, bus;
413 u8 val8;
414 u16 val16;
415 u32 val32;
416
417
418 /* Decode the configuration register values for the register we wish to
419 * access
420 */
421 regOffset += (_BE_env.configAddress & 0xFF);
422 function = (_BE_env.configAddress >> 8) & 0x7;
423 device = (_BE_env.configAddress >> 11) & 0x1F;
424 bus = (_BE_env.configAddress >> 16) & 0xFF;
425
426 /* Ignore accesses to all devices other than the one we're POSTing */
427 if ((function == _BE_env.vgaInfo.function) &&
428 (device == _BE_env.vgaInfo.device) &&
429 (bus == _BE_env.vgaInfo.bus)) {
430 switch (func) {
431 case REG_READ_BYTE:
432 pci_read_config_byte(_BE_env.vgaInfo.pcidev, regOffset,
433 &val8);
434 return val8;
435 case REG_READ_WORD:
436 pci_read_config_word(_BE_env.vgaInfo.pcidev, regOffset,
437 &val16);
438 return val16;
439 case REG_READ_DWORD:
440 pci_read_config_dword(_BE_env.vgaInfo.pcidev, regOffset,
441 &val32);
442 return val32;
443 case REG_WRITE_BYTE:
444 pci_write_config_byte(_BE_env.vgaInfo.pcidev, regOffset,
445 value);
446
447 return 0;
448 case REG_WRITE_WORD:
449 pci_write_config_word(_BE_env.vgaInfo.pcidev, regOffset,
450 value);
451
452 return 0;
453 case REG_WRITE_DWORD:
454 pci_write_config_dword(_BE_env.vgaInfo.pcidev,
455 regOffset, value);
456
457 return 0;
458 }
459 }
460 return 0;
461#else
462 PCIDeviceInfo pciInfo;
463
464 pciInfo.mech1 = 1;
465 pciInfo.slot.i = 0;
466 pciInfo.slot.p.Function = (_BE_env.configAddress >> 8) & 0x7;
467 pciInfo.slot.p.Device = (_BE_env.configAddress >> 11) & 0x1F;
468 pciInfo.slot.p.Bus = (_BE_env.configAddress >> 16) & 0xFF;
469 pciInfo.slot.p.Enable = 1;
470
471 /* Ignore accesses to all devices other than the one we're POSTing */
472 if ((pciInfo.slot.p.Function ==
473 _BE_env.vgaInfo.pciInfo->slot.p.Function)
474 && (pciInfo.slot.p.Device == _BE_env.vgaInfo.pciInfo->slot.p.Device)
475 && (pciInfo.slot.p.Bus == _BE_env.vgaInfo.pciInfo->slot.p.Bus))
476 return PCI_accessReg((_BE_env.configAddress & 0xFF) + regOffset,
477 value, func, &pciInfo);
478 return 0;
479#endif
480}
481
482/****************************************************************************
483PARAMETERS:
484port - Port to read from
485type - Type of access to perform
486
487REMARKS:
488Performs an emulated read from one of the PCI configuration space registers.
489We emulate this using our PCI_accessReg function which will access the PCI
490configuration space registers in a portable fashion.
491****************************************************************************/
492static u32 PCI_inp(int port, int type)
493{
494 switch (type) {
495 case REG_READ_BYTE:
496 if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
497 && port <= 0xCFF)
498 return BE_accessReg(port - 0xCFC, 0, REG_READ_BYTE);
499 break;
500 case REG_READ_WORD:
501 if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
502 && port <= 0xCFF)
503 return BE_accessReg(port - 0xCFC, 0, REG_READ_WORD);
504 break;
505 case REG_READ_DWORD:
506 if (port == 0xCF8)
507 return _BE_env.configAddress;
508 else if ((_BE_env.configAddress & 0x80000000) && port == 0xCFC)
509 return BE_accessReg(0, 0, REG_READ_DWORD);
510 break;
511 }
512 return 0;
513}
514
515/****************************************************************************
516PARAMETERS:
517port - Port to write to
518type - Type of access to perform
519
520REMARKS:
521Performs an emulated write to one of the PCI control registers.
522****************************************************************************/
523static void PCI_outp(int port, u32 val, int type)
524{
525 switch (type) {
526 case REG_WRITE_BYTE:
527 if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
528 && port <= 0xCFF)
529 BE_accessReg(port - 0xCFC, val, REG_WRITE_BYTE);
530 break;
531 case REG_WRITE_WORD:
532 if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
533 && port <= 0xCFF)
534 BE_accessReg(port - 0xCFC, val, REG_WRITE_WORD);
535 break;
536 case REG_WRITE_DWORD:
537 if (port == 0xCF8)
538 {
539 _BE_env.configAddress = val & 0x80FFFFFC;
540 }
541 else if ((_BE_env.configAddress & 0x80000000) && port == 0xCFC)
542 BE_accessReg(0, val, REG_WRITE_DWORD);
543 break;
544 }
545}
546
547#endif
548
549/****************************************************************************
550PARAMETERS:
551port - Port to write to
552
553RETURNS:
554Value read from the I/O port
555
556REMARKS:
557Performs an emulated 8-bit read from an I/O port. We handle special cases
558that we need to emulate in here, and fall through to reflecting the write
559through to the real hardware if we don't need to special case it.
560****************************************************************************/
561u8 X86API BE_inb(X86EMU_pioAddr port)
562{
563 u8 val = 0;
564
Simon Glassad6edca2014-11-14 20:56:39 -0700565#if !defined(CONFIG_X86EMU_RAW_IO)
Jason Jinece92f82007-07-06 08:34:56 +0800566 if (IS_VGA_PORT(port)){
567 /*seems reading port 0x3c3 return the high 16 bit of io port*/
568 if(port == 0x3c3)
569 val = LOG_inpb(port);
570 else
571 val = VGA_inpb(port);
572 }
573 else if (IS_TIMER_PORT(port))
574 DB(printf("Can not interept TIMER port now!\n");)
575 else if (IS_SPKR_PORT(port))
576 DB(printf("Can not interept SPEAKER port now!\n");)
577 else if (IS_CMOS_PORT(port))
578 DB(printf("Can not interept CMOS port now!\n");)
579 else if (IS_PCI_PORT(port))
580 val = PCI_inp(port, REG_READ_BYTE);
581 else if (port < 0x100) {
582 DB(printf("WARN: INVALID inb.%04X -> %02X\n", (u16) port, val);)
583 val = LOG_inpb(port);
584 } else
585#endif
586 val = LOG_inpb(port);
587 return val;
588}
589
590/****************************************************************************
591PARAMETERS:
592port - Port to write to
593
594RETURNS:
595Value read from the I/O port
596
597REMARKS:
598Performs an emulated 16-bit read from an I/O port. We handle special cases
599that we need to emulate in here, and fall through to reflecting the write
600through to the real hardware if we don't need to special case it.
601****************************************************************************/
602u16 X86API BE_inw(X86EMU_pioAddr port)
603{
604 u16 val = 0;
605
Simon Glassad6edca2014-11-14 20:56:39 -0700606#if !defined(CONFIG_X86EMU_RAW_IO)
Jason Jinece92f82007-07-06 08:34:56 +0800607 if (IS_PCI_PORT(port))
608 val = PCI_inp(port, REG_READ_WORD);
609 else if (port < 0x100) {
610 DB(printf("WARN: Maybe INVALID inw.%04X -> %04X\n", (u16) port, val);)
611 val = LOG_inpw(port);
612 } else
613#endif
614 val = LOG_inpw(port);
615 return val;
616}
617
618/****************************************************************************
619PARAMETERS:
620port - Port to write to
621
622RETURNS:
623Value read from the I/O port
624
625REMARKS:
626Performs an emulated 32-bit read from an I/O port. We handle special cases
627that we need to emulate in here, and fall through to reflecting the write
628through to the real hardware if we don't need to special case it.
629****************************************************************************/
630u32 X86API BE_inl(X86EMU_pioAddr port)
631{
632 u32 val = 0;
633
Simon Glassad6edca2014-11-14 20:56:39 -0700634#if !defined(CONFIG_X86EMU_RAW_IO)
Jason Jinece92f82007-07-06 08:34:56 +0800635 if (IS_PCI_PORT(port))
636 val = PCI_inp(port, REG_READ_DWORD);
637 else if (port < 0x100) {
638 val = LOG_inpd(port);
639 } else
640#endif
641 val = LOG_inpd(port);
642 return val;
643}
644
645/****************************************************************************
646PARAMETERS:
647port - Port to write to
648val - Value to write to port
649
650REMARKS:
651Performs an emulated 8-bit write to an I/O port. We handle special cases
652that we need to emulate in here, and fall through to reflecting the write
653through to the real hardware if we don't need to special case it.
654****************************************************************************/
655void X86API BE_outb(X86EMU_pioAddr port, u8 val)
656{
Simon Glassad6edca2014-11-14 20:56:39 -0700657#if !defined(CONFIG_X86EMU_RAW_IO)
Jason Jinece92f82007-07-06 08:34:56 +0800658 if (IS_VGA_PORT(port))
659 VGA_outpb(port, val);
660 else if (IS_TIMER_PORT(port))
661 DB(printf("Can not interept TIMER port now!\n");)
662 else if (IS_SPKR_PORT(port))
663 DB(printf("Can not interept SPEAKER port now!\n");)
664 else if (IS_CMOS_PORT(port))
665 DB(printf("Can not interept CMOS port now!\n");)
666 else if (IS_PCI_PORT(port))
667 PCI_outp(port, val, REG_WRITE_BYTE);
668 else if (port < 0x100) {
669 DB(printf("WARN:Maybe INVALID outb.%04X <- %02X\n", (u16) port, val);)
670 LOG_outpb(port, val);
671 } else
672#endif
673 LOG_outpb(port, val);
674}
675
676/****************************************************************************
677PARAMETERS:
678port - Port to write to
679val - Value to write to port
680
681REMARKS:
682Performs an emulated 16-bit write to an I/O port. We handle special cases
683that we need to emulate in here, and fall through to reflecting the write
684through to the real hardware if we don't need to special case it.
685****************************************************************************/
686void X86API BE_outw(X86EMU_pioAddr port, u16 val)
687{
Simon Glassad6edca2014-11-14 20:56:39 -0700688#if !defined(CONFIG_X86EMU_RAW_IO)
Jason Jinece92f82007-07-06 08:34:56 +0800689 if (IS_VGA_PORT(port)) {
690 VGA_outpb(port, val);
691 VGA_outpb(port + 1, val >> 8);
692 } else if (IS_PCI_PORT(port))
693 PCI_outp(port, val, REG_WRITE_WORD);
694 else if (port < 0x100) {
695 DB(printf("WARN: MAybe INVALID outw.%04X <- %04X\n", (u16) port,
696 val);)
697 LOG_outpw(port, val);
698 } else
699#endif
700 LOG_outpw(port, val);
701}
702
703/****************************************************************************
704PARAMETERS:
705port - Port to write to
706val - Value to write to port
707
708REMARKS:
709Performs an emulated 32-bit write to an I/O port. We handle special cases
710that we need to emulate in here, and fall through to reflecting the write
711through to the real hardware if we don't need to special case it.
712****************************************************************************/
713void X86API BE_outl(X86EMU_pioAddr port, u32 val)
714{
Simon Glassad6edca2014-11-14 20:56:39 -0700715#if !defined(CONFIG_X86EMU_RAW_IO)
Simon Glass4c59f952014-11-14 20:56:40 -0700716 if (IS_PCI_PORT(port)) {
Jason Jinece92f82007-07-06 08:34:56 +0800717 PCI_outp(port, val, REG_WRITE_DWORD);
Simon Glass4c59f952014-11-14 20:56:40 -0700718 } else if (port < 0x100) {
Jason Jinece92f82007-07-06 08:34:56 +0800719 DB(printf("WARN: INVALID outl.%04X <- %08X\n", (u16) port,val);)
720 LOG_outpd(port, val);
721 } else
722#endif
723 LOG_outpd(port, val);
724}