ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

winldr.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Boot Loader
00003  * LICENSE:         BSD - See COPYING.ARM in the top level directory
00004  * FILE:            boot/freeldr/arch/arm/loader.c
00005  * PURPOSE:         ARM Kernel Loader
00006  * PROGRAMMERS:     ReactOS Portable Systems Group
00007  */
00008 
00009 /* INCLUDES ***************************************************************/
00010 
00011 #include <freeldr.h>
00012 #include <debug.h>
00013 #include <internal/arm/mm.h>
00014 #include <internal/arm/intrin_i.h>
00015 
00016 #define PFN_SHIFT                   12
00017 #define LARGE_PFN_SHIFT             20
00018 
00019 #define PTE_BASE                    0xC0000000
00020 #define PDE_BASE                    0xC0400000
00021 #define PDR_BASE                    0xFFD00000
00022 #define VECTOR_BASE                 0xFFFF0000
00023 
00024 #ifdef _ZOOM2_
00025 #define IDMAP_BASE                  0x81000000
00026 #define MMIO_BASE                   0x10000000
00027 #else
00028 #define IDMAP_BASE                  0x00000000
00029 #define MMIO_BASE                   0x10000000
00030 #endif
00031 
00032 #define LowMemPageTableIndex        (IDMAP_BASE >> PDE_SHIFT)
00033 #define MmioPageTableIndex          (MMIO_BASE >> PDE_SHIFT)
00034 #define KernelPageTableIndex        (KSEG0_BASE >> PDE_SHIFT)
00035 #define StartupPtePageTableIndex    (PTE_BASE >> PDE_SHIFT)
00036 #define StartupPdePageTableIndex    (PDE_BASE >> PDE_SHIFT)
00037 #define PdrPageTableIndex           (PDR_BASE >> PDE_SHIFT)
00038 #define VectorPageTableIndex        (VECTOR_BASE >> PDE_SHIFT)
00039 
00040 #ifndef _ZOOM2_
00041 PVOID MempPdrBaseAddress = (PVOID)0x70000;
00042 PVOID MempKernelBaseAddress = (PVOID)0;
00043 #else
00044 PVOID MempPdrBaseAddress = (PVOID)0x81100000;
00045 PVOID MempKernelBaseAddress = (PVOID)0x80000000;
00046 #endif
00047 
00048 /* Converts a Physical Address into a Page Frame Number */
00049 #define PaToPfn(p)                  ((p) >> PFN_SHIFT)
00050 #define PaToLargePfn(p)             ((p) >> LARGE_PFN_SHIFT)
00051 #define PaPtrToPfn(p)               (((ULONG_PTR)(p)) >> PFN_SHIFT)
00052 
00053 /* Converts a Physical Address into a Coarse Page Table PFN */
00054 #define PaPtrToPdePfn(p)            (((ULONG_PTR)(p)) >> CPT_SHIFT)
00055 
00056 typedef struct _KPDR_PAGE
00057 {
00058     PAGE_DIRECTORY_ARM PageDir;             // 0xC0400000 [0xFFD00000]
00059     CHAR HyperSpace[233 * PAGE_SIZE];       // 0xC0404000 [0xFFD04000]
00060     PAGE_TABLE_ARM KernelPageTable[3];      // 0xC04ED000 [0xFFDED000]
00061     CHAR SharedData[PAGE_SIZE];             // 0xC04F0000 [0xFFDF0000]
00062     CHAR KernelStack[KERNEL_STACK_SIZE];    // 0xC04F1000 [0xFFDF1000]
00063     CHAR PanicStack[KERNEL_STACK_SIZE];     // 0xC04F4000 [0xFFDF4000]
00064     CHAR InterruptStack[KERNEL_STACK_SIZE]; // 0xC04F7000 [0xFFDF7000]
00065     CHAR InitialProcess[PAGE_SIZE];         // 0xC04FA000 [0xFFDFA000]
00066     CHAR InitialThread[PAGE_SIZE];          // 0xC04FB000 [0xFFDFB000]
00067     CHAR Prcb[PAGE_SIZE];                   // 0xC04FC000 [0xFFDFC000]
00068     PAGE_TABLE_ARM PageDirPageTable;        // 0xC04FD000 [0xFFDFD000]
00069     PAGE_TABLE_ARM VectorPageTable;         // 0xC04FE000 [0xFFDFE000]
00070     CHAR Pcr[PAGE_SIZE];                    // 0xC04FF000 [0xFFDFF000]
00071 } KPDR_PAGE, *PKPDR_PAGE;
00072 
00073 C_ASSERT(sizeof(KPDR_PAGE) == (1 * 1024 * 1024));
00074 
00075 HARDWARE_PTE_ARMV6 TempPte;
00076 HARDWARE_LARGE_PTE_ARMV6 TempLargePte;
00077 HARDWARE_PDE_ARMV6 TempPde;
00078 PKPDR_PAGE PdrPage;
00079 
00080 /* FUNCTIONS **************************************************************/
00081 
00082 BOOLEAN
00083 MempSetupPaging(IN PFN_NUMBER StartPage,
00084                 IN PFN_COUNT NumberOfPages)
00085 {
00086     return TRUE;
00087 }
00088 
00089 VOID
00090 MempUnmapPage(IN PFN_NUMBER Page)
00091 {
00092     return;
00093 }
00094 
00095 VOID
00096 MempDump(VOID)
00097 {
00098     return;
00099 }
00100 
00101 BOOLEAN
00102 WinLdrMapSpecialPages(ULONG PcrBasePage)
00103 {
00104     ULONG i;
00105     PHARDWARE_PTE_ARMV6 PointerPte;
00106     PHARDWARE_PDE_ARMV6 PointerPde;
00107     PHARDWARE_LARGE_PTE_ARMV6 LargePte;
00108     PFN_NUMBER Pfn;
00109     
00110     /* Setup the Startup PDE */
00111     LargePte = &PdrPage->PageDir.Pte[StartupPdePageTableIndex];
00112     TempLargePte.PageFrameNumber = PaToLargePfn((ULONG_PTR)&PdrPage->PageDir);
00113     *LargePte = TempLargePte;
00114     
00115     /* Map-in the PDR */
00116     LargePte = &PdrPage->PageDir.Pte[PdrPageTableIndex];
00117     *LargePte = TempLargePte;
00118 
00119     /* After this point, any MiAddressToPde is guaranteed not to fault */
00120 
00121     /*
00122      * Link them in the Startup PDE.
00123      * Note these are the entries in the PD at (MiAddressToPde(PTE_BASE)).
00124      */
00125     PointerPde = &PdrPage->PageDir.Pde[StartupPtePageTableIndex];
00126     Pfn = PaPtrToPdePfn(&PdrPage->PageDirPageTable);
00127     for (i = 0; i < 4; i++)
00128     {
00129         TempPde.PageFrameNumber = Pfn++;
00130         *PointerPde++ = TempPde;
00131     }
00132 
00133     /* 
00134      * Now map these page tables in PTE space (MiAddressToPte(PTE_BASE)).
00135      * Note that they all live on a single page, since each is 1KB.
00136      */
00137     PointerPte = &PdrPage->PageDirPageTable.Pte[0x300];
00138     TempPte.PageFrameNumber = PaPtrToPfn(&PdrPage->PageDirPageTable);
00139     *PointerPte = TempPte;
00140 
00141     /*
00142      * After this point, MiAddressToPte((PDE_BASE) to MiAddressToPte(PDE_TOP))
00143      * is guaranteed not to fault.
00144      * Any subsequent page allocation will first need its page table created
00145      * and mapped in the PTE_BASE first, then the page table itself will be
00146      * editable through its flat PTE address.
00147      */
00148 
00149     /* Setup the Vector PDE */
00150     PointerPde = &PdrPage->PageDir.Pde[VectorPageTableIndex];
00151     TempPde.PageFrameNumber = PaPtrToPdePfn(&PdrPage->VectorPageTable);
00152     *PointerPde = TempPde;
00153 
00154     /* Setup the Vector PTEs */
00155     PointerPte = &PdrPage->VectorPageTable.Pte[0xF0];
00156     TempPte.PageFrameNumber = 0;
00157     *PointerPte = TempPte;
00158 
00159     /* TODO: Map in the kernel CPTs */ 
00160     return TRUE;
00161 }
00162 
00163 VOID
00164 WinLdrSetupForNt(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
00165                  IN PVOID *GdtIdt,
00166                  IN ULONG *PcrBasePage,
00167                  IN ULONG *TssBasePage)
00168 {
00169     PKPDR_PAGE PdrPage = (PVOID)0xFFD00000;
00170 
00171     /* Load cache information */
00172     LoaderBlock->u.Arm.FirstLevelDcacheSize = FirstLevelDcacheSize;
00173     LoaderBlock->u.Arm.FirstLevelDcacheFillSize = FirstLevelDcacheFillSize;
00174     LoaderBlock->u.Arm.FirstLevelIcacheSize = FirstLevelIcacheSize;
00175     LoaderBlock->u.Arm.FirstLevelIcacheFillSize = FirstLevelIcacheFillSize;
00176     LoaderBlock->u.Arm.SecondLevelDcacheSize = SecondLevelDcacheSize;
00177     LoaderBlock->u.Arm.SecondLevelDcacheFillSize = SecondLevelDcacheFillSize;
00178     LoaderBlock->u.Arm.SecondLevelIcacheSize = SecondLevelIcacheSize;
00179     LoaderBlock->u.Arm.SecondLevelIcacheFillSize = SecondLevelIcacheSize;
00180     
00181     /* Write initial context information */
00182     LoaderBlock->KernelStack = (ULONG_PTR)PdrPage->KernelStack;
00183     LoaderBlock->KernelStack += KERNEL_STACK_SIZE;
00184     LoaderBlock->u.Arm.PanicStack = (ULONG_PTR)PdrPage->PanicStack;
00185     LoaderBlock->u.Arm.PanicStack += KERNEL_STACK_SIZE;
00186     LoaderBlock->u.Arm.InterruptStack = (ULONG_PTR)PdrPage->InterruptStack;
00187     LoaderBlock->u.Arm.InterruptStack += KERNEL_STACK_SIZE;
00188     LoaderBlock->Prcb = (ULONG_PTR)PdrPage->Prcb;
00189     LoaderBlock->Process = (ULONG_PTR)PdrPage->InitialProcess;
00190     LoaderBlock->Thread = (ULONG_PTR)PdrPage->InitialThread;
00191 }
00192 
00193 BOOLEAN
00194 MempAllocatePageTables(VOID)
00195 {
00196     ULONG i;
00197     PHARDWARE_PTE_ARMV6 PointerPte;
00198     PHARDWARE_PDE_ARMV6 PointerPde;
00199     PHARDWARE_LARGE_PTE_ARMV6 LargePte;
00200     PFN_NUMBER Pfn;
00201 
00202     /* Setup templates */
00203     TempPte.Sbo = TempPte.Valid = TempLargePte.LargePage = TempLargePte.Sbo = TempPde.Valid = 1;
00204 
00205     /* Allocate the 1MB "PDR" (Processor Data Region). Must be 1MB aligned */
00206     PdrPage = MmAllocateMemoryAtAddress(sizeof(KPDR_PAGE),
00207                                         MempPdrBaseAddress,
00208                                         LoaderMemoryData);
00209 
00210     /* Setup the Low Memory PDE as an identity-mapped Large Page (1MB) */
00211     LargePte = &PdrPage->PageDir.Pte[LowMemPageTableIndex];
00212     TempLargePte.PageFrameNumber = PaToLargePfn(IDMAP_BASE);
00213     *LargePte = TempLargePte;
00214 
00215     /* Setup the MMIO PDE as two identity mapped large pages -- the kernel will blow these away later */
00216     LargePte = &PdrPage->PageDir.Pte[MmioPageTableIndex];
00217     Pfn = PaToLargePfn(MMIO_BASE);
00218     for (i = 0; i < 2; i++)
00219     {
00220         TempLargePte.PageFrameNumber = Pfn++;
00221         *LargePte++ = TempLargePte;
00222     }
00223 
00224     /* Setup the Kernel PDEs */
00225     PointerPde = &PdrPage->PageDir.Pde[KernelPageTableIndex];
00226     Pfn = PaPtrToPdePfn(PdrPage->KernelPageTable);
00227     for (i = 0; i < 12; i++)
00228     {
00229         TempPde.PageFrameNumber = Pfn;
00230         *PointerPde++ = TempPde;
00231         Pfn++;
00232     }
00233 
00234     /* Setup the Kernel PTEs */
00235     PointerPte = PdrPage->KernelPageTable[0].Pte;
00236     Pfn = PaPtrToPfn(MempKernelBaseAddress);
00237     for (i = 0; i < 3072; i++)
00238     {
00239         TempPte.PageFrameNumber = Pfn++;
00240         *PointerPte++ = TempPte;
00241     }
00242 
00243     /* Done */
00244     return TRUE;
00245 }
00246 
00247 VOID
00248 WinLdrSetProcessorContext(PVOID GdtIdt,
00249                           IN ULONG Pcr,
00250                           IN ULONG Tss)
00251 {    
00252     ARM_CONTROL_REGISTER ControlRegister;
00253     ARM_TTB_REGISTER TtbRegister;
00254     ARM_DOMAIN_REGISTER DomainRegister;
00255     
00256     /* Set the TTBR */
00257     TtbRegister.AsUlong = (ULONG_PTR)&PdrPage->PageDir;
00258     ASSERT(TtbRegister.Reserved == 0);
00259     KeArmTranslationTableRegisterSet(TtbRegister);
00260 
00261     /* Disable domains and simply use access bits on PTEs */
00262     DomainRegister.AsUlong = 0;
00263     DomainRegister.Domain0 = ClientDomain;
00264     KeArmDomainRegisterSet(DomainRegister);
00265 
00266     /* Enable ARMv6+ paging (MMU), caches and the access bit */
00267     ControlRegister = KeArmControlRegisterGet();
00268     ControlRegister.MmuEnabled = TRUE;
00269     ControlRegister.ICacheEnabled = TRUE;
00270     ControlRegister.DCacheEnabled = TRUE;
00271     ControlRegister.ForceAp = TRUE;
00272     ControlRegister.ExtendedPageTables = TRUE;
00273     KeArmControlRegisterSet(ControlRegister); 
00274 }

Generated on Sat May 26 2012 04:17:51 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.