ReactOS  0.4.15-dev-985-gd905dd5
arch.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING.ARM in the top level directory
3  * PROJECT: ReactOS UEFI Boot Library
4  * FILE: boot/environ/lib/arch/i386/arch.c
5  * PURPOSE: Boot Library Architectural Initialization for i386
6  * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include "bl.h"
12 
13 /* DATA VARIABLES ************************************************************/
14 
18 
19 /* FUNCTIONS *****************************************************************/
20 
21 VOID
24  VOID
25  )
26 {
27  /* Do nothing, this is an unsupported debugging interrupt */
28 #if defined(__GNUC__)
29  __asm__ __volatile__ ("iret");
30 #elif defined (_MSC_VER)
31  _asm { iret };
32 #else
33 #error wtf are you using
34 #endif
35  __assume(0);
36 }
37 
38 VOID
42  )
43 {
44  /* Are we switching to real mode? */
45  if (NewContext->Mode == BlRealMode)
46  {
47  /* Disable paging */
49 
50  /* Are we coming from PAE mode? */
51  if ((OldContext != NULL) && (OldContext->TranslationType == BlPae))
52  {
53  /* Turn off PAE */
55  }
56 
57  /* Enable interrupts */
58  _enable();
59  }
60  else
61  {
62  /* Switching to protected mode -- disable interrupts if needed */
63  if (!(NewContext->ContextFlags & BL_CONTEXT_INTERRUPTS_ON))
64  {
65  _disable();
66  }
67 
68  /* Are we enabling paging for the first time? */
69  if (NewContext->ContextFlags & BL_CONTEXT_PAGING_ON)
70  {
71  /* In PAE mode? */
72  if (NewContext->TranslationType == BlPae)
73  {
74  /* Turn on PAE */
76  }
77 
78  /* Turn on paging */
80  }
81  }
82 }
83 
87  )
88 {
90 
91  /* Are we initializing real mode? */
92  if (Context->Mode == BlRealMode)
93  {
94  /* Disable paging, enable interrupts */
95  Context->ContextFlags &= ~BL_CONTEXT_PAGING_ON;
96  Context->ContextFlags |= BL_CONTEXT_INTERRUPTS_ON;
97  }
100  {
101  /* Read the current translation type */
102  Context->TranslationType = BlpLibraryParameters.TranslationType;
103 
104  /* Disable paging (it's already on), enable interrupts */
105  Context->ContextFlags &= ~BL_CONTEXT_PAGING_ON;
106  Context->ContextFlags |= BL_CONTEXT_INTERRUPTS_ON;
107 
108  /* Enable FXSR support in the FPU */
110  }
111  else
112  {
113  /* Invalid context */
115  }
116 
117  /* Return context status */
118  return Status;
119 }
120 
121 NTSTATUS
123  VOID
124  )
125 {
127  NTSTATUS EfiStatus, AppStatus;
128 
129  /* No current context */
131 
132  /* Setup the EFI and Application modes respectively */
135 
136  /* Initialize application mode */
138  if (NT_SUCCESS(AppStatus))
139  {
140  /* Set it as current if it worked */
143  }
144 
145  /* Initialize EFI mode */
147  if (NT_SUCCESS(EfiStatus))
148  {
149  /* Set it as current if application context failed */
150  if (!NT_SUCCESS(AppStatus))
151  {
154  }
155 
156  /* Switch to application mode, or EFI if that one failed */
158  EfiStatus = STATUS_SUCCESS;
159  }
160 
161  /* Return initialization state */
162  return EfiStatus;
163 }
164 
165 VOID
167  _In_ BL_ARCH_MODE NewMode
168  )
169 {
171 
172  /* In real mode, use EFI, otherwise, use the application mode */
174  if (NewMode != BlRealMode)
175  {
177  }
178 
179  /* Are we in a different mode? */
180  if (CurrentExecutionContext->Mode != NewMode)
181  {
182  /* Switch to the new one */
185  }
186 }
187 
188 VOID
190  VOID
191  )
192 {
194 
195  /* Does the current execution context already have paging enabled? */
197  if (!(Context->ContextFlags & BL_CONTEXT_PAGING_ON))
198  {
199  /* No -- does it have interrupts enabled? */
200  if (Context->ContextFlags & BL_CONTEXT_INTERRUPTS_ON)
201  {
202  /* Disable them */
203  _disable();
204  Context->ContextFlags &= ~BL_CONTEXT_INTERRUPTS_ON;
205  }
206 
207  /* Are we enabling PAE? */
208  if (Context->TranslationType == BlPae)
209  {
210  /* Make sure CR4 reflects this */
212  }
213 
214  /* Enable paging in the CPU */
216 
217  /* Reflect that paging is enabled */
218  Context->ContextFlags |= BL_CONTEXT_PAGING_ON;
219  }
220 }
221 
222 /*++
223 * @name BlpArchInitialize
224 *
225 * The BlpArchInitialize function initializes the Boot Library.
226 *
227 * @param Phase
228 * Pointer to the Boot Application Parameter Block.
229 *
230 * @return NT_SUCCESS if the boot library was loaded correctly, relevant error
231 * otherwise.
232 *
233 *--*/
234 NTSTATUS
236  _In_ ULONG Phase
237  )
238 {
239  KDESCRIPTOR Idtr;
240  USHORT CodeSegment;
242  PKIDTENTRY IdtBase;
243 
244  /* Assume success */
246 
247  /* Is this phase 1? */
248  if (Phase != 0)
249  {
250  /* Get the IDT */
251  __sidt(&Idtr);
252  IdtBase = (PKIDTENTRY)Idtr.Base;
253 
254  /* Get the Code Segment */
255 #if defined(__GNUC__)
256  __asm__ __volatile__ ("mov %%cs,%0\n\t" :"=r" (CodeSegment));
257 #elif defined (_MSC_VER)
258  _asm { mov CodeSegment, cs };
259 #else
260 #error wtf are you using
261 #endif
262 
263  /* Set up INT 3, ASSERT, and SECURITY_ASSERT to be no-op (for Rtl) */
264  IdtBase[3].Offset = (USHORT)(ULONG_PTR)ArchTrapNoProcess;
265  IdtBase[3].Selector = CodeSegment;
266  IdtBase[3].Access = 0x8E00u;
267  IdtBase[3].ExtendedOffset = (ULONG_PTR)ArchTrapNoProcess >> 16;
268  IdtBase[0x2C].Offset = (USHORT)(ULONG_PTR)ArchTrapNoProcess;
269  IdtBase[0x2C].Selector = CodeSegment;
270  IdtBase[0x2C].Access = 0x8E00u;
271  IdtBase[0x2C].ExtendedOffset = (ULONG_PTR)ArchTrapNoProcess >> 16;
272  IdtBase[0x2D].Offset = (USHORT)(ULONG_PTR)ArchTrapNoProcess;
273  IdtBase[0x2D].Selector = CodeSegment;
274  IdtBase[0x2D].Access = 0x8E00u;
275  IdtBase[0x2D].ExtendedOffset = (ULONG_PTR)ArchTrapNoProcess >> 16;
276 
277  /* Write the IDT back */
278  Idtr.Base = (ULONG)IdtBase;
279  __lidt(&Idtr);
280 
281  /* Reset FPU state */
282 #if defined(__GNUC__)
283  __asm__ __volatile__ ("fninit");
284 #elif defined (_MSC_VER)
285  _asm { fninit };
286 #else
287 #error wtf are you using
288 #endif
289  }
290  else
291  {
292  /* Reset TSC if needed */
293  if ((__readmsr(0x10) >> 32) & 0xFFC00000)
294  {
295  __writemsr(0x10, 0);
296  }
297 
298  /* Initialize all the contexts */
300  }
301 
302  /* Return initialization state */
303  return Status;
304 }
305 
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define BL_APPLICATION_FLAG_CONVERTED_FROM_EFI
Definition: bl.h:52
__INTRIN_INLINE void __writecr4(unsigned int Data)
Definition: intrin_x86.h:1694
BL_LIBRARY_PARAMETERS BlpLibraryParameters
Definition: bootlib.c:15
#define __GNUC__
Definition: _icc.h:38
BL_ARCH_CONTEXT FirmwareExecutionContext
Definition: arch.c:15
void __cdecl _enable(void)
Definition: intrin_arm.h:373
LONG NTSTATUS
Definition: precomp.h:26
#define CR4_FXSR
Definition: ketypes.h:92
#define BL_CONTEXT_PAGING_ON
Definition: bl.h:84
__INTRIN_INLINE void __lidt(void *Source)
Definition: intrin_x86.h:1929
NTSTATUS BlpArchInitialize(_In_ ULONG Phase)
Definition: arch.c:235
USHORT Access
Definition: ketypes.h:388
PVOID Base
Definition: ketypes.h:486
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS ArchInitializeContext(_In_ PBL_ARCH_CONTEXT Context)
Definition: arch.c:85
uint32_t cs
Definition: isohybrid.c:75
__asm__("\t.globl GetPhys\n" "GetPhys:\t\n" "mflr 0\n\t" "stwu 0,-16(1)\n\t" "mfmsr 5\n\t" "andi. 6,5,0xffef\n\t" "mtmsr 6\n\t" "isync\n\t" "sync\n\t" "lwz 3,0(3)\n\t" "mtmsr 5\n\t" "isync\n\t" "sync\n\t" "lwz 0,0(1)\n\t" "addi 1,1,16\n\t" "mtlr 0\n\t" "blr")
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:1934
NTSTATUS ArchInitializeContexts(VOID)
Definition: arch.c:122
smooth NULL
Definition: ftsmooth.c:416
__INTRIN_INLINE void __writecr0(unsigned int Data)
Definition: intrin_x86.h:1684
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
Definition: bl.h:240
VOID BlpArchEnableTranslation(VOID)
Definition: arch.c:189
#define CR0_PG
Definition: asm.h:255
VOID ArchSwitchContext(_In_ PBL_ARCH_CONTEXT NewContext, _In_ PBL_ARCH_CONTEXT OldContext)
Definition: arch.c:39
BL_ARCH_CONTEXT ApplicationExecutionContext
Definition: arch.c:16
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: bl.h:231
_In_ FLT_SET_CONTEXT_OPERATION _In_ PFLT_CONTEXT _Outptr_opt_result_maybenull_ PFLT_CONTEXT * OldContext
Definition: fltkernel.h:1468
USHORT Offset
Definition: ketypes.h:386
enum _BL_ARCH_MODE BL_ARCH_MODE
USHORT ExtendedOffset
Definition: ketypes.h:389
VOID BlpArchSwitchContext(_In_ BL_ARCH_MODE NewMode)
Definition: arch.c:166
Status
Definition: gdiplustypes.h:24
#define PKIDTENTRY
Definition: ketypes.h:480
__INTRIN_INLINE unsigned long __readcr0(void)
Definition: intrin_x86.h:1706
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1727
ULONG BlpApplicationFlags
Definition: bootlib.c:21
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
ULONG TranslationType
Definition: bl.h:759
#define _In_
Definition: no_sal2.h:204
#define BL_CONTEXT_INTERRUPTS_ON
Definition: bl.h:85
unsigned short USHORT
Definition: pedump.c:61
#define CR4_PAE
Definition: ketypes.h:89
VOID DECLSPEC_NORETURN ArchTrapNoProcess(VOID)
Definition: arch.c:23
_In_ FLT_SET_CONTEXT_OPERATION _In_ PFLT_CONTEXT NewContext
Definition: fltkernel.h:1468
PBL_ARCH_CONTEXT CurrentExecutionContext
Definition: arch.c:17
void __cdecl _disable(void)
Definition: intrin_arm.h:365
struct tagContext Context
Definition: acpixf.h:1034
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
BL_ARCH_MODE Mode
Definition: bl.h:1000
return STATUS_SUCCESS
Definition: btrfs.c:3014
USHORT Selector
Definition: ketypes.h:387
Definition: bl.h:233