xref: /freebsd/sys/compat/linuxkpi/common/include/linux/page.h (revision 80aa295a5272d01b7f21eff6719dcd45e14e8e09)
18d59ecb2SHans Petter Selasky /*-
28d59ecb2SHans Petter Selasky  * Copyright (c) 2010 Isilon Systems, Inc.
38d59ecb2SHans Petter Selasky  * Copyright (c) 2010 iX Systems, Inc.
48d59ecb2SHans Petter Selasky  * Copyright (c) 2010 Panasas, Inc.
583d5d45eSHans Petter Selasky  * Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
68d59ecb2SHans Petter Selasky  * All rights reserved.
78d59ecb2SHans Petter Selasky  *
88d59ecb2SHans Petter Selasky  * Redistribution and use in source and binary forms, with or without
98d59ecb2SHans Petter Selasky  * modification, are permitted provided that the following conditions
108d59ecb2SHans Petter Selasky  * are met:
118d59ecb2SHans Petter Selasky  * 1. Redistributions of source code must retain the above copyright
128d59ecb2SHans Petter Selasky  *    notice unmodified, this list of conditions, and the following
138d59ecb2SHans Petter Selasky  *    disclaimer.
148d59ecb2SHans Petter Selasky  * 2. Redistributions in binary form must reproduce the above copyright
158d59ecb2SHans Petter Selasky  *    notice, this list of conditions and the following disclaimer in the
168d59ecb2SHans Petter Selasky  *    documentation and/or other materials provided with the distribution.
178d59ecb2SHans Petter Selasky  *
188d59ecb2SHans Petter Selasky  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
198d59ecb2SHans Petter Selasky  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
208d59ecb2SHans Petter Selasky  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
218d59ecb2SHans Petter Selasky  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
228d59ecb2SHans Petter Selasky  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
238d59ecb2SHans Petter Selasky  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
248d59ecb2SHans Petter Selasky  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
258d59ecb2SHans Petter Selasky  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268d59ecb2SHans Petter Selasky  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
278d59ecb2SHans Petter Selasky  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
288d59ecb2SHans Petter Selasky  */
29307f78f3SVladimir Kondratyev #ifndef	_LINUXKPI_LINUX_PAGE_H_
30307f78f3SVladimir Kondratyev #define _LINUXKPI_LINUX_PAGE_H_
318d59ecb2SHans Petter Selasky 
328d59ecb2SHans Petter Selasky #include <linux/types.h>
338d59ecb2SHans Petter Selasky 
348d59ecb2SHans Petter Selasky #include <sys/param.h>
359ed01c32SGleb Smirnoff #include <sys/vmmeter.h>
368d59ecb2SHans Petter Selasky 
378d59ecb2SHans Petter Selasky #include <machine/atomic.h>
388d59ecb2SHans Petter Selasky #include <vm/vm.h>
398d59ecb2SHans Petter Selasky #include <vm/vm_page.h>
4083d5d45eSHans Petter Selasky #include <vm/pmap.h>
4183d5d45eSHans Petter Selasky 
42c072f6e8SVladimir Kondratyev #if defined(__i386__) || defined(__amd64__)
43c072f6e8SVladimir Kondratyev #include <machine/md_var.h>
44c072f6e8SVladimir Kondratyev #endif
45c072f6e8SVladimir Kondratyev 
4676fe8c93SHans Petter Selasky typedef unsigned long linux_pte_t;
4776fe8c93SHans Petter Selasky typedef unsigned long linux_pmd_t;
4876fe8c93SHans Petter Selasky typedef unsigned long linux_pgd_t;
4983d5d45eSHans Petter Selasky typedef unsigned long pgprot_t;
508d59ecb2SHans Petter Selasky 
518d59ecb2SHans Petter Selasky #define page	vm_page
528d59ecb2SHans Petter Selasky 
53ebf85480SHans Petter Selasky #define	LINUXKPI_PROT_VALID (1 << 3)
54ebf85480SHans Petter Selasky #define	LINUXKPI_CACHE_MODE_SHIFT 4
55ebf85480SHans Petter Selasky 
56ebf85480SHans Petter Selasky CTASSERT((VM_PROT_ALL & -LINUXKPI_PROT_VALID) == 0);
571ea4c857SHans Petter Selasky 
58c072f6e8SVladimir Kondratyev #define	PAGE_KERNEL_IO	0x0000
59c072f6e8SVladimir Kondratyev 
601ea4c857SHans Petter Selasky static inline pgprot_t
cachemode2protval(vm_memattr_t attr)611ea4c857SHans Petter Selasky cachemode2protval(vm_memattr_t attr)
621ea4c857SHans Petter Selasky {
63ebf85480SHans Petter Selasky 	return ((attr << LINUXKPI_CACHE_MODE_SHIFT) | LINUXKPI_PROT_VALID);
641ea4c857SHans Petter Selasky }
651ea4c857SHans Petter Selasky 
661ea4c857SHans Petter Selasky static inline vm_memattr_t
pgprot2cachemode(pgprot_t prot)671ea4c857SHans Petter Selasky pgprot2cachemode(pgprot_t prot)
681ea4c857SHans Petter Selasky {
69ebf85480SHans Petter Selasky 	if (prot & LINUXKPI_PROT_VALID)
70ebf85480SHans Petter Selasky 		return (prot >> LINUXKPI_CACHE_MODE_SHIFT);
711ea4c857SHans Petter Selasky 	else
721ea4c857SHans Petter Selasky 		return (VM_MEMATTR_DEFAULT);
731ea4c857SHans Petter Selasky }
741ea4c857SHans Petter Selasky 
75*80aa295aSVladimir Kondratyev #define	page_to_virt(page)	linux_page_address(page)
76ebf85480SHans Petter Selasky #define	virt_to_page(x)		PHYS_TO_VM_PAGE(vtophys(x))
77ebf85480SHans Petter Selasky #define	page_to_pfn(pp)		(VM_PAGE_TO_PHYS(pp) >> PAGE_SHIFT)
7883d5d45eSHans Petter Selasky #define	pfn_to_page(pfn)	(PHYS_TO_VM_PAGE((pfn) << PAGE_SHIFT))
79ebf85480SHans Petter Selasky #define	nth_page(page,n)	pfn_to_page(page_to_pfn(page) + (n))
80c072f6e8SVladimir Kondratyev #define	page_to_phys(page)	VM_PAGE_TO_PHYS(page)
818d59ecb2SHans Petter Selasky 
82ebf85480SHans Petter Selasky #define	clear_page(page)		memset(page, 0, PAGE_SIZE)
83e51dd47bSMark Johnston #define	pgprot_noncached(prot)		\
84ebf85480SHans Petter Selasky 	(((prot) & VM_PROT_ALL) | cachemode2protval(VM_MEMATTR_UNCACHEABLE))
858167c92fSJessica Clarke #ifdef VM_MEMATTR_WRITE_COMBINING
86e51dd47bSMark Johnston #define	pgprot_writecombine(prot)	\
87ebf85480SHans Petter Selasky 	(((prot) & VM_PROT_ALL) | cachemode2protval(VM_MEMATTR_WRITE_COMBINING))
888167c92fSJessica Clarke #else
898167c92fSJessica Clarke #define	pgprot_writecombine(prot)	pgprot_noncached(prot)
908167c92fSJessica Clarke #endif
918d59ecb2SHans Petter Selasky 
928d59ecb2SHans Petter Selasky #undef	PAGE_MASK
938d59ecb2SHans Petter Selasky #define	PAGE_MASK	(~(PAGE_SIZE-1))
9483d5d45eSHans Petter Selasky /*
9583d5d45eSHans Petter Selasky  * Modifying PAGE_MASK in the above way breaks trunc_page, round_page,
9683d5d45eSHans Petter Selasky  * and btoc macros. Therefore, redefine them in a way that makes sense
9783d5d45eSHans Petter Selasky  * so the LinuxKPI consumers don't get totally broken behavior.
9883d5d45eSHans Petter Selasky  */
9983d5d45eSHans Petter Selasky #undef	btoc
10083d5d45eSHans Petter Selasky #define	btoc(x)	(((vm_offset_t)(x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
10183d5d45eSHans Petter Selasky #undef	round_page
10283d5d45eSHans Petter Selasky #define	round_page(x)	((((uintptr_t)(x)) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
10383d5d45eSHans Petter Selasky #undef	trunc_page
10483d5d45eSHans Petter Selasky #define	trunc_page(x)	((uintptr_t)(x) & ~(PAGE_SIZE - 1))
1058d59ecb2SHans Petter Selasky 
106c072f6e8SVladimir Kondratyev #if defined(__i386__) || defined(__amd64__)
1079a79e08aSVladimir Kondratyev #undef clflush
108c072f6e8SVladimir Kondratyev #undef clflushopt
109c072f6e8SVladimir Kondratyev static inline void
lkpi_clflushopt(unsigned long addr)110c072f6e8SVladimir Kondratyev lkpi_clflushopt(unsigned long addr)
111c072f6e8SVladimir Kondratyev {
112c072f6e8SVladimir Kondratyev 	if (cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT)
113c072f6e8SVladimir Kondratyev 		clflushopt(addr);
114c072f6e8SVladimir Kondratyev 	else if (cpu_feature & CPUID_CLFSH)
115c072f6e8SVladimir Kondratyev 		clflush(addr);
116c072f6e8SVladimir Kondratyev 	else
117c072f6e8SVladimir Kondratyev 		pmap_invalidate_cache();
118c072f6e8SVladimir Kondratyev }
1199a79e08aSVladimir Kondratyev #define	clflush(x)	clflush((unsigned long)(x))
120c072f6e8SVladimir Kondratyev #define	clflushopt(x)	lkpi_clflushopt((unsigned long)(x))
121db562aefSVladimir Kondratyev 
122db562aefSVladimir Kondratyev static inline void
clflush_cache_range(void * addr,unsigned int size)123db562aefSVladimir Kondratyev clflush_cache_range(void *addr, unsigned int size)
124db562aefSVladimir Kondratyev {
125db562aefSVladimir Kondratyev 	pmap_force_invalidate_cache_range((vm_offset_t)addr,
126db562aefSVladimir Kondratyev 	    (vm_offset_t)addr + size);
127db562aefSVladimir Kondratyev }
128c072f6e8SVladimir Kondratyev #endif
129c072f6e8SVladimir Kondratyev 
130307f78f3SVladimir Kondratyev #endif	/* _LINUXKPI_LINUX_PAGE_H_ */
131