Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm64/arm64/pmap.c
Show First 20 Lines • Show All 209 Lines • ▼ Show 20 Lines | |||||
vm_offset_t virtual_avail; /* VA of first avail page (after kernel bss) */ | vm_offset_t virtual_avail; /* VA of first avail page (after kernel bss) */ | ||||
vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */ | vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */ | ||||
vm_offset_t kernel_vm_end = 0; | vm_offset_t kernel_vm_end = 0; | ||||
struct msgbuf *msgbufp = NULL; | struct msgbuf *msgbufp = NULL; | ||||
static struct rwlock_padalign pvh_global_lock; | static struct rwlock_padalign pvh_global_lock; | ||||
vm_paddr_t dmap_phys_base; /* The start of the dmap region */ | |||||
/* | /* | ||||
* Data for the pv entry allocation mechanism | * Data for the pv entry allocation mechanism | ||||
*/ | */ | ||||
static TAILQ_HEAD(pch, pv_chunk) pv_chunks = TAILQ_HEAD_INITIALIZER(pv_chunks); | static TAILQ_HEAD(pch, pv_chunk) pv_chunks = TAILQ_HEAD_INITIALIZER(pv_chunks); | ||||
static struct mtx pv_chunks_mutex; | static struct mtx pv_chunks_mutex; | ||||
static struct rwlock pv_list_locks[NPV_LIST_LOCKS]; | static struct rwlock pv_list_locks[NPV_LIST_LOCKS]; | ||||
static void free_pv_chunk(struct pv_chunk *pc); | static void free_pv_chunk(struct pv_chunk *pc); | ||||
▲ Show 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | pmap_early_vtophys(vm_offset_t l1pt, vm_offset_t va) | ||||
pt_entry_t *l2; | pt_entry_t *l2; | ||||
l2 = pmap_early_page_idx(l1pt, va, &l1_slot, &l2_slot); | l2 = pmap_early_page_idx(l1pt, va, &l1_slot, &l2_slot); | ||||
return ((l2[l2_slot] & ~ATTR_MASK) + (va & L2_OFFSET)); | return ((l2[l2_slot] & ~ATTR_MASK) + (va & L2_OFFSET)); | ||||
} | } | ||||
static void | static void | ||||
pmap_bootstrap_dmap(vm_offset_t l1pt) | pmap_bootstrap_dmap(vm_offset_t l1pt, vm_paddr_t kernstart) | ||||
{ | { | ||||
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; | ||||
pa = dmap_phys_base = kernstart & ~L1_OFFSET; | |||||
va = DMAP_MIN_ADDRESS; | va = DMAP_MIN_ADDRESS; | ||||
l1 = (pd_entry_t *)l1pt; | l1 = (pd_entry_t *)l1pt; | ||||
l1_slot = pmap_l1_index(DMAP_MIN_ADDRESS); | l1_slot = pmap_l1_index(DMAP_MIN_ADDRESS); | ||||
for (pa = 0; va < DMAP_MAX_ADDRESS; | for (; va < DMAP_MAX_ADDRESS; | ||||
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); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart, vm_size_t kernlen) | pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart, vm_size_t kernlen) | ||||
{ | { | ||||
u_int l1_slot, l2_slot, avail_slot, map_slot, used_map_slot; | u_int l1_slot, l2_slot, avail_slot, map_slot, used_map_slot; | ||||
uint64_t kern_delta; | uint64_t kern_delta; | ||||
pt_entry_t *l2; | pt_entry_t *l2; | ||||
vm_offset_t va, freemempos; | vm_offset_t va, freemempos; | ||||
vm_offset_t dpcpu, msgbufpv; | vm_offset_t dpcpu, msgbufpv; | ||||
vm_paddr_t pa; | vm_paddr_t pa, min_pa; | ||||
int i; | |||||
kern_delta = KERNBASE - kernstart; | kern_delta = KERNBASE - kernstart; | ||||
physmem = 0; | physmem = 0; | ||||
printf("pmap_bootstrap %lx %lx %lx\n", l1pt, kernstart, kernlen); | printf("pmap_bootstrap %lx %lx %lx\n", l1pt, kernstart, kernlen); | ||||
printf("%lx\n", l1pt); | printf("%lx\n", l1pt); | ||||
printf("%lx\n", (KERNBASE >> L1_SHIFT) & Ln_ADDR_MASK); | printf("%lx\n", (KERNBASE >> L1_SHIFT) & Ln_ADDR_MASK); | ||||
/* Set this early so we can use the pagetable walking functions */ | /* Set this early so we can use the pagetable walking functions */ | ||||
kernel_pmap_store.pm_l1 = (pd_entry_t *)l1pt; | kernel_pmap_store.pm_l1 = (pd_entry_t *)l1pt; | ||||
PMAP_LOCK_INIT(kernel_pmap); | PMAP_LOCK_INIT(kernel_pmap); | ||||
/* | /* | ||||
* Initialize the global pv list lock. | * Initialize the global pv list lock. | ||||
*/ | */ | ||||
rw_init(&pvh_global_lock, "pmap pv global"); | rw_init(&pvh_global_lock, "pmap pv global"); | ||||
/* Assume the address we were loaded to is a valid physical address */ | |||||
min_pa = KERNBASE - kern_delta; | |||||
/* | |||||
* Find the minimum physical address. physmap is sorted, | |||||
* but may contain empty ranges. | |||||
*/ | |||||
for (i = 0; i < (physmap_idx * 2); i += 2) { | |||||
if (physmap[i] == physmap[i + 1]) | |||||
continue; | |||||
if (physmap[i] <= min_pa) | |||||
min_pa = physmap[i]; | |||||
break; | |||||
} | |||||
/* Create a direct map region early so we can use it for pa -> va */ | /* Create a direct map region early so we can use it for pa -> va */ | ||||
pmap_bootstrap_dmap(l1pt); | pmap_bootstrap_dmap(l1pt, min_pa); | ||||
va = KERNBASE; | va = KERNBASE; | ||||
pa = KERNBASE - kern_delta; | pa = KERNBASE - kern_delta; | ||||
/* | /* | ||||
* Start to initialise phys_avail by copying from physmap | * Start to initialise phys_avail by copying from physmap | ||||
* up to the physical address KERNBASE points at. | * up to the physical address KERNBASE points at. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 2,659 Lines • Show Last 20 Lines |