stupid old pc. Have to add idt for vga bios.

This commit is contained in:
Ronald G. Minnich 2002-03-27 21:25:27 +00:00
commit c50f85267b
3 changed files with 150 additions and 10 deletions

View file

@ -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.
*/

132
src/arch/i386/lib/idt.c Normal file
View file

@ -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.
}

View file

@ -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)