114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras/* 214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * This file contains the routines setting up the linux page tables. 314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * -- paulus 414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * 514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Derived from arch/ppc/mm/init.c: 614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * 814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * and Cort Dougan (PReP) (cort@cs.nmt.edu) 1014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Copyright (C) 1996 Paul Mackerras 1114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * 1214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Derived from "arch/i386/mm/init.c" 1314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 1414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * 1514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * This program is free software; you can redistribute it and/or 1614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * modify it under the terms of the GNU General Public License 1714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * as published by the Free Software Foundation; either version 1814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * 2 of the License, or (at your option) any later version. 1914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * 2014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 2114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 2214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/kernel.h> 2314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/module.h> 2414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/types.h> 2514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/mm.h> 2614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/vmalloc.h> 2714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/init.h> 2814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/highmem.h> 2995f72d1ed41a66f1c1c29c24d479de81a0bea36fYinghai Lu#include <linux/memblock.h> 305a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 3114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 3214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <asm/pgtable.h> 3314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <asm/pgalloc.h> 342c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala#include <asm/fixmap.h> 3514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <asm/io.h> 36ae3a197e3d0bfe3f4bf1693723e82dc018c096f3David Howells#include <asm/setup.h> 3714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 3814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include "mmu_decl.h" 3914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 4014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasunsigned long ioremap_base; 4114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasunsigned long ioremap_bot; 42920573bd03bf690135967b5022362d34ede589c3Olaf HeringEXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */ 4314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 44c3993f10076ae1fa479d5b3e227fe15e001c45a9Michael Ellerman#ifdef CONFIG_6xx 4514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define HAVE_BATS 1 4614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#endif 4714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 4814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#if defined(CONFIG_FSL_BOOKE) 4914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define HAVE_TLBCAM 1 5014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#endif 5114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 5214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasextern char etext[], _stext[]; 5314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 5414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#ifdef HAVE_BATS 557c5c4325d2d911fe54db3bc14149bfa558ae0acbBecky Bruceextern phys_addr_t v_mapped_by_bats(unsigned long va); 567c5c4325d2d911fe54db3bc14149bfa558ae0acbBecky Bruceextern unsigned long p_mapped_by_bats(phys_addr_t pa); 577c5c4325d2d911fe54db3bc14149bfa558ae0acbBecky Brucevoid setbat(int index, unsigned long virt, phys_addr_t phys, 5814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras unsigned int size, int flags); 5914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 6014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#else /* !HAVE_BATS */ 6114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define v_mapped_by_bats(x) (0UL) 6214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define p_mapped_by_bats(x) (0UL) 6314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#endif /* HAVE_BATS */ 6414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 6514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#ifdef HAVE_TLBCAM 6614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasextern unsigned int tlbcam_index; 676c24b17453c8dc444a746e45b8a404498fc9fcf7Kumar Galaextern phys_addr_t v_mapped_by_tlbcam(unsigned long va); 686c24b17453c8dc444a746e45b8a404498fc9fcf7Kumar Galaextern unsigned long p_mapped_by_tlbcam(phys_addr_t pa); 6914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#else /* !HAVE_TLBCAM */ 7014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define v_mapped_by_tlbcam(x) (0UL) 7114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define p_mapped_by_tlbcam(x) (0UL) 7214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#endif /* HAVE_TLBCAM */ 7314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 74ca9153a3a2a7556d091dfe080e42b0e67881fff6Ilya Yanok#define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT) 7514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 7614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerraspgd_t *pgd_alloc(struct mm_struct *mm) 7714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 7814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras pgd_t *ret; 7914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 80ca9153a3a2a7556d091dfe080e42b0e67881fff6Ilya Yanok /* pgdir take page or two with 4K pages and a page fraction otherwise */ 81ca9153a3a2a7556d091dfe080e42b0e67881fff6Ilya Yanok#ifndef CONFIG_PPC_4K_PAGES 82ae9fd31a3668ca97e8f37698b927ae7c0b70807aJesper Juhl ret = kzalloc(1 << PGDIR_ORDER, GFP_KERNEL); 83ca9153a3a2a7556d091dfe080e42b0e67881fff6Ilya Yanok#else 84ca9153a3a2a7556d091dfe080e42b0e67881fff6Ilya Yanok ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, 85ca9153a3a2a7556d091dfe080e42b0e67881fff6Ilya Yanok PGDIR_ORDER - PAGE_SHIFT); 86ca9153a3a2a7556d091dfe080e42b0e67881fff6Ilya Yanok#endif 8714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return ret; 8814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 8914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 905e5419734c8719cbc01af959ad9c0844002c0df5Benjamin Herrenschmidtvoid pgd_free(struct mm_struct *mm, pgd_t *pgd) 9114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 92ca9153a3a2a7556d091dfe080e42b0e67881fff6Ilya Yanok#ifndef CONFIG_PPC_4K_PAGES 93ca9153a3a2a7556d091dfe080e42b0e67881fff6Ilya Yanok kfree((void *)pgd); 94ca9153a3a2a7556d091dfe080e42b0e67881fff6Ilya Yanok#else 95ca9153a3a2a7556d091dfe080e42b0e67881fff6Ilya Yanok free_pages((unsigned long)pgd, PGDIR_ORDER - PAGE_SHIFT); 96ca9153a3a2a7556d091dfe080e42b0e67881fff6Ilya Yanok#endif 9714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 9814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 99f1aed92464def83fc3677cade823cad71cf5f0d4Kumar Gala__init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) 10014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 10114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras pte_t *pte; 10214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras extern int mem_init_done; 10314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras extern void *early_get_page(void); 10414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 10514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (mem_init_done) { 10614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); 10714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } else { 10814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras pte = (pte_t *)early_get_page(); 10914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (pte) 11014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras clear_page(pte); 11114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 11214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return pte; 11314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 11414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 1152f569afd9ced9ebec9a6eb3dbf6f83429be0a7b4Martin Schwidefskypgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) 11614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 11714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras struct page *ptepage; 11814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 1192f569afd9ced9ebec9a6eb3dbf6f83429be0a7b4Martin Schwidefsky gfp_t flags = GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO; 12014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 12114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras ptepage = alloc_pages(flags, 0); 1222f569afd9ced9ebec9a6eb3dbf6f83429be0a7b4Martin Schwidefsky if (!ptepage) 1232f569afd9ced9ebec9a6eb3dbf6f83429be0a7b4Martin Schwidefsky return NULL; 1244f804943f99454ac79e0f448428447f1a72d09fcKirill A. Shutemov if (!pgtable_page_ctor(ptepage)) { 1254f804943f99454ac79e0f448428447f1a72d09fcKirill A. Shutemov __free_page(ptepage); 1264f804943f99454ac79e0f448428447f1a72d09fcKirill A. Shutemov return NULL; 1274f804943f99454ac79e0f448428447f1a72d09fcKirill A. Shutemov } 12814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return ptepage; 12914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 13014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 13114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasvoid __iomem * 13214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasioremap(phys_addr_t addr, unsigned long size) 13314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 1341cdab55d8a8313f77a95fb8ca966dc4334f8e810Benjamin Herrenschmidt return __ioremap_caller(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED, 1351cdab55d8a8313f77a95fb8ca966dc4334f8e810Benjamin Herrenschmidt __builtin_return_address(0)); 13614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 137920573bd03bf690135967b5022362d34ede589c3Olaf HeringEXPORT_SYMBOL(ioremap); 13814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 13914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasvoid __iomem * 140be135f40899cb3334faa7d2e27025055da311ec4Anton Blanchardioremap_wc(phys_addr_t addr, unsigned long size) 141be135f40899cb3334faa7d2e27025055da311ec4Anton Blanchard{ 142be135f40899cb3334faa7d2e27025055da311ec4Anton Blanchard return __ioremap_caller(addr, size, _PAGE_NO_CACHE, 143be135f40899cb3334faa7d2e27025055da311ec4Anton Blanchard __builtin_return_address(0)); 144be135f40899cb3334faa7d2e27025055da311ec4Anton Blanchard} 145be135f40899cb3334faa7d2e27025055da311ec4Anton BlanchardEXPORT_SYMBOL(ioremap_wc); 146be135f40899cb3334faa7d2e27025055da311ec4Anton Blanchard 147be135f40899cb3334faa7d2e27025055da311ec4Anton Blanchardvoid __iomem * 14840f1ce7fb7e8b5d4d0821c0f3dc866cb1d47d99cAnton Blanchardioremap_prot(phys_addr_t addr, unsigned long size, unsigned long flags) 14968a64357d15ae4f596e92715719071952006e83cBenjamin Herrenschmidt{ 150a1f242ff460e4b50a045fa237c3c56cce9eabf83Benjamin Herrenschmidt /* writeable implies dirty for kernel addresses */ 151a1f242ff460e4b50a045fa237c3c56cce9eabf83Benjamin Herrenschmidt if (flags & _PAGE_RW) 152a1f242ff460e4b50a045fa237c3c56cce9eabf83Benjamin Herrenschmidt flags |= _PAGE_DIRTY | _PAGE_HWWRITE; 153a1f242ff460e4b50a045fa237c3c56cce9eabf83Benjamin Herrenschmidt 154a1f242ff460e4b50a045fa237c3c56cce9eabf83Benjamin Herrenschmidt /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */ 155ea3cc330ac0cd521ff07c7cd432a1848c19a7e92Benjamin Herrenschmidt flags &= ~(_PAGE_USER | _PAGE_EXEC); 156a1f242ff460e4b50a045fa237c3c56cce9eabf83Benjamin Herrenschmidt 15755052eeca6d71d76f7c3f156c0501814d8e5e6d3Benjamin Herrenschmidt#ifdef _PAGE_BAP_SR 15855052eeca6d71d76f7c3f156c0501814d8e5e6d3Benjamin Herrenschmidt /* _PAGE_USER contains _PAGE_BAP_SR on BookE using the new PTE format 15955052eeca6d71d76f7c3f156c0501814d8e5e6d3Benjamin Herrenschmidt * which means that we just cleared supervisor access... oops ;-) This 16055052eeca6d71d76f7c3f156c0501814d8e5e6d3Benjamin Herrenschmidt * restores it 16155052eeca6d71d76f7c3f156c0501814d8e5e6d3Benjamin Herrenschmidt */ 16255052eeca6d71d76f7c3f156c0501814d8e5e6d3Benjamin Herrenschmidt flags |= _PAGE_BAP_SR; 16355052eeca6d71d76f7c3f156c0501814d8e5e6d3Benjamin Herrenschmidt#endif 16455052eeca6d71d76f7c3f156c0501814d8e5e6d3Benjamin Herrenschmidt 1651cdab55d8a8313f77a95fb8ca966dc4334f8e810Benjamin Herrenschmidt return __ioremap_caller(addr, size, flags, __builtin_return_address(0)); 16668a64357d15ae4f596e92715719071952006e83cBenjamin Herrenschmidt} 16740f1ce7fb7e8b5d4d0821c0f3dc866cb1d47d99cAnton BlanchardEXPORT_SYMBOL(ioremap_prot); 16868a64357d15ae4f596e92715719071952006e83cBenjamin Herrenschmidt 16968a64357d15ae4f596e92715719071952006e83cBenjamin Herrenschmidtvoid __iomem * 17014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags) 17114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 1721cdab55d8a8313f77a95fb8ca966dc4334f8e810Benjamin Herrenschmidt return __ioremap_caller(addr, size, flags, __builtin_return_address(0)); 1731cdab55d8a8313f77a95fb8ca966dc4334f8e810Benjamin Herrenschmidt} 1741cdab55d8a8313f77a95fb8ca966dc4334f8e810Benjamin Herrenschmidt 1751cdab55d8a8313f77a95fb8ca966dc4334f8e810Benjamin Herrenschmidtvoid __iomem * 1761cdab55d8a8313f77a95fb8ca966dc4334f8e810Benjamin Herrenschmidt__ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags, 1771cdab55d8a8313f77a95fb8ca966dc4334f8e810Benjamin Herrenschmidt void *caller) 1781cdab55d8a8313f77a95fb8ca966dc4334f8e810Benjamin Herrenschmidt{ 17914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras unsigned long v, i; 18014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras phys_addr_t p; 18114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras int err; 18214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 183a1f242ff460e4b50a045fa237c3c56cce9eabf83Benjamin Herrenschmidt /* Make sure we have the base flags */ 184a1f242ff460e4b50a045fa237c3c56cce9eabf83Benjamin Herrenschmidt if ((flags & _PAGE_PRESENT) == 0) 1858d1cf34e7ad5c7738ce20d20bd7f002f562cb8b5Benjamin Herrenschmidt flags |= PAGE_KERNEL; 186a1f242ff460e4b50a045fa237c3c56cce9eabf83Benjamin Herrenschmidt 187a1f242ff460e4b50a045fa237c3c56cce9eabf83Benjamin Herrenschmidt /* Non-cacheable page cannot be coherent */ 188a1f242ff460e4b50a045fa237c3c56cce9eabf83Benjamin Herrenschmidt if (flags & _PAGE_NO_CACHE) 189a1f242ff460e4b50a045fa237c3c56cce9eabf83Benjamin Herrenschmidt flags &= ~_PAGE_COHERENT; 190a1f242ff460e4b50a045fa237c3c56cce9eabf83Benjamin Herrenschmidt 19114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* 19214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Choose an address to map it to. 19314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Once the vmalloc system is running, we use it. 19414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Before then, we use space going down from ioremap_base 19514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * (ioremap_bot records where we're up to). 19614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 19714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras p = addr & PAGE_MASK; 19814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras size = PAGE_ALIGN(addr + size) - p; 19914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 20014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* 20114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * If the address lies within the first 16 MB, assume it's in ISA 20214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * memory space 20314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 20414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (p < 16*1024*1024) 20514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras p += _ISA_MEM_BASE; 20614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 20701695a9687e5a8d78589605037cc7828a5b67ac9Anton Vorontsov#ifndef CONFIG_CRASH_DUMP 20814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* 20914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Don't allow anybody to remap normal RAM that we're using. 21014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * mem_init() sets high_memory so only do the check after that. 21114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 212c5df7f775148723de39274537a886e9502eef336Albert Herranz if (mem_init_done && (p < virt_to_phys(high_memory)) && 21395f72d1ed41a66f1c1c29c24d479de81a0bea36fYinghai Lu !(__allow_ioremap_reserved && memblock_is_region_reserved(p, size))) { 214a2234b4baefe2a2742b5fa8839be1ab1aca39057Joe Perches printk("__ioremap(): phys addr 0x%llx is RAM lr %pf\n", 21537f01d64d83705f82bb06eac8134acc8ef665565David Gibson (unsigned long long)p, __builtin_return_address(0)); 21614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return NULL; 21714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 21801695a9687e5a8d78589605037cc7828a5b67ac9Anton Vorontsov#endif 21914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 22014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (size == 0) 22114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return NULL; 22214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 22314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* 22414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Is it already mapped? Perhaps overlapped by a previous 22514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * BAT mapping. If the whole area is mapped then we're done, 22614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * otherwise remap it since we want to keep the virt addrs for 22714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * each request contiguous. 22814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * 22914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * We make the assumption here that if the bottom and top 23014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * of the range we want are mapped then it's mapped to the 23114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * same virt address (and this is contiguous). 23214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * -- Cort 23314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 23414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ ) 23514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras goto out; 23614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 23714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if ((v = p_mapped_by_tlbcam(p))) 23814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras goto out; 23914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 24014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (mem_init_done) { 24114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras struct vm_struct *area; 2421cdab55d8a8313f77a95fb8ca966dc4334f8e810Benjamin Herrenschmidt area = get_vm_area_caller(size, VM_IOREMAP, caller); 24314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (area == 0) 24414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return NULL; 2457a9d12568e34e37a72d9e00ce01b62dec527e663Michael Ellerman area->phys_addr = p; 24614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras v = (unsigned long) area->addr; 24714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } else { 24814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras v = (ioremap_bot -= size); 24914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 25014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 25114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* 25214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Should check if it is a candidate for a BAT mapping 25314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 25414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 25514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras err = 0; 25614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras for (i = 0; i < size && err == 0; i += PAGE_SIZE) 25714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras err = map_page(v+i, p+i, flags); 25814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (err) { 25914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (mem_init_done) 26014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras vunmap((void *)v); 26114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return NULL; 26214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 26314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 26414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasout: 26514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return (void __iomem *) (v + ((unsigned long)addr & ~PAGE_MASK)); 26614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 267920573bd03bf690135967b5022362d34ede589c3Olaf HeringEXPORT_SYMBOL(__ioremap); 26814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 26914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasvoid iounmap(volatile void __iomem *addr) 27014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 27114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* 27214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * If mapped by BATs then there is nothing to do. 27314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Calling vfree() generates a benign warning. 27414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 27514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (v_mapped_by_bats((unsigned long)addr)) return; 27614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 27714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (addr > high_memory && (unsigned long) addr < ioremap_bot) 27814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras vunmap((void *) (PAGE_MASK & (unsigned long)addr)); 27914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 280920573bd03bf690135967b5022362d34ede589c3Olaf HeringEXPORT_SYMBOL(iounmap); 28114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 28268a64357d15ae4f596e92715719071952006e83cBenjamin Herrenschmidtint map_page(unsigned long va, phys_addr_t pa, int flags) 28314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 28414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras pmd_t *pd; 28514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras pte_t *pg; 28614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras int err = -ENOMEM; 28714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 28814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* Use upper 10 bits of VA to index the first level map */ 289d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson pd = pmd_offset(pud_offset(pgd_offset_k(va), va), va); 29014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* Use middle 10 bits of VA to index the second-level map */ 291e2f2e58e7968f8446b1078a20a18bf8ea12b4fbcPaul Mackerras pg = pte_alloc_kernel(pd, va); 29214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (pg != 0) { 29314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras err = 0; 2943be4e6990edf65624cfcbf8f7e33810626b2eefaBenjamin Herrenschmidt /* The PTE should never be already set nor present in the 2953be4e6990edf65624cfcbf8f7e33810626b2eefaBenjamin Herrenschmidt * hash table 2963be4e6990edf65624cfcbf8f7e33810626b2eefaBenjamin Herrenschmidt */ 2977021d86afa6f3a8bf76218ac97f5847a6d985730Anton Vorontsov BUG_ON((pte_val(*pg) & (_PAGE_PRESENT | _PAGE_HASHPTE)) && 2987021d86afa6f3a8bf76218ac97f5847a6d985730Anton Vorontsov flags); 2993be4e6990edf65624cfcbf8f7e33810626b2eefaBenjamin Herrenschmidt set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, 3003be4e6990edf65624cfcbf8f7e33810626b2eefaBenjamin Herrenschmidt __pgprot(flags))); 30114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 30247ce8af4209f4344f152aa6fc538efe9d6bdfd1aScott Wood smp_wmb(); 30314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return err; 30414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 30514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 30614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras/* 307de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz * Map in a chunk of physical memory starting at start. 30814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 309de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranzvoid __init __mapin_ram_chunk(unsigned long offset, unsigned long top) 31014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 31199c62dd773797b68f3b1ca6bb3274725d1852fa2Kumar Gala unsigned long v, s, f; 31299c62dd773797b68f3b1ca6bb3274725d1852fa2Kumar Gala phys_addr_t p; 313ee4f2ea48674b6c9d91bc854edc51a3e6a7168c4Benjamin Herrenschmidt int ktext; 31414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 315de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz s = offset; 316ccdcef72c249c289898b164eada89a61855b9287Dale Farnsworth v = PAGE_OFFSET + s; 31799c62dd773797b68f3b1ca6bb3274725d1852fa2Kumar Gala p = memstart_addr + s; 318de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz for (; s < top; s += PAGE_SIZE) { 319ee4f2ea48674b6c9d91bc854edc51a3e6a7168c4Benjamin Herrenschmidt ktext = ((char *) v >= _stext && (char *) v < etext); 3208d1cf34e7ad5c7738ce20d20bd7f002f562cb8b5Benjamin Herrenschmidt f = ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL; 32114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras map_page(v, p, f); 322ee4f2ea48674b6c9d91bc854edc51a3e6a7168c4Benjamin Herrenschmidt#ifdef CONFIG_PPC_STD_MMU_32 323ee4f2ea48674b6c9d91bc854edc51a3e6a7168c4Benjamin Herrenschmidt if (ktext) 324ee4f2ea48674b6c9d91bc854edc51a3e6a7168c4Benjamin Herrenschmidt hash_preload(&init_mm, v, 0, 0x300); 325ee4f2ea48674b6c9d91bc854edc51a3e6a7168c4Benjamin Herrenschmidt#endif 32614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras v += PAGE_SIZE; 32714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras p += PAGE_SIZE; 32814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 32914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 33014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 331de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranzvoid __init mapin_ram(void) 332de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz{ 333de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz unsigned long s, top; 334de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz 335de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz#ifndef CONFIG_WII 336de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz top = total_lowmem; 337de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz s = mmu_mapin_ram(top); 338de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz __mapin_ram_chunk(s, top); 339de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz#else 340de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz if (!wii_hole_size) { 341de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz s = mmu_mapin_ram(total_lowmem); 342de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz __mapin_ram_chunk(s, total_lowmem); 343de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz } else { 344de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz top = wii_hole_start; 345de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz s = mmu_mapin_ram(top); 346de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz __mapin_ram_chunk(s, top); 347de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz 34895f72d1ed41a66f1c1c29c24d479de81a0bea36fYinghai Lu top = memblock_end_of_DRAM(); 349de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz s = wii_mmu_mapin_mem2(top); 350de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz __mapin_ram_chunk(s, top); 351de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz } 352de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz#endif 353de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz} 354de32400dd26e743c5d500aa42d8d6818b79edb73Albert Herranz 35514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras/* Scan the real Linux page tables and return a PTE pointer for 35614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * a virtual address in a context. 35714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Returns true (1) if PTE was found, zero otherwise. The pointer to 35814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * the PTE pointer is unmodified if PTE is not found. 35914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 36014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasint 361bab70a4af737f623de5b034976a311055308ab86Eugene Suroveginget_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) 36214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 36314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras pgd_t *pgd; 364d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson pud_t *pud; 36514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras pmd_t *pmd; 36614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras pte_t *pte; 36714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras int retval = 0; 36814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 36914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras pgd = pgd_offset(mm, addr & PAGE_MASK); 37014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (pgd) { 371d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson pud = pud_offset(pgd, addr & PAGE_MASK); 372d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson if (pud && pud_present(*pud)) { 373d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson pmd = pmd_offset(pud, addr & PAGE_MASK); 374d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson if (pmd_present(*pmd)) { 375d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson pte = pte_offset_map(pmd, addr & PAGE_MASK); 376d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson if (pte) { 377d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson retval = 1; 378d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson *ptep = pte; 379d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson if (pmdp) 380d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson *pmdp = pmd; 381d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson /* XXX caller needs to do pte_unmap, yuck */ 382d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson } 383d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson } 384d1953c8888ef034b912ee33bc2ea2cce6a414402David Gibson } 38514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 38614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return(retval); 38714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 38814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 38988df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt#ifdef CONFIG_DEBUG_PAGEALLOC 39088df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt 39188df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidtstatic int __change_page_attr(struct page *page, pgprot_t prot) 39288df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt{ 39388df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt pte_t *kpte; 39488df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt pmd_t *kpmd; 39588df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt unsigned long address; 39688df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt 39788df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt BUG_ON(PageHighMem(page)); 39888df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt address = (unsigned long)page_address(page); 39988df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt 40088df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt if (v_mapped_by_bats(address) || v_mapped_by_tlbcam(address)) 40188df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt return 0; 40288df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt if (!get_pteptr(&init_mm, address, &kpte, &kpmd)) 40388df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt return -EINVAL; 40450891457f1001450be61be0861b2b49abdcb5fb9Benjamin Herrenschmidt __set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0); 40588df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt wmb(); 406f63837f0581fe580168ae1a7d178ded935411747Benjamin Herrenschmidt flush_tlb_page(NULL, address); 40788df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt pte_unmap(kpte); 40888df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt 40988df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt return 0; 41088df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt} 41188df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt 41288df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt/* 41388df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt * Change the page attributes of an page in the linear mapping. 41488df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt * 41588df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt * THIS CONFLICTS WITH BAT MAPPINGS, DEBUG USE ONLY 41688df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt */ 41788df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidtstatic int change_page_attr(struct page *page, int numpages, pgprot_t prot) 41888df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt{ 41988df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt int i, err = 0; 42088df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt unsigned long flags; 42188df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt 42288df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt local_irq_save(flags); 42388df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt for (i = 0; i < numpages; i++, page++) { 42488df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt err = __change_page_attr(page, prot); 42588df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt if (err) 42688df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt break; 42788df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt } 42888df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt local_irq_restore(flags); 42988df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt return err; 43088df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt} 43188df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt 43288df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt 43388df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidtvoid kernel_map_pages(struct page *page, int numpages, int enable) 43488df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt{ 43588df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt if (PageHighMem(page)) 43688df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt return; 43788df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt 43888df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0)); 43988df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt} 44088df6e90fa9782dbf44d936e44649afe271e4790Benjamin Herrenschmidt#endif /* CONFIG_DEBUG_PAGEALLOC */ 4412c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala 4422c419bdeca1d958bb02228b5141695f312d8c633Kumar Galastatic int fixmaps; 4432c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala 4442c419bdeca1d958bb02228b5141695f312d8c633Kumar Galavoid __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags) 4452c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala{ 4462c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala unsigned long address = __fix_to_virt(idx); 4472c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala 4482c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala if (idx >= __end_of_fixed_addresses) { 4492c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala BUG(); 4502c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala return; 4512c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala } 4522c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala 45346a7417963a84f67984af1af59d43261159dd96bDavid Gibson map_page(address, phys, pgprot_val(flags)); 4542c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala fixmaps++; 4552c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala} 4562c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala 4572c419bdeca1d958bb02228b5141695f312d8c633Kumar Galavoid __this_fixmap_does_not_exist(void) 4582c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala{ 4592c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala WARN_ON(1); 4602c419bdeca1d958bb02228b5141695f312d8c633Kumar Gala} 461