blob: 2e31a6e113bc6c972d9dcb1c0f257232d05c671c [file] [log] [blame]
Eric Biedermanfcd5ace2004-10-14 19:29:29 +00001#include <cpu/x86/cache.h>
2#include <cpu/x86/mtrr.h>
3#include <cpu/x86/msr.h>
4
Kyösti Mälkki88a67f02013-12-12 12:27:53 +02005#ifdef __ROMCC__
6static
7#endif
8void set_var_mtrr(
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00009 unsigned reg, unsigned base, unsigned size, unsigned type)
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000010{
11 /* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
Yinghai Lu21332b82007-04-06 19:49:05 +000012 /* FIXME: It only support 4G less range */
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000013 msr_t basem, maskm;
14 basem.lo = base | type;
15 basem.hi = 0;
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070016 wrmsr(MTRR_PHYS_BASE(reg), basem);
17 maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID;
Stefan Reinauer23f49a82011-04-14 20:39:49 +000018 maskm.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1;
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070019 wrmsr(MTRR_PHYS_MASK(reg), maskm);
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000020}
21
Martin Rothc4e49f62015-07-11 13:42:54 -060022#if !IS_ENABLED(CONFIG_CACHE_AS_RAM)
Stefan Reinauerb91a0f22012-06-15 15:34:24 -070023static void cache_ramstage(void)
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000024{
Stefan Reinauerb91a0f22012-06-15 15:34:24 -070025 /* Enable caching for lower 1MB and ram stage using variable mtrr */
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000026 disable_cache();
Stefan Reinauerb91a0f22012-06-15 15:34:24 -070027 set_var_mtrr(0, 0x00000000, CONFIG_RAMTOP, MTRR_TYPE_WRBACK);
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000028 enable_cache();
29}
30
Patrick Georgi1da10462011-10-28 20:28:03 +020031const int addr_det = 0;
32
Paul Menzel4fe98132014-01-25 15:55:28 +010033/* the fixed and variable MTRRs are power-up with random values,
Martin Roth4c3ab732013-07-08 16:23:54 -060034 * clear them to MTRR_TYPE_UNCACHEABLE for safety.
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000035 */
36static void do_early_mtrr_init(const unsigned long *mtrr_msrs)
37{
38 /* Precondition:
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070039 * The cache is not enabled in cr0 nor in MTRR_DEF_TYPE_MSR
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000040 * entry32.inc ensures the cache is not enabled in cr0
41 */
42 msr_t msr;
43 const unsigned long *msr_addr;
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000044
Martin Roth4c3ab732013-07-08 16:23:54 -060045 /* Initialize all of the relevant msrs to 0 */
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000046 msr.lo = 0;
47 msr.hi = 0;
48 unsigned long msr_nr;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000049 for(msr_addr = mtrr_msrs; (msr_nr = *msr_addr); msr_addr++) {
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000050 wrmsr(msr_nr, msr);
51 }
52
Martin Roth46cf9f72015-07-11 13:56:58 -060053#if defined(CONFIG_XIP_ROM_SIZE) && CONFIG_XIP_ROM_SIZE
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000054 /* enable write through caching so we can do execute in place
55 * on the flash rom.
Patrick Georgi1da10462011-10-28 20:28:03 +020056 * Determine address by calculating the XIP_ROM_SIZE sized area with
57 * XIP_ROM_SIZE alignment that contains the global variable defined above;
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000058 */
Patrick Georgi1da10462011-10-28 20:28:03 +020059 unsigned long f = (unsigned long)&addr_det & ~(CONFIG_XIP_ROM_SIZE - 1);
60 set_var_mtrr(1, f, CONFIG_XIP_ROM_SIZE, MTRR_TYPE_WRBACK);
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000061#endif
62
Stefan Reinauer14e22772010-04-27 06:56:47 +000063 /* Set the default memory type and enable fixed and variable MTRRs
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000064 */
65 /* Enable Variable MTRRs */
66 msr.hi = 0x00000000;
67 msr.lo = 0x00000800;
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070068 wrmsr(MTRR_DEF_TYPE_MSR, msr);
Stefan Reinauer14e22772010-04-27 06:56:47 +000069
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000070}
71
Stefan Reinauerd4f53732010-04-09 14:46:51 +000072static inline void early_mtrr_init(void)
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000073{
74 static const unsigned long mtrr_msrs[] = {
75 /* fixed mtrr */
76 0x250, 0x258, 0x259,
77 0x268, 0x269, 0x26A,
78 0x26B, 0x26C, 0x26D,
79 0x26E, 0x26F,
80 /* var mtrr */
81 0x200, 0x201, 0x202, 0x203,
82 0x204, 0x205, 0x206, 0x207,
83 0x208, 0x209, 0x20A, 0x20B,
84 0x20C, 0x20D, 0x20E, 0x20F,
85 /* NULL end of table */
86 0
87 };
88 disable_cache();
89 do_early_mtrr_init(mtrr_msrs);
90 enable_cache();
91}
92
Stefan Reinauer8a9268452010-04-07 03:40:37 +000093static inline int early_mtrr_init_detected(void)
Jason Schildt6a2c09a2005-10-25 21:07:34 +000094{
95 msr_t msr;
96 /* See if MTRR's are enabled.
97 * a #RESET disables them while an #INIT
98 * preserves their state. This works
99 * on both Intel and AMD cpus, at least
100 * according to the documentation.
101 */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700102 msr = rdmsr(MTRR_DEF_TYPE_MSR);
103 return msr.lo & MTRR_DEF_TYPE_EN;
Jason Schildt6a2c09a2005-10-25 21:07:34 +0000104}
Stefan Reinauer23f49a82011-04-14 20:39:49 +0000105#endif