https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3381bf39db36a2b763c83a...
commit 3381bf39db36a2b763c83a9411f69acf7329acfe Author: Timo Kreuzer timo.kreuzer@reactos.org AuthorDate: Sun Aug 14 14:41:53 2022 +0200 Commit: Timo Kreuzer timo.kreuzer@reactos.org CommitDate: Thu Nov 24 21:17:58 2022 +0200
[HAL/x64] Fix x86BiosCall
Use an INT call stub and exit on the address after the stub instead or using iret (some BIOS code uses int / iret internally). This fixes the messed up display when trying to switch modes. --- hal/halx86/amd64/x86bios.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/hal/halx86/amd64/x86bios.c b/hal/halx86/amd64/x86bios.c index 6d7ce9ae083..80cefebc322 100644 --- a/hal/halx86/amd64/x86bios.c +++ b/hal/halx86/amd64/x86bios.c @@ -412,12 +412,8 @@ x86BiosCall( _In_ ULONG InterruptNumber, _Inout_ PX86_BIOS_REGISTERS Registers) { + const ULONG StackBase = 0x2000; FAST486_STATE EmulatorContext; - struct - { - USHORT Ip; - USHORT SegCs; - } *Ivt; ULONG FlatIp; PUCHAR InstructionPointer;
@@ -432,8 +428,6 @@ x86BiosCall( NULL, // FpuCallback, NULL); // Tlb
-//RegisterBop(BOP_UNSIMULATE, CpuUnsimulateBop); - /* Copy the registers */ EmulatorContext.GeneralRegs[FAST486_REG_EAX].Long = Registers->Eax; EmulatorContext.GeneralRegs[FAST486_REG_EBX].Long = Registers->Ebx; @@ -449,36 +443,41 @@ x86BiosCall( EmulatorContext.Flags.AlwaysSet = 1; EmulatorContext.Flags.If = 1;
+ /* Set up the INT stub */ + FlatIp = StackBase - 4; + InstructionPointer = x86BiosMemoryMapping + FlatIp; + InstructionPointer[0] = 0xCD; // INT instruction + InstructionPointer[1] = (UCHAR)InterruptNumber; + InstructionPointer[2] = 0x90; // NOP. We will stop at this address. + /* Set the stack pointer */ - Fast486SetStack(&EmulatorContext, 0, 0x2000 - 2); // FIXME + Fast486SetStack(&EmulatorContext, 0, StackBase - 8);
- /* Set CS:EIP from the IVT entry */ - Ivt = (PVOID)x86BiosMemoryMapping; - Fast486ExecuteAt(&EmulatorContext, - Ivt[InterruptNumber].SegCs, - Ivt[InterruptNumber].Ip); + /* Start execution at the INT stub */ + Fast486ExecuteAt(&EmulatorContext, 0x00, FlatIp);
while (TRUE) { - /* Step one instruction */ - Fast486StepInto(&EmulatorContext); - - /* Check for iret */ + /* Get the current flat IP */ FlatIp = (EmulatorContext.SegmentRegs[FAST486_REG_CS].Selector << 4) + EmulatorContext.InstPtr.Long; + + /* Make sure we haven't left the allowed memory range */ if (FlatIp >= 0x100000) { DPRINT1("x86BiosCall: invalid IP (0x%lx) during BIOS execution", FlatIp); return FALSE; }
- /* Read the next instruction and check if it's IRET */ - InstructionPointer = x86BiosMemoryMapping + FlatIp; - if (*InstructionPointer == 0xCF) + /* Check if we returned from our int stub */ + if (FlatIp == (StackBase - 2)) { /* We are done! */ break; } + + /* Emulate one instruction */ + Fast486StepInto(&EmulatorContext); }
/* Copy the registers back */