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