diff options
Diffstat (limited to 'arch/xtensa/mm/mmu.c')
-rw-r--r-- | arch/xtensa/mm/mmu.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index 3429b483d9f8..abe4513eb0dd 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c | |||
@@ -18,32 +18,38 @@ | |||
18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | 19 | ||
20 | #if defined(CONFIG_HIGHMEM) | 20 | #if defined(CONFIG_HIGHMEM) |
21 | static void * __init init_pmd(unsigned long vaddr) | 21 | static void * __init init_pmd(unsigned long vaddr, unsigned long n_pages) |
22 | { | 22 | { |
23 | pgd_t *pgd = pgd_offset_k(vaddr); | 23 | pgd_t *pgd = pgd_offset_k(vaddr); |
24 | pmd_t *pmd = pmd_offset(pgd, vaddr); | 24 | pmd_t *pmd = pmd_offset(pgd, vaddr); |
25 | pte_t *pte; | ||
26 | unsigned long i; | ||
25 | 27 | ||
26 | if (pmd_none(*pmd)) { | 28 | n_pages = ALIGN(n_pages, PTRS_PER_PTE); |
27 | unsigned i; | ||
28 | pte_t *pte = alloc_bootmem_low_pages(PAGE_SIZE); | ||
29 | 29 | ||
30 | for (i = 0; i < 1024; i++) | 30 | pr_debug("%s: vaddr: 0x%08lx, n_pages: %ld\n", |
31 | pte_clear(NULL, 0, pte + i); | 31 | __func__, vaddr, n_pages); |
32 | 32 | ||
33 | set_pmd(pmd, __pmd(((unsigned long)pte) & PAGE_MASK)); | 33 | pte = alloc_bootmem_low_pages(n_pages * sizeof(pte_t)); |
34 | BUG_ON(pte != pte_offset_kernel(pmd, 0)); | 34 | |
35 | pr_debug("%s: vaddr: 0x%08lx, pmd: 0x%p, pte: 0x%p\n", | 35 | for (i = 0; i < n_pages; ++i) |
36 | __func__, vaddr, pmd, pte); | 36 | pte_clear(NULL, 0, pte + i); |
37 | return pte; | 37 | |
38 | } else { | 38 | for (i = 0; i < n_pages; i += PTRS_PER_PTE, ++pmd) { |
39 | return pte_offset_kernel(pmd, 0); | 39 | pte_t *cur_pte = pte + i; |
40 | |||
41 | BUG_ON(!pmd_none(*pmd)); | ||
42 | set_pmd(pmd, __pmd(((unsigned long)cur_pte) & PAGE_MASK)); | ||
43 | BUG_ON(cur_pte != pte_offset_kernel(pmd, 0)); | ||
44 | pr_debug("%s: pmd: 0x%p, pte: 0x%p\n", | ||
45 | __func__, pmd, cur_pte); | ||
40 | } | 46 | } |
47 | return pte; | ||
41 | } | 48 | } |
42 | 49 | ||
43 | static void __init fixedrange_init(void) | 50 | static void __init fixedrange_init(void) |
44 | { | 51 | { |
45 | BUILD_BUG_ON(FIXADDR_SIZE > PMD_SIZE); | 52 | init_pmd(__fix_to_virt(0), __end_of_fixed_addresses); |
46 | init_pmd(__fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK); | ||
47 | } | 53 | } |
48 | #endif | 54 | #endif |
49 | 55 | ||
@@ -52,7 +58,7 @@ void __init paging_init(void) | |||
52 | memset(swapper_pg_dir, 0, PAGE_SIZE); | 58 | memset(swapper_pg_dir, 0, PAGE_SIZE); |
53 | #ifdef CONFIG_HIGHMEM | 59 | #ifdef CONFIG_HIGHMEM |
54 | fixedrange_init(); | 60 | fixedrange_init(); |
55 | pkmap_page_table = init_pmd(PKMAP_BASE); | 61 | pkmap_page_table = init_pmd(PKMAP_BASE, LAST_PKMAP); |
56 | kmap_init(); | 62 | kmap_init(); |
57 | #endif | 63 | #endif |
58 | } | 64 | } |