ReactOS 0.4.15-dev-7788-g1ad9096
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
21VOID
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
38VOID
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 */
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
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
165VOID
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
188VOID
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*--*/
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) */
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
#define __GNUC__
Definition: _icc.h:38
LONG NTSTATUS
Definition: precomp.h:26
#define BL_APPLICATION_FLAG_CONVERTED_FROM_EFI
Definition: bl.h:51
@ BlPae
Definition: bl.h:232
@ BlNone
Definition: bl.h:230
ULONG BlpApplicationFlags
Definition: bootlib.c:21
BL_LIBRARY_PARAMETERS BlpLibraryParameters
Definition: bootlib.c:15
#define BL_CONTEXT_INTERRUPTS_ON
Definition: bl.h:84
#define BL_CONTEXT_PAGING_ON
Definition: bl.h:83
@ BlProtectedMode
Definition: bl.h:238
@ BlRealMode
Definition: bl.h:239
enum _BL_ARCH_MODE BL_ARCH_MODE
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ULONG_PTR
Definition: config.h:101
_In_ FLT_SET_CONTEXT_OPERATION _In_ PFLT_CONTEXT NewContext
Definition: fltkernel.h:1468
_In_ FLT_SET_CONTEXT_OPERATION _In_ PFLT_CONTEXT _Outptr_opt_result_maybenull_ PFLT_CONTEXT * OldContext
Definition: fltkernel.h:1469
Status
Definition: gdiplustypes.h:25
#define cs
Definition: i386-dis.c:442
VOID BlpArchEnableTranslation(VOID)
Definition: arch.c:189
NTSTATUS ArchInitializeContexts(VOID)
Definition: arch.c:122
VOID BlpArchSwitchContext(_In_ BL_ARCH_MODE NewMode)
Definition: arch.c:166
PBL_ARCH_CONTEXT CurrentExecutionContext
Definition: arch.c:17
NTSTATUS ArchInitializeContext(_In_ PBL_ARCH_CONTEXT Context)
Definition: arch.c:85
VOID ArchSwitchContext(_In_ PBL_ARCH_CONTEXT NewContext, _In_ PBL_ARCH_CONTEXT OldContext)
Definition: arch.c:39
VOID DECLSPEC_NORETURN ArchTrapNoProcess(VOID)
Definition: arch.c:23
BL_ARCH_CONTEXT ApplicationExecutionContext
Definition: arch.c:16
BL_ARCH_CONTEXT FirmwareExecutionContext
Definition: arch.c:15
NTSTATUS BlpArchInitialize(_In_ ULONG Phase)
Definition: arch.c:235
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
__INTRIN_INLINE void __lidt(void *Source)
Definition: intrin_x86.h:2018
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1825
__INTRIN_INLINE unsigned long __readcr0(void)
Definition: intrin_x86.h:1804
__INTRIN_INLINE void __writecr0(unsigned int Data)
Definition: intrin_x86.h:1789
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2023
__INTRIN_INLINE void __writecr4(unsigned int Data)
Definition: intrin_x86.h:1799
#define __assume(x)
Definition: intrin.h:108
#define _In_
Definition: ms_sal.h:308
#define CR0_PG
Definition: asm.h:255
#define CR4_PAE
Definition: ketypes.h:150
#define PKIDTENTRY
Definition: ketypes.h:550
#define CR4_FXSR
Definition: ketypes.h:153
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
unsigned short USHORT
Definition: pedump.c:61
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tmov %rdx, %rbp\n" "\tjmp *%rax\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $32, %rsp\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
#define STATUS_SUCCESS
Definition: shellext.h:65
BL_ARCH_MODE Mode
Definition: bl.h:999
ULONG TranslationType
Definition: bl.h:758
PVOID Base
Definition: ketypes.h:556
USHORT Offset
Definition: ketypes.h:440
USHORT Selector
Definition: ketypes.h:441
USHORT Access
Definition: ketypes.h:442
USHORT ExtendedOffset
Definition: ketypes.h:443
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59