Jan Klötzke <jan.kloetzke@xxxxxxxxxx> wrote: > Stephan Assmus <superstippi@xxxxxx> wrote: > > I know that Ingo is experiencing the same behavior. On my system, I just > > get "General System Error" when I try to change resolution (VESA also) > > during runtime. But I think if I have a vesa kernel settings file with > > anything different than the native resolution, my system does not boot. I > > am not sure, but I thought for the behavior you describe, there is a bug > > report, but I could be wrong. > > > > Jan, any ideas? > > Unfortunately not really. I suspect that there is an error in the > instruction emulation part of the vm86 stuff which confuses the BIOS. Just > a wild guess. I was not able yet to reproduce it on any of my systems here. > > What makes it really interesting and what is new to me is that you get > a "General System Error". Would you mind to enable TRACE_VM86 in > src/system/kernel/arch/x86/vm86.cpp and capture the output? Maybe I can > spot something there because the traces I've got so far did not contain > anything suspicious... Wait a minute... I found something. The PUSHF/POPF instructions were not emulated correctly! The attached patch should fix that. Hope that solves the problems. At least it should be applied nonetheless. /Jan
diff --git a/src/system/kernel/arch/x86/vm86.cpp b/src/system/kernel/arch/x86/vm86.cpp index dbadced..5e41a9b 100644 --- a/src/system/kernel/arch/x86/vm86.cpp +++ b/src/system/kernel/arch/x86/vm86.cpp @@ -44,8 +44,8 @@ #define PUSHF 0x9c #define STI 0xfb -#define I_FLAG (1 << 9) -#define DIRECTION_FLAG (1 << 10) +#define I_FLAG (1u << 9) +#define DIRECTION_FLAG (1u << 10) #define CSEG 0x2e #define SSEG 0x36 @@ -442,7 +442,7 @@ emulate(struct vm86_state *state) uint16 flags = state->regs.flags; /* store real IF */ - flags &= I_FLAG; + flags &= ~I_FLAG; flags |= (uint16)state->if_flag << 9; pushw(&state->regs, flags); @@ -475,10 +475,11 @@ emulate(struct vm86_state *state) case PUSHF: { TRACE_NP("PUSHF"); - uint16 flags = state->regs.flags & I_FLAG; + uint32 flags = state->regs.flags; /* store real IF */ - flags |= (uint16)state->if_flag << 9; + flags &= ~I_FLAG; + flags |= (uint32)state->if_flag << 9; if (prefix.size) pushl(&state->regs, flags); else