1 #ifndef __ASM_X86_MTRR_H__
2 #define __ASM_X86_MTRR_H__
3 
4 #include <xen/mm.h>
5 
6 #define MTRR_NUM_TYPES       X86_MT_UCM
7 #define MEMORY_NUM_TYPES     MTRR_NUM_TYPES
8 #define NO_HARDCODE_MEM_TYPE MTRR_NUM_TYPES
9 
10 #define NORMAL_CACHE_MODE          0
11 #define NO_FILL_CACHE_MODE         2
12 
13 #define INVALID_MEM_TYPE X86_NUM_MT
14 
15 /* In the Intel processor's MTRR interface, the MTRR type is always held in
16    an 8 bit field: */
17 typedef u8 mtrr_type;
18 
19 #define MTRR_PHYSMASK_VALID_BIT  11
20 #define MTRR_PHYSMASK_VALID      (1 << MTRR_PHYSMASK_VALID_BIT)
21 #define MTRR_PHYSMASK_SHIFT      12
22 #define MTRR_PHYSBASE_TYPE_MASK  0xff
23 #define MTRR_PHYSBASE_SHIFT      12
24 /* Number of variable range MSR pairs we emulate for HVM guests: */
25 #define MTRR_VCNT                8
26 /* Maximum number of variable range MSR pairs if FE is supported. */
27 #define MTRR_VCNT_MAX            ((MSR_MTRRfix64K_00000 - \
28                                    MSR_IA32_MTRR_PHYSBASE(0)) / 2)
29 
30 struct mtrr_var_range {
31 	uint64_t base;
32 	uint64_t mask;
33 };
34 
35 #define NUM_FIXED_RANGES 88
36 #define NUM_FIXED_MSR 11
37 struct mtrr_state {
38 	struct mtrr_var_range *var_ranges;
39 	mtrr_type fixed_ranges[NUM_FIXED_RANGES];
40 	bool enabled;
41 	bool fixed_enabled;
42 	bool have_fixed;
43 	mtrr_type def_type;
44 
45 	u64       mtrr_cap;
46 	/* ranges in var MSRs are overlapped or not:0(no overlapped) */
47 	bool      overlapped;
48 };
49 extern struct mtrr_state mtrr_state;
50 
51 extern void cf_check mtrr_save_fixed_ranges(void *info);
52 extern void mtrr_save_state(void);
53 extern int mtrr_add(unsigned long base, unsigned long size,
54                     unsigned int type, char increment);
55 extern int mtrr_add_page(unsigned long base, unsigned long size,
56                          unsigned int type, char increment);
57 extern int mtrr_del(int reg, unsigned long base, unsigned long size);
58 extern int mtrr_del_page(int reg, unsigned long base, unsigned long size);
59 extern int mtrr_get_type(const struct mtrr_state *m, paddr_t pa,
60                          unsigned int order);
61 extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi);
62 extern uint32_t get_pat_flags(struct vcpu *v, uint32_t gl1e_flags,
63                               paddr_t gpaddr, paddr_t spaddr,
64                               uint8_t gmtrr_mtype);
65 extern uint8_t pat_type_2_pte_flags(uint8_t pat_type);
66 extern void mtrr_aps_sync_begin(void);
67 extern void mtrr_aps_sync_end(void);
68 
69 extern bool mtrr_var_range_msr_set(struct domain *d, struct mtrr_state *m,
70                                    uint32_t msr, uint64_t msr_content);
71 extern bool mtrr_fix_range_msr_set(struct domain *d, struct mtrr_state *m,
72                                    uint32_t row, uint64_t msr_content);
73 extern bool mtrr_def_type_msr_set(struct domain *d, struct mtrr_state *m,
74                                   uint64_t msr_content);
75 #ifdef CONFIG_HVM
76 extern void memory_type_changed(struct domain *d);
77 #else
memory_type_changed(struct domain * d)78 static inline void memory_type_changed(struct domain *d) {}
79 #endif
80 
81 extern bool pat_msr_set(uint64_t *pat, uint64_t msr);
82 
83 bool is_var_mtrr_overlapped(const struct mtrr_state *m);
84 bool mtrr_pat_not_equal(const struct vcpu *vd, const struct vcpu *vs);
85 
86 #endif /* __ASM_X86_MTRR_H__ */
87