ReactOS  r76032
winldr.c File Reference
#include <freeldr.h>
#include <debug.h>
#include <internal/arm/mm.h>
#include <internal/arm/intrin_i.h>
Include dependency graph for winldr.c:

Go to the source code of this file.

Classes

struct  _KPDR_PAGE
 

Macros

#define PFN_SHIFT   12
 
#define LARGE_PFN_SHIFT   20
 
#define PTE_BASE   0xC0000000
 
#define PDE_BASE   0xC0400000
 
#define PDR_BASE   0xFFD00000
 
#define VECTOR_BASE   0xFFFF0000
 
#define IDMAP_BASE   0x00000000
 
#define MMIO_BASE   0x10000000
 
#define LowMemPageTableIndex   (IDMAP_BASE >> PDE_SHIFT)
 
#define MmioPageTableIndex   (MMIO_BASE >> PDE_SHIFT)
 
#define KernelPageTableIndex   (KSEG0_BASE >> PDE_SHIFT)
 
#define StartupPtePageTableIndex   (PTE_BASE >> PDE_SHIFT)
 
#define StartupPdePageTableIndex   (PDE_BASE >> PDE_SHIFT)
 
#define PdrPageTableIndex   (PDR_BASE >> PDE_SHIFT)
 
#define VectorPageTableIndex   (VECTOR_BASE >> PDE_SHIFT)
 
#define PaToPfn(p)   ((p) >> PFN_SHIFT)
 
#define PaToLargePfn(p)   ((p) >> LARGE_PFN_SHIFT)
 
#define PaPtrToPfn(p)   (((ULONG_PTR)(p)) >> PFN_SHIFT)
 
#define PaPtrToPdePfn(p)   (((ULONG_PTR)(p)) >> CPT_SHIFT)
 

Typedefs

typedef struct _KPDR_PAGE KPDR_PAGE
 
typedef struct _KPDR_PAGEPKPDR_PAGE
 

Functions

 C_ASSERT (sizeof(KPDR_PAGE)==(1 *1024 *1024))
 
BOOLEAN MempSetupPaging (IN PFN_NUMBER StartPage, IN PFN_NUMBER NumberOfPages, IN BOOLEAN KernelMapping)
 
VOID MempUnmapPage (IN PFN_NUMBER Page)
 
VOID MempDump (VOID)
 
static BOOLEAN WinLdrMapSpecialPages (ULONG PcrBasePage)
 
VOID WinLdrSetupForNt (IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PVOID *GdtIdt, IN ULONG *PcrBasePage, IN ULONG *TssBasePage)
 
static BOOLEAN MempAllocatePageTables (VOID)
 
VOID WinLdrSetProcessorContext (VOID)
 
VOID WinLdrSetupMachineDependent (PLOADER_PARAMETER_BLOCK LoaderBlock)
 

Variables

PVOID MempPdrBaseAddress = (PVOID)0x70000
 
PVOID MempKernelBaseAddress = (PVOID)0
 
HARDWARE_PTE_ARMV6 TempPte
 
HARDWARE_LARGE_PTE_ARMV6 TempLargePte
 
HARDWARE_PDE_ARMV6 TempPde
 
PKPDR_PAGE PdrPage
 

Macro Definition Documentation

#define IDMAP_BASE   0x00000000

Definition at line 28 of file winldr.c.

Referenced by MempAllocatePageTables().

#define KernelPageTableIndex   (KSEG0_BASE >> PDE_SHIFT)

Definition at line 34 of file winldr.c.

Referenced by MempAllocatePageTables().

#define LARGE_PFN_SHIFT   20

Definition at line 17 of file winldr.c.

#define LowMemPageTableIndex   (IDMAP_BASE >> PDE_SHIFT)

Definition at line 32 of file winldr.c.

Referenced by MempAllocatePageTables().

#define MMIO_BASE   0x10000000

Definition at line 29 of file winldr.c.

Referenced by MempAllocatePageTables().

#define MmioPageTableIndex   (MMIO_BASE >> PDE_SHIFT)

Definition at line 33 of file winldr.c.

Referenced by MempAllocatePageTables().

#define PaPtrToPdePfn (   p)    (((ULONG_PTR)(p)) >> CPT_SHIFT)

Definition at line 54 of file winldr.c.

Referenced by MempAllocatePageTables(), and WinLdrMapSpecialPages().

#define PaPtrToPfn (   p)    (((ULONG_PTR)(p)) >> PFN_SHIFT)

Definition at line 51 of file winldr.c.

Referenced by MempAllocatePageTables(), and WinLdrMapSpecialPages().

#define PaToLargePfn (   p)    ((p) >> LARGE_PFN_SHIFT)

Definition at line 50 of file winldr.c.

Referenced by MempAllocatePageTables(), and WinLdrMapSpecialPages().

#define PaToPfn (   p)    ((p) >> PFN_SHIFT)

Definition at line 49 of file winldr.c.

#define PDR_BASE   0xFFD00000

Definition at line 21 of file winldr.c.

#define PdrPageTableIndex   (PDR_BASE >> PDE_SHIFT)

Definition at line 37 of file winldr.c.

Referenced by WinLdrMapSpecialPages().

#define PFN_SHIFT   12

Definition at line 16 of file winldr.c.

#define PTE_BASE   0xC0000000

Definition at line 19 of file winldr.c.

#define StartupPdePageTableIndex   (PDE_BASE >> PDE_SHIFT)

Definition at line 36 of file winldr.c.

Referenced by WinLdrMapSpecialPages().

#define StartupPtePageTableIndex   (PTE_BASE >> PDE_SHIFT)

Definition at line 35 of file winldr.c.

Referenced by WinLdrMapSpecialPages().

#define VECTOR_BASE   0xFFFF0000

Definition at line 22 of file winldr.c.

#define VectorPageTableIndex   (VECTOR_BASE >> PDE_SHIFT)

Definition at line 38 of file winldr.c.

Referenced by WinLdrMapSpecialPages().

Typedef Documentation

Function Documentation

C_ASSERT ( sizeof(KPDR_PAGE = =(1 *1024 *1024))
static BOOLEAN MempAllocatePageTables ( VOID  )
static

Definition at line 197 of file winldr.c.

198 {
199  ULONG i;
200  PHARDWARE_PTE_ARMV6 PointerPte;
201  PHARDWARE_PDE_ARMV6 PointerPde;
202  PHARDWARE_LARGE_PTE_ARMV6 LargePte;
203  PFN_NUMBER Pfn;
204 
205  /* Setup templates */
207 
208  /* Allocate the 1MB "PDR" (Processor Data Region). Must be 1MB aligned */
212 
213  /* Setup the Low Memory PDE as an identity-mapped Large Page (1MB) */
214  LargePte = &PdrPage->PageDir.Pte[LowMemPageTableIndex];
216  *LargePte = TempLargePte;
217 
218  /* Setup the MMIO PDE as two identity mapped large pages -- the kernel will blow these away later */
219  LargePte = &PdrPage->PageDir.Pte[MmioPageTableIndex];
220  Pfn = PaToLargePfn(MMIO_BASE);
221  for (i = 0; i < 2; i++)
222  {
224  *LargePte++ = TempLargePte;
225  }
226 
227  /* Setup the Kernel PDEs */
228  PointerPde = &PdrPage->PageDir.Pde[KernelPageTableIndex];
230  for (i = 0; i < 12; i++)
231  {
232  TempPde.PageFrameNumber = Pfn;
233  *PointerPde++ = TempPde;
234  Pfn++;
235  }
236 
237  /* Setup the Kernel PTEs */
238  PointerPte = PdrPage->KernelPageTable[0].Pte;
240  for (i = 0; i < 3072; i++)
241  {
242  TempPte.PageFrameNumber = Pfn++;
243  *PointerPte++ = TempPte;
244  }
245 
246  /* Done */
247  return TRUE;
248 }
#define TRUE
Definition: types.h:120
HARDWARE_PDE_ARMV6 Pde[4096]
Definition: hardware.h:52
#define LowMemPageTableIndex
Definition: winldr.c:32
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:77
PVOID MempPdrBaseAddress
Definition: winldr.c:41
HARDWARE_LARGE_PTE_ARMV6 Pte[4096]
Definition: hardware.h:53
#define MMIO_BASE
Definition: winldr.c:29
GLenum GLclampf GLint i
Definition: glfuncs.h:14
ULONG PFN_NUMBER
Definition: ke.h:8
#define PaPtrToPdePfn(p)
Definition: winldr.c:54
#define MmioPageTableIndex
Definition: winldr.c:33
PAGE_DIRECTORY_ARM PageDir
Definition: winldr.c:58
PVOID MempKernelBaseAddress
Definition: winldr.c:42
ULONG PageFrameNumber
Definition: mmtypes.h:74
PAGE_TABLE_ARM KernelPageTable[3]
Definition: winldr.c:60
#define KernelPageTableIndex
Definition: winldr.c:34
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
#define PaToLargePfn(p)
Definition: winldr.c:50
PKPDR_PAGE PdrPage
Definition: winldr.c:78
PVOID MmAllocateMemoryAtAddress(SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:85
HARDWARE_PTE_ARMV6 Pte[1024]
Definition: hardware.h:44
#define IDMAP_BASE
Definition: winldr.c:28
unsigned int ULONG
Definition: retypes.h:1
#define PaPtrToPfn(p)
Definition: winldr.c:51
ULONG PageFrameNumber
Definition: mmtypes.h:109
HARDWARE_LARGE_PTE_ARMV6 TempLargePte
Definition: winldr.c:76
VOID MempDump ( VOID  )

Definition at line 97 of file winldr.c.

98 {
99  return;
100 }
BOOLEAN MempSetupPaging ( IN PFN_NUMBER  StartPage,
IN PFN_NUMBER  NumberOfPages,
IN BOOLEAN  KernelMapping 
)

Definition at line 83 of file winldr.c.

86 {
87  return TRUE;
88 }
#define TRUE
Definition: types.h:120
VOID MempUnmapPage ( IN PFN_NUMBER  Page)

Definition at line 91 of file winldr.c.

92 {
93  return;
94 }
static BOOLEAN WinLdrMapSpecialPages ( ULONG  PcrBasePage)
static

Definition at line 104 of file winldr.c.

105 {
106  ULONG i;
107  PHARDWARE_PTE_ARMV6 PointerPte;
108  PHARDWARE_PDE_ARMV6 PointerPde;
109  PHARDWARE_LARGE_PTE_ARMV6 LargePte;
110  PFN_NUMBER Pfn;
111 
112  /* Setup the Startup PDE */
115  *LargePte = TempLargePte;
116 
117  /* Map-in the PDR */
118  LargePte = &PdrPage->PageDir.Pte[PdrPageTableIndex];
119  *LargePte = TempLargePte;
120 
121  /* After this point, any MiAddressToPde is guaranteed not to fault */
122 
123  /*
124  * Link them in the Startup PDE.
125  * Note these are the entries in the PD at (MiAddressToPde(PTE_BASE)).
126  */
129  for (i = 0; i < 4; i++)
130  {
131  TempPde.PageFrameNumber = Pfn++;
132  *PointerPde++ = TempPde;
133  }
134 
135  /*
136  * Now map these page tables in PTE space (MiAddressToPte(PTE_BASE)).
137  * Note that they all live on a single page, since each is 1KB.
138  */
139  PointerPte = &PdrPage->PageDirPageTable.Pte[0x300];
141  *PointerPte = TempPte;
142 
143  /*
144  * After this point, MiAddressToPte((PDE_BASE) to MiAddressToPte(PDE_TOP))
145  * is guaranteed not to fault.
146  * Any subsequent page allocation will first need its page table created
147  * and mapped in the PTE_BASE first, then the page table itself will be
148  * editable through its flat PTE address.
149  */
150 
151  /* Setup the Vector PDE */
152  PointerPde = &PdrPage->PageDir.Pde[VectorPageTableIndex];
154  *PointerPde = TempPde;
155 
156  /* Setup the Vector PTEs */
157  PointerPte = &PdrPage->VectorPageTable.Pte[0xF0];
159  *PointerPte = TempPte;
160 
161  /* TODO: Map in the kernel CPTs */
162  return TRUE;
163 }
#define TRUE
Definition: types.h:120
HARDWARE_PDE_ARMV6 Pde[4096]
Definition: hardware.h:52
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:77
HARDWARE_LARGE_PTE_ARMV6 Pte[4096]
Definition: hardware.h:53
uint32_t ULONG_PTR
Definition: typedefs.h:63
GLenum GLclampf GLint i
Definition: glfuncs.h:14
ULONG PFN_NUMBER
Definition: ke.h:8
#define PaPtrToPdePfn(p)
Definition: winldr.c:54
PAGE_DIRECTORY_ARM PageDir
Definition: winldr.c:58
ULONG PageFrameNumber
Definition: mmtypes.h:74
PAGE_TABLE_ARM PageDirPageTable
Definition: winldr.c:68
#define StartupPdePageTableIndex
Definition: winldr.c:36
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
#define PaToLargePfn(p)
Definition: winldr.c:50
PKPDR_PAGE PdrPage
Definition: winldr.c:78
HARDWARE_PTE_ARMV6 Pte[1024]
Definition: hardware.h:44
PAGE_TABLE_ARM VectorPageTable
Definition: winldr.c:69
#define VectorPageTableIndex
Definition: winldr.c:38
#define PdrPageTableIndex
Definition: winldr.c:37
unsigned int ULONG
Definition: retypes.h:1
#define PaPtrToPfn(p)
Definition: winldr.c:51
ULONG PageFrameNumber
Definition: mmtypes.h:109
#define StartupPtePageTableIndex
Definition: winldr.c:35
HARDWARE_LARGE_PTE_ARMV6 TempLargePte
Definition: winldr.c:76
VOID WinLdrSetProcessorContext ( VOID  )

Definition at line 251 of file winldr.c.

252 {
253  ARM_CONTROL_REGISTER ControlRegister;
254  ARM_TTB_REGISTER TtbRegister;
255  ARM_DOMAIN_REGISTER DomainRegister;
256 
257  /* Set the TTBR */
258  TtbRegister.AsUlong = (ULONG_PTR)&PdrPage->PageDir;
259  ASSERT(TtbRegister.Reserved == 0);
261 
262  /* Disable domains and simply use access bits on PTEs */
263  DomainRegister.AsUlong = 0;
264  DomainRegister.Domain0 = ClientDomain;
265  KeArmDomainRegisterSet(DomainRegister);
266 
267  /* Enable ARMv6+ paging (MMU), caches and the access bit */
268  ControlRegister = KeArmControlRegisterGet();
269  ControlRegister.MmuEnabled = TRUE;
270  ControlRegister.ICacheEnabled = TRUE;
271  ControlRegister.DCacheEnabled = TRUE;
272  ControlRegister.ForceAp = TRUE;
273  ControlRegister.ExtendedPageTables = TRUE;
274  KeArmControlRegisterSet(ControlRegister);
275 }
#define TRUE
Definition: types.h:120
FORCEINLINE VOID KeArmDomainRegisterSet(IN ARM_DOMAIN_REGISTER DomainRegister)
Definition: intrin_i.h:155
FORCEINLINE ARM_CONTROL_REGISTER KeArmControlRegisterGet(VOID)
Definition: intrin_i.h:18
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE VOID KeArmControlRegisterSet(IN ARM_CONTROL_REGISTER ControlRegister)
Definition: intrin_i.h:135
PAGE_DIRECTORY_ARM PageDir
Definition: winldr.c:58
PKPDR_PAGE PdrPage
Definition: winldr.c:78
ULONG ExtendedPageTables
Definition: ketypes.h:494
#define ULONG_PTR
Definition: config.h:101
FORCEINLINE VOID KeArmTranslationTableRegisterSet(IN ARM_TTB_REGISTER Ttb)
Definition: intrin_i.h:145
VOID WinLdrSetupForNt ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock,
IN PVOID GdtIdt,
IN ULONG PcrBasePage,
IN ULONG TssBasePage 
)

Definition at line 166 of file winldr.c.

170 {
171  PKPDR_PAGE PdrPage = (PVOID)0xFFD00000;
172 
173  /* Load cache information */
174  LoaderBlock->u.Arm.FirstLevelDcacheSize = FirstLevelDcacheSize;
175  LoaderBlock->u.Arm.FirstLevelDcacheFillSize = FirstLevelDcacheFillSize;
176  LoaderBlock->u.Arm.FirstLevelIcacheSize = FirstLevelIcacheSize;
177  LoaderBlock->u.Arm.FirstLevelIcacheFillSize = FirstLevelIcacheFillSize;
178  LoaderBlock->u.Arm.SecondLevelDcacheSize = SecondLevelDcacheSize;
179  LoaderBlock->u.Arm.SecondLevelDcacheFillSize = SecondLevelDcacheFillSize;
180  LoaderBlock->u.Arm.SecondLevelIcacheSize = SecondLevelIcacheSize;
181  LoaderBlock->u.Arm.SecondLevelIcacheFillSize = SecondLevelIcacheSize;
182 
183  /* Write initial context information */
184  LoaderBlock->KernelStack = (ULONG_PTR)PdrPage->KernelStack;
185  LoaderBlock->KernelStack += KERNEL_STACK_SIZE;
186  LoaderBlock->u.Arm.PanicStack = (ULONG_PTR)PdrPage->PanicStack;
187  LoaderBlock->u.Arm.PanicStack += KERNEL_STACK_SIZE;
188  LoaderBlock->u.Arm.InterruptStack = (ULONG_PTR)PdrPage->InterruptStack;
189  LoaderBlock->u.Arm.InterruptStack += KERNEL_STACK_SIZE;
190  LoaderBlock->Prcb = (ULONG_PTR)PdrPage->Prcb;
191  LoaderBlock->Process = (ULONG_PTR)PdrPage->InitialProcess;
192  LoaderBlock->Thread = (ULONG_PTR)PdrPage->InitialThread;
193 }
DWORD *typedef PVOID
Definition: winlogon.h:52
ULONG FirstLevelIcacheSize
Definition: macharm.c:25
ULONG FirstLevelDcacheSize
Definition: macharm.c:23
ULONG SecondLevelDcacheSize
Definition: macharm.c:27
uint32_t ULONG_PTR
Definition: typedefs.h:63
CHAR InitialProcess[PAGE_SIZE]
Definition: winldr.c:65
ULONG SecondLevelDcacheFillSize
Definition: macharm.c:28
#define KERNEL_STACK_SIZE
PKPDR_PAGE PdrPage
Definition: winldr.c:78
ULONG FirstLevelDcacheFillSize
Definition: macharm.c:24
ULONG SecondLevelIcacheSize
Definition: macharm.c:29
CHAR InitialThread[PAGE_SIZE]
Definition: winldr.c:66
CHAR KernelStack[KERNEL_STACK_SIZE]
Definition: winldr.c:62
#define ULONG_PTR
Definition: config.h:101
CHAR Prcb[PAGE_SIZE]
Definition: winldr.c:67
CHAR InterruptStack[KERNEL_STACK_SIZE]
Definition: winldr.c:64
ULONG FirstLevelIcacheFillSize
Definition: macharm.c:26
CHAR PanicStack[KERNEL_STACK_SIZE]
Definition: winldr.c:63
VOID WinLdrSetupMachineDependent ( PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 278 of file winldr.c.

280 {
281 }

Variable Documentation

PVOID MempKernelBaseAddress = (PVOID)0

Definition at line 42 of file winldr.c.

Referenced by MempAllocatePageTables().

PVOID MempPdrBaseAddress = (PVOID)0x70000

Definition at line 41 of file winldr.c.

Referenced by MempAllocatePageTables().

PKPDR_PAGE PdrPage

Definition at line 78 of file winldr.c.

Definition at line 76 of file winldr.c.

Referenced by MempAllocatePageTables(), and WinLdrMapSpecialPages().