^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/mmzone.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <asm/io-workarounds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) unsigned long ioremap_bot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) EXPORT_SYMBOL(ioremap_bot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) void __iomem *ioremap(phys_addr_t addr, unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) pgprot_t prot = pgprot_noncached(PAGE_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) void *caller = __builtin_return_address(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) if (iowa_is_active())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) return iowa_ioremap(addr, size, prot, caller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) return __ioremap_caller(addr, size, prot, caller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) EXPORT_SYMBOL(ioremap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) void __iomem *ioremap_wc(phys_addr_t addr, unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) pgprot_t prot = pgprot_noncached_wc(PAGE_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) void *caller = __builtin_return_address(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if (iowa_is_active())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return iowa_ioremap(addr, size, prot, caller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return __ioremap_caller(addr, size, prot, caller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) EXPORT_SYMBOL(ioremap_wc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) void __iomem *ioremap_coherent(phys_addr_t addr, unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) pgprot_t prot = pgprot_cached(PAGE_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) void *caller = __builtin_return_address(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (iowa_is_active())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return iowa_ioremap(addr, size, prot, caller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return __ioremap_caller(addr, size, prot, caller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) void __iomem *ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) pte_t pte = __pte(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) void *caller = __builtin_return_address(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* writeable implies dirty for kernel addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (pte_write(pte))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) pte = pte_mkdirty(pte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) pte = pte_exprotect(pte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) pte = pte_mkprivileged(pte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (iowa_is_active())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return iowa_ioremap(addr, size, pte_pgprot(pte), caller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return __ioremap_caller(addr, size, pte_pgprot(pte), caller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) EXPORT_SYMBOL(ioremap_prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int early_ioremap_range(unsigned long ea, phys_addr_t pa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) unsigned long size, pgprot_t prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) for (i = 0; i < size; i += PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int err = map_kernel_page(ea + i, pa + i, prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (WARN_ON_ONCE(err)) /* Should clean up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) void __iomem *do_ioremap(phys_addr_t pa, phys_addr_t offset, unsigned long size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) pgprot_t prot, void *caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct vm_struct *area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned long va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) area = __get_vm_area_caller(size, VM_IOREMAP, IOREMAP_START, IOREMAP_END, caller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (area == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) area->phys_addr = pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) va = (unsigned long)area->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ret = ioremap_page_range(va, va + size, pa, prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return (void __iomem *)area->addr + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unmap_kernel_range(va, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) free_vm_area(area);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #ifdef CONFIG_ZONE_DEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * Override the generic version in mm/memremap.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * With hash translation, the direct-map range is mapped with just one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * page size selected by htab_init_page_sizes(). Consult
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * mmu_psize_defs[] to determine the minimum page size alignment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned long memremap_compat_align(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned int shift = mmu_psize_defs[mmu_linear_psize].shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (radix_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return SUBSECTION_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return max(SUBSECTION_SIZE, 1UL << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) EXPORT_SYMBOL_GPL(memremap_compat_align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #endif