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:         EFI Windows Loader
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            freeldr/winldr/i386/wlmemory.c
00005  * PURPOSE:         Memory related routines
00006  * PROGRAMMERS:     Aleksey Bragin (aleksey@reactos.org)
00007  */
00008 
00009 /* INCLUDES ***************************************************************/
00010 
00011 #include <freeldr.h>
00012 
00013 #include <ndk/asm.h>
00014 #include <debug.h>
00015 
00016 // This is needed because headers define wrong one for ReactOS
00017 #undef KIP0PCRADDRESS
00018 #define KIP0PCRADDRESS                      0xffdff000
00019 
00020 #define HYPER_SPACE_ENTRY       0x300
00021 
00022 // This is needed only for SetProcessorContext routine
00023 #pragma pack(2)
00024     typedef struct
00025     {
00026         USHORT Limit;
00027         ULONG Base;
00028     } GDTIDT;
00029 #pragma pack(4)
00030 
00031 DBG_DEFAULT_CHANNEL(WINDOWS);
00032 
00033 /* GLOBALS ***************************************************************/
00034 
00035 PHARDWARE_PTE PDE;
00036 PHARDWARE_PTE HalPageTable;
00037 
00038 PUCHAR PhysicalPageTablesBuffer;
00039 PUCHAR KernelPageTablesBuffer;
00040 ULONG PhysicalPageTables;
00041 ULONG KernelPageTables;
00042 
00043 ULONG PcrBasePage;
00044 ULONG TssBasePage;
00045 PVOID GdtIdt;
00046 
00047 /* FUNCTIONS **************************************************************/
00048 
00049 BOOLEAN
00050 MempAllocatePageTables()
00051 {
00052     ULONG NumPageTables, TotalSize;
00053     PUCHAR Buffer;
00054     // It's better to allocate PDE + PTEs contigiuos
00055 
00056     // Max number of entries = MaxPageNum >> 10
00057     // FIXME: This is a number to describe ALL physical memory
00058     // and windows doesn't expect ALL memory mapped...
00059     NumPageTables = TotalPagesInLookupTable >> 10;
00060 
00061     TRACE("NumPageTables = %d\n", NumPageTables);
00062 
00063     // Allocate memory block for all these things:
00064     // PDE, HAL mapping page table, physical mapping, kernel mapping
00065     TotalSize = (1 + 1 + NumPageTables * 2) * MM_PAGE_SIZE;
00066 
00067     // PDE+HAL+KernelPTEs == MemoryData
00068     Buffer = MmAllocateMemoryWithType(TotalSize, LoaderMemoryData);
00069 
00070     // Physical PTEs = FirmwareTemporary
00071     PhysicalPageTablesBuffer = (PUCHAR)Buffer + TotalSize - NumPageTables*MM_PAGE_SIZE;
00072     MmSetMemoryType(PhysicalPageTablesBuffer,
00073                     NumPageTables*MM_PAGE_SIZE,
00074                     LoaderFirmwareTemporary);
00075 
00076     // This check is now redundant
00077     if (Buffer + (TotalSize - NumPageTables*MM_PAGE_SIZE) !=
00078         PhysicalPageTablesBuffer)
00079     {
00080         TRACE("There was a problem allocating two adjacent blocks of memory!");
00081     }
00082 
00083     if (Buffer == NULL || PhysicalPageTablesBuffer == NULL)
00084     {
00085         UiMessageBox("Impossible to allocate memory block for page tables!");
00086         return FALSE;
00087     }
00088 
00089     // Zero all this memory block
00090     RtlZeroMemory(Buffer, TotalSize);
00091 
00092     // Set up pointers correctly now
00093     PDE = (PHARDWARE_PTE)Buffer;
00094 
00095     // Map the page directory at 0xC0000000 (maps itself)
00096     PDE[HYPER_SPACE_ENTRY].PageFrameNumber = (ULONG)PDE >> MM_PAGE_SHIFT;
00097     PDE[HYPER_SPACE_ENTRY].Valid = 1;
00098     PDE[HYPER_SPACE_ENTRY].Write = 1;
00099 
00100     // The last PDE slot is allocated for HAL's memory mapping (Virtual Addresses 0xFFC00000 - 0xFFFFFFFF)
00101     HalPageTable = (PHARDWARE_PTE)&Buffer[MM_PAGE_SIZE*1];
00102 
00103     // Map it
00104     PDE[1023].PageFrameNumber = (ULONG)HalPageTable >> MM_PAGE_SHIFT;
00105     PDE[1023].Valid = 1;
00106     PDE[1023].Write = 1;
00107 
00108     // Store pointer to the table for easier access
00109     KernelPageTablesBuffer = &Buffer[MM_PAGE_SIZE*2];
00110 
00111     // Zero counters of page tables used
00112     PhysicalPageTables = 0;
00113     KernelPageTables = 0;
00114 
00115     return TRUE;
00116 }
00117 
00118 VOID
00119 MempAllocatePTE(ULONG Entry, PHARDWARE_PTE *PhysicalPT, PHARDWARE_PTE *KernelPT)
00120 {
00121     //Print(L"Creating PDE Entry %X\n", Entry);
00122 
00123     // Identity mapping
00124     *PhysicalPT = (PHARDWARE_PTE)&PhysicalPageTablesBuffer[PhysicalPageTables*MM_PAGE_SIZE];
00125     PhysicalPageTables++;
00126 
00127     PDE[Entry].PageFrameNumber = (ULONG)*PhysicalPT >> MM_PAGE_SHIFT;
00128     PDE[Entry].Valid = 1;
00129     PDE[Entry].Write = 1;
00130 
00131     if (Entry+(KSEG0_BASE >> 22) > 1023)
00132     {
00133         TRACE("WARNING! Entry: %X > 1023\n", Entry+(KSEG0_BASE >> 22));
00134     }
00135 
00136     // Kernel-mode mapping
00137     *KernelPT = (PHARDWARE_PTE)&KernelPageTablesBuffer[KernelPageTables*MM_PAGE_SIZE];
00138     KernelPageTables++;
00139 
00140     PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber = ((ULONG)*KernelPT >> MM_PAGE_SHIFT);
00141     PDE[Entry+(KSEG0_BASE >> 22)].Valid = 1;
00142     PDE[Entry+(KSEG0_BASE >> 22)].Write = 1;
00143 }
00144 
00145 BOOLEAN
00146 MempSetupPaging(IN PFN_NUMBER StartPage,
00147         IN PFN_COUNT NumberOfPages,
00148         IN BOOLEAN KernelMapping)
00149 {
00150     PHARDWARE_PTE PhysicalPT;
00151     PHARDWARE_PTE KernelPT;
00152     PFN_COUNT Entry, Page;
00153 
00154     TRACE("MempSetupPaging: SP 0x%X, Number: 0x%X, Kernel: %s\n",
00155        StartPage, NumberOfPages, KernelMapping ? "yes" : "no");
00156 
00157     // HACK
00158     if (StartPage+NumberOfPages >= 0x80000)
00159     {
00160         //
00161         // We can't map this as it requires more than 1 PDE
00162         // and in fact it's not possible at all ;)
00163         //
00164         //Print(L"skipping...\n");
00165         return TRUE;
00166     }
00167 
00168     //
00169     // Now actually set up the page tables for identity mapping
00170     //
00171     for (Page = StartPage; Page < StartPage + NumberOfPages; Page++)
00172     {
00173         Entry = Page >> 10;
00174 
00175         if (((PULONG)PDE)[Entry] == 0)
00176         {
00177             MempAllocatePTE(Entry, &PhysicalPT, &KernelPT);
00178         }
00179         else
00180         {
00181             PhysicalPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT);
00182             KernelPT = (PHARDWARE_PTE)(PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber << MM_PAGE_SHIFT);
00183         }
00184 
00185         PhysicalPT[Page & 0x3ff].PageFrameNumber = Page;
00186         PhysicalPT[Page & 0x3ff].Valid = (Page != 0);
00187         PhysicalPT[Page & 0x3ff].Write = (Page != 0);
00188 
00189         if (KernelMapping)
00190         {
00191              if (KernelPT[Page & 0x3ff].Valid) WARN("xxx already mapped \n");
00192             KernelPT[Page & 0x3ff].PageFrameNumber = Page;
00193             KernelPT[Page & 0x3ff].Valid = (Page != 0);
00194             KernelPT[Page & 0x3ff].Write = (Page != 0);
00195         }
00196     }
00197 
00198     return TRUE;
00199 }
00200 
00201 VOID
00202 MempUnmapPage(PFN_NUMBER Page)
00203 {
00204     PHARDWARE_PTE KernelPT;
00205     PFN_NUMBER Entry = (Page >> 10) + (KSEG0_BASE >> 22);
00206 
00207     /* Don't unmap hyperspace or HAL entries */
00208     if (Entry == HYPER_SPACE_ENTRY || Entry == 1023)
00209         return;
00210 
00211     if (PDE[Entry].Valid)
00212     {
00213         KernelPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT);
00214 
00215         if (KernelPT)
00216         {
00217             KernelPT[Page & 0x3ff].PageFrameNumber = 0;
00218             KernelPT[Page & 0x3ff].Valid = 0;
00219             KernelPT[Page & 0x3ff].Write = 0;
00220         }
00221     }
00222 }
00223 
00224 VOID
00225 WinLdrpMapApic()
00226 {
00227     BOOLEAN LocalAPIC;
00228     LARGE_INTEGER MsrValue;
00229     ULONG APICAddress, CpuInfo[4];
00230 
00231     /* Check if we have a local APIC */
00232     __cpuid((int*)CpuInfo, 1);
00233     LocalAPIC = (((CpuInfo[3] >> 9) & 1) != 0);
00234 
00235     /* If there is no APIC, just return */
00236     if (!LocalAPIC)
00237         return;
00238 
00239     /* Read the APIC Address */
00240     MsrValue.QuadPart = __readmsr(0x1B);
00241     APICAddress = (MsrValue.LowPart & 0xFFFFF000);
00242 
00243     TRACE("Local APIC detected at address 0x%x\n",
00244         APICAddress);
00245 
00246     /* Map it */
00247     HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber
00248         = APICAddress >> MM_PAGE_SHIFT;
00249     HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
00250     HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
00251     HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].WriteThrough = 1;
00252     HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].CacheDisable = 1;
00253 }
00254 
00255 BOOLEAN
00256 WinLdrMapSpecialPages(void)
00257 {
00258 
00259     //VideoDisplayString(L"Hello from VGA, going into the kernel\n");
00260     TRACE("HalPageTable: 0x%X\n", HalPageTable);
00261 
00262     // Page Tables have been setup, make special handling for PCR and TSS
00263     // (which is done in BlSetupFotNt in usual ntldr)
00264     HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage+1;
00265     HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
00266     HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
00267 
00268     HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage;
00269     HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
00270     HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
00271 
00272     // Map APIC
00273     WinLdrpMapApic();
00274 
00275     // Map VGA memory
00276     //VideoMemoryBase = MmMapIoSpace(0xb8000, 4000, MmNonCached);
00277     //TRACE("VideoMemoryBase: 0x%X\n", VideoMemoryBase);
00278 
00279     return TRUE;
00280 }
00281 
00282 #define ExtendedBIOSDataArea ((PULONG)0x740)
00283 #define ExtendedBIOSDataSize ((PULONG)0x744)
00284 #define RomFontPointers ((PULONG)0x700)
00285 
00286 enum
00287 {
00288     INT1FhFont = 0x00,
00289     INT43hFont = 0x01,
00290     ROM_8x14CharacterFont = 0x02,
00291     ROM_8x8DoubleDotFontLo = 0x03,
00292     ROM_8x8DoubleDotFontHi = 0x04,
00293     ROM_AlphaAlternate = 0x05,
00294     ROM_8x16Font = 0x06,
00295     ROM_Alternate9x16Font = 0x07,
00296     UltraVision_8x20Font = 0x11,
00297     UltraVision_8x10Font = 0x12,
00298 };
00299 
00300 void WinLdrSetupSpecialDataPointers()
00301 {
00302     REGS BiosRegs;
00303 
00304     /* Get the address of the bios rom fonts. Win 2003 videoprt reads these
00305        values from address 0x700 .. 0x718 and store them in the registry
00306        in HKLM\System\CurrentControlSet\Control\Wow\RomFontPointers
00307        Int 10h, AX=1130h, BH = pointer specifier
00308        returns: es:bp = address */
00309     BiosRegs.d.eax = 0x1130;
00310     BiosRegs.b.bh = ROM_8x14CharacterFont;
00311     Int386(0x10, &BiosRegs, &BiosRegs);
00312     RomFontPointers[0] = BiosRegs.w.es << 4 | BiosRegs.w.bp;
00313 
00314     BiosRegs.b.bh = ROM_8x8DoubleDotFontLo;
00315     Int386(0x10, &BiosRegs, &BiosRegs);
00316     RomFontPointers[1] = BiosRegs.w.es << 16 | BiosRegs.w.bp;
00317 
00318     BiosRegs.b.bh = ROM_8x8DoubleDotFontHi;
00319     Int386(0x10, &BiosRegs, &BiosRegs);
00320     RomFontPointers[2] = BiosRegs.w.es << 16 | BiosRegs.w.bp;
00321 
00322     BiosRegs.b.bh = ROM_AlphaAlternate;
00323     Int386(0x10, &BiosRegs, &BiosRegs);
00324     RomFontPointers[3] = BiosRegs.w.es << 16 | BiosRegs.w.bp;
00325 
00326     BiosRegs.b.bh = ROM_8x16Font;
00327     Int386(0x10, &BiosRegs, &BiosRegs);
00328     RomFontPointers[4] = BiosRegs.w.es << 16 | BiosRegs.w.bp;
00329 
00330     BiosRegs.b.bh = ROM_Alternate9x16Font;
00331     Int386(0x10, &BiosRegs, &BiosRegs);
00332     RomFontPointers[5] = BiosRegs.w.es << 16 | BiosRegs.w.bp;
00333 
00334     /* Store address of the extended bios data area in 0x740 */
00335     BiosRegs.d.eax = 0xC100;
00336     Int386(0x15, &BiosRegs, &BiosRegs);
00337     if (INT386_SUCCESS(BiosRegs))
00338     {
00339         *ExtendedBIOSDataArea = BiosRegs.w.es << 4;
00340         *ExtendedBIOSDataSize = 1024;
00341         TRACE("*ExtendedBIOSDataArea = 0x%lx\n", *ExtendedBIOSDataArea);
00342     }
00343     else
00344     {
00345         WARN("Couldn't get address of extended BIOS data area\n");
00346         *ExtendedBIOSDataArea = 0;
00347         *ExtendedBIOSDataSize = 0;
00348     }
00349 }
00350 
00351 void WinLdrSetupMachineDependent(PLOADER_PARAMETER_BLOCK LoaderBlock)
00352 {
00353     ULONG TssSize;
00354     //ULONG TssPages;
00355     ULONG_PTR Pcr = 0;
00356     ULONG_PTR Tss = 0;
00357     ULONG BlockSize, NumPages;
00358 
00359     LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support
00360     LoaderBlock->u.I386.MachineType = MACHINE_TYPE_ISA;
00361 
00362     /* Allocate 2 pages for PCR */
00363     Pcr = (ULONG_PTR)MmAllocateMemoryWithType(2 * MM_PAGE_SIZE, LoaderStartupPcrPage);
00364     PcrBasePage = Pcr >> MM_PAGE_SHIFT;
00365 
00366     if (Pcr == 0)
00367     {
00368         UiMessageBox("Can't allocate PCR\n");
00369         return;
00370     }
00371 
00372     /* Allocate TSS */
00373     TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1);
00374     //TssPages = TssSize / MM_PAGE_SIZE;
00375 
00376     Tss = (ULONG_PTR)MmAllocateMemoryWithType(TssSize, LoaderMemoryData);
00377 
00378     TssBasePage = Tss >> MM_PAGE_SHIFT;
00379 
00380     /* Allocate space for new GDT + IDT */
00381     BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here?
00382     NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT;
00383     GdtIdt = (PKGDTENTRY)MmAllocateMemoryWithType(NumPages * MM_PAGE_SIZE, LoaderMemoryData);
00384 
00385     if (GdtIdt == NULL)
00386     {
00387         UiMessageBox("Can't allocate pages for GDT+IDT!\n");
00388         return;
00389     }
00390 
00391     /* Zero newly prepared GDT+IDT */
00392     RtlZeroMemory(GdtIdt, NumPages << MM_PAGE_SHIFT);
00393 
00394     // Before we start mapping pages, create a block of memory, which will contain
00395     // PDE and PTEs
00396     if (MempAllocatePageTables() == FALSE)
00397     {
00398         BugCheck("MempAllocatePageTables failed!\n");
00399     }
00400 
00401     /* Map stuff like PCR, KI_USER_SHARED_DATA and Apic */
00402     WinLdrMapSpecialPages();
00403 
00404     /* Set some special fields */
00405     WinLdrSetupSpecialDataPointers();
00406 }
00407 
00408 
00409 VOID
00410 WinLdrSetProcessorContext(void)
00411 {
00412     GDTIDT GdtDesc, IdtDesc, OldIdt;
00413     PKGDTENTRY  pGdt;
00414     PKIDTENTRY  pIdt;
00415     USHORT Ldt = 0;
00416     ULONG Pcr;
00417     ULONG Tss;
00418     //ULONG i;
00419 
00420     Pcr = KIP0PCRADDRESS;
00421     Tss = KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT);
00422 
00423     TRACE("GDtIdt %p, Pcr %p, Tss 0x%08X\n",
00424         GdtIdt, Pcr, Tss);
00425 
00426     // Enable paging
00427     //BS->ExitBootServices(ImageHandle,MapKey);
00428 
00429     // Disable Interrupts
00430     _disable();
00431 
00432     // Re-initalize EFLAGS
00433     __writeeflags(0);
00434 
00435     // Set the PDBR
00436     __writecr3((ULONG_PTR)PDE);
00437 
00438     // Enable paging by modifying CR0
00439     __writecr0(__readcr0() | CR0_PG);
00440 
00441     // Kernel expects the PCR to be zero-filled on startup
00442     // FIXME: Why zero it here when we can zero it right after allocation?
00443     RtlZeroMemory((PVOID)Pcr, MM_PAGE_SIZE); //FIXME: Why zero only 1 page when we allocate 2?
00444 
00445     // Get old values of GDT and IDT
00446     Ke386GetGlobalDescriptorTable(&GdtDesc);
00447     __sidt(&IdtDesc);
00448 
00449     // Save old IDT
00450     OldIdt.Base = IdtDesc.Base;
00451     OldIdt.Limit = IdtDesc.Limit;
00452 
00453     // Prepare new IDT+GDT
00454     GdtDesc.Base  = KSEG0_BASE | (ULONG_PTR)GdtIdt;
00455     GdtDesc.Limit = NUM_GDT * sizeof(KGDTENTRY) - 1;
00456     IdtDesc.Base  = (ULONG)((PUCHAR)GdtDesc.Base + GdtDesc.Limit + 1);
00457     IdtDesc.Limit = NUM_IDT * sizeof(KIDTENTRY) - 1;
00458 
00459     // ========================
00460     // Fill all descriptors now
00461     // ========================
00462 
00463     pGdt = (PKGDTENTRY)GdtDesc.Base;
00464     pIdt = (PKIDTENTRY)IdtDesc.Base;
00465 
00466     //
00467     // Code selector (0x8)
00468     // Flat 4Gb
00469     //
00470     pGdt[1].LimitLow                = 0xFFFF;
00471     pGdt[1].BaseLow                 = 0;
00472     pGdt[1].HighWord.Bytes.BaseMid  = 0;
00473     pGdt[1].HighWord.Bytes.Flags1   = 0x9A;
00474     pGdt[1].HighWord.Bytes.Flags2   = 0xCF;
00475     pGdt[1].HighWord.Bytes.BaseHi   = 0;
00476 
00477     //
00478     // Data selector (0x10)
00479     // Flat 4Gb
00480     //
00481     pGdt[2].LimitLow                = 0xFFFF;
00482     pGdt[2].BaseLow                 = 0;
00483     pGdt[2].HighWord.Bytes.BaseMid  = 0;
00484     pGdt[2].HighWord.Bytes.Flags1   = 0x92;
00485     pGdt[2].HighWord.Bytes.Flags2   = 0xCF;
00486     pGdt[2].HighWord.Bytes.BaseHi   = 0;
00487 
00488     //
00489     // Selector (0x18)
00490     // Flat 2Gb
00491     //
00492     pGdt[3].LimitLow                = 0xFFFF;
00493     pGdt[3].BaseLow                 = 0;
00494     pGdt[3].HighWord.Bytes.BaseMid  = 0;
00495     pGdt[3].HighWord.Bytes.Flags1   = 0xFA;
00496     pGdt[3].HighWord.Bytes.Flags2   = 0xCF;
00497     pGdt[3].HighWord.Bytes.BaseHi   = 0;
00498 
00499     //
00500     // Selector (0x20)
00501     // Flat 2Gb
00502     //
00503     pGdt[4].LimitLow                = 0xFFFF;
00504     pGdt[4].BaseLow                 = 0;
00505     pGdt[4].HighWord.Bytes.BaseMid  = 0;
00506     pGdt[4].HighWord.Bytes.Flags1   = 0xF2;
00507     pGdt[4].HighWord.Bytes.Flags2   = 0xCF;
00508     pGdt[4].HighWord.Bytes.BaseHi   = 0;
00509 
00510     //
00511     // TSS Selector (0x28)
00512     //
00513     pGdt[5].LimitLow                = 0x78-1; //FIXME: Check this
00514     pGdt[5].BaseLow = (USHORT)(Tss & 0xffff);
00515     pGdt[5].HighWord.Bytes.BaseMid = (UCHAR)((Tss >> 16) & 0xff);
00516     pGdt[5].HighWord.Bytes.Flags1   = 0x89;
00517     pGdt[5].HighWord.Bytes.Flags2   = 0x00;
00518     pGdt[5].HighWord.Bytes.BaseHi  = (UCHAR)((Tss >> 24) & 0xff);
00519 
00520     //
00521     // PCR Selector (0x30)
00522     //
00523     pGdt[6].LimitLow                = 0x01;
00524     pGdt[6].BaseLow  = (USHORT)(Pcr & 0xffff);
00525     pGdt[6].HighWord.Bytes.BaseMid = (UCHAR)((Pcr >> 16) & 0xff);
00526     pGdt[6].HighWord.Bytes.Flags1   = 0x92;
00527     pGdt[6].HighWord.Bytes.Flags2   = 0xC0;
00528     pGdt[6].HighWord.Bytes.BaseHi  = (UCHAR)((Pcr >> 24) & 0xff);
00529 
00530     //
00531     // Selector (0x38)
00532     //
00533     pGdt[7].LimitLow                = 0xFFFF;
00534     pGdt[7].BaseLow                 = 0;
00535     pGdt[7].HighWord.Bytes.BaseMid  = 0;
00536     pGdt[7].HighWord.Bytes.Flags1   = 0xF3;
00537     pGdt[7].HighWord.Bytes.Flags2   = 0x40;
00538     pGdt[7].HighWord.Bytes.BaseHi   = 0;
00539 
00540     //
00541     // Some BIOS stuff (0x40)
00542     //
00543     pGdt[8].LimitLow                = 0xFFFF;
00544     pGdt[8].BaseLow                 = 0x400;
00545     pGdt[8].HighWord.Bytes.BaseMid  = 0;
00546     pGdt[8].HighWord.Bytes.Flags1   = 0xF2;
00547     pGdt[8].HighWord.Bytes.Flags2   = 0x0;
00548     pGdt[8].HighWord.Bytes.BaseHi   = 0;
00549 
00550     //
00551     // Selector (0x48)
00552     //
00553     pGdt[9].LimitLow                = 0;
00554     pGdt[9].BaseLow                 = 0;
00555     pGdt[9].HighWord.Bytes.BaseMid  = 0;
00556     pGdt[9].HighWord.Bytes.Flags1   = 0;
00557     pGdt[9].HighWord.Bytes.Flags2   = 0;
00558     pGdt[9].HighWord.Bytes.BaseHi   = 0;
00559 
00560     //
00561     // Selector (0x50)
00562     //
00563     pGdt[10].LimitLow               = 0xFFFF; //FIXME: Not correct!
00564     pGdt[10].BaseLow                = 0;
00565     pGdt[10].HighWord.Bytes.BaseMid = 0x2;
00566     pGdt[10].HighWord.Bytes.Flags1  = 0x89;
00567     pGdt[10].HighWord.Bytes.Flags2  = 0;
00568     pGdt[10].HighWord.Bytes.BaseHi  = 0;
00569 
00570     //
00571     // Selector (0x58)
00572     //
00573     pGdt[11].LimitLow               = 0xFFFF;
00574     pGdt[11].BaseLow                = 0;
00575     pGdt[11].HighWord.Bytes.BaseMid = 0x2;
00576     pGdt[11].HighWord.Bytes.Flags1  = 0x9A;
00577     pGdt[11].HighWord.Bytes.Flags2  = 0;
00578     pGdt[11].HighWord.Bytes.BaseHi  = 0;
00579 
00580     //
00581     // Selector (0x60)
00582     //
00583     pGdt[12].LimitLow               = 0xFFFF;
00584     pGdt[12].BaseLow                = 0; //FIXME: Maybe not correct, but noone cares
00585     pGdt[12].HighWord.Bytes.BaseMid = 0x2;
00586     pGdt[12].HighWord.Bytes.Flags1  = 0x92;
00587     pGdt[12].HighWord.Bytes.Flags2  = 0;
00588     pGdt[12].HighWord.Bytes.BaseHi  = 0;
00589 
00590     //
00591     // Video buffer Selector (0x68)
00592     //
00593     pGdt[13].LimitLow               = 0x3FFF;
00594     pGdt[13].BaseLow                = 0x8000;
00595     pGdt[13].HighWord.Bytes.BaseMid = 0x0B;
00596     pGdt[13].HighWord.Bytes.Flags1  = 0x92;
00597     pGdt[13].HighWord.Bytes.Flags2  = 0;
00598     pGdt[13].HighWord.Bytes.BaseHi  = 0;
00599 
00600     //
00601     // Points to GDT (0x70)
00602     //
00603     pGdt[14].LimitLow               = NUM_GDT*sizeof(KGDTENTRY) - 1;
00604     pGdt[14].BaseLow                = 0x7000;
00605     pGdt[14].HighWord.Bytes.BaseMid = 0xFF;
00606     pGdt[14].HighWord.Bytes.Flags1  = 0x92;
00607     pGdt[14].HighWord.Bytes.Flags2  = 0;
00608     pGdt[14].HighWord.Bytes.BaseHi  = 0xFF;
00609 
00610     //
00611     // Some unused descriptors should go here
00612     //
00613 
00614     // Copy the old IDT
00615     RtlCopyMemory(pIdt, (PVOID)OldIdt.Base, OldIdt.Limit + 1);
00616 
00617     // Mask interrupts
00618     //asm("cli\n"); // they are already masked before enabling paged mode
00619 
00620     // Load GDT+IDT
00621     Ke386SetGlobalDescriptorTable(&GdtDesc);
00622     __lidt(&IdtDesc);
00623 
00624     // Jump to proper CS and clear prefetch queue
00625 #if defined(__GNUC__)
00626     asm("ljmp   $0x08, $1f\n"
00627         "1:\n");
00628 #elif defined(_MSC_VER)
00629     /* We can't express the above in MASM so we use this far return instead */
00630     __asm
00631     {
00632         push 8
00633         push offset resume
00634         retf
00635         resume:
00636     };
00637 #else
00638 #error
00639 #endif
00640 
00641     // Set SS selector
00642     Ke386SetSs(0x10); // DataSelector=0x10
00643 
00644     // Set DS and ES selectors
00645     Ke386SetDs(0x10);
00646     Ke386SetEs(0x10); // this is vital for rep stosd
00647 
00648     // LDT = not used ever, thus set to 0
00649     Ke386SetLocalDescriptorTable(Ldt);
00650 
00651     // Load TSR
00652     Ke386SetTr(KGDT_TSS);
00653 
00654     // Clear GS
00655     Ke386SetGs(0);
00656 
00657     // Set FS to PCR
00658     Ke386SetFs(0x30);
00659 
00660         // Real end of the function, just for information
00661         /* do not uncomment!
00662         pop edi;
00663         pop esi;
00664         pop ebx;
00665         mov esp, ebp;
00666         pop ebp;
00667         ret
00668         */
00669 }
00670 
00671 #if DBG
00672 VOID
00673 MempDump()
00674 {
00675     ULONG *PDE_Addr=(ULONG *)PDE;//0xC0300000;
00676     int i, j;
00677 
00678     TRACE("\nPDE\n");
00679 
00680     for (i=0; i<128; i++)
00681     {
00682         TRACE("0x%04X | ", i*8);
00683 
00684         for (j=0; j<8; j++)
00685         {
00686             TRACE("0x%08X ", PDE_Addr[i*8+j]);
00687         }
00688 
00689         TRACE("\n");
00690     }
00691 }
00692 #endif
00693 

Generated on Sun May 27 2012 04:19:07 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.