From ffa5f05eca541ea43f3429b76eaa997005cc5929 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sat, 15 Dec 2007 17:15:48 +0000 Subject: [PATCH] - Implement BIOS access routines in HAL. - Implement HalResetDisplay using those routines. - Uncomment a display reset in bootvid (as real Windows bootvid does). - Remove 1 sec delay from the shutdown thread. - As a result, no more red screen flashing at the end of the 1st stage, shutdown quotes are displayed again, and BSODs are shown correctly. svn path=/trunk/; revision=31251 --- reactos/drivers/base/bootvid/bootvid.c | 8 +- reactos/hal/halx86/generic/bios.c | 237 ++++++++++++ reactos/hal/halx86/generic/generic.rbuild | 2 + reactos/hal/halx86/generic/halinit.c | 1 + reactos/hal/halx86/generic/v86.s | 417 ++++++++++++++++++++++ reactos/hal/halx86/include/halp.h | 42 +++ reactos/include/ndk/i386/ketypes.h | 10 + reactos/ntoskrnl/ex/shutdown.c | 6 +- reactos/ntoskrnl/inbv/inbv.c | 4 + 9 files changed, 717 insertions(+), 10 deletions(-) create mode 100644 reactos/hal/halx86/generic/bios.c create mode 100644 reactos/hal/halx86/generic/v86.s diff --git a/reactos/drivers/base/bootvid/bootvid.c b/reactos/drivers/base/bootvid/bootvid.c index b9e00a3c6da..9dbff2649c8 100644 --- a/reactos/drivers/base/bootvid/bootvid.c +++ b/reactos/drivers/base/bootvid/bootvid.c @@ -420,10 +420,8 @@ TryAgain: /* Now check if we have to set the mode */ if (SetMode) { - // - // Reset the display - // - //HalResetDisplay(); + /* Reset the display */ + HalResetDisplay(); curr_x = 0; curr_y = 0; @@ -463,7 +461,7 @@ VidResetDisplay(IN BOOLEAN HalReset) curr_y = 0; /* Clear the screen with HAL if we were asked to */ - //if (HalReset) HalResetDisplay(); + if (HalReset) HalResetDisplay(); /* Re-initialize the VGA Display */ VgaInterpretCmdStream(AT_Initialization); diff --git a/reactos/hal/halx86/generic/bios.c b/reactos/hal/halx86/generic/bios.c new file mode 100644 index 00000000000..279764da007 --- /dev/null +++ b/reactos/hal/halx86/generic/bios.c @@ -0,0 +1,237 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/generic/bios.c + * PURPOSE: BIOS Access Routines + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +UCHAR HalpIopmSaveBuffer[0x2000]; +ULONG HalpSavedPfn; +HARDWARE_PTE HalpSavedPte; +ULONG HalpGpfHandler; +ULONG HalpBopHandler; +USHORT HalpSavedIopmBase; +PUCHAR HalpSavedIoMap; +ULONG HalpSavedEsp0; + +#define GetPdeAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 22) << 2) + 0xC0300000) +#define GetPteAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 12) << 2) + 0xC0000000) + +/* FUNCTIONS ******************************************************************/ + +VOID +NTAPI +HalpStoreAndClearIopm(IN PUCHAR IoMap) +{ + ULONG i; + + /* Backup the old I/O Map */ + RtlCopyMemory(HalpIopmSaveBuffer, IoMap, 0x2000); + + /* Erase the current one */ + for (i = 0; i < 0x2000; i++) IoMap[i] = 0; + for (i = 0x2000; i < 0x2004; i++) IoMap[i] = 0xFF; +} + +VOID +NTAPI +HalpRestoreIopm(IN PUCHAR IoMap) +{ + ULONG i; + + /* Restore the backed up copy, and initialize it */ + RtlCopyMemory(IoMap, HalpIopmSaveBuffer, 0x2000); + for (i = 0x2000; i < 0x2004; i++) IoMap[i] = 0xFF; +} + +VOID +NTAPI +HalpMapRealModeMemory(VOID) +{ + PHARDWARE_PTE Pte, V86Pte; + ULONG i; + + /* Get the page table directory for the lowest meg of memory */ + Pte = GetPdeAddress(0); + HalpSavedPfn = Pte->PageFrameNumber; + HalpSavedPte = *Pte; + + /* Map it to the HAL reserved region and make it valid */ + Pte->Valid = 1; + Pte->Write = 1; + Pte->Owner = 1; + Pte->PageFrameNumber = (GetPdeAddress(0xFFC00000))->PageFrameNumber; + + /* Flush the TLB by resetting CR3 */ + __writecr3(__readcr3()); + + /* Now loop the first meg of memory */ + for (i = 0; i < 0x100000; i += PAGE_SIZE) + { + /* Identity map it */ + Pte = GetPteAddress((PVOID)i); + Pte->PageFrameNumber = i >> PAGE_SHIFT; + Pte->Valid = 1; + Pte->Write = 1; + Pte->Owner = 1; + } + + /* Now get the entry for our real mode V86 code and the target */ + Pte = GetPteAddress(0x20000); + V86Pte = GetPteAddress(&HalpRealModeStart); + do + { + /* Map the physical address into our real-mode region */ + Pte->PageFrameNumber = V86Pte->PageFrameNumber; + + /* Keep going until we've reached the end of our region */ + Pte++; + V86Pte++; + } while (V86Pte <= GetPteAddress(&HalpRealModeEnd)); + + /* Flush the TLB by resetting CR3 */ + __writecr3(__readcr3()); +} + +VOID +NTAPI +HalpSwitchToRealModeTrapHandlers(VOID) +{ + ULONG Handler; + + /* Save the current Invalid Opcode and General Protection Fault Handlers */ + HalpGpfHandler = ((((PKIPCR)KeGetPcr())->IDT[13].ExtendedOffset << 16) & + 0xFFFF0000) | + (((PKIPCR)KeGetPcr())->IDT[13].Offset & 0xFFFF); + HalpBopHandler = ((((PKIPCR)KeGetPcr())->IDT[6].ExtendedOffset << 16) & + 0xFFFF0000) | + (((PKIPCR)KeGetPcr())->IDT[6].Offset & 0xFFFF); + + /* Now set our own GPF handler to handle exceptions while in real mode */ + Handler = (ULONG_PTR)HalpTrap0D; + ((PKIPCR)KeGetPcr())->IDT[13].ExtendedOffset = + (USHORT)((Handler >> 16) & 0xFFFF); + ((PKIPCR)KeGetPcr())->IDT[13].Offset = (USHORT)Handler; + + /* And our own invalid opcode handler to detect the BOP to get us out */ + Handler = (ULONG_PTR)HalpTrap06; + ((PKIPCR)KeGetPcr())->IDT[6].ExtendedOffset = + (USHORT)((Handler >> 16) & 0xFFFF); + ((PKIPCR)KeGetPcr())->IDT[6].Offset = (USHORT)Handler; +} + +VOID +NTAPI +HalpSetupRealModeIoPermissionsAndTask(VOID) +{ + /* Save a copy of the I/O Map and delete it */ + HalpSavedIoMap = (PUCHAR)&(KeGetPcr()->TSS->IoMaps[0]); + HalpStoreAndClearIopm(HalpSavedIoMap); + + /* Save the IOPM and switch to the real-mode one */ + HalpSavedIopmBase = KeGetPcr()->TSS->IoMapBase; + KeGetPcr()->TSS->IoMapBase = KiComputeIopmOffset(1); + + /* Save our stack pointer */ + HalpSavedEsp0 = KeGetPcr()->TSS->Esp0; +} + +VOID +NTAPI +HalpRestoreTrapHandlers(VOID) +{ + /* We're back, restore the handlers we over-wrote */ + ((PKIPCR)KeGetPcr())->IDT[13].ExtendedOffset = + (USHORT)((HalpGpfHandler >> 16) & 0xFFFF); + ((PKIPCR)KeGetPcr())->IDT[13].Offset = (USHORT)HalpGpfHandler; + ((PKIPCR)KeGetPcr())->IDT[6].ExtendedOffset = + (USHORT)((HalpBopHandler >> 16) & 0xFFFF); + ((PKIPCR)KeGetPcr())->IDT[6].Offset = (USHORT)HalpBopHandler; +} + +VOID +NTAPI +HalpRestoreIoPermissionsAndTask(VOID) +{ + /* Restore the stack pointer */ + KeGetPcr()->TSS->Esp0 = HalpSavedEsp0; + + /* Restore the I/O Map */ + HalpRestoreIopm(HalpSavedIoMap); + + /* Restore the IOPM */ + KeGetPcr()->TSS->IoMapBase = HalpSavedIopmBase; +} + +VOID +NTAPI +HalpUnmapRealModeMemory(VOID) +{ + ULONG i; + PHARDWARE_PTE Pte; + + /* Loop the first meg of memory */ + for (i = 0; i < 0x100000; i += PAGE_SIZE) + { + /* Invalidate each PTE */ + Pte = GetPteAddress((PVOID)i); + Pte->Valid = 0; + Pte->Write = 0; + Pte->PageFrameNumber = 0; + } + + /* Restore the PDE for the lowest megabyte of memory */ + Pte = GetPdeAddress(0); + *Pte = HalpSavedPte; + Pte->PageFrameNumber = HalpSavedPfn; + + /* Flush the TLB by resetting CR3 */ + __writecr3(__readcr3()); +} + +BOOLEAN +NTAPI +HalpBiosDisplayReset(VOID) +{ + ULONG Flags = 0; + + /* Disable interrupts */ + Ke386SaveFlags(Flags); + _disable(); + + /* Map memory available to the V8086 real-mode code */ + HalpMapRealModeMemory(); + + /* Use special invalid opcode and GPF trap handlers */ + HalpSwitchToRealModeTrapHandlers(); + + /* Configure the IOPM and TSS */ + HalpSetupRealModeIoPermissionsAndTask(); + + /* Now jump to real mode */ + HalpBiosCall(); + + /* Restore kernel trap handlers */ + HalpRestoreTrapHandlers(); + + /* Restore TSS and IOPM */ + HalpRestoreIoPermissionsAndTask(); + + /* Restore low memory mapping */ + HalpUnmapRealModeMemory(); + + /* Restore interrupts if they were previously enabled */ + Ke386RestoreFlags(Flags); + return TRUE; +} + +/* EOF */ diff --git a/reactos/hal/halx86/generic/generic.rbuild b/reactos/hal/halx86/generic/generic.rbuild index bf35d302b2d..a89f6f6be4d 100644 --- a/reactos/hal/halx86/generic/generic.rbuild +++ b/reactos/hal/halx86/generic/generic.rbuild @@ -7,6 +7,7 @@ beep.c + bios.c bus.c cmos.c dma.c @@ -20,6 +21,7 @@ sysinfo.c timer.c systimer.S + v86.s ../include/hal.h diff --git a/reactos/hal/halx86/generic/halinit.c b/reactos/hal/halx86/generic/halinit.c index 21b142a0f28..bae45fa01cd 100644 --- a/reactos/hal/halx86/generic/halinit.c +++ b/reactos/hal/halx86/generic/halinit.c @@ -109,6 +109,7 @@ HalInitSystem(IN ULONG BootPhase, HalInitPnpDriver = NULL; // FIXME: TODO HalGetDmaAdapter = HalpGetDmaAdapter; HalGetInterruptTranslator = NULL; // FIXME: TODO + HalResetDisplay = HalpBiosDisplayReset; /* Initialize the hardware lock (CMOS) */ KeInitializeSpinLock(&HalpSystemHardwareLock); diff --git a/reactos/hal/halx86/generic/v86.s b/reactos/hal/halx86/generic/v86.s new file mode 100644 index 00000000000..5dc6d8090ed --- /dev/null +++ b/reactos/hal/halx86/generic/v86.s @@ -0,0 +1,417 @@ +/* + * FILE: hal/halx86/generic/bios.S + * COPYRIGHT: See COPYING in the top level directory + * PURPOSE: V8086 Real-Mode BIOS Thunking + * PROGRAMMER: Alex Ionescu (alex@relsoft.net) + */ + +/* INCLUDES ******************************************************************/ + +#include +#include +.intel_syntax noprefix + +// +// HAL BIOS Frame +// +#define HALP_BIOS_FRAME_SS 0x00 +#define HALP_BIOS_FRAME_ESP 0x04 +#define HALP_BIOS_FRAME_EFLAGS 0x08 +#define HALP_BIOS_FRAME_CS 0x0C +#define HALP_BIOS_FRAME_EIP 0x10 +#define HALP_BIOS_FRAME_TRAP_FRAME 0x14 +#define HALP_BIOS_FRAME_CS_LIMIT 0x18 +#define HALP_BIOS_FRAME_CS_BASE 0x1C +#define HALP_BIOS_FRAME_CS_FLAGS 0x20 +#define HALP_BIOS_FRAME_SS_LIMIT 0x24 +#define HALP_BIOS_FRAME_SS_BASE 0x28 +#define HALP_BIOS_FRAME_SS_FLAGS 0x2C +#define HALP_BIOS_FRAME_PREFIX 0x30 +#define HALP_BIOS_FRAME_LENGTH 0x34 + +/* GLOBALS *******************************************************************/ + +_HalpSavedEsp: + .long 0 + +_UnhandledMsg: + .asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx!!!\n" + +/* FUNCTIONS *****************************************************************/ + +.globl _HalpBiosCall@0 +.func HalpBiosCall@0 +_HalpBiosCall@0: + + /* Set up stack pointer */ + push ebp + mov ebp, esp + + /* Build a trap frame */ + pushfd + push edi + push esi + push ebx + push ds + push es + push fs + push gs + push offset _HalpRealModeEnd + + /* Save the stack */ + mov _HalpSavedEsp, esp + + /* Turn off alignment faults */ + mov eax, cr0 + and eax, ~CR0_AM + mov cr0, eax + + /* Setup a new stack */ + mov esi, fs:KPCR_TSS + mov eax, esp + sub eax, NPX_FRAME_LENGTH + mov [esi+KTSS_ESP0], eax + + /* Save V86 registers */ + push 0 + push 0 + push 0 + push 0 + push 0x2000 + + /* Get linear delta between stack and code */ + mov eax, offset _HalpRealModeEnd-4 + sub eax, offset _HalpRealModeStart + + /* Get offset of code */ + mov edx, offset _HalpRealModeStart + and edx, 0xFFF + + /* Add offset to linear address and save the new V86 SP */ + add eax, edx + push eax + + /* Start building interrupt frame. Setup V86 EFLAGS and IOPL 3 */ + pushfd + or dword ptr [esp], EFLAGS_V86_MASK + or dword ptr [esp], 0x3000 + + /* Push the CS and IP */ + push 0x2000 + push edx + + /* Do the interrupt return (jump to V86 mode) */ + iretd + +.globl _HalpRealModeStart +_HalpRealModeStart: + + /* Set mode 13 */ + mov ax, 0x12 + .byte 0 + .byte 0 + + /* Do the interrupt */ + int 0x10 + + /* BOP to exit V86 mode */ + .byte 0xC4 + .byte 0xC4 + + /* The stack lives here */ +.align 4 + .space 2048 +.globl _HalpRealModeEnd +_HalpRealModeEnd: + + /* We're back, clean up the trap frame */ + pop gs + pop fs + pop es + pop ds + pop ebx + pop esi + pop edi + popfd + + /* Return to caller */ + pop ebp + ret 0 +.endfunc + +.globl _HalpOpcodeInvalid@0 +.func HalpOpcodeInvalid@0 +_HalpOpcodeInvalid@0: + + /* Unhandled */ + UNHANDLED_PATH + + /* Nothing to return */ + xor eax, eax + ret 0 +.endfunc + +.globl _HalpPushInt@0 +.func HalpPushInt@0 +_HalpPushInt@0: + + /* Save EBX */ + push ebx + + /* Get SS offset and base */ + mov edx, [esi+HALP_BIOS_FRAME_ESP] + mov ebx, [esi+HALP_BIOS_FRAME_SS_BASE] + + /* Convert to 16-bits */ + and edx, 0xFFFF + sub dx, 2 + + /* Get EFLAGS and write them into the linear address of SP */ + mov ax, word ptr [esi+HALP_BIOS_FRAME_EFLAGS] + mov [ebx+edx], ax + sub dx, 2 + + /* Get CS segment and write it into SP */ + mov ax, word ptr [esi+HALP_BIOS_FRAME_CS] + mov [ebx+edx], ax + sub dx, 2 + + /* Get IP and write it into SP */ + mov ax, word ptr [esi+HALP_BIOS_FRAME_EIP] + mov [ebx+edx], ax + + /* Get new IP value (the interrupt ID is in ECX, so this is in the IVT) */ + mov eax, [ecx*4] + push eax + + /* Now save the new IP */ + movzx eax, ax + mov [esi+HALP_BIOS_FRAME_EIP], eax + + /* Save the new CS of this IP */ + pop eax + shr eax, 16 + mov [esi+HALP_BIOS_FRAME_CS], eax + + /* Update the stack pointer after our manual interrupt frame construction */ + mov word ptr [esi+HALP_BIOS_FRAME_ESP], dx + + /* Get CS and convert it to linear format */ + mov eax, [esi+HALP_BIOS_FRAME_CS] + shl eax, 4 + mov [esi+HALP_BIOS_FRAME_CS_BASE], eax + mov dword ptr [esi+HALP_BIOS_FRAME_CS_LIMIT], 0xFFFF + mov dword ptr [esi+HALP_BIOS_FRAME_CS_FLAGS], 0 + + /* Return success and restore EBX */ + mov eax, 1 + pop ebx + ret 0 +.endfunc + +.globl _HalpOpcodeINTnn@0 +.func HalpOpcodeINTnn@0 +_HalpOpcodeINTnn@0: + + /* Save non-volatiles and stack */ + push ebp + push esi + push ebx + + /* Get SS and convert it to linear format */ + mov eax, [esi+HALP_BIOS_FRAME_SS] + shl eax, 4 + mov [esi+HALP_BIOS_FRAME_SS_BASE], eax + mov dword ptr [esi+HALP_BIOS_FRAME_SS_LIMIT], 0xFFFF + mov dword ptr [esi+HALP_BIOS_FRAME_SS_FLAGS], 0 + + /* Increase IP and check if we're past the CS limit */ + inc dword ptr [esi+HALP_BIOS_FRAME_EIP] + mov edi, [esi+HALP_BIOS_FRAME_EIP] + cmp edi, [esi+HALP_BIOS_FRAME_CS_LIMIT] + ja EipLimitReached + + /* Convert IP to linear address and read the interrupt number */ + add edi, [esi+HALP_BIOS_FRAME_CS_BASE] + movzx ecx, byte ptr [edi] + + /* Increase EIP and do the interrupt, check for status */ + inc dword ptr [esi+HALP_BIOS_FRAME_EIP] + call _HalpPushInt@0 + test eax, 0xFFFF + jz Done + + /* Update the trap frame */ + mov ebp, [esi+HALP_BIOS_FRAME_TRAP_FRAME] + mov eax, [esi+HALP_BIOS_FRAME_SS] + mov [ebp+KTRAP_FRAME_SS], eax + mov eax, [esi+HALP_BIOS_FRAME_ESP] + mov [ebp+KTRAP_FRAME_ESP], eax + mov eax, [esi+HALP_BIOS_FRAME_CS] + mov [ebp+KTRAP_FRAME_CS], eax + mov eax, [esi+HALP_BIOS_FRAME_EFLAGS] + mov [ebp+KTRAP_FRAME_EFLAGS], eax + + /* Set success code */ + mov eax, 1 + +Done: + /* Restore volatiles */ + pop ebx + pop edi + pop ebp + ret 0 + +EipLimitReached: + /* Set failure code */ + xor eax, eax + jmp Done +.endfunc + +.globl _HalpDispatchV86Opcode@0 +.func HalpDispatchV86Opcode@0 +_HalpDispatchV86Opcode@0: + + /* Make space for the HAL BIOS Frame on the stack */ + push ebp + mov ebp, esp + sub esp, HALP_BIOS_FRAME_LENGTH + + /* Save non-volatiles */ + push esi + push edi + + /* Save pointer to the trap frame */ + mov esi, [ebp] + mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_TRAP_FRAME], esi + + /* Save SS */ + movzx eax, word ptr [esi+KTRAP_FRAME_SS] + mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_SS], eax + + /* Save ESP */ + mov eax, [esi+KTRAP_FRAME_ESP] + mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_ESP], eax + + /* Save EFLAGS */ + mov eax, [esi+KTRAP_FRAME_EFLAGS] + mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_EFLAGS], eax + + /* Save CS */ + movzx eax, word ptr [esi+KTRAP_FRAME_CS] + mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_CS], eax + + /* Save EIP */ + mov eax, [esi+KTRAP_FRAME_EIP] + mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_EIP], eax + + /* No prefix */ + xor eax, eax + mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_PREFIX], eax + + /* Set pointer to HAL BIOS Frame */ + lea esi, [ebp-HALP_BIOS_FRAME_LENGTH] + + /* Convert CS to linear format */ + mov eax, [esi+HALP_BIOS_FRAME_CS] + shl eax, 4 + mov [esi+HALP_BIOS_FRAME_CS_BASE], eax + mov dword ptr [esi+HALP_BIOS_FRAME_CS_LIMIT], 0xFFFF + mov dword ptr [esi+HALP_BIOS_FRAME_CS_FLAGS], 0 + + /* Make sure IP is within the CS Limit */ + mov edi, [esi+HALP_BIOS_FRAME_EIP] + cmp edi, [esi+HALP_BIOS_FRAME_CS_LIMIT] + ja DispatchError + + /* Convert IP to linear address and read the opcode */ + add edi, [esi+HALP_BIOS_FRAME_CS_BASE] + mov dl, [edi] + + /* We only deal with interrupts */ + cmp dl, 0xCD + je DispatchInt + + /* Anything else is invalid */ + call _HalpOpcodeInvalid@0 + jmp DispatchError + +DispatchInt: + /* Handle dispatching the interrupt */ + call _HalpOpcodeINTnn@0 + test eax, 0xFFFF + jz DispatchReturn + + /* Update the trap frame EIP */ + mov edi, [ebp-0x20] + mov eax, [ebp-0x24] + mov [edi+KTRAP_FRAME_EIP], eax + + /* Set success code */ + mov eax, 1 + +DispatchReturn: + /* Restore registers and return */ + pop edi + pop esi + mov esp, ebp + pop ebp + ret 0 + +DispatchError: + /* Set failure code and return */ + xor eax, eax + jmp DispatchReturn +.endfunc + +.func Ki16BitStackException +_Ki16BitStackException: + + /* Save stack */ + push ss + push esp + + /* Go to kernel mode thread stack */ + mov eax, PCR[KPCR_CURRENT_THREAD] + add esp, [eax+KTHREAD_INITIAL_STACK] + + /* Switch to good stack segment */ + UNHANDLED_PATH +.endfunc + +.globl _HalpTrap0D@0 +.func HalpTrap0D@0 +TRAP_FIXUPS htd_a, htd_t, DoFixupV86, DoFixupAbios +_HalpTrap0D@0: + + /* Enter trap */ + TRAP_PROLOG htd_a, htd_t + + /* Check if this is a V86 trap */ + test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK + jnz DoDispatch + + /* Unhandled */ + UNHANDLED_PATH + +DoDispatch: + /* Handle the opcode */ + call _HalpDispatchV86Opcode@0 + + /* Exit the interrupt */ + jmp _Kei386EoiHelper@0 +.endfunc + +.globl _HalpTrap06@0 +.func HalpTrap06@0 +_HalpTrap06@0: + + /* Restore DS/ES segments */ + mov eax, KGDT_R3_DATA | RPL_MASK + mov ds, ax + mov es, ax + + /* Restore ESP and return */ + mov esp, _HalpSavedEsp + ret 0 +.endfunc diff --git a/reactos/hal/halx86/include/halp.h b/reactos/hal/halx86/include/halp.h index 704969816d5..e1b91270914 100644 --- a/reactos/hal/halx86/include/halp.h +++ b/reactos/hal/halx86/include/halp.h @@ -115,6 +115,48 @@ HaliSetSystemInformation( IN OUT PVOID Buffer ); +// +// BIOS Routines +// +BOOLEAN +NTAPI +HalpBiosDisplayReset( + VOID +); + +ULONG +NTAPI +HalpBorrowTss( + VOID +); + +ULONG +NTAPI +HalpReturnTss( + ULONG SavedTss +); + +VOID +NTAPI +HalpBiosCall( + VOID +); + +VOID +NTAPI +HalpTrap0D( + VOID +); + +VOID +NTAPI +HalpTrap06( + VOID +); + +extern PVOID HalpRealModeStart; +extern PVOID HalpRealModeEnd; + extern KSPIN_LOCK HalpSystemHardwareLock; #endif /* __INTERNAL_HAL_HAL_H */ diff --git a/reactos/include/ndk/i386/ketypes.h b/reactos/include/ndk/i386/ketypes.h index b9107ed8661..f1549950751 100644 --- a/reactos/include/ndk/i386/ketypes.h +++ b/reactos/include/ndk/i386/ketypes.h @@ -108,6 +108,16 @@ Author: // #define INITIAL_STALL_COUNT 0x64 +// +// IOPM Definitions +// +#define IO_ACCESS_MAP_NONE 0 +#define IOPM_OFFSET FIELD_OFFSET(KTSS, IoMaps[0].IoMap) +#define KiComputeIopmOffset(MapNumber) \ + (MapNumber == IO_ACCESS_MAP_NONE) ? \ + (USHORT)(sizeof(KTSS)) : \ + (USHORT)(FIELD_OFFSET(KTSS, IoMaps[MapNumber-1].IoMap)) + // // Static Kernel-Mode Address start (use MM_KSEG0_BASE for actual) // diff --git a/reactos/ntoskrnl/ex/shutdown.c b/reactos/ntoskrnl/ex/shutdown.c index 47eaf6a082a..b1f6d9f6a9a 100644 --- a/reactos/ntoskrnl/ex/shutdown.c +++ b/reactos/ntoskrnl/ex/shutdown.c @@ -48,7 +48,6 @@ VOID STDCALL ShutdownThreadMain(PVOID Context) { SHUTDOWN_ACTION Action = (SHUTDOWN_ACTION)Context; - LARGE_INTEGER Waittime; static PCH FamousLastWords[] = { @@ -167,16 +166,13 @@ ShutdownThreadMain(PVOID Context) } PspShutdownProcessManager(); - Waittime.QuadPart = (LONGLONG)-10000000; /* 1sec */ - KeDelayExecutionThread(KernelMode, FALSE, &Waittime); - + CmShutdownSystem(); IoShutdownRegisteredFileSystems(); IoShutdownRegisteredDevices(); MiShutdownMemoryManager(); - if (Action == ShutdownNoReboot) { HalDisplayString("\nYou can switch off your computer now\n"); diff --git a/reactos/ntoskrnl/inbv/inbv.c b/reactos/ntoskrnl/inbv/inbv.c index a579873524f..9fcba6a7579 100644 --- a/reactos/ntoskrnl/inbv/inbv.c +++ b/reactos/ntoskrnl/inbv/inbv.c @@ -111,6 +111,7 @@ InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock, PCHAR CommandLine; BOOLEAN CustomLogo = FALSE; ULONG i; + extern BOOLEAN ExpInTextModeSetup; /* Quit if we're already installed */ if (InbvBootDriverInstalled) return TRUE; @@ -124,6 +125,9 @@ InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock, CustomLogo = strstr(CommandLine, "BOOTLOGO") ? TRUE: FALSE; } + /* For SetupLDR, don't reset the BIOS Display -- FIXME! */ + if (ExpInTextModeSetup) CustomLogo = TRUE; + /* Initialize the video */ InbvBootDriverInstalled = VidInitialize(!CustomLogo); if (InbvBootDriverInstalled)