diff options
author | Jack Steiner <steiner@sgi.com> | 2008-07-01 15:45:32 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-09 01:43:23 -0400 |
commit | 3a9e189d69479736a0d0901c87ad08c9e328b389 (patch) | |
tree | e08bc871290cba63e8c8038a77be6c0732e17a1f /arch/x86/mm/init_64.c | |
parent | fc9036ea1a4b14229788e6df3936b451a6abac98 (diff) |
x86: map UV chipset space - pagetable
Add boot-time function for creating additional 2MB page table entries for
mapping chipset specific cached/uncached ranges.
Signed-off-by: Jack Steiner <steiner@sgi.com>
Cc: linux-mm@kvack.org
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm/init_64.c')
-rw-r--r-- | arch/x86/mm/init_64.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 77d129d62c97..57d5eff754c9 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -202,6 +202,46 @@ set_pte_vaddr(unsigned long vaddr, pte_t pteval) | |||
202 | } | 202 | } |
203 | 203 | ||
204 | /* | 204 | /* |
205 | * Create large page table mappings for a range of physical addresses. | ||
206 | */ | ||
207 | static void __init __init_extra_mapping(unsigned long phys, unsigned long size, | ||
208 | pgprot_t prot) | ||
209 | { | ||
210 | pgd_t *pgd; | ||
211 | pud_t *pud; | ||
212 | pmd_t *pmd; | ||
213 | |||
214 | BUG_ON((phys & ~PMD_MASK) || (size & ~PMD_MASK)); | ||
215 | for (; size; phys += PMD_SIZE, size -= PMD_SIZE) { | ||
216 | pgd = pgd_offset_k((unsigned long)__va(phys)); | ||
217 | if (pgd_none(*pgd)) { | ||
218 | pud = (pud_t *) spp_getpage(); | ||
219 | set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE | | ||
220 | _PAGE_USER)); | ||
221 | } | ||
222 | pud = pud_offset(pgd, (unsigned long)__va(phys)); | ||
223 | if (pud_none(*pud)) { | ||
224 | pmd = (pmd_t *) spp_getpage(); | ||
225 | set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | | ||
226 | _PAGE_USER)); | ||
227 | } | ||
228 | pmd = pmd_offset(pud, phys); | ||
229 | BUG_ON(!pmd_none(*pmd)); | ||
230 | set_pmd(pmd, __pmd(phys | pgprot_val(prot))); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | void __init init_extra_mapping_wb(unsigned long phys, unsigned long size) | ||
235 | { | ||
236 | __init_extra_mapping(phys, size, PAGE_KERNEL_LARGE); | ||
237 | } | ||
238 | |||
239 | void __init init_extra_mapping_uc(unsigned long phys, unsigned long size) | ||
240 | { | ||
241 | __init_extra_mapping(phys, size, PAGE_KERNEL_LARGE_NOCACHE); | ||
242 | } | ||
243 | |||
244 | /* | ||
205 | * The head.S code sets up the kernel high mapping: | 245 | * The head.S code sets up the kernel high mapping: |
206 | * | 246 | * |
207 | * from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text) | 247 | * from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text) |