aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/mm/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/tile/mm/init.c')
-rw-r--r--arch/tile/mm/init.c70
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__
154static 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
162static 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 */
165static void __init page_table_range_init(unsigned long start, 179static 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__
408static 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
413static 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. */
423static pgd_t pgtables[PTRS_PER_PGD] 415static 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 */
780void __init paging_init(void) 771void __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