1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2a117e66eSKAMEZAWA Hiroyuki #ifndef __ASM_MEMORY_MODEL_H
3a117e66eSKAMEZAWA Hiroyuki #define __ASM_MEMORY_MODEL_H
4a117e66eSKAMEZAWA Hiroyuki 
58f235d1aSChen Gang #include <linux/pfn.h>
68f235d1aSChen Gang 
7a117e66eSKAMEZAWA Hiroyuki #ifndef __ASSEMBLY__
8a117e66eSKAMEZAWA Hiroyuki 
9bb1c50d3SMike Rapoport /*
10bb1c50d3SMike Rapoport  * supports 3 memory models.
11bb1c50d3SMike Rapoport  */
12a117e66eSKAMEZAWA Hiroyuki #if defined(CONFIG_FLATMEM)
13a117e66eSKAMEZAWA Hiroyuki 
14a117e66eSKAMEZAWA Hiroyuki #ifndef ARCH_PFN_OFFSET
15a117e66eSKAMEZAWA Hiroyuki #define ARCH_PFN_OFFSET		(0UL)
16a117e66eSKAMEZAWA Hiroyuki #endif
17a117e66eSKAMEZAWA Hiroyuki 
1867de6482SAndy Whitcroft #define __pfn_to_page(pfn)	(mem_map + ((pfn) - ARCH_PFN_OFFSET))
1967de6482SAndy Whitcroft #define __page_to_pfn(page)	((unsigned long)((page) - mem_map) + \
20a117e66eSKAMEZAWA Hiroyuki 				 ARCH_PFN_OFFSET)
21a117e66eSKAMEZAWA Hiroyuki 
22*e5080a96SMike Rapoport (IBM) #ifndef pfn_valid
pfn_valid(unsigned long pfn)23*e5080a96SMike Rapoport (IBM) static inline int pfn_valid(unsigned long pfn)
24*e5080a96SMike Rapoport (IBM) {
25*e5080a96SMike Rapoport (IBM) 	/* avoid <linux/mm.h> include hell */
26*e5080a96SMike Rapoport (IBM) 	extern unsigned long max_mapnr;
27*e5080a96SMike Rapoport (IBM) 	unsigned long pfn_offset = ARCH_PFN_OFFSET;
28*e5080a96SMike Rapoport (IBM) 
29*e5080a96SMike Rapoport (IBM) 	return pfn >= pfn_offset && (pfn - pfn_offset) < max_mapnr;
30*e5080a96SMike Rapoport (IBM) }
31*e5080a96SMike Rapoport (IBM) #define pfn_valid pfn_valid
32*e5080a96SMike Rapoport (IBM) #endif
33*e5080a96SMike Rapoport (IBM) 
348f6aac41SChristoph Lameter #elif defined(CONFIG_SPARSEMEM_VMEMMAP)
358f6aac41SChristoph Lameter 
36af901ca1SAndré Goddard Rosa /* memmap is virtually contiguous.  */
378f6aac41SChristoph Lameter #define __pfn_to_page(pfn)	(vmemmap + (pfn))
3832272a26SMartin Schwidefsky #define __page_to_pfn(page)	(unsigned long)((page) - vmemmap)
398f6aac41SChristoph Lameter 
40a117e66eSKAMEZAWA Hiroyuki #elif defined(CONFIG_SPARSEMEM)
41a117e66eSKAMEZAWA Hiroyuki /*
421a49123bSZhang Yanfei  * Note: section's mem_map is encoded to reflect its start_pfn.
43a117e66eSKAMEZAWA Hiroyuki  * section[i].section_mem_map == mem_map's address - start_pfn;
44a117e66eSKAMEZAWA Hiroyuki  */
4567de6482SAndy Whitcroft #define __page_to_pfn(pg)					\
46aa462abeSIan Campbell ({	const struct page *__pg = (pg);				\
47a117e66eSKAMEZAWA Hiroyuki 	int __sec = page_to_section(__pg);			\
48f05b6284SRandy Dunlap 	(unsigned long)(__pg - __section_mem_map_addr(__nr_to_section(__sec)));	\
49a117e66eSKAMEZAWA Hiroyuki })
50a117e66eSKAMEZAWA Hiroyuki 
5167de6482SAndy Whitcroft #define __pfn_to_page(pfn)				\
52a117e66eSKAMEZAWA Hiroyuki ({	unsigned long __pfn = (pfn);			\
53a117e66eSKAMEZAWA Hiroyuki 	struct mem_section *__sec = __pfn_to_section(__pfn);	\
54a117e66eSKAMEZAWA Hiroyuki 	__section_mem_map_addr(__sec) + __pfn;		\
55a117e66eSKAMEZAWA Hiroyuki })
56bb1c50d3SMike Rapoport #endif /* CONFIG_FLATMEM/SPARSEMEM */
5767de6482SAndy Whitcroft 
58012dcef3SChristoph Hellwig /*
59012dcef3SChristoph Hellwig  * Convert a physical address to a Page Frame Number and back
60012dcef3SChristoph Hellwig  */
618f235d1aSChen Gang #define	__phys_to_pfn(paddr)	PHYS_PFN(paddr)
62ae4f9769STyler Baker #define	__pfn_to_phys(pfn)	PFN_PHYS(pfn)
63012dcef3SChristoph Hellwig 
6467de6482SAndy Whitcroft #define page_to_pfn __page_to_pfn
6567de6482SAndy Whitcroft #define pfn_to_page __pfn_to_page
66a117e66eSKAMEZAWA Hiroyuki 
67a117e66eSKAMEZAWA Hiroyuki #endif /* __ASSEMBLY__ */
68a117e66eSKAMEZAWA Hiroyuki 
69a117e66eSKAMEZAWA Hiroyuki #endif
70