L4_TABLE* NewL4Table(){ L4_TABLE* l4t = (L4_TABLE*) PageAlloc(); L3_TABLE* l3t = (L3_TABLE*) PageAlloc(); //L4.Addr -> L3 l4t->table[0].p = 1; l4t->table[0].rw = 1; l4t->table[0].us = 0; l4t->table[0].addr = (uint64)((uint64)l3t/PAGE_SIZE); L2_TABLE* l2t = (L2_TABLE*) PageAlloc(); //L3.Addr -> L2 l3t->table[0].p = 1; l3t->table[0].rw = 1; l3t->table[0].us = 0; l3t->table[0].addr = (uint64)((uint64)l2t/PAGE_SIZE); //L2 mapping int i; for (i = 0; i < 6; i++) { l2t->table[i].p = 1; l2t->table[i].rw = 1; l2t->table[i].addr = (uint64)l1_tables[i]/PAGE_SIZE; if(i == 2){ l2t->table[i].us = 1; }else{ l2t->table[i].us = 0; } } }
void PageTable2 (TPageTable *This, uint32 MemSize) { This->TableAllocated = true; This->Table = (TARMV6MMU_LEVEL1_SECTION_DESCRIPTOR *) PageAlloc(); for (unsigned EntryIndex = 0; EntryIndex < SDRAM_SIZE_MBYTE; EntryIndex++) { uint32 BaseAddress = MEGABYTE * EntryIndex; TARMV6MMU_LEVEL1_SECTION_DESCRIPTOR* Entry = &This->Table[EntryIndex]; Entry->Value10 = 2; Entry->BBit = 1; Entry->CBit = 1; Entry->XNBit = 0; Entry->Domain = 0; Entry->IMPBit = 0; Entry->AP = AP_SYSTEM_ACCESS; Entry->TEX = 0; Entry->APXBit = APX_RW_ACCESS; Entry->SBit = 0; Entry->NGBit = 0; Entry->Value0 = 0; Entry->SBZ = 0; Entry->Base = ARMV6MMUL1SECTIONBASE(BaseAddress); } CleanDataCache (); DataSyncBarrier (); }
uint64 GetPhysicalPage(L1_TABLE* l1t, uint64 offset, int rw, int us){ if (l1t->table[offset].p == 0) { l1t->table[offset].p = 1; l1t->table[offset].rw = rw; l1t->table[offset].us = us; l1t->table[offset].addr = (uint64)((uint64)PageAlloc() / PAGE_SIZE); } return (uint64) ((uint64)(l1t->table[offset].addr * PAGE_SIZE)); }
L4_TABLE * InitializeIdentityDirectories(){ L4_TABLE* l4t = (L4_TABLE*) PageAlloc(); L3_TABLE* l3t = (L3_TABLE*) PageAlloc(); //L4.Addr -> L3 l4t->table[0].p = 1; l4t->table[0].rw = 1; l4t->table[0].us = 0; l4t->table[0].addr = (uint64)((uint64)l3t/PAGE_SIZE); L2_TABLE* l2t = (L2_TABLE*) PageAlloc(); //L3.Addr -> L2 l3t->table[0].p = 1; l3t->table[0].rw = 1; l3t->table[0].us = 0; l3t->table[0].addr = (uint64)((uint64)l2t/PAGE_SIZE); //L2.Addr -> L1 //L1.Addr = physical addr ( Identity ) int i; int j; for (i = 0; i < 256; i++) { L1_TABLE* l1t = (L1_TABLE*)PageAlloc(); l2t->table[i].p = 1; l2t->table[i].us = 0; l2t->table[i].rw = 0; l2t->table[i].addr = ((uint64)l1t/PAGE_SIZE); for (j = 0; j < 512; j++) { l1t->table[j].p = 1; l1t->table[j].us = 0; l1t->table[j].rw = 0; l1t->table[j].addr = (uint64)(((i * 2 * 0x100000)+(j * PAGE_SIZE ))/PAGE_SIZE); } } return l4t; }
L1_TABLE* CreateIdentityL1Table(int readWrite, int userSupervisor, int offsetIndex) { L1_TABLE* l1t = (L1_TABLE*)PageAlloc(); int i; for (i = 0; i < 512; i++) { l1t->table[i].p = 1; l1t->table[i].rw = readWrite; l1t->table[i].us = userSupervisor; // each l2 table uses 2MiB, so index * 2MiB gives us the starting position // We divide by PAGE_SIZE so it shifts the 12 0's and maps correctly virtual to physical adress l1t->table[i].addr = ((offsetIndex * 2 * 0x100000) + (i*PAGE_SIZE))/PAGE_SIZE; } return l1t; }
L1_TABLE* GetL1(L2_TABLE* l2t, uint64 offset, int rw, int us){ if (l2t->table[offset].p == 0) { l2t->table[offset].p = 1; l2t->table[offset].rw = rw; l2t->table[offset].us = us; L1_TABLE* l1t = (L1_TABLE*)PageAlloc(); l2t->table[offset].addr = (uint64) ((uint64)l1t / PAGE_SIZE); return l1t; }else{ return (L1_TABLE*) ((uint64)(l2t->table[offset].addr * PAGE_SIZE)); } }
L2_TABLE* GetL2(L3_TABLE* l3t, uint64 offset, int rw, int us){ if (l3t->table[offset].p == 0) { l3t->table[offset].p = 1; l3t->table[offset].rw = rw; l3t->table[offset].us = us; L2_TABLE* l2t = (L2_TABLE*)PageAlloc(); l3t->table[offset].addr = (uint64) ((uint64)l2t / PAGE_SIZE); return l2t; }else{ return (L2_TABLE*) ((uint64)(l3t->table[offset].addr * PAGE_SIZE)); } }
L3_TABLE* GetL3(L4_TABLE* l4t, uint64 offset, int rw, int us){ if (l4t->table[offset].p == 0) { l4t->table[offset].p = 1; l4t->table[offset].rw = rw; l4t->table[offset].us = us; L3_TABLE* l3t = (L3_TABLE*)PageAlloc(); l4t->table[offset].addr = (uint64) ((uint64)l3t / PAGE_SIZE); return l3t; }else{ return (L3_TABLE*) ((uint64)(l4t->table[offset].addr * PAGE_SIZE)); } }
/** Locate the pointer of bitmap from the guarded memory bitmap tables, which covers the given Address. @param[in] Address Start address to search the bitmap for. @param[in] AllocMapUnit Flag to indicate memory allocation for the table. @param[out] BitMap Pointer to bitmap which covers the Address. @return The bit number from given Address to the end of current map table. **/ UINTN FindGuardedMemoryMap ( IN EFI_PHYSICAL_ADDRESS Address, IN BOOLEAN AllocMapUnit, OUT UINT64 **BitMap ) { UINTN Level; UINT64 *GuardMap; UINT64 MapMemory; UINTN Index; UINTN Size; UINTN BitsToUnitEnd; // // Adjust current map table depth according to the address to access // while (AllocMapUnit && mMapLevel < GUARDED_HEAP_MAP_TABLE_DEPTH && RShiftU64 ( Address, mLevelShift[GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel - 1] ) != 0) { if (mGuardedMemoryMap != 0) { Size = (mLevelMask[GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel - 1] + 1) * GUARDED_HEAP_MAP_ENTRY_BYTES; MapMemory = (UINT64)(UINTN)PageAlloc (EFI_SIZE_TO_PAGES (Size)); ASSERT (MapMemory != 0); SetMem ((VOID *)(UINTN)MapMemory, Size, 0); *(UINT64 *)(UINTN)MapMemory = mGuardedMemoryMap; mGuardedMemoryMap = MapMemory; } mMapLevel++; } GuardMap = &mGuardedMemoryMap; for (Level = GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel; Level < GUARDED_HEAP_MAP_TABLE_DEPTH; ++Level) { if (*GuardMap == 0) { if (!AllocMapUnit) { GuardMap = NULL; break; } Size = (mLevelMask[Level] + 1) * GUARDED_HEAP_MAP_ENTRY_BYTES; MapMemory = (UINT64)(UINTN)PageAlloc (EFI_SIZE_TO_PAGES (Size)); ASSERT (MapMemory != 0); SetMem ((VOID *)(UINTN)MapMemory, Size, 0); *GuardMap = MapMemory; } Index = (UINTN)RShiftU64 (Address, mLevelShift[Level]); Index &= mLevelMask[Level]; GuardMap = (UINT64 *)(UINTN)((*GuardMap) + Index * sizeof (UINT64)); } BitsToUnitEnd = GUARDED_HEAP_MAP_BITS - GUARDED_HEAP_MAP_BIT_INDEX (Address); *BitMap = GuardMap; return BitsToUnitEnd; }
void* DzPageAlloc( size_t size ) { return PageAlloc( size ); }