Пример #1
0
void     map_pages(uint32_t physical_address, uint32_t virtual_address, uint32_t size, uint32_t protect = PT_PRESENT | PT_WRITABLE | PT_USER)
{
	int pages = SIZE_TO_PAGES(size);
	for (int i = 0; i < pages; i++)
	{
		UINT32 pde_index = PDE_INDEX(virtual_address);
		UINT32 pte_index = PTE_INDEX(virtual_address);
		UINT32* page_table = (UINT32*)(PAGE_TABLE_PHYSICAL_ADDR + pde_index*PAGE_SIZE);
		page_table[pte_index] = physical_address | protect;
		physical_address += PAGE_SIZE;
		virtual_address += PAGE_SIZE;
	}
}
Пример #2
0
static void pt_map(pmap_t *pmap, vm_addr_t vaddr, pm_addr_t paddr,
                   uint8_t flags) {
  pde_map(pmap, vaddr);
  pte_t entry = flags;
  uint32_t pt_index = PTE_INDEX(vaddr);
  ENTRYLO_SET_PADDR(entry , paddr);
  pmap->pte[pt_index] = entry;

  /* invalidate proper entry in tlb */
  tlbhi_t entryhi = 0;
  ENTRYHI_SET_VADDR(entryhi, vaddr);
  ENTRYHI_SET_ASID(entryhi, pmap->asid);
  tlb_invalidate(entryhi);
}
Пример #3
0
void unmap(pgd_t *pgd_now, uint32_t va)
{
        uint32_t pgd_idx = PGD_INDEX(va);
        uint32_t pte_idx = PTE_INDEX(va);

        pte_t *pte = (pte_t *)(pgd_now[pgd_idx] & PAGE_MASK);

        if (!pte) {
                return;
        }

        // 转换到内核线性地址
        pte = (pte_t *)(pa_to_ka(pte));

        pte[pte_idx] = 0;
        
        tlb_reload_page(va);
}
Пример #4
0
void map(pgd_t *pgd_now, uint32_t va, uint32_t pa, uint32_t flags)
{       
        uint32_t pgd_idx = PGD_INDEX(va);
        uint32_t pte_idx = PTE_INDEX(va); 
        
        pte_t *pte = (pte_t *)(pgd_now[pgd_idx] & PAGE_MASK);
        if (!pte) {
                pte = (pte_t *)alloc_pages(1);
                pgd_now[pgd_idx] = (uint32_t)pte | PAGE_PRESENT | PAGE_WRITE;
                pte = (pte_t *)pa_to_ka(pte);
        } else {
                pte = (pte_t *)pa_to_ka(pte);
        }

        pte[pte_idx] = (pa & PAGE_MASK) | flags;

        tlb_reload_page(va);
}
Пример #5
0
uint32_t get_mapping(pgd_t *pgd_now, uint32_t va, uint32_t *pa)
{
        uint32_t pgd_idx = PGD_INDEX(va);
        uint32_t pte_idx = PTE_INDEX(va);

        pte_t *pte = (pte_t *)(pgd_now[pgd_idx] & PAGE_MASK);
        if (!pte) {
              return 0;
        }
        
        // 转换到内核线性地址
        pte = (pte_t *)(pa_to_ka(pte));

        // 如果地址有效而且指针不为NULL,则返回地址
        if (pte[pte_idx] != 0 && pa) {
                 *pa = pte[pte_idx] & PAGE_MASK;
                return 1;
        }

        return 0;
}
Пример #6
0
VOID
HalpReleaseReservedVirtualSpace(
    PVOID VirtualAddress,
    ULONG LengthInPages
    )

/*++

 Routine Description:

    This function will release the virtual address range previously
    allocated with HalpAssignReservedVirtualSpace and should be 
    called with a virtual address previously allocated by a call to
    HalpAssignReservedVirtualSpace the number of pages to release.

 Arguments:

    VirtualAddress of a previously allocated page in the HAL reserved
    space.

    Length (in pages) to be released.

 Return Value:

    None.

--*/

{
    PHARDWARE_PTE PPte;

    //
    // Sanity Checks
    //

    if ( (LengthInPages > MAX_LENGTH)     ||
         (!LengthInPages)                 ||
         ((ULONG)VirtualAddress < MIN_VA) ||
         ((ULONG)VirtualAddress > MAX_VA) ) {
        KeBugCheck(HAL_INITIALIZATION_FAILED);
        return;
    }

    if ( !HalpReservedPtes ) {
        KeBugCheck(HAL_INITIALIZATION_FAILED);
        return;
    }

    PPte = HalpReservedPtes + PTE_INDEX(VirtualAddress);

    do {
        if ( !PPte->Valid ) {
            break;
        }
        PPte->Valid = FALSE;
        PPte++;
    } while ( --LengthInPages );

    if ( LengthInPages ) {
        KeBugCheck(HAL_INITIALIZATION_FAILED);
    }

    KeFlushCurrentTb();
           
    return;
}
Пример #7
0
PVOID
HalpAssignReservedVirtualSpace(
    ULONG BasePage,
    ULONG LengthInPages
    )

/*++

 Routine Description:

    This function will attempt to allocate a contiguous range of
    virtual address to provide access to memory at the requested
    physical address.

 Arguments:

    Physical page number for which a Virtual Address assignment is 
    needed.

    Length (in pages) of the region to be mapped.

 Return Value:

    Virtual Address in the range HAL_BASE thru HAL_TOP + fff,

    -or-

    NULL if the assignment couldn't be made.


--*/

{
    ULONG Length;
    HARDWARE_PTE TempPte;
    HARDWARE_PTE ZeroPte;
    PHARDWARE_PTE PPte;
    PHARDWARE_PTE StartingPte;

    //
    // Sanity Checks
    //

    if ( (LengthInPages > MAX_LENGTH) ||
         (!LengthInPages)             ||
         (BasePage & ~PAGE_MASK)      ) {
        KeBugCheck(HAL_INITIALIZATION_FAILED);
        return NULL;
    }

    if ( !HalpReservedPtes ) {
        //
        // Not initialized yet,... fix it.
        //
        HalpLocateReservedPtes();
    }

    PPte = HalpReservedPtes + PTE_INDEX(MIN_VA);
    Length = LengthInPages;

    while ( PPte <= (HalpReservedPtes + PTE_INDEX(MIN_VA)) || Length ) {
        if ( PPte->Valid ) {
            Length = LengthInPages;
        } else {
            Length--;
        }
        PPte++;
    }

    if ( Length ) {
        return NULL;
    }

    //
    // Found a range of pages.  PPte is pointing to the entry
    // beyond the end of the range.
    //

    StartingPte = PPte - LengthInPages;
    PPte = StartingPte;
    *(PULONG)&ZeroPte = 0;
    TempPte = ZeroPte;
    TempPte.Write = TRUE;
    TempPte.CacheDisable = TRUE;
    TempPte.MemoryCoherence = TRUE;
    TempPte.GuardedStorage = TRUE;
    TempPte.Dirty = 0x00;   // PP bits KM read/write, UM no access.
    TempPte.Valid = TRUE;

    while ( LengthInPages-- ) {
        //
        // The following is done in a Temp so the actual write
        // to the page table is done in a single write.
        //
        TempPte.PageFrameNumber = BasePage++;
        *PPte++ = TempPte;
    }
    return (PVOID)(BASE_VA |
           ((ULONG)(StartingPte - HalpReservedPtes) << PAGE_SHIFT));
}