diff options
author | Guo Ren <guoren@linux.alibaba.com> | 2019-12-01 22:34:19 +0800 |
---|---|---|
committer | Guo Ren <guoren@linux.alibaba.com> | 2020-02-21 15:43:24 +0800 |
commit | f136008f31e91060d6b6e6e031cb2c827448e280 (patch) | |
tree | c3b978edb1107ca151b85c75c729f6f78c543bf4 /arch/csky/mm/init.c | |
parent | f525bb2c9e7cf1e3c43ab57704c9e1c836d30b34 (diff) | |
download | linux-f136008f31e91060d6b6e6e031cb2c827448e280.tar.gz linux-f136008f31e91060d6b6e6e031cb2c827448e280.tar.bz2 linux-f136008f31e91060d6b6e6e031cb2c827448e280.zip |
csky: Separate fixaddr_init from highmem
After fixaddr_init is separated from highmem, we could use tcm
without highmem selected. (610 (abiv1) don't support highmem,
but it could use tcm now.)
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Diffstat (limited to 'arch/csky/mm/init.c')
-rw-r--r-- | arch/csky/mm/init.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/arch/csky/mm/init.c b/arch/csky/mm/init.c index d4c2292ea46b..322eb7bd7962 100644 --- a/arch/csky/mm/init.c +++ b/arch/csky/mm/init.c @@ -101,3 +101,50 @@ void __init pre_mmu_init(void) /* Setup page mask to 4k */ write_mmu_pagemask(0); } + +void __init fixrange_init(unsigned long start, unsigned long end, + pgd_t *pgd_base) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + int i, j, k; + unsigned long vaddr; + + vaddr = start; + i = __pgd_offset(vaddr); + j = __pud_offset(vaddr); + k = __pmd_offset(vaddr); + pgd = pgd_base + i; + + for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) { + pud = (pud_t *)pgd; + for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) { + pmd = (pmd_t *)pud; + for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) { + if (pmd_none(*pmd)) { + pte = (pte_t *) memblock_alloc_low(PAGE_SIZE, PAGE_SIZE); + if (!pte) + panic("%s: Failed to allocate %lu bytes align=%lx\n", + __func__, PAGE_SIZE, + PAGE_SIZE); + + set_pmd(pmd, __pmd(__pa(pte))); + BUG_ON(pte != pte_offset_kernel(pmd, 0)); + } + vaddr += PMD_SIZE; + } + k = 0; + } + j = 0; + } +} + +void __init fixaddr_init(void) +{ + unsigned long vaddr; + + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; + fixrange_init(vaddr, vaddr + PMD_SIZE, swapper_pg_dir); +} |