From: Kevin O'Connor Date: Tue, 5 Jan 2010 01:48:20 +0000 (-0500) Subject: Add int1589 support. X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=643062f9bc208911e3f27265c697dbde151d4f56;p=seabios.git Add int1589 support. Int1589 switches into protected mode for the caller. Also, consistently use BUILD_BIOS_ADDR/SIZE in GDT macros. --- diff --git a/TODO b/TODO index 8411620..07bb082 100644 --- a/TODO +++ b/TODO @@ -1,19 +1,15 @@ If POST is rerun, try to do a machine reboot. -Add int 0x1589 support. - Review changes committed to coreboot, virtualbox, qemu, kvm, and bochs cvs tip. - * bochs cvs (20091017): - -- 32bit pcibios, int1589 + * bochs cvs (20100104): + -- changes synched * coreboot (r3348): (bochs 20060708) -- no noteworthy enhancements - * qemu (da5ff65d): (bochs 20090210) - -- changes synched - * kvm (e5c31442): (bochs 20090210) - -- tpr patching, 16MB rom, acpi-ssdt.dsl, 4K aligned pci mem + * qemu - now uses SeaBIOS + * kvm - now uses SeaBIOS * virtualbox (r13560): (bochs 20061231) - -- lots of mouse changes, logo, scsi/etherboot hooks, int 1589, + -- lots of mouse changes, logo, scsi/etherboot hooks, floppy data rate?, int19 calls post Possibly move code from entry_post in romlayout.S to C code in diff --git a/src/misc.c b/src/misc.c index b33ef64..354df87 100644 --- a/src/misc.c +++ b/src/misc.c @@ -153,7 +153,7 @@ u64 rombios32_gdt[] VAR16VISIBLE __aligned(8) = { // 32 bit flat data segment (SEG32_MODE32_DS) GDT_LIMIT(0xfffff) | GDT_DATA | GDT_B | GDT_G, // 16 bit code segment base=0xf0000 limit=0xffff (SEG32_MODE16_CS) - GDT_LIMIT(0x0ffff) | GDT_CODE | GDT_BASE(0xf0000), + GDT_LIMIT(BUILD_BIOS_SIZE-1) | GDT_CODE | GDT_BASE(BUILD_BIOS_ADDR), // 16 bit data segment base=0x0 limit=0xffff (SEG32_MODE16_DS) GDT_LIMIT(0x0ffff) | GDT_DATA, // 16 bit code segment base=0 limit=0xffffffff (SEG32_MODE16BIG_CS) diff --git a/src/pic.c b/src/pic.c index f421bec..8992a8b 100644 --- a/src/pic.c +++ b/src/pic.c @@ -10,15 +10,14 @@ #include "config.h" // CONFIG_* void -pic_setup(void) +set_pics(u8 irq0, u8 irq8) { - dprintf(3, "init pic\n"); // Send ICW1 (select OCW1 + will send ICW4) outb(0x11, PORT_PIC1_CMD); outb(0x11, PORT_PIC2_CMD); // Send ICW2 (base irqs: 0x08-0x0f for irq0-7, 0x70-0x77 for irq8-15) - outb(0x08, PORT_PIC1_DATA); - outb(0x70, PORT_PIC2_DATA); + outb(irq0, PORT_PIC1_DATA); + outb(irq8, PORT_PIC2_DATA); // Send ICW3 (cascaded pic ids) outb(0x04, PORT_PIC1_DATA); outb(0x02, PORT_PIC2_DATA); @@ -30,6 +29,13 @@ pic_setup(void) outb(~0, PORT_PIC2_DATA); } +void +pic_setup(void) +{ + dprintf(3, "init pic\n"); + set_pics(0x08, 0x70); +} + // Handler for otherwise unused hardware irqs. void VISIBLE16 handle_hwpic1(struct bregs *regs) diff --git a/src/pic.h b/src/pic.h index 290fcb0..586ef38 100644 --- a/src/pic.h +++ b/src/pic.h @@ -98,6 +98,7 @@ __enable_hwirq(int hwirq, void (*func)(void)) __enable_hwirq(irq, func); \ } while (0) +void set_pics(u8 irq0, u8 irq8); void pic_setup(void); #endif // pic.h diff --git a/src/system.c b/src/system.c index ffcced9..f72151b 100644 --- a/src/system.c +++ b/src/system.c @@ -111,8 +111,8 @@ handle_1587(struct bregs *regs) SET_FARVAR(gdt_seg, gdt_far[1], GDT_DATA | GDT_LIMIT((6*sizeof(u64))-1) | GDT_BASE(loc)); // Initialize CS descriptor - SET_FARVAR(gdt_seg, gdt_far[4], GDT_CODE | GDT_LIMIT(0x0ffff) - | GDT_BASE(0xf0000)); + SET_FARVAR(gdt_seg, gdt_far[4], GDT_CODE | GDT_LIMIT(BUILD_BIOS_SIZE-1) + | GDT_BASE(BUILD_BIOS_ADDR)); // Initialize SS descriptor loc = (u32)MAKE_FLATPTR(GET_SEG(SS), 0); SET_FARVAR(gdt_seg, gdt_far[5], GDT_DATA | GDT_LIMIT(0x0ffff) @@ -182,6 +182,47 @@ handle_1588(struct bregs *regs) set_success(regs); } +// Switch to protected mode +static void +handle_1589(struct bregs *regs) +{ + set_a20(1); + + set_pics(regs->bl, regs->bh); + + u64 *gdt_far = (void*)(regs->si + 0); + u16 gdt_seg = regs->es; + SET_FARVAR(gdt_seg, gdt_far[7], GDT_CODE | GDT_LIMIT(BUILD_BIOS_SIZE-1) + | GDT_BASE(BUILD_BIOS_ADDR)); + + regs->ds = 3<<3; // 3rd gdt descriptor is %ds + regs->es = 4<<3; // 4th gdt descriptor is %es + regs->code.seg = 6<<3; // 6th gdt descriptor is %cs + + set_code_success(regs); + + asm volatile( + // Load new descriptor tables + " lgdtw %%es:(1<<3)(%%si)\n" + " lidtw %%es:(2<<3)(%%si)\n" + + // Enable protected mode + " movl %%cr0, %%eax\n" + " orl $" __stringify(CR0_PE) ", %%eax\n" + " movl %%eax, %%cr0\n" + + // far jump to flush CPU queue after transition to protected mode + " ljmpw $(7<<3), $1f\n" + + // GDT points to valid descriptor table, now load SS + "1:movw $(5<<3), %%ax\n" + " movw %%ax, %%ds\n" + " movw %%ax, %%ss\n" + : + : "S"(gdt_far) + : "eax", "cc"); +} + // Device busy interrupt. Called by Int 16h when no key available static void handle_1590(struct bregs *regs) @@ -309,6 +350,7 @@ handle_15(struct bregs *regs) case 0x86: handle_1586(regs); break; case 0x87: handle_1587(regs); break; case 0x88: handle_1588(regs); break; + case 0x89: handle_1589(regs); break; case 0x90: handle_1590(regs); break; case 0x91: handle_1591(regs); break; case 0xc0: handle_15c0(regs); break;