| 636 | } |
| 637 | |
| 638 | static int _map_single_page_2M(unsigned long *lv0_tbl, unsigned long va, |
| 639 | unsigned long pa, unsigned long attr, |
| 640 | rt_bool_t flush) |
| 641 | { |
| 642 | int level; |
| 643 | unsigned long *cur_lv_tbl = lv0_tbl; |
| 644 | unsigned long page; |
| 645 | unsigned long off; |
| 646 | int level_shift = MMU_ADDRESS_BITS; |
| 647 | |
| 648 | if (va & ARCH_SECTION_MASK) |
| 649 | { |
| 650 | return MMU_MAP_ERROR_VANOTALIGN; |
| 651 | } |
| 652 | if (pa & ARCH_PAGE_MASK) |
| 653 | { |
| 654 | return MMU_MAP_ERROR_PANOTALIGN; |
| 655 | } |
| 656 | for (level = 0; level < MMU_TBL_BLOCK_2M_LEVEL; level++) |
| 657 | { |
| 658 | off = (va >> level_shift); |
| 659 | off &= MMU_LEVEL_MASK; |
| 660 | if (!(cur_lv_tbl[off] & MMU_TYPE_USED)) |
| 661 | { |
| 662 | page = get_free_page(); |
| 663 | if (!page) |
| 664 | { |
| 665 | return MMU_MAP_ERROR_NOPAGE; |
| 666 | } |
| 667 | rt_memset((char *)page, 0, ARCH_PAGE_SIZE); |
| 668 | cur_lv_tbl[off] = page | MMU_TYPE_TABLE; |
| 669 | if (flush) |
| 670 | { |
| 671 | rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cur_lv_tbl + off, sizeof(void *)); |
| 672 | } |
| 673 | } |
| 674 | page = cur_lv_tbl[off]; |
| 675 | if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK) |
| 676 | { |
| 677 | /* is block! error! */ |
| 678 | return MMU_MAP_ERROR_CONFLICT; |
| 679 | } |
| 680 | cur_lv_tbl = (unsigned long *)(page & MMU_ADDRESS_MASK); |
| 681 | level_shift -= MMU_LEVEL_SHIFT; |
| 682 | } |
| 683 | attr &= MMU_ATTRIB_MASK; |
| 684 | pa |= (attr | MMU_TYPE_BLOCK); /* block */ |
| 685 | off = (va >> ARCH_SECTION_SHIFT); |
| 686 | off &= MMU_LEVEL_MASK; |
| 687 | cur_lv_tbl[off] = pa; |
| 688 | if (flush) |
| 689 | { |
| 690 | rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cur_lv_tbl + off, sizeof(void *)); |
| 691 | } |
| 692 | return 0; |
| 693 | } |
| 694 | |
| 695 | void *rt_hw_mmu_tbl_get(void) |
no test coverage detected