unmap page table entry */
| 218 | |
| 219 | /* unmap page table entry */ |
| 220 | static void _unmap_pte(rt_ubase_t *pentry, rt_ubase_t *lvl_entry[], int level) |
| 221 | { |
| 222 | int loop_flag = 1; |
| 223 | while (loop_flag) |
| 224 | { |
| 225 | loop_flag = 0; |
| 226 | *pentry = 0; |
| 227 | rt_hw_cpu_dcache_clean(pentry, sizeof(*pentry)); |
| 228 | |
| 229 | /* we don't handle level 0, which is maintained by caller */ |
| 230 | if (level > 0) |
| 231 | { |
| 232 | void *page = (void *)((rt_ubase_t)pentry & ~ARCH_PAGE_MASK); |
| 233 | |
| 234 | /* decrease reference from child page to parent */ |
| 235 | rt_pages_free(page, 0); |
| 236 | |
| 237 | int free = rt_page_ref_get(page, 0); |
| 238 | if (free == 1) |
| 239 | { |
| 240 | rt_pages_free(page, 0); |
| 241 | pentry = lvl_entry[--level]; |
| 242 | loop_flag = 1; |
| 243 | } |
| 244 | } |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | /* Unmaps a virtual address range (1GB/2MB/4KB according to actual page level) from the page table. */ |
| 249 | static size_t _unmap_area(struct rt_aspace *aspace, void *v_addr) |
no test coverage detected