stupid old pc. Have to add idt for vga bios.
This commit is contained in:
parent
56a01c28dc
commit
c50f85267b
3 changed files with 150 additions and 10 deletions
|
|
@ -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
132
src/arch/i386/lib/idt.c
Normal 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.
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue