Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/pmap.c
| Show First 20 Lines • Show All 1,446 Lines • ▼ Show 20 Lines | pmap_kextract(vm_offset_t va) | ||||
| return (pa); | return (pa); | ||||
| } | } | ||||
| /*************************************************** | /*************************************************** | ||||
| * Low level mapping routines..... | * Low level mapping routines..... | ||||
| ***************************************************/ | ***************************************************/ | ||||
| void | void | ||||
| pmap_kenter(vm_offset_t sva, vm_size_t size, vm_paddr_t pa, int mode) | pmap_kenter_arm64(vm_offset_t sva, vm_size_t size, vm_paddr_t pa, int mode) | ||||
| { | { | ||||
| pd_entry_t *pde; | pd_entry_t *pde; | ||||
| pt_entry_t *pte, attr; | pt_entry_t *pte, attr; | ||||
| vm_offset_t va; | vm_offset_t va; | ||||
| int lvl; | int lvl; | ||||
| KASSERT((pa & L3_OFFSET) == 0, | KASSERT((pa & L3_OFFSET) == 0, | ||||
| ("pmap_kenter: Invalid physical address")); | ("%s: Invalid physical address", __func__)); | ||||
| KASSERT((sva & L3_OFFSET) == 0, | KASSERT((sva & L3_OFFSET) == 0, | ||||
| ("pmap_kenter: Invalid virtual address")); | ("%s: Invalid virtual address", __func__)); | ||||
| KASSERT((size & PAGE_MASK) == 0, | KASSERT((size & PAGE_MASK) == 0, | ||||
| ("pmap_kenter: Mapping is not page-sized")); | ("%s: Mapping is not page-sized", __func__)); | ||||
| attr = ATTR_DEFAULT | ATTR_S1_AP(ATTR_S1_AP_RW) | ATTR_S1_XN | | attr = ATTR_DEFAULT | ATTR_S1_AP(ATTR_S1_AP_RW) | ATTR_S1_XN | | ||||
| ATTR_S1_IDX(mode) | L3_PAGE; | ATTR_S1_IDX(mode) | L3_PAGE; | ||||
| va = sva; | va = sva; | ||||
| while (size != 0) { | while (size != 0) { | ||||
| pde = pmap_pde(kernel_pmap, va, &lvl); | pde = pmap_pde(kernel_pmap, va, &lvl); | ||||
| KASSERT(pde != NULL, | KASSERT(pde != NULL, | ||||
| ("pmap_kenter: Invalid page entry, va: 0x%lx", va)); | ("%s: Invalid page entry, va: 0x%lx", __func__, va)); | ||||
| KASSERT(lvl == 2, ("pmap_kenter: Invalid level %d", lvl)); | KASSERT(lvl == 2, ("%s: Invalid level %d", __func__, lvl)); | ||||
| pte = pmap_l2_to_l3(pde, va); | pte = pmap_l2_to_l3(pde, va); | ||||
| pmap_load_store(pte, (pa & ~L3_OFFSET) | attr); | pmap_load_store(pte, (pa & ~L3_OFFSET) | attr); | ||||
| va += PAGE_SIZE; | va += PAGE_SIZE; | ||||
| pa += PAGE_SIZE; | pa += PAGE_SIZE; | ||||
| size -= PAGE_SIZE; | size -= PAGE_SIZE; | ||||
| } | } | ||||
| pmap_invalidate_range(kernel_pmap, sva, va); | pmap_invalidate_range(kernel_pmap, sva, va); | ||||
| } | } | ||||
| void | void | ||||
| pmap_kenter_device(vm_offset_t sva, vm_size_t size, vm_paddr_t pa) | pmap_kenter_device(vm_offset_t sva, vm_size_t size, vm_paddr_t pa) | ||||
| { | { | ||||
| pmap_kenter(sva, size, pa, VM_MEMATTR_DEVICE); | pmap_kenter_arm64(sva, size, pa, VM_MEMATTR_DEVICE); | ||||
| } | } | ||||
| /* | /* | ||||
| * Remove a page from the kernel pagetables. | * Remove a page from the kernel pagetables. | ||||
| */ | */ | ||||
| PMAP_INLINE void | PMAP_INLINE void | ||||
| pmap_kremove(vm_offset_t va) | pmap_kremove(vm_offset_t va) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 4,463 Lines • ▼ Show 20 Lines | if (va == 0) | ||||
| panic("%s: Couldn't allocate KVA", __func__); | panic("%s: Couldn't allocate KVA", __func__); | ||||
| pde = pmap_pde(kernel_pmap, va, &lvl); | pde = pmap_pde(kernel_pmap, va, &lvl); | ||||
| KASSERT(lvl == 2, ("pmap_mapbios: Invalid level %d", lvl)); | KASSERT(lvl == 2, ("pmap_mapbios: Invalid level %d", lvl)); | ||||
| /* L3 table is linked */ | /* L3 table is linked */ | ||||
| va = trunc_page(va); | va = trunc_page(va); | ||||
| pa = trunc_page(pa); | pa = trunc_page(pa); | ||||
| pmap_kenter(va, size, pa, memory_mapping_mode(pa)); | pmap_kenter_arm64(va, size, pa, memory_mapping_mode(pa)); | ||||
| } | } | ||||
| return ((void *)(va + offset)); | return ((void *)(va + offset)); | ||||
| } | } | ||||
| void | void | ||||
| pmap_unmapbios(vm_offset_t va, vm_size_t size) | pmap_unmapbios(vm_offset_t va, vm_size_t size) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 244 Lines • ▼ Show 20 Lines | for (i = 0; i < Ln_ENTRIES; i++) { | ||||
| l2[i] = newl2 | phys; | l2[i] = newl2 | phys; | ||||
| phys += L2_SIZE; | phys += L2_SIZE; | ||||
| } | } | ||||
| KASSERT(l2[0] == ((oldl1 & ~ATTR_DESCR_MASK) | L2_BLOCK), | KASSERT(l2[0] == ((oldl1 & ~ATTR_DESCR_MASK) | L2_BLOCK), | ||||
| ("Invalid l2 page (%lx != %lx)", l2[0], | ("Invalid l2 page (%lx != %lx)", l2[0], | ||||
| (oldl1 & ~ATTR_DESCR_MASK) | L2_BLOCK)); | (oldl1 & ~ATTR_DESCR_MASK) | L2_BLOCK)); | ||||
| if (tmpl1 != 0) { | if (tmpl1 != 0) { | ||||
| pmap_kenter(tmpl1, PAGE_SIZE, | pmap_kenter_arm64(tmpl1, PAGE_SIZE, | ||||
| DMAP_TO_PHYS((vm_offset_t)l1) & ~L3_OFFSET, | DMAP_TO_PHYS((vm_offset_t)l1) & ~L3_OFFSET, | ||||
| VM_MEMATTR_WRITE_BACK); | VM_MEMATTR_WRITE_BACK); | ||||
| l1 = (pt_entry_t *)(tmpl1 + ((vm_offset_t)l1 & PAGE_MASK)); | l1 = (pt_entry_t *)(tmpl1 + ((vm_offset_t)l1 & PAGE_MASK)); | ||||
| } | } | ||||
| pmap_update_entry(pmap, l1, l2phys | L1_TABLE, va, PAGE_SIZE); | pmap_update_entry(pmap, l1, l2phys | L1_TABLE, va, PAGE_SIZE); | ||||
| if (tmpl1 != 0) { | if (tmpl1 != 0) { | ||||
| ▲ Show 20 Lines • Show All 127 Lines • ▼ Show 20 Lines | pmap_demote_l2_locked(pmap_t pmap, pt_entry_t *l2, vm_offset_t va, | ||||
| */ | */ | ||||
| if (ml3->valid == 0 || (l3[0] & ATTR_MASK) != (newl3 & ATTR_MASK)) | if (ml3->valid == 0 || (l3[0] & ATTR_MASK) != (newl3 & ATTR_MASK)) | ||||
| pmap_fill_l3(l3, newl3); | pmap_fill_l3(l3, newl3); | ||||
| /* | /* | ||||
| * Map the temporary page so we don't lose access to the l2 table. | * Map the temporary page so we don't lose access to the l2 table. | ||||
| */ | */ | ||||
| if (tmpl2 != 0) { | if (tmpl2 != 0) { | ||||
| pmap_kenter(tmpl2, PAGE_SIZE, | pmap_kenter_arm64(tmpl2, PAGE_SIZE, | ||||
| DMAP_TO_PHYS((vm_offset_t)l2) & ~L3_OFFSET, | DMAP_TO_PHYS((vm_offset_t)l2) & ~L3_OFFSET, | ||||
| VM_MEMATTR_WRITE_BACK); | VM_MEMATTR_WRITE_BACK); | ||||
| l2 = (pt_entry_t *)(tmpl2 + ((vm_offset_t)l2 & PAGE_MASK)); | l2 = (pt_entry_t *)(tmpl2 + ((vm_offset_t)l2 & PAGE_MASK)); | ||||
| } | } | ||||
| /* | /* | ||||
| * The spare PV entries must be reserved prior to demoting the | * The spare PV entries must be reserved prior to demoting the | ||||
| * mapping, that is, prior to changing the PDE. Otherwise, the state | * mapping, that is, prior to changing the PDE. Otherwise, the state | ||||
| ▲ Show 20 Lines • Show All 835 Lines • Show Last 20 Lines | |||||