[SeaBIOS] vgabios testing
Julian Pidancet
julian.pidancet at gmail.com
Sun Mar 4 04:03:49 CET 2012
On 03/04/12 00:21, Julian Pidancet wrote:
> On 03/02/12 09:09, Gerd Hoffmann wrote:
>> Hi,
>>
>> Did some more testing of the vgabios today, two issues popped up:
>>
>> (1) screen isn't cleared in some cases. Visible with grub1 in text
>> mode. When it displays the menu a few stray chars are visible.
>> Even more obvious it becomes when hitting 'c' then to get a
>> prompt, then alot of the menu is still visible.
>>
>> (2) The Xorg Server has trouble, the VESA driver doesn't work.
>>
>> There are also some good news: linux kernel with vesafb active works
>> fine, likewise winxp guests.
>
> Hi Gerd.
>
> I took a look at the issue with Xorg. According to my diagnostic, x86emu
> (the real-mode emulator that the X server uses) seems to have problems
> emulating mov instructions that uses segment selectors other than DS and SS.
>
> In lots of places in the vga bios code, we use instructions like
> mov %cs:(%eax), %ebp to access global variables (mostly when we
> use the GET_GLOBAL macro). We also might have a problem we use the
> SET_FARVAR macro because it uses ES.
>
> This issue with segment selector seems to be confirmed by some comments
> I found in x86emu's code while doing my research:
> http://cgit.freedesktop.org/xorg/xserver/tree/hw/xfree86/x86emu/decode.c
> The comment describing the decode_rm00_address function (line 838) seems
> to imply that only DS or SS can be used.
>
> Kevin, would you see a problem modifying the READx_SEG macros in
> src/farptr.h to only dereference memory using the DS selector, in the
> vgabios case ?
>
> For example:
>
> #define READ8_SEG(prefix, SEG, value, var) \
> __asm__(prefix "push %%ds\n" \
> "movw %%" #SEG " , %%ax\n" \
> "movw %%ax, %%ds\n" \
> "movb %1, %b0\n" \
> "pop %%ds" : "=Qi"(value) \
> : "m"(var), "m"(__segment_ ## SEG))
>
> instead of:
>
> #define READ8_SEG(prefix, SEG, value, var) \
> __asm__(prefix "movb %%" #SEG ":%1, %b0" : "=Qi"(value) \
>
>
Hi again,
I've done further debugging, and you can ignore all of the crap above.
x86emu badly handles the retl instruction and only pops a 16bit wide
value from the stack, whereas the corresponding calll pushes a 32bit
return address. leavel suffers from the same problem.
I've applied the following patch to x86emu and it seems to work better:
diff --git a/hw/xfree86/x86emu/ops.c b/hw/xfree86/x86emu/ops.c
index 5d3cac1..dd15387 100644
--- a/hw/xfree86/x86emu/ops.c
+++ b/hw/xfree86/x86emu/ops.c
@@ -8503,7 +8503,11 @@ static void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
DECODE_PRINTF("RET\n");
RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
TRACE_AND_STEP();
- M.x86.R_IP = pop_word();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ M.x86.R_EIP = pop_long();
+ } else {
+ M.x86.R_IP = pop_word();
+ }
DECODE_CLEAR_SEGOVR();
END_OF_INSTR();
}
@@ -8807,8 +8811,13 @@ static void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
START_OF_INSTR();
DECODE_PRINTF("LEAVE\n");
TRACE_AND_STEP();
- M.x86.R_SP = M.x86.R_BP;
- M.x86.R_BP = pop_word();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ M.x86.R_ESP = M.x86.R_EBP;
+ M.x86.R_EBP = pop_long();
+ } else {
+ M.x86.R_SP = M.x86.R_BP;
+ M.x86.R_BP = pop_word();
+ }
DECODE_CLEAR_SEGOVR();
END_OF_INSTR();
}
I am now wondering why Xorg calls VBE function 4f01 on the ROM so many
times. It might be another bug.
Also, in my test environment, Xorg still reports a bad checksum.
--
Julian
More information about the SeaBIOS
mailing list