static int remap_area_pages(unsigned long address, phys_t phys_addr, phys_t size, unsigned long flags) { int error; pgd_t * dir; unsigned long end = address + size; phys_addr -= address; dir = pgd_offset(&init_mm, address); flush_cache_all(); BUG_ON(address >= end); do { pud_t *pud; pmd_t *pmd; error = -ENOMEM; pud = pud_alloc(&init_mm, dir, address); if (!pud) break; pmd = pmd_alloc(&init_mm, pud, address); if (!pmd) break; if (remap_area_pmd(pmd, address, end - address, phys_addr + address, flags)) break; error = 0; address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); flush_tlb_all(); return error; }
static int remap_area_pages(unsigned long address, unsigned long phys_addr, unsigned long size, unsigned long flags) { pgd_t * dir; unsigned long end = address + size; phys_addr -= address; dir = pgd_offset(&init_mm, address); flush_cache_all(); if (address >= end) BUG(); do { pmd_t *pmd = pmd_alloc_kernel(dir, address); if (!pmd) return -ENOMEM; if (remap_area_pmd(pmd, address, end - address, phys_addr + address, flags)) return -ENOMEM; set_pgdir(address, *dir); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); flush_tlb_all(); return 0; }
static int remap_area_pages(unsigned long address, unsigned long phys_addr, unsigned long size, unsigned long flags) { int error; pgd_t * dir; unsigned long end = address + size; phys_addr -= address; dir = pgd_offset(&init_mm, address); flush_cache_all(); if (address >= end) BUG(); spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; pmd = pmd_alloc(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; if (remap_area_pmd(pmd, address, end - address, phys_addr + address, flags)) break; error = 0; address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); spin_unlock(&init_mm.page_table_lock); flush_tlb_all(); return error; }
static int remap_area_pages(unsigned long start, unsigned long phys_addr, unsigned long size, unsigned long flags) { unsigned long address = start; unsigned long end = start + size; int err = 0; pgd_t * dir; phys_addr -= address; dir = pgd_offset(&init_mm, address); BUG_ON(address >= end); spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd = pmd_alloc(&init_mm, dir, address); if (!pmd) { err = -ENOMEM; break; } if (remap_area_pmd(pmd, address, end - address, phys_addr + address, flags)) { err = -ENOMEM; break; } address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); spin_unlock(&init_mm.page_table_lock); flush_cache_vmap(start, end); return err; }
static int remap_area_pages(unsigned long start, unsigned long pfn, size_t size, const struct mem_type *type) { unsigned long addr = start; unsigned long next, end = start + size; unsigned long phys_addr = __pfn_to_phys(pfn); pgd_t *pgd; int err = 0; BUG_ON(addr >= end); pgd = pgd_offset_k(addr); do { next = pgd_addr_end(addr, end); err = remap_area_pmd(pgd, addr, next, phys_addr, type); if (err) break; phys_addr += next - addr; } while (pgd++, addr = next, addr != end); return err; }
static inline int remap_area_pud(pud_t * pud, unsigned long address, unsigned long size, unsigned long phys_addr, unsigned long flags) { unsigned long end; address &= ~PGDIR_MASK; end = address + size; if (end > PGDIR_SIZE) end = PGDIR_SIZE; phys_addr -= address; if (address >= end) BUG(); do { pmd_t * pmd = pmd_alloc(&init_mm, pud, address); if (!pmd) return -ENOMEM; remap_area_pmd(pmd, address, end - address, address + phys_addr, flags); address = (address + PUD_SIZE) & PUD_MASK; pud++; } while (address && (address < end)); return 0; }
static int remap_area_pages(unsigned long start, unsigned long pfn, unsigned long size, unsigned long flags) { unsigned long addr = start; unsigned long next, end = start + size; unsigned long phys_addr = __pfn_to_phys(pfn); pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags); pgd_t *pgd; int err = 0; BUG_ON(addr >= end); pgd = pgd_offset_k(addr); do { next = pgd_addr_end(addr, end); err = remap_area_pmd(pgd, addr, next, phys_addr, prot); if (err) break; phys_addr += next - addr; } while (pgd++, addr = next, addr != end); return err; }