aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/mm/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/mm/init.c')
-rw-r--r--arch/sh/mm/init.c68
1 files changed, 53 insertions, 15 deletions
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index d5e160da64b2..2918c6b14659 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -23,9 +23,7 @@
23 23
24DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 24DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
25pgd_t swapper_pg_dir[PTRS_PER_PGD]; 25pgd_t swapper_pg_dir[PTRS_PER_PGD];
26 26unsigned long cached_to_uncached = 0;
27void (*copy_page)(void *from, void *to);
28void (*clear_page)(void *to);
29 27
30void show_mem(void) 28void show_mem(void)
31{ 29{
@@ -102,7 +100,8 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
102 100
103 set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot)); 101 set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
104 102
105 flush_tlb_one(get_asid(), addr); 103 if (cached_to_uncached)
104 flush_tlb_one(get_asid(), addr);
106} 105}
107 106
108/* 107/*
@@ -131,6 +130,37 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
131 130
132 set_pte_phys(address, phys, prot); 131 set_pte_phys(address, phys, prot);
133} 132}
133
134void __init page_table_range_init(unsigned long start, unsigned long end,
135 pgd_t *pgd_base)
136{
137 pgd_t *pgd;
138 pud_t *pud;
139 pmd_t *pmd;
140 int pgd_idx;
141 unsigned long vaddr;
142
143 vaddr = start & PMD_MASK;
144 end = (end + PMD_SIZE - 1) & PMD_MASK;
145 pgd_idx = pgd_index(vaddr);
146 pgd = pgd_base + pgd_idx;
147
148 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
149 BUG_ON(pgd_none(*pgd));
150 pud = pud_offset(pgd, 0);
151 BUG_ON(pud_none(*pud));
152 pmd = pmd_offset(pud, 0);
153
154 if (!pmd_present(*pmd)) {
155 pte_t *pte_table;
156 pte_table = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
157 memset(pte_table, 0, PAGE_SIZE);
158 pmd_populate_kernel(&init_mm, pmd, pte_table);
159 }
160
161 vaddr += PMD_SIZE;
162 }
163}
134#endif /* CONFIG_MMU */ 164#endif /* CONFIG_MMU */
135 165
136/* 166/*
@@ -150,6 +180,11 @@ void __init paging_init(void)
150 * check for a null value. */ 180 * check for a null value. */
151 set_TTB(swapper_pg_dir); 181 set_TTB(swapper_pg_dir);
152 182
183 /* Populate the relevant portions of swapper_pg_dir so that
184 * we can use the fixmap entries without calling kmalloc.
185 * pte's will be filled in by __set_fixmap(). */
186 page_table_range_init(FIXADDR_START, FIXADDR_TOP, swapper_pg_dir);
187
153 memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); 188 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
154 189
155 for_each_online_node(nid) { 190 for_each_online_node(nid) {
@@ -167,9 +202,22 @@ void __init paging_init(void)
167 } 202 }
168 203
169 free_area_init_nodes(max_zone_pfns); 204 free_area_init_nodes(max_zone_pfns);
205
206 /* Set up the uncached fixmap */
207 set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start));
208
209#ifdef CONFIG_29BIT
210 /*
211 * Handle trivial transitions between cached and uncached
212 * segments, making use of the 1:1 mapping relationship in
213 * 512MB lowmem.
214 */
215 cached_to_uncached = P2SEG - P1SEG;
216#endif
170} 217}
171 218
172static struct kcore_list kcore_mem, kcore_vmalloc; 219static struct kcore_list kcore_mem, kcore_vmalloc;
220int after_bootmem = 0;
173 221
174void __init mem_init(void) 222void __init mem_init(void)
175{ 223{
@@ -202,17 +250,7 @@ void __init mem_init(void)
202 memset(empty_zero_page, 0, PAGE_SIZE); 250 memset(empty_zero_page, 0, PAGE_SIZE);
203 __flush_wback_region(empty_zero_page, PAGE_SIZE); 251 __flush_wback_region(empty_zero_page, PAGE_SIZE);
204 252
205 /* 253 after_bootmem = 1;
206 * Setup wrappers for copy/clear_page(), these will get overridden
207 * later in the boot process if a better method is available.
208 */
209#ifdef CONFIG_MMU
210 copy_page = copy_page_slow;
211 clear_page = clear_page_slow;
212#else
213 copy_page = copy_page_nommu;
214 clear_page = clear_page_nommu;
215#endif
216 254
217 codesize = (unsigned long) &_etext - (unsigned long) &_text; 255 codesize = (unsigned long) &_etext - (unsigned long) &_text;
218 datasize = (unsigned long) &_edata - (unsigned long) &_etext; 256 datasize = (unsigned long) &_edata - (unsigned long) &_etext;