First cut at running vgabios code.

This commit is contained in:
Ronald G. Minnich 2002-03-27 04:14:40 +00:00
commit 4355f389e2
3 changed files with 116 additions and 123 deletions

View file

@ -2,3 +2,4 @@ object i386_subr.o
object params.o
object hardwaremain.o
object pirq_routing.o HAVE_PIRQ_TABLE
object vgabios.o CONFIG_VGABIOS

View file

@ -1,3 +1,14 @@
#ifndef lint
static char rcsid[] = "$Id$";
#endif
#include <pci.h>
#include <pci_ids.h>
#undef __KERNEL__
#include <arch/io.h>
#include <printk.h>
#include <string.h>
/* vgabios.c. Derived from: */
/*------------------------------------------------------------ -*- C -*-
@ -54,123 +65,78 @@
*
* $Id$
*--------------------------------------------------------------------*/
/* andrey -- ugly */
memcpy(regions->addr, vgarom, 1024*64);
printk("copied region...");
//for(err = 0; err < 16; err++)
// printk("0x%x ", *(regions->addr+err));
printk("\n");
/* end andrey -- ugly */
#if (CONFIG_VGABIOS == 1)
#if defined(__i386__)
/*-------------------------------------------------------------------------
* Machine restart code - x86
*-----------------------------------------------------------------------*/
static unsigned long long
real_mode_gdt_entries [] = {
0x0000000000000000ULL, /* 00h: Null descriptor */
0x0000000000000000ULL, /* 08h: Unused... */
0x00cf9a000000ffffULL, /* 10h: 32-bit 4GB code at 0x00000000 */
0x00cf92000000ffffULL, /* 18h: 32-bit 4GB data at 0x00000000 */
0x00009a000000ffffULL, /* 20h: 16-bit 64k code at 0x00000000 */
0x000092000000ffffULL /* 28h: 16-bit 64k data at 0x00000000 */
};
static struct {
unsigned short size __attribute__ ((packed));
unsigned long long * base __attribute__ ((packed));
}
real_mode_gdt = { sizeof (real_mode_gdt_entries)-1, 0 },
real_mode_idt = { 0x3ff, 0 };
/*
Registers:
eax - scratch
ebx - memory list pointer
ecx - counter
edx - entry point
esi - scratch memcpy pointer
edi - scratch memcpy pointer
ebp - flags
*/
/* The address arguments to this function are PHYSICAL ADDRESSES */
static void real_mode_switch(struct monte_reloc_page_t *mem_list,
void *entry,
unsigned long flags) {
static void real_mode_switch_call_vga(void)
{
__asm__ __volatile__
(
/* Now that our memcpy is done we can get to 16 bit code
* segment. This configures CS properly for real mode. */
" ljmp $0x20, $0x1000-(real_mode_switch_end - __rms_16bit) \n"
" ljmp $0x28, $0x1000-(real_mode_switch_end - __rms_16bit) \n"
"__rms_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 $0x28, %%ax \n"
" mov %%ax, %%ds \n"
" mov %%ax, %%es \n"
" mov %%ax, %%fs \n"
" mov %%ax, %%gs \n"
" mov %%ax, %%ss \n"
" 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"
" movl %cr0, %eax \n"
" andl $0xFFFFFFFE, %eax \n"
" movl %eax, %cr0 \n"
/* Now really going into real mode */
" ljmp $0, $0x1000-(real_mode_switch_end - __rms_real) \n"
"__rms_real: \n"
/* Setup a stack */
" mov $0x9000, %%ax \n"
" mov %%ax, %%ss \n"
" mov $0xAFFE, %%ax \n"
" mov %%ax, %%sp \n"
" mov $0x9000, %ax \n"
" mov %ax, %ss \n"
" mov $0xAFFE, %ax \n"
" mov %ax, %sp \n"
/* ebugging for RGM */
" mov $0x11, %%al \n"
" outb %%al, $0x80\n"
" 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"
" sti \n" /* Enable interrupts */
/* Try and sanitize the video hardware state. */
" mov $0x0003, %%ax \n" /* Ask for 80x25 */
" int $0x10 \n"
" xor %ax, %ax \n"
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" .byte 0x9a, 0x03, 0, 0, 0xc0 \n"
" movb $0x55, %%al\noutb %%al, $0x80\n"
#if 0
" push %%edx \n" /* Kludge to do far jump */
" lret \n"
#endif
/*" jmp *%%edx \n"*/
/*" ljmp $0x9020, $0x0000 \n"*/
#if 0
/* Debugging tools... */
" .byte 0xcc \n" /* XXX DEBUG triple fault XXXX */
" .byte 0xeb, 0xfe \n" /* XXX DEBUG wedge XXXXX */
#endif
".code32 \n" /* Restore mode for rest of file */
: : "m" (mem_list), "m" (entry), "m" (flags));
" 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 */
"movl %eax, %cr0\n"
/* Now that we are in protected mode jump to a 32 bit code segment. */
"data32 ljmp $0x10, $vgarestart\n"
"vgarestart:\n"
".code32\n"
" movw $0x18, %ax \n"
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
"ret\n"
);
}
__asm__ (".text\n""real_mode_switch_end:\n");
extern char real_mode_switch_end[];
#if 0
//static
int monte_restart(unsigned long entry_addr, unsigned long flags) {
void * ptr;
@ -199,34 +165,35 @@ int monte_restart(unsigned long entry_addr, unsigned long flags) {
/* NOT REACHED */
while(1); /* Shut up gcc. */
}
#endif /* defined(__i386__) */
#endif
void
do_vgabios(void)
{
struct pci_dev *dev;
unsigned int rom = 0;
unsigned char *buf;
int i;
dev = pci_find_class(PCI_CLASS_DISPLAY_VGA <<8, NULL);
/* andrey stuff starts here */
{
struct pci_dev *dev;
unsigned int rom = 0;
unsigned char *buf;
if (! dev) {
printk_debug("NO VGA FOUND\n");
return;
}
printk_debug("found VGA: vid=%ux, did=%ux\n", dev->vendor, dev->device);
pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom);
// paranoia
rom &= ~1;
pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom|1);
printk_debug("rom base, size: %x\n", rom);
buf = (unsigned char *) rom;
memcpy((void *) 0xc0000, buf, 64*1024);
for(i = 0; i < 16; i++)
printk_debug("0x%x ", buf[i]);
pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom);
// check signature here later!
real_mode_switch_call_vga();
}
dev = pci_find_class(PCI_CLASS_DISPLAY_VGA <<8, NULL);
printk("found VGA: vid=%ux, did=%ux\n", dev->vendor, dev->device);
pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom);
// paranoia
rom &= ~1;
pci_write_config_byte(dev, PCI_ROM_ADDRESS, 1);
printk("rom base, size: %x\n", rom);
buf = ioremap(rom, sizeof(vgarom));
printk("buf is %p\n" ,buf);
if (buf) {
int i;
memcpy(vgarom, buf, sizeof(vgarom));
iounmap(buf);
for(i = 0; i < 16; i++)
printk("0x%x ", vgarom[i]);
printk("\n");
}
pci_write_config_byte(dev, PCI_ROM_ADDRESS, 0);
printk("done...");
}
#endif // (CONFIG_VGABIOS == 1)

View file

@ -20,22 +20,47 @@ EXT(gdtptr):
.long gdt /* we know the offset */
gdt:
// selgdt 0
.word 0x0000, 0x0000 /* dummy */
.byte 0x00, 0x00, 0x00, 0x00
.word 0xffff, _cache_ram_seg_base_low /* flat cache ram offset data segment */
// selgdt 8
/* flat cache ram offset data segment */
.word 0xffff, _cache_ram_seg_base_low
.byte _cache_ram_seg_base_middle, 0x93, 0xcf
.byte _cache_ram_seg_base_high
.word 0xffff, 0x0000 /* flat code segment */
// selgdt 0x10
/* flat code segment */
.word 0xffff, 0x0000
.byte 0x00, 0x9b, 0xcf, 0x00
.word 0xffff, 0x0000 /* flat data segment */
//selgdt 0x18
/* flat data segment */
.word 0xffff, 0x0000
.byte 0x00, 0x93, 0xcf, 0x00
.word 0xffff, _rom_code_seg_base_low /* flat rom offset code segment */
//selgdt 0x20
/* flat rom offset code segment */
.word 0xffff, _rom_code_seg_base_low
.byte _rom_code_seg_base_middle, 0x9b, 0xcf
.byte _rom_code_seg_base_high
#if defined(CONFIG_VGABIOS) && (CONFIG_VGABIOS == 1)
// from monty:
/* 0x00009a00,0000ffffULL, 20h: 16-bit 64k code at 0x00000000 */
/* 0x00009200,0000ffffULL 28h: 16-bit 64k data at 0x00000000 */
// selgdt 0x28
/*16-bit 64k code at 0x00000000 */
.word 0xffff, 0x0000
.byte 0, 0x9a, 0, 0
// selgdt 0x30
/*16-bit 64k data at 0x00000000 */
.word 0xffff, 0x0000
.byte 0, 0x92, 0, 0
#endif // defined(CONFIG_VGABIOS) && (CONFIG_VGABIOS == 1)
gdt_end: