mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 10:31:43 +00:00
* Create a branch for USB experiments.
svn path=/branches/usb-experiments/; revision=72629
This commit is contained in:
parent
28d8ba0d3e
commit
0ee830d7a4
23049 changed files with 0 additions and 1313991 deletions
268
boot/environ/lib/arch/i386/arch.c
Normal file
268
boot/environ/lib/arch/i386/arch.c
Normal file
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING.ARM in the top level directory
|
||||
* PROJECT: ReactOS UEFI Boot Library
|
||||
* FILE: boot/environ/lib/arch/i386/arch.c
|
||||
* PURPOSE: Boot Library Architectural Initialization for i386
|
||||
* PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "bl.h"
|
||||
|
||||
/* DATA VARIABLES ************************************************************/
|
||||
|
||||
BL_ARCH_CONTEXT FirmwareExecutionContext;
|
||||
BL_ARCH_CONTEXT ApplicationExecutionContext;
|
||||
PBL_ARCH_CONTEXT CurrentExecutionContext;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
DECLSPEC_NORETURN
|
||||
ArchTrapNoProcess (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
/* Do nothing, this is an unsupported debugging interrupt */
|
||||
#if defined(__GNUC__)
|
||||
__asm__ __volatile__ ("iret");
|
||||
#elif defined (_MSC_VER)
|
||||
_asm { iret };
|
||||
#else
|
||||
#error wtf are you using
|
||||
#endif
|
||||
__assume(0);
|
||||
}
|
||||
|
||||
VOID
|
||||
ArchSwitchContext (
|
||||
_In_ PBL_ARCH_CONTEXT NewContext,
|
||||
_In_ PBL_ARCH_CONTEXT OldContext
|
||||
)
|
||||
{
|
||||
/* Are we switching to real mode? */
|
||||
if (NewContext->Mode == BlRealMode)
|
||||
{
|
||||
/* Disable paging */
|
||||
__writecr0(__readcr0() & ~CR0_PG);
|
||||
|
||||
/* Are we coming from PAE mode? */
|
||||
if ((OldContext != NULL) && (OldContext->TranslationType == BlPae))
|
||||
{
|
||||
/* Turn off PAE */
|
||||
__writecr4(__readcr4() & ~CR4_PAE);
|
||||
}
|
||||
|
||||
/* Enable interrupts */
|
||||
_enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Switching to protected mode -- disable interrupts if needed */
|
||||
if (!(NewContext->ContextFlags & BL_CONTEXT_INTERRUPTS_ON))
|
||||
{
|
||||
_disable();
|
||||
}
|
||||
|
||||
/* Are we enabling paging for the first time? */
|
||||
if (NewContext->ContextFlags & BL_CONTEXT_PAGING_ON)
|
||||
{
|
||||
/* In PAE mode? */
|
||||
if (NewContext->TranslationType == BlPae)
|
||||
{
|
||||
/* Turn on PAE */
|
||||
__writecr4(__readcr4() | CR4_PAE);
|
||||
}
|
||||
|
||||
/* Turn on paging */
|
||||
__writecr0(__readcr0() | CR0_PG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ArchInitializeContext (
|
||||
_In_ PBL_ARCH_CONTEXT Context
|
||||
)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
/* Are we initializing real mode? */
|
||||
if (Context->Mode == BlRealMode)
|
||||
{
|
||||
/* Disable paging, enable interrupts */
|
||||
Context->ContextFlags &= ~BL_CONTEXT_PAGING_ON;
|
||||
Context->ContextFlags |= BL_CONTEXT_INTERRUPTS_ON;
|
||||
}
|
||||
else if (!(BlpApplicationFlags & BL_APPLICATION_FLAG_CONVERTED_FROM_EFI) ||
|
||||
(BlpLibraryParameters.TranslationType != BlNone))
|
||||
{
|
||||
/* Read the current translation type */
|
||||
Context->TranslationType = BlpLibraryParameters.TranslationType;
|
||||
|
||||
/* Disable paging (it's already on), enable interrupts */
|
||||
Context->ContextFlags &= ~BL_CONTEXT_PAGING_ON;
|
||||
Context->ContextFlags |= BL_CONTEXT_INTERRUPTS_ON;
|
||||
|
||||
/* Enable FXSR support in the FPU */
|
||||
__writecr4(__readcr4() | CR4_FXSR);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid context */
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Return context status */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ArchInitializeContexts (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
PBL_ARCH_CONTEXT Context = NULL;
|
||||
NTSTATUS EfiStatus, AppStatus;
|
||||
|
||||
/* No current context */
|
||||
CurrentExecutionContext = NULL;
|
||||
|
||||
/* Setup the EFI and Application modes respectively */
|
||||
FirmwareExecutionContext.Mode = BlRealMode;
|
||||
ApplicationExecutionContext.Mode = BlProtectedMode;
|
||||
|
||||
/* Initialize application mode */
|
||||
AppStatus = ArchInitializeContext(&ApplicationExecutionContext);
|
||||
if (NT_SUCCESS(AppStatus))
|
||||
{
|
||||
/* Set it as current if it worked */
|
||||
Context = &ApplicationExecutionContext;
|
||||
CurrentExecutionContext = &ApplicationExecutionContext;
|
||||
}
|
||||
|
||||
/* Initialize EFI mode */
|
||||
EfiStatus = ArchInitializeContext(&FirmwareExecutionContext);
|
||||
if (NT_SUCCESS(EfiStatus))
|
||||
{
|
||||
/* Set it as current if application context failed */
|
||||
if (!NT_SUCCESS(AppStatus))
|
||||
{
|
||||
Context = &FirmwareExecutionContext;
|
||||
CurrentExecutionContext = &FirmwareExecutionContext;
|
||||
}
|
||||
|
||||
/* Switch to application mode, or EFI if that one failed */
|
||||
ArchSwitchContext(Context, NULL);
|
||||
EfiStatus = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return initialization state */
|
||||
return EfiStatus;
|
||||
}
|
||||
|
||||
VOID
|
||||
BlpArchSwitchContext (
|
||||
_In_ BL_ARCH_MODE NewMode
|
||||
)
|
||||
{
|
||||
PBL_ARCH_CONTEXT Context;
|
||||
|
||||
/* In real mode, use EFI, otherwise, use the application mode */
|
||||
Context = &FirmwareExecutionContext;
|
||||
if (NewMode != BlProtectedMode) Context = &ApplicationExecutionContext;
|
||||
|
||||
/* Are we in a different mode? */
|
||||
if (CurrentExecutionContext->Mode != NewMode)
|
||||
{
|
||||
/* Switch to the new one */
|
||||
ArchSwitchContext(Context, CurrentExecutionContext);
|
||||
CurrentExecutionContext = Context;
|
||||
}
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name BlpArchInitialize
|
||||
*
|
||||
* The BlpArchInitialize function initializes the Boot Library.
|
||||
*
|
||||
* @param Phase
|
||||
* Pointer to the Boot Application Parameter Block.
|
||||
*
|
||||
* @return NT_SUCCESS if the boot library was loaded correctly, relevant error
|
||||
* otherwise.
|
||||
*
|
||||
*--*/
|
||||
NTSTATUS
|
||||
BlpArchInitialize (
|
||||
_In_ ULONG Phase
|
||||
)
|
||||
{
|
||||
KDESCRIPTOR Idtr;
|
||||
USHORT CodeSegment;
|
||||
NTSTATUS Status;
|
||||
PKIDTENTRY IdtBase;
|
||||
|
||||
/* Assume success */
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
/* Is this phase 1? */
|
||||
if (Phase != 0)
|
||||
{
|
||||
/* Get the IDT */
|
||||
__sidt(&Idtr);
|
||||
IdtBase = (PKIDTENTRY)Idtr.Base;
|
||||
|
||||
/* Get the Code Segment */
|
||||
#if defined(__GNUC__)
|
||||
__asm__ __volatile__ ("mov %%cs,%0\n\t" :"=r" (CodeSegment));
|
||||
#elif defined (_MSC_VER)
|
||||
_asm { mov CodeSegment, cs };
|
||||
#else
|
||||
#error wtf are you using
|
||||
#endif
|
||||
|
||||
/* Set up INT 3, ASSERT, and SECURITY_ASSERT to be no-op (for Rtl) */
|
||||
IdtBase[3].Offset = (USHORT)(ULONG_PTR)ArchTrapNoProcess;
|
||||
IdtBase[3].Selector = CodeSegment;
|
||||
IdtBase[3].Access = 0x8E00u;
|
||||
IdtBase[3].ExtendedOffset = (ULONG_PTR)ArchTrapNoProcess >> 16;
|
||||
IdtBase[0x2C].Offset = (USHORT)(ULONG_PTR)ArchTrapNoProcess;
|
||||
IdtBase[0x2C].Selector = CodeSegment;
|
||||
IdtBase[0x2C].Access = 0x8E00u;
|
||||
IdtBase[0x2C].ExtendedOffset = (ULONG_PTR)ArchTrapNoProcess >> 16;
|
||||
IdtBase[0x2D].Offset = (USHORT)(ULONG_PTR)ArchTrapNoProcess;
|
||||
IdtBase[0x2D].Selector = CodeSegment;
|
||||
IdtBase[0x2D].Access = 0x8E00u;
|
||||
IdtBase[0x2D].ExtendedOffset = (ULONG_PTR)ArchTrapNoProcess >> 16;
|
||||
|
||||
/* Write the IDT back */
|
||||
Idtr.Base = (ULONG)IdtBase;
|
||||
__lidt(&Idtr);
|
||||
|
||||
/* Reset FPU state */
|
||||
#if defined(__GNUC__)
|
||||
__asm__ __volatile__ ("fninit");
|
||||
#elif defined (_MSC_VER)
|
||||
_asm { fninit };
|
||||
#else
|
||||
#error wtf are you using
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset TSC if needed */
|
||||
if ((__readmsr(0x10) >> 32) & 0xFFC00000)
|
||||
{
|
||||
__writemsr(0x10, 0);
|
||||
}
|
||||
|
||||
/* Initialize all the contexts */
|
||||
Status = ArchInitializeContexts();
|
||||
}
|
||||
|
||||
/* Return initialization state */
|
||||
return Status;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue