Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/pmap.c
Show First 20 Lines • Show All 446 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
pmap_bootstrap_dmap(vm_offset_t l1pt) | pmap_bootstrap_dmap(vm_offset_t l1pt) | ||||
{ | { | ||||
vm_offset_t va; | vm_offset_t va; | ||||
vm_paddr_t pa; | vm_paddr_t pa; | ||||
pd_entry_t *l1; | pd_entry_t *l1; | ||||
u_int l1_slot; | u_int l1_slot; | ||||
struct direct_map_desc *desc; | |||||
int a; | |||||
va = DMAP_MIN_ADDRESS; | for (a = 0; a < MAX_DMAP_ENTRIES; a++) { | ||||
desc = &arm64_dmap_desc[a]; | |||||
if (desc->flags == DMAP_FLAG_VALID) { | |||||
va = desc->va_start; | |||||
l1 = (pd_entry_t *)l1pt; | l1 = (pd_entry_t *)l1pt; | ||||
l1_slot = pmap_l1_index(DMAP_MIN_ADDRESS); | l1_slot = pmap_l1_index(va); | ||||
for (pa = 0; va < DMAP_MAX_ADDRESS; | for (pa = desc->pa_start; va < desc->va_end; | ||||
pa += L1_SIZE, va += L1_SIZE, l1_slot++) { | pa += L1_SIZE, va += L1_SIZE, l1_slot++) { | ||||
KASSERT(l1_slot < Ln_ENTRIES, ("Invalid L1 index")); | KASSERT(l1_slot < Ln_ENTRIES, | ||||
("Invalid L1 index")); | |||||
pmap_load_store(&l1[l1_slot], | pmap_load_store(&l1[l1_slot], | ||||
(pa & ~L1_OFFSET) | ATTR_DEFAULT | | (pa & ~L1_OFFSET) | ATTR_DEFAULT | | ||||
ATTR_IDX(CACHED_MEMORY) | L1_BLOCK); | ATTR_IDX(CACHED_MEMORY) | L1_BLOCK); | ||||
} | } | ||||
cpu_dcache_wb_range((vm_offset_t)l1, PAGE_SIZE); | cpu_dcache_wb_range((vm_offset_t)l1, PAGE_SIZE); | ||||
} | |||||
desc++; | |||||
} | |||||
cpu_tlb_flushID(); | cpu_tlb_flushID(); | ||||
} | } | ||||
static vm_offset_t | static vm_offset_t | ||||
pmap_bootstrap_l2(vm_offset_t l1pt, vm_offset_t va, vm_offset_t l2_start) | pmap_bootstrap_l2(vm_offset_t l1pt, vm_offset_t va, vm_offset_t l2_start) | ||||
{ | { | ||||
vm_offset_t l2pt; | vm_offset_t l2pt; | ||||
vm_paddr_t pa; | vm_paddr_t pa; | ||||
▲ Show 20 Lines • Show All 373 Lines • ▼ Show 20 Lines | |||||
vm_paddr_t | vm_paddr_t | ||||
pmap_kextract(vm_offset_t va) | pmap_kextract(vm_offset_t va) | ||||
{ | { | ||||
pd_entry_t *l2; | pd_entry_t *l2; | ||||
pt_entry_t *l3; | pt_entry_t *l3; | ||||
vm_paddr_t pa; | vm_paddr_t pa; | ||||
if (va >= DMAP_MIN_ADDRESS && va < DMAP_MAX_ADDRESS) { | if (VIRT_IN_DMAP(va)) { | ||||
andrew: Good | |||||
pa = DMAP_TO_PHYS(va); | pa = DMAP_TO_PHYS(va); | ||||
} else { | } else { | ||||
l2 = pmap_l2(kernel_pmap, va); | l2 = pmap_l2(kernel_pmap, va); | ||||
if (l2 == NULL) | if (l2 == NULL) | ||||
panic("pmap_kextract: No l2"); | panic("pmap_kextract: No l2"); | ||||
if ((*l2 & ATTR_DESCR_MASK) == L2_BLOCK) | if ((*l2 & ATTR_DESCR_MASK) == L2_BLOCK) | ||||
return ((*l2 & ~ATTR_MASK) | (va & L2_OFFSET)); | return ((*l2 & ~ATTR_MASK) | (va & L2_OFFSET)); | ||||
▲ Show 20 Lines • Show All 2,247 Lines • ▼ Show 20 Lines | pmap_map_io_transient(vm_page_t page[], vm_offset_t vaddr[], int count, | ||||
/* | /* | ||||
* Allocate any KVA space that we need, this is done in a separate | * Allocate any KVA space that we need, this is done in a separate | ||||
* loop to prevent calling vmem_alloc while pinned. | * loop to prevent calling vmem_alloc while pinned. | ||||
*/ | */ | ||||
needs_mapping = FALSE; | needs_mapping = FALSE; | ||||
for (i = 0; i < count; i++) { | for (i = 0; i < count; i++) { | ||||
paddr = VM_PAGE_TO_PHYS(page[i]); | paddr = VM_PAGE_TO_PHYS(page[i]); | ||||
if (__predict_false(paddr >= DMAP_MAX_PHYSADDR)) { | if (__predict_false(PHYS_IN_DMAP(paddr) == 0)) { | ||||
andrewUnsubmitted Not Done Inline ActionsGood andrew: Good | |||||
error = vmem_alloc(kernel_arena, PAGE_SIZE, | error = vmem_alloc(kernel_arena, PAGE_SIZE, | ||||
M_BESTFIT | M_WAITOK, &vaddr[i]); | M_BESTFIT | M_WAITOK, &vaddr[i]); | ||||
KASSERT(error == 0, ("vmem_alloc failed: %d", error)); | KASSERT(error == 0, ("vmem_alloc failed: %d", error)); | ||||
needs_mapping = TRUE; | needs_mapping = TRUE; | ||||
} else { | } else { | ||||
vaddr[i] = PHYS_TO_DMAP(paddr); | vaddr[i] = PHYS_TO_DMAP(paddr); | ||||
} | } | ||||
} | } | ||||
/* Exit early if everything is covered by the DMAP */ | /* Exit early if everything is covered by the DMAP */ | ||||
if (!needs_mapping) | if (!needs_mapping) | ||||
return (FALSE); | return (FALSE); | ||||
if (!can_fault) | if (!can_fault) | ||||
sched_pin(); | sched_pin(); | ||||
for (i = 0; i < count; i++) { | for (i = 0; i < count; i++) { | ||||
paddr = VM_PAGE_TO_PHYS(page[i]); | paddr = VM_PAGE_TO_PHYS(page[i]); | ||||
if (paddr >= DMAP_MAX_PHYSADDR) { | if (PHYS_IN_DMAP(paddr) == 0) { | ||||
andrewUnsubmitted Not Done Inline ActionsGood andrew: Good | |||||
panic( | panic( | ||||
"pmap_map_io_transient: TODO: Map out of DMAP data"); | "pmap_map_io_transient: TODO: Map out of DMAP data"); | ||||
} | } | ||||
} | } | ||||
return (needs_mapping); | return (needs_mapping); | ||||
} | } | ||||
void | void | ||||
pmap_unmap_io_transient(vm_page_t page[], vm_offset_t vaddr[], int count, | pmap_unmap_io_transient(vm_page_t page[], vm_offset_t vaddr[], int count, | ||||
boolean_t can_fault) | boolean_t can_fault) | ||||
{ | { | ||||
vm_paddr_t paddr; | vm_paddr_t paddr; | ||||
int i; | int i; | ||||
if (!can_fault) | if (!can_fault) | ||||
sched_unpin(); | sched_unpin(); | ||||
for (i = 0; i < count; i++) { | for (i = 0; i < count; i++) { | ||||
paddr = VM_PAGE_TO_PHYS(page[i]); | paddr = VM_PAGE_TO_PHYS(page[i]); | ||||
if (paddr >= DMAP_MAX_PHYSADDR) { | if (PHYS_IN_DMAP(paddr) == 0) { | ||||
andrewUnsubmitted Not Done Inline ActionsGood andrew: Good | |||||
panic("ARM64TODO: pmap_unmap_io_transient: Unmap data"); | panic("ARM64TODO: pmap_unmap_io_transient: Unmap data"); | ||||
} | } | ||||
} | } | ||||
} | } |
Good