blob: eb7d78d1c57d07ef0d7f3cc74013b6b2dbed1fd7 [file] [log] [blame]
Eric Biedermanc84c1902004-10-14 20:13:01 +00001#ifndef CPU_X86_MTRR_H
2#define CPU_X86_MTRR_H
3
Nico Huber6197b762018-05-26 20:34:21 +02004#include <commonlib/helpers.h>
Nico Huberca74f8f2018-06-01 21:57:54 +02005#ifndef __ASSEMBLER__
6#include <cpu/x86/msr.h>
7#include <arch/cpu.h>
8#endif
Nico Huber6197b762018-05-26 20:34:21 +02009
Eric Biedermanc84c1902004-10-14 20:13:01 +000010/* These are the region types */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070011#define MTRR_TYPE_UNCACHEABLE 0
12#define MTRR_TYPE_WRCOMB 1
13#define MTRR_TYPE_WRTHROUGH 4
14#define MTRR_TYPE_WRPROT 5
15#define MTRR_TYPE_WRBACK 6
16#define MTRR_NUM_TYPES 7
Eric Biedermanc84c1902004-10-14 20:13:01 +000017
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070018#define MTRR_CAP_MSR 0x0fe
Lee Leahybfdf2482015-06-18 10:55:19 -070019
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070020#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
Lee Leahybfdf2482015-06-18 10:55:19 -070024
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070025#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)
Eric Biedermanc84c1902004-10-14 20:13:01 +000029
Uwe Hermann66d16872010-10-01 07:27:51 +000030
Arthur Heymanse750b38e2018-07-20 23:31:59 +020031#define IA32_SMRR_PHYS_BASE 0x1f2
32#define IA32_SMRR_PHYS_MASK 0x1f3
Duncan Laurie7b678922012-01-09 22:05:18 -080033
Arthur Heymans06f818c2018-07-20 23:41:54 +020034/* Specific to model_6fx and model_1067x */
35#define MSR_SMRR_PHYS_BASE 0xa0
36#define MSR_SMRR_PHYS_MASK 0xa1
37
Lee Leahy84d20d02017-03-07 15:00:18 -080038#define MTRR_PHYS_BASE(reg) (0x200 + 2 * (reg))
39#define MTRR_PHYS_MASK(reg) (MTRR_PHYS_BASE(reg) + 1)
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070040#define MTRR_PHYS_MASK_VALID (1 << 11)
Eric Biedermanc84c1902004-10-14 20:13:01 +000041
Lee Leahy84d20d02017-03-07 15:00:18 -080042#define NUM_FIXED_RANGES 88
43#define RANGES_PER_FIXED_MTRR 8
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070044#define MTRR_FIX_64K_00000 0x250
45#define MTRR_FIX_16K_80000 0x258
46#define MTRR_FIX_16K_A0000 0x259
47#define MTRR_FIX_4K_C0000 0x268
48#define MTRR_FIX_4K_C8000 0x269
49#define MTRR_FIX_4K_D0000 0x26a
50#define MTRR_FIX_4K_D8000 0x26b
51#define MTRR_FIX_4K_E0000 0x26c
52#define MTRR_FIX_4K_E8000 0x26d
53#define MTRR_FIX_4K_F0000 0x26e
54#define MTRR_FIX_4K_F8000 0x26f
Eric Biedermanc84c1902004-10-14 20:13:01 +000055
Aaron Durbinea0497c2017-06-08 10:51:33 -050056#if !defined(__ASSEMBLER__) && !defined(__ROMCC__)
Aaron Durbinbb4e79a2013-03-26 14:09:47 -050057
Aaron Durbin2bebd7b2016-11-10 15:15:35 -060058#include <stdint.h>
59#include <stddef.h>
60
Aaron Durbinbb4e79a2013-03-26 14:09:47 -050061/*
62 * The MTRR code has some side effects that the callers should be aware for.
63 * 1. The call sequence matters. x86_setup_mtrrs() calls
64 * x86_setup_fixed_mtrrs_no_enable() then enable_fixed_mtrrs() (equivalent
65 * of x86_setup_fixed_mtrrs()) then x86_setup_var_mtrrs(). If the callers
66 * want to call the components of x86_setup_mtrrs() because of other
Martin Roth0cb07e32013-07-09 21:46:01 -060067 * requirements the ordering should still preserved.
Aaron Durbinbb4e79a2013-03-26 14:09:47 -050068 * 2. enable_fixed_mtrr() will enable both variable and fixed MTRRs because
69 * of the nature of the global MTRR enable flag. Therefore, all direct
70 * or indirect callers of enable_fixed_mtrr() should ensure that the
71 * variable MTRR MSRs do not contain bad ranges.
Aaron Durbine63be892016-03-07 16:05:36 -060072 *
73 * Note that this function sets up MTRRs for addresses above 4GiB.
Ronald G. Minnich69efaa02013-02-26 10:07:40 -080074 */
Sven Schnelleadfbcb792012-01-10 12:01:43 +010075void x86_setup_mtrrs(void);
Aaron Durbinbb4e79a2013-03-26 14:09:47 -050076/*
Aaron Durbine63be892016-03-07 16:05:36 -060077 * x86_setup_mtrrs_with_detect() does the same thing as x86_setup_mtrrs(), but
78 * it always dynamically detects the number of variable MTRRs available.
79 */
80void x86_setup_mtrrs_with_detect(void);
81/*
Aaron Durbinbb4e79a2013-03-26 14:09:47 -050082 * x86_setup_var_mtrrs() parameters:
83 * address_bits - number of physical address bits supported by cpu
Aaron Durbine63be892016-03-07 16:05:36 -060084 * above4gb - if set setup MTRRs for addresses above 4GiB else ignore
85 * memory ranges above 4GiB
Aaron Durbinbb4e79a2013-03-26 14:09:47 -050086 */
87void x86_setup_var_mtrrs(unsigned int address_bits, unsigned int above4gb);
88void enable_fixed_mtrr(void);
Marshall Dawsonc0dbeda2017-10-19 09:45:16 -060089/* Unhide Rd/WrDram bits and allow modification for AMD. */
90void fixed_mtrrs_expose_amd_rwdram(void);
91/* Hide Rd/WrDram bits and allow modification for AMD. */
92void fixed_mtrrs_hide_amd_rwdram(void);
Maciej Pijankaea921852009-10-27 14:29:29 +000093void x86_setup_fixed_mtrrs(void);
Aaron Durbin57686f82013-03-20 15:50:59 -050094/* Set up fixed MTRRs but do not enable them. */
95void x86_setup_fixed_mtrrs_no_enable(void);
Kyösti Mälkki38a8fb02014-06-30 13:48:18 +030096void x86_mtrr_check(void);
Aaron Durbin2bebd7b2016-11-10 15:15:35 -060097
98/* Insert a temporary MTRR range for the duration of coreboot's runtime.
99 * This function needs to be called after the first MTRR solution is derived. */
100void mtrr_use_temp_range(uintptr_t begin, size_t size, int type);
Eric Biedermanc84c1902004-10-14 20:13:01 +0000101
Nico Huberd67edca2018-11-13 19:28:07 +0100102static inline int get_var_mtrr_count(void)
103{
104 return rdmsr(MTRR_CAP_MSR).lo & MTRR_CAP_VCNT;
105}
106
Lee Leahy0ca2a062017-03-06 18:01:04 -0800107void set_var_mtrr(unsigned int reg, unsigned int base, unsigned int size,
108 unsigned int type);
Furquan Shaikh331ac1b2016-03-16 16:12:06 -0700109int get_free_var_mtrr(void);
Rizwan Qureshi8453c4f2016-09-07 20:11:11 +0530110
Nico Huberd67edca2018-11-13 19:28:07 +0100111asmlinkage void display_mtrrs(void);
112
Nico Huberca74f8f2018-06-01 21:57:54 +0200113/*
114 * Set the MTRRs using the data on the stack from setup_stack_and_mtrrs.
115 * Return a new top_of_stack value which removes the setup_stack_and_mtrrs data.
116 */
117asmlinkage void *soc_set_mtrrs(void *top_of_stack);
118asmlinkage void soc_enable_mtrrs(void);
119
Rizwan Qureshi8453c4f2016-09-07 20:11:11 +0530120/* fms: find most significant bit set, stolen from Linux Kernel Source. */
121static inline unsigned int fms(unsigned int x)
122{
123 int r;
124
125 __asm__("bsrl %1,%0\n\t"
Lee Leahy708fc272017-03-07 12:18:53 -0800126 "jnz 1f\n\t"
127 "movl $0,%0\n"
Aaron Durbinf4258de2017-11-01 15:47:05 -0600128 "1:" : "=r" (r) : "mr" (x));
Rizwan Qureshi8453c4f2016-09-07 20:11:11 +0530129 return r;
130}
131
132/* fls: find least significant bit set */
133static inline unsigned int fls(unsigned int x)
134{
135 int r;
136
137 __asm__("bsfl %1,%0\n\t"
Lee Leahy708fc272017-03-07 12:18:53 -0800138 "jnz 1f\n\t"
139 "movl $32,%0\n"
Aaron Durbinf4258de2017-11-01 15:47:05 -0600140 "1:" : "=r" (r) : "mr" (x));
Rizwan Qureshi8453c4f2016-09-07 20:11:11 +0530141 return r;
142}
Aaron Durbinea0497c2017-06-08 10:51:33 -0500143#endif /* !defined(__ASSEMBLER__) && !defined(__ROMCC__) */
Rizwan Qureshi8453c4f2016-09-07 20:11:11 +0530144
Nico Huberb4953a92018-05-26 17:47:42 +0200145/* Align up/down to next power of 2, suitable for ROMCC and assembler
146 too. Range of result 256kB to 128MB is good enough here. */
Kyösti Mälkki107f72e2014-01-06 11:06:26 +0200147#define _POW2_MASK(x) ((x>>1)|(x>>2)|(x>>3)|(x>>4)|(x>>5)| \
148 (x>>6)|(x>>7)|(x>>8)|((1<<18)-1))
149#define _ALIGN_UP_POW2(x) ((x + _POW2_MASK(x)) & ~_POW2_MASK(x))
Nico Huberb4953a92018-05-26 17:47:42 +0200150#define _ALIGN_DOWN_POW2(x) ((x) & ~_POW2_MASK(x))
151
152/* Calculate `4GiB - x` (e.g. absolute address for offset from 4GiB) */
Nico Huberc9e33572019-02-08 16:09:57 +0100153#define _FROM_4G_TOP(x) (((1 << 20) - ((x) >> 12)) << 12)
Kyösti Mälkki107f72e2014-01-06 11:06:26 +0200154
Elyes HAOUAS918535a2016-07-28 21:25:21 +0200155/* At the end of romstage, low RAM 0..CACHE_TM_RAMTOP may be set
Kyösti Mälkki65cc5262016-06-19 20:38:41 +0300156 * as write-back cacheable to speed up ramstage decompression.
157 * Note MTRR boundaries, must be power of two.
158 */
159#define CACHE_TMP_RAMTOP (16<<20)
Stefan Reinauer8f2c6162010-04-06 21:50:21 +0000160
Lee Leahyd0f26fc2017-03-08 10:15:03 -0800161#if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
Stefan Reinauer8f2c6162010-04-06 21:50:21 +0000162# error "CONFIG_XIP_ROM_SIZE is not a power of 2"
163#endif
Stefan Reinauer8f2c6162010-04-06 21:50:21 +0000164
Nico Huberb4953a92018-05-26 17:47:42 +0200165/* For ROM caching, generally, try to use the next power of 2. */
166#define OPTIMAL_CACHE_ROM_SIZE _ALIGN_UP_POW2(CONFIG_ROM_SIZE)
167#define OPTIMAL_CACHE_ROM_BASE _FROM_4G_TOP(OPTIMAL_CACHE_ROM_SIZE)
168#if (OPTIMAL_CACHE_ROM_SIZE < CONFIG_ROM_SIZE) || \
169 (OPTIMAL_CACHE_ROM_SIZE >= (2 * CONFIG_ROM_SIZE))
170# error "Optimal CACHE_ROM_SIZE can't be derived, _POW2_MASK needs refinement."
171#endif
172
173/* Make sure it doesn't overlap CAR, though. If the gap between
174 CAR and 4GiB is too small, make it at most the size of this
175 gap. As we can't align up (might overlap again), align down
176 to get a power of 2 again, for a single MTRR. */
177#define CAR_END (CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)
178#if CAR_END > OPTIMAL_CACHE_ROM_BASE
Nico Huber6197b762018-05-26 20:34:21 +0200179# define CAR_CACHE_ROM_SIZE _ALIGN_DOWN_POW2(_FROM_4G_TOP(CAR_END))
Kyösti Mälkki107f72e2014-01-06 11:06:26 +0200180#else
Nico Huber6197b762018-05-26 20:34:21 +0200181# define CAR_CACHE_ROM_SIZE OPTIMAL_CACHE_ROM_SIZE
Nico Huberb4953a92018-05-26 17:47:42 +0200182#endif
Nico Huber6197b762018-05-26 20:34:21 +0200183#if ((CAR_CACHE_ROM_SIZE & (CAR_CACHE_ROM_SIZE - 1)) != 0)
184# error "CAR CACHE_ROM_SIZE is not a power of 2, _POW2_MASK needs refinement."
185#endif
186
187/* Last but not least, most (if not all) chipsets have MMIO
188 between 0xfe000000 and 0xff000000, so limit to 16MiB. */
189#if CAR_CACHE_ROM_SIZE >= 16 * MiB
190# define CACHE_ROM_SIZE (16 * MiB)
191#else
192# define CACHE_ROM_SIZE CAR_CACHE_ROM_SIZE
Kyösti Mälkki5458b9d2012-06-30 11:41:08 +0300193#endif
194
Nico Huberb4953a92018-05-26 17:47:42 +0200195#define CACHE_ROM_BASE _FROM_4G_TOP(CACHE_ROM_SIZE)
Kyösti Mälkki107f72e2014-01-06 11:06:26 +0200196
Eric Biedermanc84c1902004-10-14 20:13:01 +0000197#endif /* CPU_X86_MTRR_H */