coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mtrr.h
Go to the documentation of this file.
1 #ifndef CPU_X86_MTRR_H
2 #define CPU_X86_MTRR_H
3 
4 #ifndef __ASSEMBLER__
5 #include <cpu/x86/msr.h>
6 #include <arch/cpu.h>
7 #endif
8 
9 /* These are the region types */
10 #define MTRR_TYPE_UNCACHEABLE 0
11 #define MTRR_TYPE_WRCOMB 1
12 #define MTRR_TYPE_WRTHROUGH 4
13 #define MTRR_TYPE_WRPROT 5
14 #define MTRR_TYPE_WRBACK 6
15 #define MTRR_NUM_TYPES 7
16 
17 #define MTRR_CAP_MSR 0x0fe
18 
19 #define MTRR_CAP_PRMRR (1 << 12)
20 #define MTRR_CAP_SMRR (1 << 11)
21 #define MTRR_CAP_WC (1 << 10)
22 #define MTRR_CAP_FIX (1 << 8)
23 #define MTRR_CAP_VCNT 0xff
24 
25 #define MTRR_DEF_TYPE_MSR 0x2ff
26 #define MTRR_DEF_TYPE_MASK 0xff
27 #define MTRR_DEF_TYPE_EN (1 << 11)
28 #define MTRR_DEF_TYPE_FIX_EN (1 << 10)
29 
30 #define IA32_SMRR_PHYS_BASE 0x1f2
31 #define IA32_SMRR_PHYS_MASK 0x1f3
32 #define SMRR_PHYS_MASK_LOCK (1 << 10)
33 
34 /* Specific to model_6fx and model_1067x.
35  These are named MSR_SMRR_PHYSBASE in the SDM. */
36 #define CORE2_SMRR_PHYS_BASE 0xa0
37 #define CORE2_SMRR_PHYS_MASK 0xa1
38 
39 #define MTRR_PHYS_BASE(reg) (0x200 + 2 * (reg))
40 #define MTRR_PHYS_MASK(reg) (MTRR_PHYS_BASE(reg) + 1)
41 #define MTRR_PHYS_MASK_VALID (1 << 11)
42 
43 #define NUM_FIXED_RANGES 88
44 #define RANGES_PER_FIXED_MTRR 8
45 #define MTRR_FIX_64K_00000 0x250
46 #define MTRR_FIX_16K_80000 0x258
47 #define MTRR_FIX_16K_A0000 0x259
48 #define MTRR_FIX_4K_C0000 0x268
49 #define MTRR_FIX_4K_C8000 0x269
50 #define MTRR_FIX_4K_D0000 0x26a
51 #define MTRR_FIX_4K_D8000 0x26b
52 #define MTRR_FIX_4K_E0000 0x26c
53 #define MTRR_FIX_4K_E8000 0x26d
54 #define MTRR_FIX_4K_F0000 0x26e
55 #define MTRR_FIX_4K_F8000 0x26f
56 
57 #if !defined(__ASSEMBLER__)
58 
59 #include <stdint.h>
60 #include <stddef.h>
61 
62 /*
63  * The MTRR code has some side effects that the callers should be aware for.
64  * 1. The call sequence matters. x86_setup_mtrrs() calls
65  * x86_setup_fixed_mtrrs_no_enable() then enable_fixed_mtrrs() (equivalent
66  * of x86_setup_fixed_mtrrs()) then x86_setup_var_mtrrs(). If the callers
67  * want to call the components of x86_setup_mtrrs() because of other
68  * requirements the ordering should still preserved.
69  * 2. enable_fixed_mtrr() will enable both variable and fixed MTRRs because
70  * of the nature of the global MTRR enable flag. Therefore, all direct
71  * or indirect callers of enable_fixed_mtrr() should ensure that the
72  * variable MTRR MSRs do not contain bad ranges.
73  *
74  * Note that this function sets up MTRRs for addresses above 4GiB.
75  */
76 void x86_setup_mtrrs(void);
77 /*
78  * x86_setup_mtrrs_with_detect() does the same thing as x86_setup_mtrrs(), but
79  * it always dynamically detects the number of variable MTRRs available.
80  */
83 /*
84  * x86_setup_var_mtrrs() parameters:
85  * address_bits - number of physical address bits supported by cpu
86  * above4gb - if set setup MTRRs for addresses above 4GiB else ignore
87  * memory ranges above 4GiB
88  */
89 void x86_setup_var_mtrrs(unsigned int address_bits, unsigned int above4gb);
90 void enable_fixed_mtrr(void);
91 /* Unhide Rd/WrDram bits and allow modification for AMD. */
93 /* Hide Rd/WrDram bits and allow modification for AMD. */
95 void x86_setup_fixed_mtrrs(void);
96 /* Set up fixed MTRRs but do not enable them. */
98 void x86_mtrr_check(void);
99 void need_restore_mtrr(void);
100 
101 /* Insert a temporary MTRR range for the duration of coreboot's runtime.
102  * This function needs to be called after the first MTRR solution is derived. */
103 void mtrr_use_temp_range(uintptr_t begin, size_t size, int type);
104 
105 static inline int get_var_mtrr_count(void)
106 {
108 }
109 
110 void set_var_mtrr(unsigned int reg, unsigned int base, unsigned int size,
111  unsigned int type);
112 int get_free_var_mtrr(void);
113 void clear_all_var_mtrr(void);
114 
115 asmlinkage void display_mtrrs(void);
116 
117 /* Variable MTRR structure to help track and set MTRRs prior to ramstage. This
118  and the following APIs can be used to set up more complex MTRR solutions
119  instead of open coding get_free_var_mtrr() and set_var_mtrr() or for determining
120  a future solution, such as postcar_loader. */
125  void *arg; /* optional callback parameter */
126 };
127 
128 /* Returns 0-relative MTRR from context. Use MTRR_PHYS_BASE|MASK macros for calculating
129  MSR address value. */
130 static inline int var_mtrr_context_current_mtrr(const struct var_mtrr_context *ctx)
131 {
132  return ctx->used_var_mtrrs;
133 }
134 
135 /* Initialize var_mtrr_context object. Assumes all variable MTRRs are not yet used. */
136 void var_mtrr_context_init(struct var_mtrr_context *ctx, void *arg);
137 /* Allocate a variable mtrr base and mask, calling the provided callback for each MTRR
138  MSR base-mask pair needed to accommodate the address and size request.
139  Returns < 0 on error and 0 on success. */
140 int var_mtrr_set_with_cb(struct var_mtrr_context *ctx,
141  uintptr_t addr, size_t size, int type,
142  void (*callback)(const struct var_mtrr_context *ctx,
143  uintptr_t base_addr, size_t size,
144  msr_t base, msr_t mask));
145 /* Same as var_mtrr_set_with_cb() but just write the MSRs directly. */
146 int var_mtrr_set(struct var_mtrr_context *ctx, uintptr_t addr, size_t size, int type);
147 
148 /*
149  * Set the MTRRs using the data on the stack from setup_stack_and_mtrrs.
150  * Return a new top_of_stack value which removes the setup_stack_and_mtrrs data.
151  */
152 asmlinkage void *soc_set_mtrrs(void *top_of_stack);
153 asmlinkage void soc_enable_mtrrs(void);
154 
155 /* fms: find most significant bit set, stolen from Linux Kernel Source. */
156 static inline unsigned int fms(unsigned int x)
157 {
158  unsigned int r;
159 
160  __asm__("bsrl %1,%0\n\t"
161  "jnz 1f\n\t"
162  "movl $0,%0\n"
163  "1:" : "=r" (r) : "mr" (x));
164  return r;
165 }
166 
167 /* fls: find least significant bit set */
168 static inline unsigned int fls(unsigned int x)
169 {
170  unsigned int r;
171 
172  __asm__("bsfl %1,%0\n\t"
173  "jnz 1f\n\t"
174  "movl $32,%0\n"
175  "1:" : "=r" (r) : "mr" (x));
176  return r;
177 }
178 #endif /* !defined(__ASSEMBLER__) */
179 
180 /* Align up/down to next power of 2, suitable for assembler
181  too. Range of result 256kB to 128MB is good enough here. */
182 #define _POW2_MASK(x) ((x>>1)|(x>>2)|(x>>3)|(x>>4)|(x>>5)| \
183  (x>>6)|(x>>7)|(x>>8)|((1<<18)-1))
184 #define _ALIGN_UP_POW2(x) ((x + _POW2_MASK(x)) & ~_POW2_MASK(x))
185 #define _ALIGN_DOWN_POW2(x) ((x) & ~_POW2_MASK(x))
186 
187 /* Calculate `4GiB - x` (e.g. absolute address for offset from 4GiB) */
188 #define _FROM_4G_TOP(x) ((0xffffffff - (x)) + 1)
189 
190 /* At the end of romstage, low RAM 0..CACHE_TM_RAMTOP may be set
191  * as write-back cacheable to speed up ramstage decompression.
192  * Note MTRR boundaries, must be power of two.
193  */
194 #define CACHE_TMP_RAMTOP (16<<20)
195 
196 /* For ROM caching, generally, try to use the next power of 2. */
197 #define OPTIMAL_CACHE_ROM_SIZE _ALIGN_UP_POW2(CONFIG_ROM_SIZE)
198 #define OPTIMAL_CACHE_ROM_BASE _FROM_4G_TOP(OPTIMAL_CACHE_ROM_SIZE)
199 #if (OPTIMAL_CACHE_ROM_SIZE < CONFIG_ROM_SIZE) || \
200  (OPTIMAL_CACHE_ROM_SIZE >= (2 * CONFIG_ROM_SIZE))
201 # error "Optimal CACHE_ROM_SIZE can't be derived, _POW2_MASK needs refinement."
202 #endif
203 
204 /* Make sure it doesn't overlap CAR, though. If the gap between
205  CAR and 4GiB is too small, make it at most the size of this
206  gap. As we can't align up (might overlap again), align down
207  to get a power of 2 again, for a single MTRR. */
208 #define CAR_END (CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)
209 #if CAR_END > OPTIMAL_CACHE_ROM_BASE
210 # define CAR_CACHE_ROM_SIZE _ALIGN_DOWN_POW2(_FROM_4G_TOP(CAR_END))
211 #else
212 # define CAR_CACHE_ROM_SIZE OPTIMAL_CACHE_ROM_SIZE
213 #endif
214 #if ((CAR_CACHE_ROM_SIZE & (CAR_CACHE_ROM_SIZE - 1)) != 0)
215 # error "CAR CACHE_ROM_SIZE is not a power of 2, _POW2_MASK needs refinement."
216 #endif
217 
218 /* Last but not least, most (if not all) chipsets have MMIO
219  between 0xfe000000 and 0xff000000, so limit to 16MiB. */
220 #if CAR_CACHE_ROM_SIZE >= 16 << 20
221 # define CACHE_ROM_SIZE (16 << 20)
222 #else
223 # define CACHE_ROM_SIZE CAR_CACHE_ROM_SIZE
224 #endif
225 
226 #define CACHE_ROM_BASE _FROM_4G_TOP(CACHE_ROM_SIZE)
227 
228 #endif /* CPU_X86_MTRR_H */
#define asmlinkage
Definition: cpu.h:8
static u32 addr
Definition: cirrus.c:14
static __always_inline msr_t rdmsr(unsigned int index)
Definition: msr.h:146
struct bootblock_arg arg
Definition: decompressor.c:22
unsigned int type
Definition: edid.c:57
int x
Definition: edid.c:994
uintptr_t base
Definition: uart.c:17
static const int mask[4]
Definition: gpio.c:308
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
unsigned int lo
Definition: msr.h:111
int max_var_mtrrs
Definition: mtrr.h:123
void * arg
Definition: mtrr.h:125
int used_var_mtrrs
Definition: mtrr.h:124
uint32_t upper_mask
Definition: mtrr.h:122
void fixed_mtrrs_hide_amd_rwdram(void)
Definition: mtrr.c:75
static unsigned int fms(unsigned int x)
Definition: mtrr.h:156
void enable_fixed_mtrr(void)
Definition: mtrr.c:54
void var_mtrr_context_init(struct var_mtrr_context *ctx, void *arg)
Definition: earlymtrr.c:9
static unsigned int fls(unsigned int x)
Definition: mtrr.h:168
void need_restore_mtrr(void)
Definition: mtrr.c:863
void x86_setup_var_mtrrs(unsigned int address_bits, unsigned int above4gb)
Definition: mtrr.c:786
static int get_var_mtrr_count(void)
Definition: mtrr.h:105
int get_free_var_mtrr(void)
Definition: mtrrlib.c:11
void x86_mtrr_check(void)
Definition: mtrr.c:836
asmlinkage void * soc_set_mtrrs(void *top_of_stack)
Definition: mtrr.c:8
void mtrr_use_temp_range(uintptr_t begin, size_t size, int type)
Definition: mtrr.c:868
void clear_all_var_mtrr(void)
Definition: mtrrlib.c:53
static int var_mtrr_context_current_mtrr(const struct var_mtrr_context *ctx)
Definition: mtrr.h:130
void x86_setup_mtrrs_with_detect_no_above_4gb(void)
Definition: mtrr.c:830
#define MTRR_CAP_VCNT
Definition: mtrr.h:23
int var_mtrr_set_with_cb(struct var_mtrr_context *ctx, uintptr_t addr, size_t size, int type, void(*callback)(const struct var_mtrr_context *ctx, uintptr_t base_addr, size_t size, msr_t base, msr_t mask))
Definition: earlymtrr.c:17
void x86_setup_fixed_mtrrs_no_enable(void)
Definition: mtrr.c:348
asmlinkage void soc_enable_mtrrs(void)
Definition: mtrr.c:69
void x86_setup_mtrrs_with_detect(void)
Definition: mtrr.c:823
#define MTRR_CAP_MSR
Definition: mtrr.h:17
asmlinkage void display_mtrrs(void)
Definition: debug.c:186
void fixed_mtrrs_expose_amd_rwdram(void)
Definition: mtrr.c:63
void x86_setup_mtrrs(void)
Definition: mtrr.c:815
void set_var_mtrr(unsigned int reg, unsigned int base, unsigned int size, unsigned int type)
Definition: mtrrlib.c:30
int var_mtrr_set(struct var_mtrr_context *ctx, uintptr_t addr, size_t size, int type)
Definition: earlymtrr.c:71
void x86_setup_fixed_mtrrs(void)
Definition: mtrr.c:354