1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * VGA BIOS initialization File: VGAINIT.C
6 * This module interfaces with the X86 emulator borrowed from
7 * XFree86 to do VGA initialization.
9 * WARNING: This code is SB1250-specific for now. It's not
10 * hard to change, but then again, aren't we interested in the 1250?
12 * Author: Mitch Lichtenberg (mpl@broadcom.com)
14 *********************************************************************
16 * Copyright 2000,2001,2002,2003
17 * Broadcom Corporation. All rights reserved.
19 * This software is furnished under license and may be used and
20 * copied only in accordance with the following terms and
21 * conditions. Subject to these conditions, you may download,
22 * copy, install, use, modify and distribute modified or unmodified
23 * copies of this software in source and/or binary form. No title
24 * or ownership is transferred hereby.
26 * 1) Any source code used, modified or distributed must reproduce
27 * and retain this copyright notice and list of conditions
28 * as they appear in the source file.
30 * 2) No right is granted to use any trade name, trademark, or
31 * logo of Broadcom Corporation. The "Broadcom Corporation"
32 * name may not be used to endorse or promote products derived
33 * from this software without the prior written permission of
34 * Broadcom Corporation.
36 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
37 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
38 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
39 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
40 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
41 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
42 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
44 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
45 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
46 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
47 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
48 * THE POSSIBILITY OF SUCH DAMAGE.
49 ********************************************************************* */
52 #include "lib_types.h"
53 #include "lib_string.h"
54 #include "lib_printf.h"
55 #include "lib_malloc.h"
58 #include "cfe_console.h"
61 #include "lib_physio.h"
68 /* *********************************************************************
70 ********************************************************************* */
72 #define BYTESONLY 0 /* Always write registers as bytes */
73 #define VGAINIT_NOISY 0 /* lots of debug output */
75 #define SB1250_PASS2_WORKAROUNDS
77 /* *********************************************************************
78 * ISA port macros - currently SB1250-specific
79 ********************************************************************* */
84 #define OUTB(x,y) outb(x,y)
85 #define OUTW(x,y) outw(x,y)
86 #define OUTL(x,y) outl(x,y)
88 /* *********************************************************************
89 * ISA memory macros - currently SB1250-specific
90 ********************************************************************* */
92 typedef uintptr_t vm_offset_t
;
94 #if defined(_P5064_) || defined(_P6064_)
95 #define PCI_MEM_SPACE 0x10000000 /* 128MB: s/w configurable */
96 #define __ISAaddr(addr) ((physaddr_t)(PCI_MEM_SPACE+(addr)))
98 #define __ISAaddr(addr) ((physaddr_t)0x40000000+(addr))
101 #define __ISAreadbyte(addr) phys_read8(__ISAaddr(addr))
102 #define __ISAreadword(addr) phys_read16(__ISAaddr(addr))
103 #define __ISAreaddword(addr) phys_read32(__ISAaddr(addr))
104 #define __ISAwritebyte(addr,data) phys_write8(__ISAaddr(addr),(data))
105 #define __ISAwriteword(addr,data) phys_write16(__ISAaddr(addr),(data))
106 #define __ISAwritedword(addr,data) phys_write32(__ISAaddr(addr),(data))
108 /* *********************************************************************
110 ********************************************************************* */
112 #define OFFSET(addr) (((addr) >> 0) & 0xffff)
113 #define SEGMENT(addr) (((addr) >> 4) & 0xf000)
115 #define BSWAP_SHORT(s) ((((s) >> 8) & 0xFF) | (((s)&0xFF) << 8))
116 #define BSWAP_LONG(s) ((((s) & 0xFF000000) >> 24) | \
117 (((s) & 0x00FF0000) >> 8) | \
118 (((s) & 0x0000FF00) << 8) | \
119 (((s) & 0x000000FF) << 24))
123 #define CPU_TO_LE16(s) BSWAP_SHORT(s)
124 #define CPU_TO_LE32(s) BSWAP_LONG(s)
125 #define LE16_TO_CPU(s) BSWAP_SHORT(s)
126 #define LE32_TO_CPU(s) BSWAP_LONG(s)
128 #define CPU_TO_LE16(s) (s)
129 #define CPU_TO_LE32(s) (s)
130 #define LE16_TO_CPU(s) (s)
131 #define LE32_TO_CPU(s) (s)
135 /* *********************************************************************
137 ********************************************************************* */
139 int vga_biosinit(void);
141 extern void ui_restart(int);
142 void vgaraw_dump(char *tail
);
143 int x86emutest(void);
145 /* *********************************************************************
147 ********************************************************************* */
149 static vga_term_t vga
;
150 static x86mem_t x86mem
;
152 #define BIOSRAMLOC (0xC0000)
153 #define STACKSIZE 4096
154 #define IRETOFFSET 12
155 static uint8_t x86initcode
[] = {
156 #if (VGA_TEXTMODE_ROWS == 60)
157 0xB8,0x02,0x4F, /* mov ax,042F */
158 0xBB,0x08,0x01, /* mov bx,0108 */ /* VESA 80x60 */
160 0xB8,0x03,0x00, /* mov AX,0003 */ /* 80x25 mode */
163 0xCD,0x10, /* int 10 */
164 0xB8,0x34,0x12, /* mov ax,1234 */
165 0xBB,0x78,0x56, /* mov bx,5678 */
169 static uint8_t x86testcode
[] = {
170 0x90,0x90,0x90,0x90,0x90, /* nop, nop, nop, nop, nop */
171 0xeb,0x09, /* jmp 10 */
172 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, /* 9 nops */
173 0xb8,0x34,0x12, /* mov ax,1234 */
174 0xbb,0x78,0x56, /* mov bx,5678 */
178 static uint32_t __ISAreadmem(x86mem_t
*mem
,uint32_t addr
,int size
)
184 val
= __ISAreadbyte(addr
);
187 if (BYTESONLY
|| (addr
& 0x1)) {
188 val
= (__ISAreadbyte(addr
) | (__ISAreadbyte(addr
+ 1) << 8));
191 val
= __ISAreadword(addr
);
192 val
= LE16_TO_CPU(val
);
196 if (BYTESONLY
|| (addr
& 0x3)) {
197 val
= (__ISAreadbyte(addr
) |
198 (__ISAreadbyte(addr
+ 1) << 8) |
199 (__ISAreadbyte(addr
+ 2) << 16) |
200 (__ISAreadbyte(addr
+ 3) << 24));
203 val
= __ISAreaddword(addr
);
204 val
= LE32_TO_CPU(val
);
216 static void __ISAwritemem(x86mem_t
*mem
,uint32_t addr
,uint32_t data
,int size
)
220 __ISAwritebyte(addr
, data
);
224 if (BYTESONLY
|| (addr
& 0x1)) {
225 __ISAwritebyte(addr
, data
>> 0);
226 __ISAwritebyte(addr
+ 1, data
>> 8);
229 data
= CPU_TO_LE16(data
);
230 __ISAwriteword(addr
, data
);
235 if (BYTESONLY
|| (addr
& 0x3)) {
236 __ISAwritebyte(addr
, data
>> 0);
237 __ISAwritebyte(addr
+ 1, data
>> 8);
238 __ISAwritebyte(addr
+ 2, data
>> 16);
239 __ISAwritebyte(addr
+ 3, data
>> 24);
242 data
= CPU_TO_LE32(data
);
243 __ISAwritedword(addr
, data
);
250 static u8
__x86emu_rdb(u32 addr
)
253 if ((addr
< 0x400) || (addr
> 0x100000)) {
254 xprintf("Read %08X (int %02X) ",addr
,addr
/4);
255 printf("CS:IP = %04X:%04X\n",M
.x86
.R_CS
,M
.x86
.R_IP
);
258 return x86mem_readb(&x86mem
,addr
);
262 static u16
__x86emu_rdw(u32 addr
)
265 if ((addr
< 0x400) || (addr
> 0x100000)) {
266 xprintf("Read %08X (int %02X) ",addr
,addr
/4);
267 printf("CS:IP = %04X:%04X\n",M
.x86
.R_CS
,M
.x86
.R_IP
);
270 return x86mem_readw(&x86mem
,addr
);
274 static u32
__x86emu_rdl(u32 addr
)
277 if ((addr
< 0x400) || (addr
> 0x100000)) {
278 xprintf("Read %08X (int %02X) ",addr
,addr
/4);
279 printf("CS:IP = %04X:%04X\n",M
.x86
.R_CS
,M
.x86
.R_IP
);
282 return x86mem_readl(&x86mem
,addr
);
286 static void __x86emu_wrb(u32 addr
, u8 val
)
289 if ((addr
< 0x400) || (addr
> 0x100000)) {
290 xprintf("Write %08X (int %02X) ",addr
,addr
/4);
291 printf("CS:IP = %04X:%04X\n",M
.x86
.R_CS
,M
.x86
.R_IP
);
294 x86mem_writeb(&x86mem
,addr
,val
);
298 static void __x86emu_wrw(u32 addr
, u16 val
)
301 if ((addr
< 0x400) || (addr
> 0x100000)) {
302 xprintf("Write %08X %04X (int %02X) ",addr
,val
,addr
/4);
303 printf("CS:IP = %04X:%04X\n",M
.x86
.R_CS
,M
.x86
.R_IP
);
306 x86mem_writew(&x86mem
,addr
,val
);
310 static void __x86emu_wrl(u32 addr
, u32 val
)
313 if ((addr
< 0x400) || (addr
> 0x100000)) {
314 xprintf("Write %08X (int %02X) ",addr
,addr
/4);
315 printf("CS:IP = %04X:%04X\n",M
.x86
.R_CS
,M
.x86
.R_IP
);
318 x86mem_writel(&x86mem
,addr
,val
);
325 static uint16_t timerCount
= 0;
326 static int timerState
= TS_COMMAND
;
327 static u8
__x86emu_inb(X86EMU_pioAddr port
)
332 * Emulate just enough functionality of the
333 * timer chip to fool the Trident BIOS
337 switch (timerState
) {
341 timerState
= TS_DATA1
;
342 return timerCount
& 0xFF;
344 timerState
= TS_COMMAND
;
345 return (timerCount
>> 8) & 0xFF;
349 #ifdef SB1250_PASS2_WORKAROUNDS
350 if ((port
< 0x3BC) || (port
> 0x3DF)) {
358 /*if (port < 0x100)*/ xprintf("INB %08X %02X\n",port
,val
);
359 if (console_status()) ui_restart(0);
367 static u16
__x86emu_inw(X86EMU_pioAddr port
)
371 #ifdef SB1250_PASS2_WORKAROUNDS
372 if ((port
< 0x3BC) || (port
> 0x3DF)) {
379 val
= LE16_TO_CPU(val
);
382 /*if (port < 0x100)*/ xprintf("INW %08X %04X\n",port
,val
);
389 static u32
__x86emu_inl(X86EMU_pioAddr port
)
393 #ifdef SB1250_PASS2_WORKAROUNDS
394 if ((port
< 0x3BC) || (port
> 0x3DF)) {
401 val
= LE32_TO_CPU(val
);
404 /*if (port < 0x100)*/ xprintf("INL %08X %08X\n",port
,val
);
412 static void __x86emu_outb(X86EMU_pioAddr port
, u8 val
)
415 * Emulate just enough functionality of the timer
416 * chip to fool the Trident BIOS
420 timerState
= TS_DATA1
;
425 /*if (port < 0x100)*/ xprintf("OUTB %08X %08X\n",port
,val
);
428 #ifdef SB1250_PASS2_WORKAROUNDS
429 if ((port
< 0x3BC) || (port
> 0x3DF)) {
438 static void __x86emu_outw(X86EMU_pioAddr port
, u16 val
)
440 val
= CPU_TO_LE16(val
);
443 /*if (port < 0x100)*/ xprintf("OUTW %08X %04X ",port
,val
);
444 printf("CS:IP = %04X:%04X\n",M
.x86
.R_CS
,M
.x86
.R_IP
);
447 #ifdef SB1250_PASS2_WORKAROUNDS
448 if ((port
< 0x3BC) || (port
> 0x3DF)) {
457 static void __x86emu_outl(X86EMU_pioAddr port
, u32 val
)
459 if (port
== 0x2D) return;
461 val
= CPU_TO_LE32(val
);
464 /*if (port < 0x100)*/ xprintf("OUTL %08X %08X ",port
,val
);
465 printf("CS:IP = %04X:%04X\n",M
.x86
.R_CS
,M
.x86
.R_IP
);
468 #ifdef SB1250_PASS2_WORKAROUNDS
469 if ((port
< 0x3BC) || (port
> 0x3DF)) {
479 static void regs2tag(pcitag_t
*tag
)
482 int bus
,device
,function
;
485 device
= M
.x86
.R_BL
>> 3;
486 function
= M
.x86
.R_BL
& 0x07;
488 mytag
= pci_make_tag(0,bus
,device
,function
);
493 static void __SIMint10(int intno
)
496 xprintf("Int10: BIOS function AX=%04X\n",M
.x86
.R_AX
);
500 * The only BIOS function that VGAs appear to
501 * depend on in the real BIOS is the one
502 * that enables/disables video memory.
505 if ((M
.x86
.R_AH
== 0x12) && (M
.x86
.R_BL
== 0x32)) {
506 if (M
.x86
.R_AL
== 0) {
507 /* enable video memory */
508 __x86emu_outb(VGA_MISCOUTPUT_W
, __x86emu_inb(VGA_MISCOUTPUT_R
) | 0x02);
511 else if (M
.x86
.R_AL
== 1) {
512 /* disable video memory */
513 __x86emu_outb(VGA_MISCOUTPUT_W
, __x86emu_inb(VGA_MISCOUTPUT_R
) & ~0x02);
517 xprintf("Int10 unknown function AX=%04X\n",
523 /* Otherwise, pass the int10 on to the ROM */
525 X86EMU_prepareForInt(0x10);
530 static void __SIMint3(int intno
)
533 xprintf("Int3: Breakpoint reached.\n");
539 static void __SIMintunk(int intno
)
542 xprintf("Int%02X: Unhandled interrupt!\n",intno
);
547 static void __SIMint42(int intno
)
550 xprintf("Int42: Function AX=%04X\n",M
.x86
.R_AX
);
552 switch (M
.x86
.R_AH
) {
558 xprintf("Int42: Unknown INT42 command: %x\n",M
.x86
.R_AH
);
565 static void __SIMint6D(int intno
)
570 xprintf("Int6D: Function AX=%04X\n",M
.x86
.R_AX
);
573 switch (M
.x86
.R_AH
) {
577 if (M
.x86
.R_AL
== 1) {
582 addr
= (M
.x86
.R_ES
<< 4) + M
.x86
.R_BP
;
586 ch
= __x86emu_rdb(addr
);
587 vga_writechar(&vga
,ch
,M
.x86
.R_BL
);
596 xprintf("Unknown INT6D command: %x\n",M
.x86
.R_AH
);
601 if (reflect
) X86EMU_prepareForInt(0x6D);
606 static void __SIMint1A(int intno
)
609 int bus
,device
,function
;
612 if (M
.x86
.R_AH
!= PCIBIOS_FN_MAJOR
) return;
614 switch (M
.x86
.R_AL
) {
615 case PCIBIOS_FN_INSTCHK
:
618 M
.x86
.R_EDX
= PCIBIOS_SIGNATURE
;
619 M
.x86
.R_EBX
= PCIBIOS_VERSION
;
620 M
.x86
.R_ECX
&= 0xFF00;
621 M
.x86
.R_CL
= 0; /* Highest bus number */
623 xprintf("Int1A: Installation check\n");
628 case PCIBIOS_FN_FINDDEV
:
629 ret
= pci_find_device(M
.x86
.R_DX
,M
.x86
.R_CX
,M
.x86
.R_SI
,&tag
);
631 xprintf("Int1A: Find device VID=%04X,DID=%04X,Idx=%d: ",
632 M
.x86
.R_DX
,M
.x86
.R_CX
,M
.x86
.R_SI
);
634 pci_break_tag(tag
,NULL
,&bus
,&device
,&function
);
635 xprintf("Found Bus%d, Dev%d, Func%d\n",bus
,device
,function
);
638 xprintf("not found.\n");
642 pci_break_tag(tag
,NULL
,&bus
,&device
,&function
);
644 M
.x86
.R_BL
= (device
<< 3) | function
;
645 M
.x86
.R_AH
= PCIBIOS_SUCCESSFUL
;
648 M
.x86
.R_AH
= PCIBIOS_DEVICE_NOT_FOUND
;
651 CONDITIONAL_SET_FLAG((M
.x86
.R_AH
!= PCIBIOS_SUCCESSFUL
),F_CF
);
654 case PCIBIOS_FN_FINDCLASS
:
655 ret
= pci_find_class(M
.x86
.R_ECX
,M
.x86
.R_SI
,&tag
);
657 xprintf("Int1A: Find Class %08X,Idx=%d: ",
658 M
.x86
.R_ECX
,M
.x86
.R_SI
);
660 pci_break_tag(tag
,NULL
,&bus
,&device
,&function
);
661 xprintf("Found Bus%d, Dev%d, Func%d\n",bus
,device
,function
);
664 xprintf("not found.\n");
669 pci_break_tag(tag
,NULL
,&bus
,&device
,&function
);
671 M
.x86
.R_BL
= (device
<< 3) | function
;
672 M
.x86
.R_AH
= PCIBIOS_SUCCESSFUL
;
675 M
.x86
.R_AH
=PCIBIOS_DEVICE_NOT_FOUND
;
678 CONDITIONAL_SET_FLAG((M
.x86
.R_AH
!= PCIBIOS_SUCCESSFUL
),F_CF
);
681 case PCIBIOS_FN_RDCFGBYTE
:
683 M
.x86
.R_CL
= pci_conf_read8(tag
,M
.x86
.R_DI
);
684 M
.x86
.R_AH
= PCIBIOS_SUCCESSFUL
;
686 xprintf("Int1A: Read Cfg Byte %04X from ",M
.x86
.R_DI
);
687 pci_break_tag(tag
,NULL
,&bus
,&device
,&function
);
688 xprintf("Bus%d, Dev%d, Func%d",bus
,device
,function
);
689 xprintf(": %02X\n",M
.x86
.R_CX
);
695 case PCIBIOS_FN_RDCFGWORD
:
697 M
.x86
.R_CX
= pci_conf_read16(tag
,M
.x86
.R_DI
);
698 M
.x86
.R_AH
= PCIBIOS_SUCCESSFUL
;
700 xprintf("Int1A: Read Cfg Word %04X from ",M
.x86
.R_DI
);
701 pci_break_tag(tag
,NULL
,&bus
,&device
,&function
);
702 xprintf("Bus%d, Dev%d, Func%d",bus
,device
,function
);
703 xprintf(": %04X\n",M
.x86
.R_CX
);
708 case PCIBIOS_FN_RDCFGDWORD
:
710 M
.x86
.R_ECX
= pci_conf_read(tag
,M
.x86
.R_DI
);
712 xprintf("Int1A: Read Cfg Dword %04X from ",M
.x86
.R_DI
);
713 pci_break_tag(tag
,NULL
,&bus
,&device
,&function
);
714 xprintf("Bus%d, Dev%d, Func%d",bus
,device
,function
);
715 xprintf(": %08X\n",M
.x86
.R_ECX
);
717 M
.x86
.R_AH
= PCIBIOS_SUCCESSFUL
;
721 case PCIBIOS_FN_WRCFGBYTE
:
723 pci_conf_write8(tag
,M
.x86
.R_DI
,M
.x86
.R_CL
);
725 xprintf("Int1A: Write Cfg byte %04X to ",M
.x86
.R_DI
);
726 pci_break_tag(tag
,NULL
,&bus
,&device
,&function
);
727 xprintf("Bus%d, Dev%d, Func%d",bus
,device
,function
);
728 xprintf(": %02X\n",M
.x86
.R_CL
);
731 M
.x86
.R_AH
= PCIBIOS_SUCCESSFUL
;
735 case PCIBIOS_FN_WRCFGWORD
:
737 pci_conf_write16(tag
,M
.x86
.R_DI
,M
.x86
.R_CX
);
739 xprintf("Int1A: Write Cfg Word %04X to ",M
.x86
.R_DI
);
740 pci_break_tag(tag
,NULL
,&bus
,&device
,&function
);
741 xprintf("Bus%d, Dev%d, Func%d",bus
,device
,function
);
742 xprintf(": %04X\n",M
.x86
.R_CX
);
744 M
.x86
.R_AH
= PCIBIOS_SUCCESSFUL
;
748 case PCIBIOS_FN_WRCFGDWORD
:
750 pci_conf_write(tag
,M
.x86
.R_DI
,M
.x86
.R_ECX
);
752 xprintf("Int1A: Write Cfg Dword %04X to ",M
.x86
.R_DI
);
753 pci_break_tag(tag
,NULL
,&bus
,&device
,&function
);
754 xprintf("Bus%d, Dev%d, Func%d",bus
,device
,function
);
755 xprintf(": %08X\n",M
.x86
.R_ECX
);
757 M
.x86
.R_AH
= PCIBIOS_SUCCESSFUL
;
763 xprintf("Int1A: Unimplemented PCI BIOS function AX=%04x\n", M
.x86
.R_AX
);
771 static int x86init(void)
774 * Access functions for I/O ports
776 static X86EMU_pioFuncs piofuncs
= {
786 * Access functions for memory
788 static X86EMU_memFuncs memfuncs
= {
800 void (*funcs
[256])(int num
);
804 * Establish hooks in the simulator
806 X86EMU_setupMemFuncs(&memfuncs
);
807 X86EMU_setupPioFuncs(&piofuncs
);
810 * Decode what X86 software interrupts we need to hook
813 for (idx
= 0; idx
< 256; idx
++) {
814 funcs
[idx
] = __SIMintunk
; /* assume all are bad */
816 funcs
[0x42] = __SIMint42
; /* int42: video BIOS */
817 funcs
[0x1F] = NULL
; /* reflect INT1F */
818 funcs
[0x43] = NULL
; /* reflect INT43 */
819 funcs
[0x6D] = __SIMint6D
; /* int6D: video BIOS */
821 funcs
[0x03] = __SIMint3
; /* int3: firmware exit */
822 funcs
[0x10] = __SIMint10
; /* int10: video BIOS */
823 funcs
[0x1A] = __SIMint1A
; /* int1A: PCI BIOS */
825 X86EMU_setupIntrFuncs(funcs
);
827 x86mem_init(&x86mem
);
828 x86mem_hook(&x86mem
,0xA0000,__ISAreadmem
,__ISAwritemem
);
829 x86mem_hook(&x86mem
,0xA8000,__ISAreadmem
,__ISAwritemem
);
830 x86mem_hook(&x86mem
,0xB0000,__ISAreadmem
,__ISAwritemem
);
831 x86mem_hook(&x86mem
,0xB8000,__ISAreadmem
,__ISAwritemem
);
838 static void x86uninit(void)
840 x86mem_uninit(&x86mem
);
848 if (pci_find_class(PCI_CLASS_DISPLAY
,0,&tag
) == 0) {
855 int vga_biosinit(void)
864 unsigned int biossize
;
865 int bus
,device
,function
;
869 if (pci_find_class(PCI_CLASS_DISPLAY
,0,&tag
) == 0) {
870 romaddr
= pci_conf_read(tag
,PCI_MAPREG_ROM
);
871 pci_conf_write(tag
,PCI_MAPREG_ROM
,romaddr
| PCI_MAPREG_ROM_ENABLE
);
874 xprintf("No suitable VGA device found in the system.\n");
879 addr
&= PCI_MAPREG_ROM_ADDR_MASK
;
880 #if defined(_P5064_) || defined(_P6064_)
881 biosaddr
= cpu_isamap((vm_offset_t
) romaddr
,0);
883 biosaddr
= (physaddr_t
) romaddr
;
887 * Check for the presence of a VGA BIOS on this adapter.
890 if (!((phys_read8(biosaddr
+PCIBIOS_ROMSIG_OFFSET
+0) == PCIBIOS_ROMSIG1
) &&
891 (phys_read8(biosaddr
+PCIBIOS_ROMSIG_OFFSET
+1) == PCIBIOS_ROMSIG2
))) {
892 xprintf("No VGA BIOS on this adapter.\n");
893 pci_conf_write(tag
,PCI_MAPREG_ROM
,romaddr
);
896 biossize
= PCIBIOS_ROMSIZE(phys_read8(biosaddr
+PCIBIOS_ROMSIZE_OFFSET
));
899 xprintf("VGA BIOS size is %d bytes\n",biossize
);
903 * Initialize the X86 emulator
906 if (x86init() != 0) {
907 xprintf("X86 emulator did not initialize.\n");
908 pci_conf_write(tag
,PCI_MAPREG_ROM
,romaddr
);
914 destaddr
= BIOSRAMLOC
;
915 stackaddr
= destaddr
+ biossize
+ STACKSIZE
;
918 * Copy the BIOS from the PCI rom into RAM
922 xprintf("Copying VGA BIOS to RAM.\n");
925 for (idx
= 0; idx
< biossize
; idx
+=4) {
928 b
= phys_read32(biosaddr
+idx
);
929 x86mem_memcpy(&x86mem
,destaddr
+idx
,(uint8_t *) &b
,sizeof(uint32_t));
933 * Gross! The NVidia TNT2 BIOS expects to
934 * find a PC ROM BIOS date (just the slashes)
935 * at the right place in the ROMs.
938 x86mem_memcpy(&x86mem
,0xFFFF5,"08/13/99",8);
941 * Turn off the BIOS ROM, we have our copy now.
944 pci_conf_write(tag
,PCI_MAPREG_ROM
,romaddr
);
947 * Point certain vectors at a dummy IRET in our code space.
948 * Some ROMs don't take too kindly to null vectors, like
949 * the 3dfx Voodoo3 BIOS, which makes sure int1a is
950 * filled in before it attempts to call it. The
951 * code here is never really executed, since the emulator
955 iretaddr
= stackaddr
+ IRETOFFSET
;
956 __x86emu_wrw(0x1A*4+0,OFFSET(iretaddr
));
957 __x86emu_wrw(0x1A*4+2,SEGMENT(iretaddr
));
961 * The actual code begins 3 bytes after the beginning of the ROM. Set
962 * the start address to the first byte of executable code.
965 M
.x86
.R_CS
= SEGMENT(destaddr
+ PCIBIOS_ROMENTRY_OFFSET
);
966 M
.x86
.R_IP
= OFFSET(destaddr
+ PCIBIOS_ROMENTRY_OFFSET
);
969 * Set the stack to point after our copy of the ROM
972 M
.x86
.R_SS
= SEGMENT(stackaddr
- 8);
973 M
.x86
.R_SP
= OFFSET(stackaddr
- 8);
976 * GROSS! The Voodoo3 card expects BP to have
977 * the following value:
983 * The PCI BIOS spec says you pass the bus, device, and function
984 * numbers in the AX register when starting the ROM code.
987 pci_break_tag(tag
,NULL
,&bus
,&device
,&function
);
989 M
.x86
.R_AL
= (device
<< 3) | (function
& 7);
992 * Arrange for the return address to point to a little piece
993 * of code that will do an int10 to set text mode, followed
994 * by storing a couple of simple signatures in the registers,
995 * and an int3 to stop the simulator.
997 * The location of this piece of code is just after our
998 * stack, and since the stack grows down, this is in 'stackaddr'
1001 __x86emu_wrw(stackaddr
-8,OFFSET(stackaddr
));
1002 __x86emu_wrw(stackaddr
-6,SEGMENT(stackaddr
));
1004 /* copy in the code. */
1006 for (idx
= 0; idx
< sizeof(x86initcode
); idx
++) {
1007 __x86emu_wrb(stackaddr
+idx
,x86initcode
[idx
]);
1011 * Set up the VGA console descriptor. We need this to process the
1012 * int10's that write firmware copyright notices and such.
1015 vga_init(&vga
,(__ISAaddr(VGA_TEXTBUF_COLOR
)),outb
);
1018 * Launch the simulator.
1021 xprintf("Initializing VGA.\n");
1028 * Check for the magic exit values in the registers. These get set
1029 * by the code in the array 'x86initcode' that was loaded above
1032 if ((M
.x86
.R_AX
== 0x1234) && (M
.x86
.R_BX
== 0x5678)) res
= 0;
1042 xprintf("VGA initialization failed.\n");
1046 char *str
= "If you can see this message, the VGA has been successfully initialized!\r\n\r\n";
1048 xprintf("VGA initialization successful.\n");
1049 vga_writestr(&vga
,str
,0x07,strlen(str
));
1051 sprintf(temp
,"%d",VGA_TEXTMODE_ROWS
);
1052 env_setenv("VGA_ROWS",temp
,ENV_FLG_BUILTIN
| ENV_FLG_READONLY
| ENV_FLG_ADMIN
);
1053 sprintf(temp
,"%d",VGA_TEXTMODE_COLS
);
1054 env_setenv("VGA_COLS",temp
,ENV_FLG_BUILTIN
| ENV_FLG_READONLY
| ENV_FLG_ADMIN
);
1061 int x86emutest(void)
1068 * Initialize the X86 emulator
1071 if (x86init() != 0) {
1072 xprintf("X86 emulator did not initialize.\n");
1076 destaddr
= BIOSRAMLOC
;
1077 stackaddr
= destaddr
+ 1024;
1080 * Copy the BIOS from the PCI rom into RAM
1083 xprintf("Copying test program to RAM.\n");
1084 x86mem_memcpy(&x86mem
,destaddr
,x86testcode
,sizeof(x86testcode
));
1087 * The actual code begins 3 bytes after the beginning of the ROM. Set
1088 * the start address to the first byte of executable code.
1091 M
.x86
.R_CS
= SEGMENT(destaddr
+ PCIBIOS_ROMENTRY_OFFSET
);
1092 M
.x86
.R_IP
= OFFSET(destaddr
+ PCIBIOS_ROMENTRY_OFFSET
);
1095 * Set the stack to point after our copy of the ROM
1098 M
.x86
.R_SS
= SEGMENT(stackaddr
- 8);
1099 M
.x86
.R_SP
= OFFSET(stackaddr
- 8);
1102 * Launch the simulator.
1105 xprintf("Running X86emu test.\n");
1112 * Check for the magic exit values in the registers. These get set
1113 * by the code in the array 'x86initcode' that was loaded above
1116 if ((M
.x86
.R_AX
== 0x1234) && (M
.x86
.R_BX
== 0x5678)) res
= 0;
1125 if (res
< 0) xprintf("X86emu test failed.\n");
1126 else xprintf("X86emu test successful.\n");
1133 void vgaraw_dump(char *tail
)
1135 physaddr_t biosaddr
;
1139 unsigned int biossize
;
1143 if (pci_find_class(PCI_CLASS_DISPLAY
,0,&tag
) == 0) {
1144 romaddr
= pci_conf_read(tag
,PCI_MAPREG_ROM
);
1145 pci_conf_write(tag
,PCI_MAPREG_ROM
,romaddr
| PCI_MAPREG_ROM_ENABLE
);
1148 xprintf("No suitable VGA device found in the system.\n");
1153 addr
&= PCI_MAPREG_ROM_ADDR_MASK
;
1155 #if defined(_P5064_) || defined(_P6064_)
1156 biosaddr
= cpu_isamap((vm_offset_t
) romaddr
,0);
1162 * Check for the presence of a VGA BIOS on this adapter.
1165 xprintf("VGA BIOS is mapped to %08X\n",(uint32_t) biosaddr
);
1167 if (!((phys_read8(biosaddr
+PCIBIOS_ROMSIG_OFFSET
+0) == PCIBIOS_ROMSIG1
) &&
1168 (phys_read8(biosaddr
+PCIBIOS_ROMSIG_OFFSET
+1) == PCIBIOS_ROMSIG2
))) {
1169 xprintf("No VGA BIOS on this adapter, assuming 32K ROM\n");
1174 biossize
= PCIBIOS_ROMSIZE(phys_read8(biosaddr
+PCIBIOS_ROMSIZE_OFFSET
));
1175 xprintf("VGA BIOS size is %d bytes\n",biossize
);
1178 for (idx
= 0; idx
< biossize
; idx
+=16) {
1179 xprintf("%04X: ",idx
);
1180 for (res
= 0; res
< 16; res
++) {
1181 xprintf("%02X ",phys_read8(biosaddr
+idx
+res
));
1184 if (console_status()) break;
1187 // pci_conf_write(tag,PCI_MAPREG_ROM,romaddr);