Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.15-rc2 86 lines 2.0 kB view raw
1#include <linux/vmalloc.h> 2#include <asm/pgalloc.h> 3#include <asm/cacheflush.h> 4 5static inline void 6remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, 7 unsigned long phys_addr, unsigned long flags) 8{ 9 unsigned long end; 10 unsigned long pfn; 11 12 address &= ~PMD_MASK; 13 end = address + size; 14 if (end > PMD_SIZE) 15 end = PMD_SIZE; 16 if (address >= end) 17 BUG(); 18 pfn = phys_addr >> PAGE_SHIFT; 19 do { 20 if (!pte_none(*pte)) { 21 printk("remap_area_pte: page already exists\n"); 22 BUG(); 23 } 24 set_pte(pte, pfn_pte(pfn, 25 __pgprot(_PAGE_VALID | _PAGE_ASM | 26 _PAGE_KRE | _PAGE_KWE | flags))); 27 address += PAGE_SIZE; 28 pfn++; 29 pte++; 30 } while (address && (address < end)); 31} 32 33static inline int 34remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, 35 unsigned long phys_addr, unsigned long flags) 36{ 37 unsigned long end; 38 39 address &= ~PGDIR_MASK; 40 end = address + size; 41 if (end > PGDIR_SIZE) 42 end = PGDIR_SIZE; 43 phys_addr -= address; 44 if (address >= end) 45 BUG(); 46 do { 47 pte_t * pte = pte_alloc_kernel(pmd, address); 48 if (!pte) 49 return -ENOMEM; 50 remap_area_pte(pte, address, end - address, 51 address + phys_addr, flags); 52 address = (address + PMD_SIZE) & PMD_MASK; 53 pmd++; 54 } while (address && (address < end)); 55 return 0; 56} 57 58int 59__alpha_remap_area_pages(unsigned long address, unsigned long phys_addr, 60 unsigned long size, unsigned long flags) 61{ 62 pgd_t * dir; 63 int error = 0; 64 unsigned long end = address + size; 65 66 phys_addr -= address; 67 dir = pgd_offset(&init_mm, address); 68 flush_cache_all(); 69 if (address >= end) 70 BUG(); 71 do { 72 pmd_t *pmd; 73 pmd = pmd_alloc(&init_mm, dir, address); 74 error = -ENOMEM; 75 if (!pmd) 76 break; 77 if (remap_area_pmd(pmd, address, end - address, 78 phys_addr + address, flags)) 79 break; 80 error = 0; 81 address = (address + PGDIR_SIZE) & PGDIR_MASK; 82 dir++; 83 } while (address && (address < end)); 84 return error; 85} 86