src/kernel/mm/vmm/vmm.c
/*!
 * @note --------walk for sv39-----------
 *       this function is designed
 *       for find 0-level pte(page table entry).
 *       if the page table is not exist, it will
 *       sent a request to alloc virtual page
 *       from kernel virtual pages pool when the
 *       param 'alloc' is set as 'true' and return
 *       corresponding pte,pdt-level when 'alloc' is
 *       set as false.
 * @param vmm_pool
 * @param vaddr : target addr
 * @param alloc
 * @return pte ptr when success
 *         NULL when fail
 */
@note walk for sv39
this function is designed
for find 0-level pte(page table entry).
@note walk for sv39 this function is designed for find 0 - level pte ( page table entry ) .
pte_t * walk(vmm_t * vmm_pool, addr_t vaddr, bool alloc){
    pte_t * ret;
    bool is_kern_addr = !addr_is_user_space(vaddr);
    pagetable_t pdt = vmm_pool->pagetable;
    if(vaddr >= VMM_VM_MAX){
        ret = NULL;
        goto out;
    }
    for(uint8_t level = 2; level > 0; level--){
        pte_t *pte = &pdt[_get_pte_index(vaddr, level)];
        if(*pte & VMM_PTE_V) {
            pdt = (pagetable_t)_pte2paddr(*pte);
        }
        else {
            if(!alloc){
                ret = NULL;
                goto out;
            }
            addr_t addr = kalloc(1);
            if (addr != NULL) {
                if (is_kern_addr) {
                    *pte = _paddr2pte((addr_t) addr) | VMM_PTE_V;
                } else {
                    *pte = _paddr2pte((addr_t) addr) | VMM_PTE_U | VMM_PTE_V;
                }
                pdt = addr;
            } else {
                ret = NULL;
                goto out;
            }
        }
    }
    ret = &pdt[_get_pte_index(vaddr, 0)];
    out:
    return ret;
}
pte_t * walk ( vmm_t * vmm_pool , addr_t vaddr , bool alloc ) { pte_t * ret ; bool is_kern_addr = ! addr_is_user_space ( vaddr ) ; pagetable_t pdt = vmm_pool -> pagetable ; if ( vaddr >= VMM_VM_MAX ) { ret = NULL ; goto out ; } for ( uint8_t level = 2 ; level > 0 ; level -- ) { pte_t * pte = & pdt [ _get_pte_index ( vaddr , level ) ] ; if ( * pte & VMM_PTE_V ) { pdt = ( pagetable_t ) _pte2paddr ( * pte ) ; } else { if ( ! alloc ) { ret = NULL ; goto out ; } addr_t addr = kalloc ( 1 ) ; if ( addr != NULL ) { if ( is_kern_addr ) { * pte = _paddr2pte ( ( addr_t ) addr ) | VMM_PTE_V ; } else { * pte = _paddr2pte ( ( addr_t ) addr ) | VMM_PTE_U | VMM_PTE_V ; } pdt = addr ; } else { ret = NULL ; goto out ; } } } ret = & pdt [ _get_pte_index ( vaddr , 0 ) ] ; out : return ret ; }
@note --------walk for sv39
       this function is designed
       for find 0-level pte(page table entry).
@note -------- walk for sv39 this function is designed for find 0 - level pte ( page table entry ) .