EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c

Go to the documentation of this file.
00001 
00029 #include "DxeIpl.h"
00030 #include "VirtualMemory.h"
00031 
00044 UINTN
00045 CreateIdentityMappingPageTables (
00046   VOID
00047   )
00048 {  
00049   UINT32                                        RegEax;
00050   UINT32                                        RegEdx;
00051   UINT8                                         PhysicalAddressBits;
00052   EFI_PHYSICAL_ADDRESS                          PageAddress;
00053   UINTN                                         IndexOfPml4Entries;
00054   UINTN                                         IndexOfPdpEntries;
00055   UINTN                                         IndexOfPageDirectoryEntries;
00056   UINT32                                        NumberOfPml4EntriesNeeded;
00057   UINT32                                        NumberOfPdpEntriesNeeded;
00058   PAGE_MAP_AND_DIRECTORY_POINTER                *PageMapLevel4Entry;
00059   PAGE_MAP_AND_DIRECTORY_POINTER                *PageMap;
00060   PAGE_MAP_AND_DIRECTORY_POINTER                *PageDirectoryPointerEntry;
00061   PAGE_TABLE_ENTRY                              *PageDirectoryEntry;
00062   UINTN                                         TotalPagesNum;
00063   UINTN                                         BigPageAddress;
00064   VOID                                          *Hob;
00065   BOOLEAN                                       Page1GSupport;
00066   PAGE_TABLE_1G_ENTRY                           *PageDirectory1GEntry;
00067 
00068   Page1GSupport = FALSE;
00069   if (PcdGetBool(PcdUse1GPageTable)) {
00070     AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
00071     if (RegEax >= 0x80000001) {
00072       AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
00073       if ((RegEdx & BIT26) != 0) {
00074         Page1GSupport = TRUE;
00075       }
00076     }
00077   }
00078 
00079   //
00080   // Get physical address bits supported.
00081   //
00082   Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
00083   if (Hob != NULL) {
00084     PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
00085   } else {
00086     AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
00087     if (RegEax >= 0x80000008) {
00088       AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
00089       PhysicalAddressBits = (UINT8) RegEax;
00090     } else {
00091       PhysicalAddressBits = 36;
00092     }
00093   }
00094 
00095   //
00096   // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
00097   //
00098   ASSERT (PhysicalAddressBits <= 52);
00099   if (PhysicalAddressBits > 48) {
00100     PhysicalAddressBits = 48;
00101   }
00102 
00103   //
00104   // Calculate the table entries needed.
00105   //
00106   if (PhysicalAddressBits <= 39 ) {
00107     NumberOfPml4EntriesNeeded = 1;
00108     NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
00109   } else {
00110     NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));
00111     NumberOfPdpEntriesNeeded = 512;
00112   }
00113 
00114   //
00115   // Pre-allocate big pages to avoid later allocations. 
00116   //
00117   if (!Page1GSupport) {
00118     TotalPagesNum = (NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1;
00119   } else {
00120     TotalPagesNum = NumberOfPml4EntriesNeeded + 1;
00121   }
00122   BigPageAddress = (UINTN) AllocatePages (TotalPagesNum);
00123   ASSERT (BigPageAddress != 0);
00124 
00125   //
00126   // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
00127   //
00128   PageMap         = (VOID *) BigPageAddress;
00129   BigPageAddress += SIZE_4KB;
00130 
00131   PageMapLevel4Entry = PageMap;
00132   PageAddress        = 0;
00133   for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) {
00134     //
00135     // Each PML4 entry points to a page of Page Directory Pointer entires.
00136     // So lets allocate space for them and fill them in in the IndexOfPdpEntries loop.
00137     //
00138     PageDirectoryPointerEntry = (VOID *) BigPageAddress;
00139     BigPageAddress += SIZE_4KB;
00140 
00141     //
00142     // Make a PML4 Entry
00143     //
00144     PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry;
00145     PageMapLevel4Entry->Bits.ReadWrite = 1;
00146     PageMapLevel4Entry->Bits.Present = 1;
00147 
00148     if (Page1GSupport) {
00149       PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry;
00150     
00151       for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
00152         //
00153         // Fill in the Page Directory entries
00154         //
00155         PageDirectory1GEntry->Uint64 = (UINT64)PageAddress;
00156         PageDirectory1GEntry->Bits.ReadWrite = 1;
00157         PageDirectory1GEntry->Bits.Present = 1;
00158         PageDirectory1GEntry->Bits.MustBe1 = 1;
00159       }
00160     } else {
00161       for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
00162         //
00163         // Each Directory Pointer entries points to a page of Page Directory entires.
00164         // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
00165         //       
00166         PageDirectoryEntry = (VOID *) BigPageAddress;
00167         BigPageAddress += SIZE_4KB;
00168 
00169         //
00170         // Fill in a Page Directory Pointer Entries
00171         //
00172         PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry;
00173         PageDirectoryPointerEntry->Bits.ReadWrite = 1;
00174         PageDirectoryPointerEntry->Bits.Present = 1;
00175 
00176         for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {
00177           //
00178           // Fill in the Page Directory entries
00179           //
00180           PageDirectoryEntry->Uint64 = (UINT64)PageAddress;
00181           PageDirectoryEntry->Bits.ReadWrite = 1;
00182           PageDirectoryEntry->Bits.Present = 1;
00183           PageDirectoryEntry->Bits.MustBe1 = 1;
00184         }
00185       }
00186 
00187       for (; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
00188         ZeroMem (
00189           PageDirectoryPointerEntry,
00190           sizeof(PAGE_MAP_AND_DIRECTORY_POINTER)
00191           );
00192       }
00193     }
00194   }
00195 
00196   //
00197   // For the PML4 entries we are not using fill in a null entry.
00198   //
00199   for (; IndexOfPml4Entries < 512; IndexOfPml4Entries++, PageMapLevel4Entry++) {
00200     ZeroMem (
00201       PageMapLevel4Entry,
00202       sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)
00203       );
00204   }
00205 
00206   return (UINTN)PageMap;
00207 }
00208 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines