* Remove all the allocated L1, L2 pages from SMMU pmap. * All the L3 entires must be cleared in advance, otherwise * this function panics. */
| 3785 | * this function panics. |
| 3786 | */ |
| 3787 | void |
| 3788 | pmap_sremove_pages(pmap_t pmap) |
| 3789 | { |
| 3790 | pd_entry_t l0e, *l1, l1e, *l2, l2e; |
| 3791 | pt_entry_t *l3, l3e; |
| 3792 | vm_page_t m, m0, m1; |
| 3793 | vm_offset_t sva; |
| 3794 | vm_paddr_t pa; |
| 3795 | vm_paddr_t pa0; |
| 3796 | vm_paddr_t pa1; |
| 3797 | int i, j, k, l; |
| 3798 | |
| 3799 | PMAP_LOCK(pmap); |
| 3800 | |
| 3801 | for (sva = VM_MINUSER_ADDRESS, i = pmap_l0_index(sva); |
| 3802 | (i < Ln_ENTRIES && sva < VM_MAXUSER_ADDRESS); i++) { |
| 3803 | l0e = pmap->pm_l0[i]; |
| 3804 | if ((l0e & ATTR_DESCR_VALID) == 0) { |
| 3805 | sva += L0_SIZE; |
| 3806 | continue; |
| 3807 | } |
| 3808 | pa0 = l0e & ~ATTR_MASK; |
| 3809 | m0 = PHYS_TO_VM_PAGE(pa0); |
| 3810 | l1 = (pd_entry_t *)PHYS_TO_DMAP(pa0); |
| 3811 | |
| 3812 | for (j = pmap_l1_index(sva); j < Ln_ENTRIES; j++) { |
| 3813 | l1e = l1[j]; |
| 3814 | if ((l1e & ATTR_DESCR_VALID) == 0) { |
| 3815 | sva += L1_SIZE; |
| 3816 | continue; |
| 3817 | } |
| 3818 | if ((l1e & ATTR_DESCR_MASK) == L1_BLOCK) { |
| 3819 | sva += L1_SIZE; |
| 3820 | continue; |
| 3821 | } |
| 3822 | pa1 = l1e & ~ATTR_MASK; |
| 3823 | m1 = PHYS_TO_VM_PAGE(pa1); |
| 3824 | l2 = (pd_entry_t *)PHYS_TO_DMAP(pa1); |
| 3825 | |
| 3826 | for (k = pmap_l2_index(sva); k < Ln_ENTRIES; k++) { |
| 3827 | l2e = l2[k]; |
| 3828 | if ((l2e & ATTR_DESCR_VALID) == 0) { |
| 3829 | sva += L2_SIZE; |
| 3830 | continue; |
| 3831 | } |
| 3832 | pa = l2e & ~ATTR_MASK; |
| 3833 | m = PHYS_TO_VM_PAGE(pa); |
| 3834 | l3 = (pt_entry_t *)PHYS_TO_DMAP(pa); |
| 3835 | |
| 3836 | for (l = pmap_l3_index(sva); l < Ln_ENTRIES; |
| 3837 | l++, sva += L3_SIZE) { |
| 3838 | l3e = l3[l]; |
| 3839 | if ((l3e & ATTR_DESCR_VALID) == 0) |
| 3840 | continue; |
| 3841 | panic("%s: l3e found for va %jx\n", |
| 3842 | __func__, sva); |
| 3843 | } |
| 3844 |
no test coverage detected