*参照元 [#v97fffcf] #backlinks *説明 [#tcf86616] -パス: [[linux-4.4.1/arch/arm/mm/ioremap.c]] -FIXME: これは何? --説明 **引数 [#p7f744cd] -unsigned long pfn -- -unsigned long offset -- -size_t size -- --[[linux-4.4.1/size_t]] -unsigned int mtype -- -void *caller --呼び出し元のアドレス **返り値 [#c22917b5] -void __iomem * -- **参考 [#f52fd24e] *実装 [#e4a57ea6] static void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, unsigned long offset, size_t size, unsigned int mtype, void *caller) { const struct mem_type *type; int err; unsigned long addr; struct vm_struct *area; phys_addr_t paddr = __pfn_to_phys(pfn); - --[[linux-4.4.1/mem_type]] --[[linux-4.4.1/vm_struct]] #ifndef CONFIG_ARM_LPAE - --[[linux-4.4.1/CONFIG_ARM_LPAE]] /* * High mappings must be supersection aligned */ if (pfn >= 0x100000 && (paddr & ~SUPERSECTION_MASK)) return NULL; #endif type = get_mem_type(mtype); if (!type) return NULL; - --[[linux-4.4.1/get_mem_type()]] /* * Page align the mapping size, taking account of any offset. */ size = PAGE_ALIGN(offset + size); - --[[linux-4.4.1/PAGE_ALIGN()]] /* * Try to reuse one of the static mapping whenever possible. */ if (size && !(sizeof(phys_addr_t) == 4 && pfn >= 0x100000)) { struct static_vm *svm; - --[[linux-4.4.1/static_vm]] svm = find_static_vm_paddr(paddr, size, mtype); if (svm) { addr = (unsigned long)svm->vm.addr; addr += paddr - svm->vm.phys_addr; return (void __iomem *) (offset + addr); } - --[[linux-4.4.1/find_static_vm_paddr()]] } /* * Don't allow RAM to be mapped - this causes problems with ARMv6+ */ if (WARN_ON(pfn_valid(pfn))) return NULL; - --[[linux-4.4.1/WARN_ON()]] --[[linux-4.4.1/pfn_valid()]] area = get_vm_area_caller(size, VM_IOREMAP, caller); if (!area) return NULL; addr = (unsigned long)area->addr; area->phys_addr = paddr; - --[[linux-4.4.1/get_vm_area_caller()]] #if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE) - --[[linux-4.4.1/CONFIG_SMP]] --[[linux-4.4.1/CONFIG_ARM_LPAE]] if (DOMAIN_IO == 0 && (((cpu_architecture() >= CPU_ARCH_ARMv6) && (get_cr() & CR_XP)) || cpu_is_xsc3()) && pfn >= 0x100000 && !((paddr | size | addr) & ~SUPERSECTION_MASK)) { - --[[linux-4.4.1/cpu_architecture()]] --[[linux-4.4.1/get_cr()]] --[[linux-4.4.1/cpu_is_xsc3()]] area->flags |= VM_ARM_SECTION_MAPPING; err = remap_area_supersections(addr, pfn, size, type); - --[[linux-4.4.1/remap_area_supersections()]] } else if (!((paddr | size | addr) & ~PMD_MASK)) { area->flags |= VM_ARM_SECTION_MAPPING; err = remap_area_sections(addr, pfn, size, type); - --[[linux-4.4.1/remap_area_sections()]] } else #endif err = ioremap_page_range(addr, addr + size, paddr, __pgprot(type->prot_pte)); - --[[linux-4.4.1/ioremap_page_range()]] --[[linux-4.4.1/__pgprot()]] if (err) { vunmap((void *)addr); return NULL; } - --[[linux-4.4.1/vunmap()]] flush_cache_vmap(addr, addr + size); return (void __iomem *) (offset + addr); - --[[linux-4.4.1/flush_cache_vmap()]] } *コメント [#p66850ab]