Changeset View
Changeset View
Standalone View
Standalone View
sys/arm/arm/pmap-v4.c
Show First 20 Lines • Show All 3,409 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
*/ | */ | ||||
vm_page_t | vm_page_t | ||||
pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot) | pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot) | ||||
{ | { | ||||
struct l2_dtable *l2; | struct l2_dtable *l2; | ||||
pd_entry_t l1pd; | pd_entry_t l1pd; | ||||
pt_entry_t *ptep, pte; | pt_entry_t *ptep, pte; | ||||
vm_paddr_t pa, paddr; | vm_paddr_t pa; | ||||
vm_page_t m = NULL; | vm_page_t m; | ||||
u_int l1idx; | u_int l1idx; | ||||
l1idx = L1_IDX(va); | l1idx = L1_IDX(va); | ||||
paddr = 0; | m = NULL; | ||||
PMAP_LOCK(pmap); | PMAP_LOCK(pmap); | ||||
retry: | |||||
l1pd = pmap->pm_l1->l1_kva[l1idx]; | l1pd = pmap->pm_l1->l1_kva[l1idx]; | ||||
if (l1pte_section_p(l1pd)) { | if (l1pte_section_p(l1pd)) { | ||||
/* | /* | ||||
* These should only happen for kernel_pmap | * These should only happen for kernel_pmap | ||||
*/ | */ | ||||
KASSERT(pmap == kernel_pmap, ("huh")); | KASSERT(pmap == kernel_pmap, ("huh")); | ||||
/* XXX: what to do about the bits > 32 ? */ | /* XXX: what to do about the bits > 32 ? */ | ||||
if (l1pd & L1_S_SUPERSEC) | if (l1pd & L1_S_SUPERSEC) | ||||
pa = (l1pd & L1_SUP_FRAME) | (va & L1_SUP_OFFSET); | pa = (l1pd & L1_SUP_FRAME) | (va & L1_SUP_OFFSET); | ||||
else | else | ||||
pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET); | pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET); | ||||
if (vm_page_pa_tryrelock(pmap, pa & PG_FRAME, &paddr)) | |||||
goto retry; | |||||
if (l1pd & L1_S_PROT_W || (prot & VM_PROT_WRITE) == 0) { | if (l1pd & L1_S_PROT_W || (prot & VM_PROT_WRITE) == 0) { | ||||
m = PHYS_TO_VM_PAGE(pa); | m = PHYS_TO_VM_PAGE(pa); | ||||
vm_page_wire(m); | if (!vm_page_wire_mapped(m)) | ||||
m = NULL; | |||||
} | } | ||||
} else { | } else { | ||||
/* | /* | ||||
* Note that we can't rely on the validity of the L1 | * Note that we can't rely on the validity of the L1 | ||||
* descriptor as an indication that a mapping exists. | * descriptor as an indication that a mapping exists. | ||||
* We have to look it up in the L2 dtable. | * We have to look it up in the L2 dtable. | ||||
*/ | */ | ||||
l2 = pmap->pm_l2[L2_IDX(l1idx)]; | l2 = pmap->pm_l2[L2_IDX(l1idx)]; | ||||
Show All 11 Lines | if (pte == 0) { | ||||
PMAP_UNLOCK(pmap); | PMAP_UNLOCK(pmap); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
if (pte & L2_S_PROT_W || (prot & VM_PROT_WRITE) == 0) { | if (pte & L2_S_PROT_W || (prot & VM_PROT_WRITE) == 0) { | ||||
if ((pte & L2_TYPE_MASK) == L2_TYPE_L) | if ((pte & L2_TYPE_MASK) == L2_TYPE_L) | ||||
pa = (pte & L2_L_FRAME) | (va & L2_L_OFFSET); | pa = (pte & L2_L_FRAME) | (va & L2_L_OFFSET); | ||||
else | else | ||||
pa = (pte & L2_S_FRAME) | (va & L2_S_OFFSET); | pa = (pte & L2_S_FRAME) | (va & L2_S_OFFSET); | ||||
if (vm_page_pa_tryrelock(pmap, pa & PG_FRAME, &paddr)) | |||||
goto retry; | |||||
m = PHYS_TO_VM_PAGE(pa); | m = PHYS_TO_VM_PAGE(pa); | ||||
vm_page_wire(m); | if (!vm_page_wire_mapped(m)) | ||||
m = NULL; | |||||
} | } | ||||
} | } | ||||
PMAP_UNLOCK(pmap); | PMAP_UNLOCK(pmap); | ||||
PA_UNLOCK_COND(paddr); | |||||
return (m); | return (m); | ||||
} | } | ||||
vm_paddr_t | vm_paddr_t | ||||
pmap_dump_kextract(vm_offset_t va, pt2_entry_t *pte2p) | pmap_dump_kextract(vm_offset_t va, pt2_entry_t *pte2p) | ||||
{ | { | ||||
struct l2_dtable *l2; | struct l2_dtable *l2; | ||||
pd_entry_t l1pd; | pd_entry_t l1pd; | ||||
▲ Show 20 Lines • Show All 993 Lines • Show Last 20 Lines |