xref: /openbmc/linux/arch/mips/mm/physaddr.c (revision f543a9d1)
1dfad83cbSFlorian Fainelli // SPDX-License-Identifier: GPL-2.0
2dfad83cbSFlorian Fainelli #include <linux/bug.h>
3dfad83cbSFlorian Fainelli #include <linux/export.h>
4dfad83cbSFlorian Fainelli #include <linux/types.h>
5dfad83cbSFlorian Fainelli #include <linux/mmdebug.h>
6dfad83cbSFlorian Fainelli #include <linux/mm.h>
7dfad83cbSFlorian Fainelli 
8*f543a9d1SFlorian Fainelli #include <asm/addrspace.h>
9dfad83cbSFlorian Fainelli #include <asm/sections.h>
10dfad83cbSFlorian Fainelli #include <asm/io.h>
11dfad83cbSFlorian Fainelli #include <asm/page.h>
12dfad83cbSFlorian Fainelli #include <asm/dma.h>
13dfad83cbSFlorian Fainelli 
__debug_virt_addr_valid(unsigned long x)14dfad83cbSFlorian Fainelli static inline bool __debug_virt_addr_valid(unsigned long x)
15dfad83cbSFlorian Fainelli {
16dfad83cbSFlorian Fainelli 	/*
17dfad83cbSFlorian Fainelli 	 * MAX_DMA_ADDRESS is a virtual address that may not correspond to an
18dfad83cbSFlorian Fainelli 	 * actual physical address. Enough code relies on
19dfad83cbSFlorian Fainelli 	 * virt_to_phys(MAX_DMA_ADDRESS) that we just need to work around it
20dfad83cbSFlorian Fainelli 	 * and always return true.
21dfad83cbSFlorian Fainelli 	 */
22dfad83cbSFlorian Fainelli 	if (x == MAX_DMA_ADDRESS)
23dfad83cbSFlorian Fainelli 		return true;
24dfad83cbSFlorian Fainelli 
25*f543a9d1SFlorian Fainelli 	return x >= PAGE_OFFSET && (KSEGX(x) < KSEG2 ||
26*f543a9d1SFlorian Fainelli 	       IS_ENABLED(CONFIG_EVA) ||
27*f543a9d1SFlorian Fainelli 	       !IS_ENABLED(CONFIG_HIGHMEM));
28dfad83cbSFlorian Fainelli }
29dfad83cbSFlorian Fainelli 
__virt_to_phys(volatile const void * x)30dfad83cbSFlorian Fainelli phys_addr_t __virt_to_phys(volatile const void *x)
31dfad83cbSFlorian Fainelli {
32dfad83cbSFlorian Fainelli 	WARN(!__debug_virt_addr_valid((unsigned long)x),
33dfad83cbSFlorian Fainelli 	     "virt_to_phys used for non-linear address: %pK (%pS)\n",
34dfad83cbSFlorian Fainelli 	     x, x);
35dfad83cbSFlorian Fainelli 
36dfad83cbSFlorian Fainelli 	return __virt_to_phys_nodebug(x);
37dfad83cbSFlorian Fainelli }
38dfad83cbSFlorian Fainelli EXPORT_SYMBOL(__virt_to_phys);
39dfad83cbSFlorian Fainelli 
__phys_addr_symbol(unsigned long x)40dfad83cbSFlorian Fainelli phys_addr_t __phys_addr_symbol(unsigned long x)
41dfad83cbSFlorian Fainelli {
42dfad83cbSFlorian Fainelli 	/* This is bounds checking against the kernel image only.
43dfad83cbSFlorian Fainelli 	 * __pa_symbol should only be used on kernel symbol addresses.
44dfad83cbSFlorian Fainelli 	 */
45dfad83cbSFlorian Fainelli 	VIRTUAL_BUG_ON(x < (unsigned long)_text ||
46dfad83cbSFlorian Fainelli 		       x > (unsigned long)_end);
47dfad83cbSFlorian Fainelli 
48dfad83cbSFlorian Fainelli 	return __pa_symbol_nodebug(x);
49dfad83cbSFlorian Fainelli }
50dfad83cbSFlorian Fainelli EXPORT_SYMBOL(__phys_addr_symbol);
51