diff options
Diffstat (limited to 'arch/tile/mm/init.c')
-rw-r--r-- | arch/tile/mm/init.c | 70 |
1 files changed, 29 insertions, 41 deletions
diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c index 630dd2ce2afe..ef29d6c5e10e 100644 --- a/arch/tile/mm/init.c +++ b/arch/tile/mm/init.c | |||
@@ -150,7 +150,21 @@ void __init shatter_pmd(pmd_t *pmd) | |||
150 | assign_pte(pmd, pte); | 150 | assign_pte(pmd, pte); |
151 | } | 151 | } |
152 | 152 | ||
153 | #ifdef CONFIG_HIGHMEM | 153 | #ifdef __tilegx__ |
154 | static pmd_t *__init get_pmd(pgd_t pgtables[], unsigned long va) | ||
155 | { | ||
156 | pud_t *pud = pud_offset(&pgtables[pgd_index(va)], va); | ||
157 | if (pud_none(*pud)) | ||
158 | assign_pmd(pud, alloc_pmd()); | ||
159 | return pmd_offset(pud, va); | ||
160 | } | ||
161 | #else | ||
162 | static pmd_t *__init get_pmd(pgd_t pgtables[], unsigned long va) | ||
163 | { | ||
164 | return pmd_offset(pud_offset(&pgtables[pgd_index(va)], va), va); | ||
165 | } | ||
166 | #endif | ||
167 | |||
154 | /* | 168 | /* |
155 | * This function initializes a certain range of kernel virtual memory | 169 | * This function initializes a certain range of kernel virtual memory |
156 | * with new bootmem page tables, everywhere page tables are missing in | 170 | * with new bootmem page tables, everywhere page tables are missing in |
@@ -163,24 +177,17 @@ void __init shatter_pmd(pmd_t *pmd) | |||
163 | * checking the pgd every time. | 177 | * checking the pgd every time. |
164 | */ | 178 | */ |
165 | static void __init page_table_range_init(unsigned long start, | 179 | static void __init page_table_range_init(unsigned long start, |
166 | unsigned long end, pgd_t *pgd_base) | 180 | unsigned long end, pgd_t *pgd) |
167 | { | 181 | { |
168 | pgd_t *pgd; | ||
169 | int pgd_idx; | ||
170 | unsigned long vaddr; | 182 | unsigned long vaddr; |
171 | 183 | start = round_down(start, PMD_SIZE); | |
172 | vaddr = start; | 184 | end = round_up(end, PMD_SIZE); |
173 | pgd_idx = pgd_index(vaddr); | 185 | for (vaddr = start; vaddr < end; vaddr += PMD_SIZE) { |
174 | pgd = pgd_base + pgd_idx; | 186 | pmd_t *pmd = get_pmd(pgd, vaddr); |
175 | |||
176 | for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) { | ||
177 | pmd_t *pmd = pmd_offset(pud_offset(pgd, vaddr), vaddr); | ||
178 | if (pmd_none(*pmd)) | 187 | if (pmd_none(*pmd)) |
179 | assign_pte(pmd, alloc_pte()); | 188 | assign_pte(pmd, alloc_pte()); |
180 | vaddr += PMD_SIZE; | ||
181 | } | 189 | } |
182 | } | 190 | } |
183 | #endif /* CONFIG_HIGHMEM */ | ||
184 | 191 | ||
185 | 192 | ||
186 | #if CHIP_HAS_CBOX_HOME_MAP() | 193 | #if CHIP_HAS_CBOX_HOME_MAP() |
@@ -404,21 +411,6 @@ static inline pgprot_t ktext_set_nocache(pgprot_t prot) | |||
404 | return prot; | 411 | return prot; |
405 | } | 412 | } |
406 | 413 | ||
407 | #ifndef __tilegx__ | ||
408 | static pmd_t *__init get_pmd(pgd_t pgtables[], unsigned long va) | ||
409 | { | ||
410 | return pmd_offset(pud_offset(&pgtables[pgd_index(va)], va), va); | ||
411 | } | ||
412 | #else | ||
413 | static pmd_t *__init get_pmd(pgd_t pgtables[], unsigned long va) | ||
414 | { | ||
415 | pud_t *pud = pud_offset(&pgtables[pgd_index(va)], va); | ||
416 | if (pud_none(*pud)) | ||
417 | assign_pmd(pud, alloc_pmd()); | ||
418 | return pmd_offset(pud, va); | ||
419 | } | ||
420 | #endif | ||
421 | |||
422 | /* Temporary page table we use for staging. */ | 414 | /* Temporary page table we use for staging. */ |
423 | static pgd_t pgtables[PTRS_PER_PGD] | 415 | static pgd_t pgtables[PTRS_PER_PGD] |
424 | __attribute__((aligned(HV_PAGE_TABLE_ALIGN))); | 416 | __attribute__((aligned(HV_PAGE_TABLE_ALIGN))); |
@@ -741,16 +733,15 @@ static void __init set_non_bootmem_pages_init(void) | |||
741 | for_each_zone(z) { | 733 | for_each_zone(z) { |
742 | unsigned long start, end; | 734 | unsigned long start, end; |
743 | int nid = z->zone_pgdat->node_id; | 735 | int nid = z->zone_pgdat->node_id; |
736 | #ifdef CONFIG_HIGHMEM | ||
744 | int idx = zone_idx(z); | 737 | int idx = zone_idx(z); |
738 | #endif | ||
745 | 739 | ||
746 | start = z->zone_start_pfn; | 740 | start = z->zone_start_pfn; |
747 | if (start == 0) | ||
748 | continue; /* bootmem */ | ||
749 | end = start + z->spanned_pages; | 741 | end = start + z->spanned_pages; |
750 | if (idx == ZONE_NORMAL) { | 742 | start = max(start, node_free_pfn[nid]); |
751 | BUG_ON(start != node_start_pfn[nid]); | 743 | start = max(start, max_low_pfn); |
752 | start = node_free_pfn[nid]; | 744 | |
753 | } | ||
754 | #ifdef CONFIG_HIGHMEM | 745 | #ifdef CONFIG_HIGHMEM |
755 | if (idx == ZONE_HIGHMEM) | 746 | if (idx == ZONE_HIGHMEM) |
756 | totalhigh_pages += z->spanned_pages; | 747 | totalhigh_pages += z->spanned_pages; |
@@ -779,9 +770,6 @@ static void __init set_non_bootmem_pages_init(void) | |||
779 | */ | 770 | */ |
780 | void __init paging_init(void) | 771 | void __init paging_init(void) |
781 | { | 772 | { |
782 | #ifdef CONFIG_HIGHMEM | ||
783 | unsigned long vaddr, end; | ||
784 | #endif | ||
785 | #ifdef __tilegx__ | 773 | #ifdef __tilegx__ |
786 | pud_t *pud; | 774 | pud_t *pud; |
787 | #endif | 775 | #endif |
@@ -789,14 +777,14 @@ void __init paging_init(void) | |||
789 | 777 | ||
790 | kernel_physical_mapping_init(pgd_base); | 778 | kernel_physical_mapping_init(pgd_base); |
791 | 779 | ||
792 | #ifdef CONFIG_HIGHMEM | ||
793 | /* | 780 | /* |
794 | * Fixed mappings, only the page table structure has to be | 781 | * Fixed mappings, only the page table structure has to be |
795 | * created - mappings will be set by set_fixmap(): | 782 | * created - mappings will be set by set_fixmap(): |
796 | */ | 783 | */ |
797 | vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; | 784 | page_table_range_init(fix_to_virt(__end_of_fixed_addresses - 1), |
798 | end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK; | 785 | FIXADDR_TOP, pgd_base); |
799 | page_table_range_init(vaddr, end, pgd_base); | 786 | |
787 | #ifdef CONFIG_HIGHMEM | ||
800 | permanent_kmaps_init(pgd_base); | 788 | permanent_kmaps_init(pgd_base); |
801 | #endif | 789 | #endif |
802 | 790 | ||