162306a36Sopenharmony_ci/*  Generic MTRR (Memory Type Range Register) ioctls.
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci    Copyright (C) 1997-1999  Richard Gooch
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci    This library is free software; you can redistribute it and/or
662306a36Sopenharmony_ci    modify it under the terms of the GNU Library General Public
762306a36Sopenharmony_ci    License as published by the Free Software Foundation; either
862306a36Sopenharmony_ci    version 2 of the License, or (at your option) any later version.
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci    This library is distributed in the hope that it will be useful,
1162306a36Sopenharmony_ci    but WITHOUT ANY WARRANTY; without even the implied warranty of
1262306a36Sopenharmony_ci    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1362306a36Sopenharmony_ci    Library General Public License for more details.
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci    You should have received a copy of the GNU Library General Public
1662306a36Sopenharmony_ci    License along with this library; if not, write to the Free
1762306a36Sopenharmony_ci    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci    Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
2062306a36Sopenharmony_ci    The postal address is:
2162306a36Sopenharmony_ci      Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
2262306a36Sopenharmony_ci*/
2362306a36Sopenharmony_ci#ifndef _ASM_X86_MTRR_H
2462306a36Sopenharmony_ci#define _ASM_X86_MTRR_H
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#include <linux/bits.h>
2762306a36Sopenharmony_ci#include <uapi/asm/mtrr.h>
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/* Defines for hardware MTRR registers. */
3062306a36Sopenharmony_ci#define MTRR_CAP_VCNT		GENMASK(7, 0)
3162306a36Sopenharmony_ci#define MTRR_CAP_FIX		BIT_MASK(8)
3262306a36Sopenharmony_ci#define MTRR_CAP_WC		BIT_MASK(10)
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define MTRR_DEF_TYPE_TYPE	GENMASK(7, 0)
3562306a36Sopenharmony_ci#define MTRR_DEF_TYPE_FE	BIT_MASK(10)
3662306a36Sopenharmony_ci#define MTRR_DEF_TYPE_E		BIT_MASK(11)
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define MTRR_DEF_TYPE_ENABLE	(MTRR_DEF_TYPE_FE | MTRR_DEF_TYPE_E)
3962306a36Sopenharmony_ci#define MTRR_DEF_TYPE_DISABLE	~(MTRR_DEF_TYPE_TYPE | MTRR_DEF_TYPE_ENABLE)
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#define MTRR_PHYSBASE_TYPE	GENMASK(7, 0)
4262306a36Sopenharmony_ci#define MTRR_PHYSBASE_RSVD	GENMASK(11, 8)
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci#define MTRR_PHYSMASK_RSVD	GENMASK(10, 0)
4562306a36Sopenharmony_ci#define MTRR_PHYSMASK_V		BIT_MASK(11)
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistruct mtrr_state_type {
4862306a36Sopenharmony_ci	struct mtrr_var_range var_ranges[MTRR_MAX_VAR_RANGES];
4962306a36Sopenharmony_ci	mtrr_type fixed_ranges[MTRR_NUM_FIXED_RANGES];
5062306a36Sopenharmony_ci	unsigned char enabled;
5162306a36Sopenharmony_ci	bool have_fixed;
5262306a36Sopenharmony_ci	mtrr_type def_type;
5362306a36Sopenharmony_ci};
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/*
5662306a36Sopenharmony_ci * The following functions are for use by other drivers that cannot use
5762306a36Sopenharmony_ci * arch_phys_wc_add and arch_phys_wc_del.
5862306a36Sopenharmony_ci */
5962306a36Sopenharmony_ci# ifdef CONFIG_MTRR
6062306a36Sopenharmony_civoid mtrr_bp_init(void);
6162306a36Sopenharmony_civoid mtrr_overwrite_state(struct mtrr_var_range *var, unsigned int num_var,
6262306a36Sopenharmony_ci			  mtrr_type def_type);
6362306a36Sopenharmony_ciextern u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform);
6462306a36Sopenharmony_ciextern void mtrr_save_fixed_ranges(void *);
6562306a36Sopenharmony_ciextern void mtrr_save_state(void);
6662306a36Sopenharmony_ciextern int mtrr_add(unsigned long base, unsigned long size,
6762306a36Sopenharmony_ci		    unsigned int type, bool increment);
6862306a36Sopenharmony_ciextern int mtrr_add_page(unsigned long base, unsigned long size,
6962306a36Sopenharmony_ci			 unsigned int type, bool increment);
7062306a36Sopenharmony_ciextern int mtrr_del(int reg, unsigned long base, unsigned long size);
7162306a36Sopenharmony_ciextern int mtrr_del_page(int reg, unsigned long base, unsigned long size);
7262306a36Sopenharmony_ciextern void mtrr_bp_restore(void);
7362306a36Sopenharmony_ciextern int mtrr_trim_uncached_memory(unsigned long end_pfn);
7462306a36Sopenharmony_ciextern int amd_special_default_mtrr(void);
7562306a36Sopenharmony_civoid mtrr_disable(void);
7662306a36Sopenharmony_civoid mtrr_enable(void);
7762306a36Sopenharmony_civoid mtrr_generic_set_state(void);
7862306a36Sopenharmony_ci#  else
7962306a36Sopenharmony_cistatic inline void mtrr_overwrite_state(struct mtrr_var_range *var,
8062306a36Sopenharmony_ci					unsigned int num_var,
8162306a36Sopenharmony_ci					mtrr_type def_type)
8262306a36Sopenharmony_ci{
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cistatic inline u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform)
8662306a36Sopenharmony_ci{
8762306a36Sopenharmony_ci	/*
8862306a36Sopenharmony_ci	 * Return the default MTRR type, without any known other types in
8962306a36Sopenharmony_ci	 * that range.
9062306a36Sopenharmony_ci	 */
9162306a36Sopenharmony_ci	*uniform = 1;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	return MTRR_TYPE_UNCACHABLE;
9462306a36Sopenharmony_ci}
9562306a36Sopenharmony_ci#define mtrr_save_fixed_ranges(arg) do {} while (0)
9662306a36Sopenharmony_ci#define mtrr_save_state() do {} while (0)
9762306a36Sopenharmony_cistatic inline int mtrr_add(unsigned long base, unsigned long size,
9862306a36Sopenharmony_ci			   unsigned int type, bool increment)
9962306a36Sopenharmony_ci{
10062306a36Sopenharmony_ci    return -ENODEV;
10162306a36Sopenharmony_ci}
10262306a36Sopenharmony_cistatic inline int mtrr_add_page(unsigned long base, unsigned long size,
10362306a36Sopenharmony_ci				unsigned int type, bool increment)
10462306a36Sopenharmony_ci{
10562306a36Sopenharmony_ci    return -ENODEV;
10662306a36Sopenharmony_ci}
10762306a36Sopenharmony_cistatic inline int mtrr_del(int reg, unsigned long base, unsigned long size)
10862306a36Sopenharmony_ci{
10962306a36Sopenharmony_ci    return -ENODEV;
11062306a36Sopenharmony_ci}
11162306a36Sopenharmony_cistatic inline int mtrr_del_page(int reg, unsigned long base, unsigned long size)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci    return -ENODEV;
11462306a36Sopenharmony_ci}
11562306a36Sopenharmony_cistatic inline int mtrr_trim_uncached_memory(unsigned long end_pfn)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	return 0;
11862306a36Sopenharmony_ci}
11962306a36Sopenharmony_ci#define mtrr_bp_init() do {} while (0)
12062306a36Sopenharmony_ci#define mtrr_bp_restore() do {} while (0)
12162306a36Sopenharmony_ci#define mtrr_disable() do {} while (0)
12262306a36Sopenharmony_ci#define mtrr_enable() do {} while (0)
12362306a36Sopenharmony_ci#define mtrr_generic_set_state() do {} while (0)
12462306a36Sopenharmony_ci#  endif
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci#ifdef CONFIG_COMPAT
12762306a36Sopenharmony_ci#include <linux/compat.h>
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_cistruct mtrr_sentry32 {
13062306a36Sopenharmony_ci    compat_ulong_t base;    /*  Base address     */
13162306a36Sopenharmony_ci    compat_uint_t size;    /*  Size of region   */
13262306a36Sopenharmony_ci    compat_uint_t type;     /*  Type of region   */
13362306a36Sopenharmony_ci};
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistruct mtrr_gentry32 {
13662306a36Sopenharmony_ci    compat_ulong_t regnum;   /*  Register number  */
13762306a36Sopenharmony_ci    compat_uint_t base;    /*  Base address     */
13862306a36Sopenharmony_ci    compat_uint_t size;    /*  Size of region   */
13962306a36Sopenharmony_ci    compat_uint_t type;     /*  Type of region   */
14062306a36Sopenharmony_ci};
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci#define MTRR_IOCTL_BASE 'M'
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci#define MTRRIOC32_ADD_ENTRY      _IOW(MTRR_IOCTL_BASE,  0, struct mtrr_sentry32)
14562306a36Sopenharmony_ci#define MTRRIOC32_SET_ENTRY      _IOW(MTRR_IOCTL_BASE,  1, struct mtrr_sentry32)
14662306a36Sopenharmony_ci#define MTRRIOC32_DEL_ENTRY      _IOW(MTRR_IOCTL_BASE,  2, struct mtrr_sentry32)
14762306a36Sopenharmony_ci#define MTRRIOC32_GET_ENTRY      _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
14862306a36Sopenharmony_ci#define MTRRIOC32_KILL_ENTRY     _IOW(MTRR_IOCTL_BASE,  4, struct mtrr_sentry32)
14962306a36Sopenharmony_ci#define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE,  5, struct mtrr_sentry32)
15062306a36Sopenharmony_ci#define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE,  6, struct mtrr_sentry32)
15162306a36Sopenharmony_ci#define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE,  7, struct mtrr_sentry32)
15262306a36Sopenharmony_ci#define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
15362306a36Sopenharmony_ci#define MTRRIOC32_KILL_PAGE_ENTRY		\
15462306a36Sopenharmony_ci				 _IOW(MTRR_IOCTL_BASE,  9, struct mtrr_sentry32)
15562306a36Sopenharmony_ci#endif /* CONFIG_COMPAT */
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci/* Bit fields for enabled in struct mtrr_state_type */
15862306a36Sopenharmony_ci#define MTRR_STATE_SHIFT		10
15962306a36Sopenharmony_ci#define MTRR_STATE_MTRR_FIXED_ENABLED	(MTRR_DEF_TYPE_FE >> MTRR_STATE_SHIFT)
16062306a36Sopenharmony_ci#define MTRR_STATE_MTRR_ENABLED		(MTRR_DEF_TYPE_E >> MTRR_STATE_SHIFT)
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci#endif /* _ASM_X86_MTRR_H */
163