From 02fa3b2743b3f37381b6af4ee4362422b9011c8b Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Wed, 6 Oct 2004 17:33:54 +0000 Subject: epia-m support git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1655 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/pc80/Config.lb | 2 +- src/pc80/keyboard.c | 2 +- src/pc80/vgabios.c | 258 +++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 207 insertions(+), 55 deletions(-) (limited to 'src/pc80') diff --git a/src/pc80/Config.lb b/src/pc80/Config.lb index 1261abf3f8..fb00418249 100644 --- a/src/pc80/Config.lb +++ b/src/pc80/Config.lb @@ -3,7 +3,7 @@ uses CONFIG_LEGACY_VGABIOS object mc146818rtc.o object isa-dma.o -#object i8259.o CONFIG_I8259 +object i8259.o #object udelay_timer2.o CONFIG_UDELAY_TIMER2 #object beep.o CONFIG_BEEP #object vga_load_regs.o VIDEO_CONSOLE diff --git a/src/pc80/keyboard.c b/src/pc80/keyboard.c index d293f714de..331f5ab345 100644 --- a/src/pc80/keyboard.c +++ b/src/pc80/keyboard.c @@ -5,7 +5,7 @@ /* much better keyboard init courtesy ollie@sis.com.tw TODO: Typematic Setting, the keyboard is too slow for me */ -static void pc_keyboard_init(struct pc_keyboard *keyboard) +void pc_keyboard_init(struct pc_keyboard *keyboard) { volatile unsigned char regval; diff --git a/src/pc80/vgabios.c b/src/pc80/vgabios.c index c83498e985..a6806d3947 100644 --- a/src/pc80/vgabios.c +++ b/src/pc80/vgabios.c @@ -1,8 +1,10 @@ -#include -#include +#include +#include +#include +#include #undef __KERNEL__ #include -#include +//#include #include #include "vgachip.h" @@ -121,6 +123,8 @@ static void real_mode_switch_call_vga(unsigned long devfn) " mov %ax, %es \n" " mov %ax, %fs \n" " mov %ax, %gs \n" + " mov $0x40, %ax \n" + " mov %ax, %ds \n" " mov %cx, %ax \n" " .byte 0x9a, 0x03, 0, 0, 0xc0 \n" " movb $0x55, %al\noutb %al, $0x80\n" @@ -151,10 +155,99 @@ static void real_mode_switch_call_vga(unsigned long devfn) __asm__ (".text\n""real_mode_switch_end:\n"); extern char real_mode_switch_end[]; +/* call vga bios int 10 function 0x4f14 to enable main console + epia-m does not always autosence the main console so forcing it on is good !! */ + +void vga_enable_console() +{ + __asm__ __volatile__ ( + // paranoia -- does ecx get saved? not sure. This is + // the easiest safe thing to do. + " pushal\n" + /* save the stack */ + " mov %esp, __stack\n" + + /* This configures CS properly for real mode. */ + " ljmp $0x28, $__vga_ec_16bit\n" + "__vga_ec_16bit: \n" + ".code16 \n" + /* 16 bit code from here on... */ + + /* Load the segment registers w/ properly configured segment + * descriptors. They will retain these configurations (limits, + * writability, etc.) once protected mode is turned off. */ + " mov $0x30, %ax \n" + " mov %ax, %ds \n" + " mov %ax, %es \n" + " mov %ax, %fs \n" + " mov %ax, %gs \n" + " mov %ax, %ss \n" + + /* Turn off protection (bit 0 in CR0) */ + " movl %cr0, %eax \n" + " andl $0xFFFFFFFE, %eax \n" + " movl %eax, %cr0 \n" + + /* Now really going into real mode */ + " ljmp $0, $__vga_ec_real \n" + "__vga_ec_real: \n" + + // put the stack at the end of page zero. + // that way we can easily share it between real and protected, + // since the 16-bit ESP at segment 0 will work for any case. + /* Setup a stack */ + " mov $0x0, %ax \n" + " mov %ax, %ss \n" + " movl $0x1000, %eax \n" + " movl %eax, %esp \n" + /* debugging for RGM */ + " mov $0x11, %al \n" + " outb %al, $0x80\n" + + /* Dump zeros in the other segregs */ + " xor %ax, %ax \n" + " mov %ax, %ds \n" + " mov %ax, %es \n" + " mov %ax, %fs \n" + " mov %ax, %gs \n" + /* ask bios to enable main console */ + /* set up for int 10 call - values found from X server bios call routines */ + " movw $0x4f14,%ax \n" + " movw $0x8003,%bx \n" + " movw $1, %cx \n" + " movw $0, %dx \n" + " movw $0, %di \n" + " .byte 0xcd, 0x10 \n" + " movb $0x55, %al\noutb %al, $0x80\n" + /* if we got here, just about done. + * Need to get back to protected mode */ + "movl %cr0, %eax\n" + // "andl $0x7FFAFFD1, %eax\n" /* PG,AM,WP,NE,TS,EM,MP = 0 */ + // "orl $0x60000001, %eax\n" /* CD, NW, PE = 1 */ + "orl $0x0000001, %eax\n" /* PE = 1 */ + "movl %eax, %cr0\n" + /* Now that we are in protected mode jump to a 32 bit code segment. */ + "data32 ljmp $0x10, $vga_ec_restart\n" + "vga_ec_restart:\n" + ".code32\n" + " movw $0x18, %ax \n" + " mov %ax, %ds \n" + " mov %ax, %es \n" + " mov %ax, %fs \n" + " mov %ax, %gs \n" + " mov %ax, %ss \n" + ".globl vga__ec_exit\n" + "vga_ec_exit:\n" + " mov __stack, %esp\n" + " popal\n" + ); +} + + void do_vgabios(void) { - struct pci_dev *dev; + device_t dev; unsigned long busdevfn; unsigned int rom = 0; unsigned char *buf; @@ -162,17 +255,17 @@ do_vgabios(void) int i; for (i=0x400; i<0x500; i++) { - printk_debug("%02x%c", *(unsigned char *)i, - i%16==15 ? '\n' : ' '); + //printk_debug("%02x%c", *(unsigned char *)i, + // i%16==15 ? '\n' : ' '); *(unsigned char *) i = 0; } - for (i=0x400; i<0x500; i++) { +/* for (i=0x400; i<0x500; i++) { printk_debug("%02x%c", *(unsigned char *)i, i%16==15 ? '\n' : ' '); } - - dev = pci_find_class(PCI_CLASS_DISPLAY_VGA <<8, NULL); +*/ + dev = dev_find_class(PCI_CLASS_DISPLAY_VGA<<8 , 0); if (! dev) { printk_debug("NO VGA FOUND\n"); @@ -184,7 +277,7 @@ do_vgabios(void) // Use VGA BIOS blob at specified address rom = VGABIOS_START; #else - pci_read_config32(dev, PCI_ROM_ADDRESS, &rom); + rom = pci_read_config32(dev, PCI_ROM_ADDRESS); // paranoia rom = 0xf0000000; pci_write_config32(dev, PCI_ROM_ADDRESS, rom|1); @@ -193,12 +286,28 @@ do_vgabios(void) buf = (unsigned char *) rom; if ((buf[0] == 0x55) && (buf[1] == 0xaa)) { memcpy((void *) 0xc0000, buf, size); + +#define VGABIOS_WRITE_PROTECT 1 +#ifdef VGABIOS_WRITE_PROTECT + write_protect_vgabios(); +#endif + + for(i = 0; i < 16; i++) + printk_debug("0x%x ", buf[i]); + // check signature again + buf = (unsigned char *) 0xc0000; + if (buf[0]==0x55 && buf[1]==0xAA) { + busdevfn = (dev->bus->secondary << 8) | dev->path.u.pci.devfn; + printk_debug("bus/devfn = %#x\n", busdevfn); + + real_mode_switch_call_vga(busdevfn); + //for( i = 0 ; i < 0x500; i++){ + // printk_debug("%02x%c",*(unsigned char *)i, + // i%16 == 15 ? '\n':' '); + //} + } else + printk_debug("Failed to copy VGA BIOS to 0xc0000\n"); - for(i = 0; i < 16; i++) - printk_debug("0x%x ", buf[i]); - // check signature here later! - busdevfn = (dev->bus->secondary << 8) | dev->devfn; - real_mode_switch_call_vga(busdevfn); } else printk_debug("BAD SIGNATURE 0x%x 0x%x\n", buf[0], buf[1]); #ifndef VGABIOS_START @@ -253,6 +362,10 @@ void callbiosint(void) { __asm__ __volatile__ ( ".code16\n" "callbiosint16:\n" + " push %ds \n" + " push %es \n" + " push %fs \n" + " push %gs \n" // clean up the int #. To save space we put it in the lower // byte. But the top 24 bits are junk. "andl $0xff, %eax\n" @@ -277,8 +390,8 @@ void callbiosint(void) { " mov %ax, %ss \n" " call biosint \n" // back to real mode ... - " ljmp $0x28, $__rms_16bit\n" - "__rms_16bit: \n" + " ljmp $0x28, $__rms_16bit2\n" + "__rms_16bit2: \n" ".code16 \n" /* 16 bit code from here on... */ /* Load the segment registers w/ properly configured segment @@ -297,8 +410,8 @@ void callbiosint(void) { " movl %eax, %cr0 \n" /* Now really going into real mode */ - " ljmp $0, $__rms_real \n" - "__rms_real: \n" + " ljmp $0, $__rms_real2 \n" + "__rms_real2: \n" /* Setup a stack */ " mov $0x0, %ax \n" @@ -311,10 +424,16 @@ void callbiosint(void) { " mov %ax, %es \n" " mov %ax, %fs \n" " mov %ax, %gs \n" + " mov $0x40, %ax \n" + " mov %ax, %ds \n" // pop the INT # that you pushed earlier " popl %eax\n" - " popal\n" - " iret\n" + " pop %gs \n" + " pop %fs \n" + " pop %es \n" + " pop %ds \n" + " popal\n" + " iret\n" ".code32\n" ); } @@ -336,12 +455,26 @@ pcibios( unsigned long *peax, unsigned long *pflags ); +int +handleint21( + unsigned long *pedi, + unsigned long *pesi, + unsigned long *pebp, + unsigned long *pesp, + unsigned long *pebx, + unsigned long *pedx, + unsigned long *pecx, + unsigned long *peax, + unsigned long *pflags + ); extern void vga_exit(void); int biosint( unsigned long intnumber, + unsigned long gsfs, + unsigned long dses, unsigned long edi, unsigned long esi, unsigned long ebp, @@ -393,8 +526,12 @@ biosint( eax = 64 * 1024; ret = 0; break; + case 0x15: + ret=handleint21( &edi, &esi, &ebp, &esp, + &ebx, &edx, &ecx, &eax, &flags); + break; default: - printk_info(__FUNCTION__ ": Unsupport int #0x%x\n", + printk_info("BIOSINT: Unsupport int #0x%x\n", intnumber); break; } @@ -491,7 +628,7 @@ pcibios( unsigned short devid, vendorid, devfn; short devindex; /* Use short to get rid of gabage in upper half of 32-bit register */ unsigned char bus; - struct pci_dev *dev; + device_t dev; switch(func) { case CHECK: @@ -505,7 +642,7 @@ pcibios( vendorid = *pedx; devindex = *pesi; dev = 0; - while ((dev = pci_find_device(vendorid, devid, dev))) { + while ((dev = dev_find_device(vendorid, devid, dev))) { if (devindex <= 0) break; devindex--; @@ -516,7 +653,7 @@ pcibios( // busnum is an unsigned char; // devfn is an int, so we mask it off. busdevfn = (dev->bus->secondary << 8) - | (dev->devfn & 0xff); + | (dev->path.u.pci.devfn & 0xff); printk_debug("0x%x: return 0x%x\n", func, busdevfn); *pebx = busdevfn; retval = 0; @@ -541,7 +678,7 @@ pcibios( devfn = *pebx & 0xff; bus = *pebx >> 8; reg = *pedi; - dev = pci_find_slot(bus, devfn); + dev = dev_find_slot(bus, devfn); if (! dev) { printk_debug("0x%x: BAD DEVICE bus %d devfn 0x%x\n", func, bus, devfn); // idiots. the pcibios guys assumed you'd never pass a bad bus/devfn! @@ -563,15 +700,15 @@ pcibios( break; case WRITECONFBYTE: byte = *pecx; - write_config8(dev, reg, byte); + pci_write_config8(dev, reg, byte); break; case WRITECONFWORD: word = *pecx; - write_config16(dev, reg, word); + pci_write_config16(dev, reg, word); break; case WRITECONFDWORD: - word = *pecx; - write_config32(dev, reg, dword); + dword = *pecx; + pci_write_config32(dev, reg, dword); break; } @@ -590,31 +727,46 @@ pcibios( return retval; } -static void vga_init(struct chip *chip, enum chip_pass pass) -{ - struct pc80_vgabios_config *conf = - (struct pc80_vgabios_config *)chip->chip_info; - - switch (pass) { - case CONF_PASS_PRE_BOOT: - + +int handleint21( unsigned long *edi, unsigned long *esi, unsigned long *ebp, + unsigned long *esp, unsigned long *ebx, unsigned long *edx, + unsigned long *ecx, unsigned long *eax, unsigned long *flags) +{ +int res=-1; + switch(*eax&0xffff) + { + case 0x5f19: break; - - default: - /* nothing yet */ + case 0x5f18: + *eax=0x5f; + *ebx=0x545; // MCLK = 133, 32M frame buffer, 256 M main memory + // *ebx = 0x515; // MCLK = 133, 32M frame buffer, 128 M main memory + *ecx=0x060; + res=0; + break; + case 0x5f00: + *eax = 0x8600; + break; + case 0x5f01: + *eax = 0x5f; + *ecx = (*ecx & 0xffffff00 ) | 2; // panel type = 2 = 1024 * 768 + res = 0; + break; + case 0x5f02: + *eax=0x5f; + *ebx= (*ebx & 0xffff0000) | 2; + *ecx= (*ecx & 0xffff0000) | 0x401; // PAL + crt only + *edx= (*edx & 0xffff0000) | 0; // TV Layout - default + res=0; + break; + case 0x5f0f: + *eax=0x860f; + //*ebx=0; + //*ecx=0; + //*edx=0; + //res=0; break; } + return res; } - -static void enumerate(struct chip *chip) -{ - /* don't really need to do anything */ - -} - -struct chip_control southbridge_via_vt8231_control = { - .enumerate = enumerate, - .enable = vga_init, - .name = "Legacy VGA bios" -}; -- cgit v1.2.3