Hi Sebastian,
Do you have a test case for int1589 bios support? I've coded what I think is a working implementation (see below), but I'm not sure how to test it.
BTW, I think the Bochs BIOS implementation has bh and bl backwards.
-Kevin
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..bf1fc62 100644 --- a/src/system.c +++ b/src/system.c @@ -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(0x0ffff) + | GDT_BASE(0xf0000)); + + 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;
Kevin O'Connor
Hi Sebastian,
Do you have a test case for int1589 bios support? I've coded what I think is a working implementation (see below), but I'm not sure how to test it.
You can try the test case from Bochs feature request #2629791 [1].
BTW, I think the Bochs BIOS implementation has bh and bl backwards.
Possible. I ported this change from VBox [2] and did only minimal testing whether i end up in protected mode.
[1] http://sourceforge.net/tracker/?func=detail&aid=2629791&group_id=125... [2] http://www.virtualbox.org/changeset/5196
- Sebastian
On Mon, Jan 04, 2010 at 09:25:05PM +0100, Sebastian Herbszt wrote:
Kevin O'Connor
Do you have a test case for int1589 bios support? I've coded what I think is a working implementation (see below), but I'm not sure how to test it.
You can try the test case from Bochs feature request #2629791 [1].
Thanks Sebastian!
On SeaBIOS, I too get "Protected mode has been entered !" followed by a call into resume with a shutdown code of "5". The code then hangs - probably because I also used freedos.
So, I've committed this to SeaBIOS.
-Kevin
On Mon, Jan 04, 2010 at 08:54:48PM -0500, Kevin O'Connor wrote:
On SeaBIOS, I too get "Protected mode has been entered !" followed by a call into resume with a shutdown code of "5". The code then hangs - probably because I also used freedos.
Interestingly, if I apply this change:
--- a/src/resume.c +++ b/src/resume.c @@ -29,6 +29,9 @@ void VISIBLE16 handle_resume(u8 status) { init_dma(); + pic_setup(); + asm volatile("lgdtw %cs:rombios32_gdt_48"); + asm volatile("lidtw %cs:rmode_IDT_info");
debug_serial_setup(); dprintf(1, "In resume (status=%d)\n", status);
then FreeDOS is able to resume (I see irqs working). However, the screen is still stuck under qemu - not sure why.
-Kevin
On Fri, Jan 08, 2010 at 11:19:56PM -0500, Kevin O'Connor wrote:
On Mon, Jan 04, 2010 at 08:54:48PM -0500, Kevin O'Connor wrote:
On SeaBIOS, I too get "Protected mode has been entered !" followed by a call into resume with a shutdown code of "5". The code then hangs - probably because I also used freedos.
Interestingly, if I apply this change:
--- a/src/resume.c +++ b/src/resume.c @@ -29,6 +29,9 @@ void VISIBLE16 handle_resume(u8 status) { init_dma();
- pic_setup();
- asm volatile("lgdtw %cs:rombios32_gdt_48");
- asm volatile("lidtw %cs:rmode_IDT_info");
Under bochs, with the above change, the screen doesn't hang, and the test program returns to real mode. However, the system still hangs because it looks like bochs reset the f-segment. It looks like the test program triple-faults, and bochs does more than just reset the cpu in that case:
00163682527e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 05h, resetting 00163682527i[SYS ] bx_pc_system_c::Reset(HARDWARE) called 00163682527i[CPU0 ] cpu hardware reset 00163682527i[APIC0] local apic in CPU 0 initializing 00163682527i[PLGIN] reset of 'unmapped' plugin device by virtual method 00163682527i[PLGIN] reset of 'biosdev' plugin device by virtual method 00163682527i[PLGIN] reset of 'harddrv' plugin device by virtual method 00163682527i[PLGIN] reset of 'keyboard' plugin device by virtual method 00163682527i[PLGIN] reset of 'serial' plugin device by virtual method 00163682527i[PLGIN] reset of 'parallel' plugin device by virtual method 00163682527i[PLGIN] reset of 'extfpuirq' plugin device by virtual method 00163682527i[PLGIN] reset of 'gameport' plugin device by virtual method 00163682527i[PLGIN] reset of 'speaker' plugin device by virtual method 00163682527i[PLGIN] reset of 'pci_ide' plugin device by virtual method 00163936082i[BIOS ] In resume (status=5)
then FreeDOS is able to resume (I see irqs working). However, the screen is still stuck under qemu - not sure why.
I'm guessing something similar causes the video lockup on qemu.
-Kevin
Kevin O'Connor wrote:
On Fri, Jan 08, 2010 at 11:19:56PM -0500, Kevin O'Connor wrote:
On Mon, Jan 04, 2010 at 08:54:48PM -0500, Kevin O'Connor wrote:
On SeaBIOS, I too get "Protected mode has been entered !" followed by a call into resume with a shutdown code of "5". The code then hangs - probably because I also used freedos.
Interestingly, if I apply this change:
--- a/src/resume.c +++ b/src/resume.c @@ -29,6 +29,9 @@ void VISIBLE16 handle_resume(u8 status) { init_dma();
- pic_setup();
- asm volatile("lgdtw %cs:rombios32_gdt_48");
- asm volatile("lidtw %cs:rmode_IDT_info");
Under bochs, with the above change, the screen doesn't hang, and the test program returns to real mode. However, the system still hangs because it looks like bochs reset the f-segment.
Can you elaborate on "hangs". With Bochs cvs i end up back in FreeDOS shell, the keyboard works and i can try to execute commands.
It looks like the test program triple-faults, and bochs does more than just reset the cpu in that case:
00163682527e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 05h, resetting 00163682527i[SYS ] bx_pc_system_c::Reset(HARDWARE) called 00163682527i[CPU0 ] cpu hardware reset 00163682527i[APIC0] local apic in CPU 0 initializing 00163682527i[PLGIN] reset of 'unmapped' plugin device by virtual method 00163682527i[PLGIN] reset of 'biosdev' plugin device by virtual method 00163682527i[PLGIN] reset of 'harddrv' plugin device by virtual method 00163682527i[PLGIN] reset of 'keyboard' plugin device by virtual method 00163682527i[PLGIN] reset of 'serial' plugin device by virtual method 00163682527i[PLGIN] reset of 'parallel' plugin device by virtual method 00163682527i[PLGIN] reset of 'extfpuirq' plugin device by virtual method 00163682527i[PLGIN] reset of 'gameport' plugin device by virtual method 00163682527i[PLGIN] reset of 'speaker' plugin device by virtual method 00163682527i[PLGIN] reset of 'pci_ide' plugin device by virtual method 00163936082i[BIOS ] In resume (status=5)
then FreeDOS is able to resume (I see irqs working). However, the screen is still stuck under qemu - not sure why.
I'm guessing something similar causes the video lockup on qemu.
If i try to execute commands after resume the bios freaks out:
00206894578i[BIOS ] In resume (status=5) 00219543399i[BIOS ] int13_harddisk: function 02, parameters out of range 0000/0000/0001!
If i change BX_RESET_HARDWARE to BX_RESET_SOFTWARE it works as expected.
- Sebastian
On Sun, Jan 10, 2010 at 04:11:51PM +0100, Sebastian Herbszt wrote:
Kevin O'Connor wrote:
Under bochs, with the above change, the screen doesn't hang, and the test program returns to real mode. However, the system still hangs because it looks like bochs reset the f-segment.
Can you elaborate on "hangs". With Bochs cvs i end up back in FreeDOS shell, the keyboard works and i can try to execute commands.
On qemu, the screen ceases to update. It doesn't happen on Bochs. (Interestingly, I can see from the logs that irqs and disk accesses still work under qemu - it's just that the screen stops updating.)
If i try to execute commands after resume the bios freaks out:
00206894578i[BIOS ] In resume (status=5) 00219543399i[BIOS ] int13_harddisk: function 02, parameters out of range 0000/0000/0001!
The "int13_harddisk" message indicates to me that the f-segment was reset (SeaBIOS thinks the drive has zero sectors).
If i change BX_RESET_HARDWARE to BX_RESET_SOFTWARE it works as expected.
If BX_RESET_SOFTWARE no longer resets the f-segment, that would make sense.
-Kevin
Kevin O'Connor wrote:
On Sun, Jan 10, 2010 at 04:11:51PM +0100, Sebastian Herbszt wrote:
Kevin O'Connor wrote:
Under bochs, with the above change, the screen doesn't hang, and the test program returns to real mode. However, the system still hangs because it looks like bochs reset the f-segment.
Can you elaborate on "hangs". With Bochs cvs i end up back in FreeDOS shell, the keyboard works and i can try to execute commands.
On qemu, the screen ceases to update. It doesn't happen on Bochs. (Interestingly, I can see from the logs that irqs and disk accesses still work under qemu - it's just that the screen stops updating.)
Maybe try to call the vga bios.
If i try to execute commands after resume the bios freaks out:
00206894578i[BIOS ] In resume (status=5) 00219543399i[BIOS ] int13_harddisk: function 02, parameters out of range 0000/0000/0001!
The "int13_harddisk" message indicates to me that the f-segment was reset (SeaBIOS thinks the drive has zero sectors).
If i change BX_RESET_HARDWARE to BX_RESET_SOFTWARE it works as expected.
If BX_RESET_SOFTWARE no longer resets the f-segment, that would make sense.
I think BX_RESET_SOFTWARE is like cpu #INIT.
- Sebastian
Kevin O'Connor wrote:
On Mon, Jan 04, 2010 at 08:54:48PM -0500, Kevin O'Connor wrote:
On SeaBIOS, I too get "Protected mode has been entered !" followed by a call into resume with a shutdown code of "5". The code then hangs - probably because I also used freedos.
Interestingly, if I apply this change:
--- a/src/resume.c +++ b/src/resume.c @@ -29,6 +29,9 @@ void VISIBLE16 handle_resume(u8 status) { init_dma();
pic_setup();
asm volatile("lgdtw %cs:rombios32_gdt_48");
asm volatile("lidtw %cs:rmode_IDT_info");
debug_serial_setup(); dprintf(1, "In resume (status=%d)\n", status);
then FreeDOS is able to resume (I see irqs working). However, the screen is still stuck under qemu - not sure why.
The test program sets shutdown status to 05h. Bochs BIOS has this bug filed "shtudown/reset type 05 should reinit the PICs" [1].
[1] http://sourceforge.net/tracker/?func=detail&aid=2734455&group_id=125...
- Sebastian
On Sun, Jan 10, 2010 at 04:22:09PM +0100, Sebastian Herbszt wrote:
The test program sets shutdown status to 05h. Bochs BIOS has this bug filed "shtudown/reset type 05 should reinit the PICs" [1].
[1] http://sourceforge.net/tracker/?func=detail&aid=2734455&group_id=125...
I can't seem to find documentation on what the BIOS is supposed to do here. rbrown has only a terse description. Anyone have a link?
-Kevin
Kevin O'Connor wrote:
On Sun, Jan 10, 2010 at 04:22:09PM +0100, Sebastian Herbszt wrote:
The test program sets shutdown status to 05h. Bochs BIOS has this bug filed "shtudown/reset type 05 should reinit the PICs" [1].
[1] http://sourceforge.net/tracker/?func=detail&aid=2734455&group_id=125...
I can't seem to find documentation on what the BIOS is supposed to do here. rbrown has only a terse description. Anyone have a link?
I don't think there is (still?) any public documentation. Reverse engineering is the way to go.
- Sebastian