| 206 | } |
| 207 | |
| 208 | static int _kernel_map_2M(unsigned long *lv0_tbl, void *vaddr, void *paddr, unsigned long attr) |
| 209 | { |
| 210 | int ret = 0; |
| 211 | int level; |
| 212 | unsigned long *cur_lv_tbl = lv0_tbl; |
| 213 | unsigned long page; |
| 214 | unsigned long off; |
| 215 | unsigned long va = (unsigned long)vaddr; |
| 216 | unsigned long pa = (unsigned long)paddr; |
| 217 | |
| 218 | int level_shift = MMU_ADDRESS_BITS; |
| 219 | |
| 220 | if (va & ARCH_SECTION_MASK) |
| 221 | { |
| 222 | return MMU_MAP_ERROR_VANOTALIGN; |
| 223 | } |
| 224 | if (pa & ARCH_PAGE_MASK) |
| 225 | { |
| 226 | return MMU_MAP_ERROR_PANOTALIGN; |
| 227 | } |
| 228 | for (level = 0; level < MMU_TBL_BLOCK_2M_LEVEL; level++) |
| 229 | { |
| 230 | off = (va >> level_shift); |
| 231 | off &= MMU_LEVEL_MASK; |
| 232 | if (!(cur_lv_tbl[off] & MMU_TYPE_USED)) |
| 233 | { |
| 234 | page = (unsigned long)rt_pages_alloc_ext(0, PAGE_ANY_AVAILABLE); |
| 235 | if (!page) |
| 236 | { |
| 237 | ret = MMU_MAP_ERROR_NOPAGE; |
| 238 | goto err; |
| 239 | } |
| 240 | rt_memset((char *)page, 0, ARCH_PAGE_SIZE); |
| 241 | rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)page, ARCH_PAGE_SIZE); |
| 242 | cur_lv_tbl[off] = (page + PV_OFFSET) | MMU_TYPE_TABLE; |
| 243 | rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cur_lv_tbl + off, sizeof(void *)); |
| 244 | } |
| 245 | else |
| 246 | { |
| 247 | page = cur_lv_tbl[off]; |
| 248 | page &= MMU_ADDRESS_MASK; |
| 249 | /* page to va */ |
| 250 | page -= PV_OFFSET; |
| 251 | rt_page_ref_inc((void *)page, 0); |
| 252 | } |
| 253 | page = cur_lv_tbl[off]; |
| 254 | if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK) |
| 255 | { |
| 256 | /* is block! error! */ |
| 257 | ret = MMU_MAP_ERROR_CONFLICT; |
| 258 | goto err; |
| 259 | } |
| 260 | cur_lv_tbl = (unsigned long *)(page & MMU_ADDRESS_MASK); |
| 261 | cur_lv_tbl = (unsigned long *)((unsigned long)cur_lv_tbl - PV_OFFSET); |
| 262 | level_shift -= MMU_LEVEL_SHIFT; |
| 263 | } |
| 264 | /* now is level page */ |
| 265 | attr &= MMU_ATTRIB_MASK; |
nothing calls this directly
no test coverage detected