From c50f85267b5ab099724789ce799caccd56dfebbe Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Wed, 27 Mar 2002 21:25:27 +0000 Subject: [PATCH] stupid old pc. Have to add idt for vga bios. --- src/arch/i386/lib/hardwaremain.c | 4 + src/arch/i386/lib/idt.c | 132 +++++++++++++++++++++++++++++++ src/arch/i386/lib/vgabios.c | 22 +++--- 3 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 src/arch/i386/lib/idt.c diff --git a/src/arch/i386/lib/hardwaremain.c b/src/arch/i386/lib/hardwaremain.c index 7522ccb4eb..767239ce26 100644 --- a/src/arch/i386/lib/hardwaremain.c +++ b/src/arch/i386/lib/hardwaremain.c @@ -320,6 +320,10 @@ void hardwaremain(int boot_complete) /* make certain we are the only cpu running in linuxBIOS */ wait_for_other_cpus(); +#if CONFIG_VGABIOS == 1 + printk_debug("DO THE VGA BIOS\n"); + do_vgabios(); +#endif /* Now that we have collected all of our information * write our configuration tables. */ diff --git a/src/arch/i386/lib/idt.c b/src/arch/i386/lib/idt.c new file mode 100644 index 0000000000..7b25a55d43 --- /dev/null +++ b/src/arch/i386/lib/idt.c @@ -0,0 +1,132 @@ +// we had hoped to avoid this. +#if 0 +/* + * setup_idt + * + * sets up a idt with 256 entries pointing to + * ignore_int, interrupt gates. It doesn't actually load + * idt - that can be done only after paging has been enabled + * and the kernel moved to PAGE_OFFSET. Interrupts + * are enabled elsewhere, when we can be relatively + * sure everything is ok. + */ +setup_idt: + lea ignore_int,%edx + movl $(__KERNEL_CS << 16),%eax + movw %dx,%ax /* selector = 0x0010 = cs */ + movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ + + lea SYMBOL_NAME(idt_table),%edi + mov $256,%ecx +rp_sidt: + movl %eax,(%edi) + movl %edx,4(%edi) + addl $8,%edi + dec %ecx + jne rp_sidt + ret + +ENTRY(stack_start) + .long SYMBOL_NAME(init_task_union)+8192 + .long __KERNEL_DS + +/* This is the default interrupt "handler" :-) */ +int_msg: + .asciz "Unknown interrupt\n" + ALIGN +ignore_int: + cld + pushl %eax + pushl %ecx + pushl %edx + pushl %es + pushl %ds + movl $(__KERNEL_DS),%eax + movl %eax,%ds + movl %eax,%es + pushl $int_msg + call SYMBOL_NAME(printk) + popl %eax + popl %ds + popl %es + popl %edx + popl %ecx + popl %eax + iret + +/* + * The interrupt descriptor table has room for 256 idt's, + * the global descriptor table is dependent on the number + * of tasks we can have.. + */ +#define IDT_ENTRIES 256 +#define GDT_ENTRIES (__TSS(NR_CPUS)) + + +.globl SYMBOL_NAME(idt) +.globl SYMBOL_NAME(gdt) + + ALIGN + .word 0 +idt_descr: + .word IDT_ENTRIES*8-1 # idt contains 256 entries +SYMBOL_NAME(idt): + .long SYMBOL_NAME(idt_table) + + .word 0 +#endif + +/* + * This starts the data section. Note that the above is all + * in the text section because it has alignment requirements + * that we cannot fulfill any other way. + */ +.data + +ALIGN +/* + * This contains typically 140 quadwords, depending on NR_CPUS. + * + * NOTE! Make sure the gdt descriptor in head.S matches this if you + * change anything. + */ +ENTRY(gdt_table) + .quad 0x0000000000000000 /* NULL descriptor */ + .quad 0x0000000000000000 /* not used */ + .quad 0x00cf9a000000ffff /* 0x10 kernel 4GB code at 0x00000000 */ + .quad 0x00cf92000000ffff /* 0x18 kernel 4GB data at 0x00000000 */ + .quad 0x00cffa000000ffff /* 0x23 user 4GB code at 0x00000000 */ + .quad 0x00cff2000000ffff /* 0x2b user 4GB data at 0x00000000 */ + .quad 0x0000000000000000 /* not used */ + .quad 0x0000000000000000 /* not used */ + /* + * The APM segments have byte granularity and their bases + * and limits are set at run time. + */ + .quad 0x0040920000000000 /* 0x40 APM set up for bad BIOS's */ + .quad 0x00409a0000000000 /* 0x48 APM CS code */ + .quad 0x00009a0000000000 /* 0x50 APM CS 16 code (16 bit) */ + .quad 0x0040920000000000 /* 0x58 APM DS data */ + .fill NR_CPUS*4,8,0 /* space for TSS's and LDT's */ + +/* + * This is to aid debugging, the various locking macros will be putting + * code fragments here. When an oops occurs we'd rather know that it's + * inside the .text.lock section rather than as some offset from whatever + * function happens to be last in the .text segment. + */ +.section .text.lock +ENTRY(stext_lock) +#endif + +void +lidt(void *base, unsigned int limit) +{ + + unsigned int i[2]; + + i[0] = limit << 16; + i[1] = // later +} +// this is too awful. +} diff --git a/src/arch/i386/lib/vgabios.c b/src/arch/i386/lib/vgabios.c index b9e6046eea..983f61672d 100644 --- a/src/arch/i386/lib/vgabios.c +++ b/src/arch/i386/lib/vgabios.c @@ -75,7 +75,7 @@ static void real_mode_switch_call_vga(void) ( /* Now that our memcpy is done we can get to 16 bit code * segment. This configures CS properly for real mode. */ - " ljmp $0x28, $0x1000-(real_mode_switch_end - __rms_16bit) \n" + " ljmp $0x28, $__rms_16bit\n" "__rms_16bit: \n" ".code16 \n" /* 16 bit code from here on... */ @@ -95,7 +95,7 @@ static void real_mode_switch_call_vga(void) " movl %eax, %cr0 \n" /* Now really going into real mode */ - " ljmp $0, $0x1000-(real_mode_switch_end - __rms_real) \n" + " ljmp $0, $__rms_real \n" "__rms_real: \n" /* Setup a stack */ @@ -172,6 +172,7 @@ do_vgabios(void) struct pci_dev *dev; unsigned int rom = 0; unsigned char *buf; + unsigned int size = 64*1024; int i; dev = pci_find_class(PCI_CLASS_DISPLAY_VGA <<8, NULL); @@ -183,17 +184,20 @@ do_vgabios(void) 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; + rom = 0xf0000000; 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); + if ((buf[0] == 0x55) && (buf[1] = 0xaa)) { + memcpy((void *) 0xc0000, buf, size); - 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(); + for(i = 0; i < 16; i++) + printk_debug("0x%x ", buf[i]); + // check signature here later! + real_mode_switch_call_vga(); + } else + printk_debug("BAD SIGNATURE 0x%x 0x%x\n", buf[0], buf[1]); + pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0); } #endif // (CONFIG_VGABIOS == 1)