diff --git a/src/arch/i386/lib/idt.c b/src/arch/i386/lib/idt.c index a856708272..ada0e6597d 100644 --- a/src/arch/i386/lib/idt.c +++ b/src/arch/i386/lib/idt.c @@ -1,25 +1,108 @@ #include +#include // we had hoped to avoid this. // this is a stub IDT only. It's main purpose is to ignore calls // to the BIOS. +// no longer. Dammit. We have to respond to these. struct realidt { unsigned short offset, cs; }; - +// handler. +// There are some assumptions we can make here. +// First, the Top Of Stack (TOS) is located on the top of page zero. +// we can share this stack between real and protected mode. +// that simplifies a lot of things ... +// we'll just push all the registers on the stack as longwords, +// and pop to protected mode. +// second, since this only ever runs as part of linuxbios, +// we know all the segment register values -- so we don't save any. void handler(void) { __asm__ __volatile__ ( ".code16\n" "idthandle:\n" " movb $0x55, %al\n" " outb %al, $0x80\n" + " pushl %eax\n" + " pushl %ebx\n" + " pushl %ecx\n" + " pushl %edx\n" + " pushl %edi\n" + " pushl %esi\n" + "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, $biosprotect\n" + "biosprotect:\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" + " call biosint \n" + // back to real mode ... + " ljmp $0x28, $__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 $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, $__rms_real \n" + "__rms_real: \n" + + /* Setup a stack */ + " mov $0x0, %ax \n" + " mov %ax, %ss \n" + /* ebugging for RGM */ + " mov $0x11, %al \n" + " outb %al, $0x80\n" + " xor %ax, %ax \n" + " mov %ax, %ds \n" + " mov %ax, %es \n" + " mov %ax, %fs \n" + " mov %ax, %gs \n" + " popl %eax\n" + " popl %ebx\n" + " popl %ecx\n" + " popl %edx\n" + " popl %edi\n" + " popl %esi\n" " iret\n" "end_idthandle:\n" ".code32\n" ); } +int +biosint(unsigned long eax, + unsigned long ebx, + unsigned long ecx, + unsigned long edx, + unsigned long edi, + unsigned long esi) { + printk_debug("biosint: eax 0x%lx ebx 0x%lx ecx 0x%lx edx 0x%lx\n", + eax, ebx, ecx, edx); + printk_debug("biosint: edi 0x%lx esi 0x%lx\n", edi, esi); +} void setup_realmode_idt(void) { extern unsigned char idthandle, end_idthandle; diff --git a/src/arch/i386/lib/vgabios.c b/src/arch/i386/lib/vgabios.c index 9a77e3b68a..89570c86eb 100644 --- a/src/arch/i386/lib/vgabios.c +++ b/src/arch/i386/lib/vgabios.c @@ -102,10 +102,13 @@ static void real_mode_switch_call_vga(void) " ljmp $0, $__rms_real \n" "__rms_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 $0x9000, %ax \n" + " mov $0x0, %ax \n" " mov %ax, %ss \n" - " mov $0xAFFE, %ax \n" + " mov $0x1000, %ax \n" " mov %ax, %sp \n" /* ebugging for RGM */ " mov $0x11, %al \n" diff --git a/src/mainboard/asus/cua/Config b/src/mainboard/asus/cua/Config index 5698b5128d..8524c1959c 100644 --- a/src/mainboard/asus/cua/Config +++ b/src/mainboard/asus/cua/Config @@ -14,9 +14,9 @@ southbridge acer/m1535 superio acer/m1535 mainboardinit cpu/p6/earlymtrr.inc -option ENABLE_FIXED_AND_VARIABLE_MTRRS -option FINAL_MAINBOARD_FIXUP -option HAVE_PIRQ_TABLE +option ENABLE_FIXED_AND_VARIABLE_MTRRS=1 +option FINAL_MAINBOARD_FIXUP=1 +option HAVE_PIRQ_TABLE=1 object mainboard.o object irq_tables.o keyboard pc80