summaryrefslogtreecommitdiff
path: root/src/include/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/cpu')
-rw-r--r--src/include/cpu/x86/mtrr.h34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/include/cpu/x86/mtrr.h b/src/include/cpu/x86/mtrr.h
index 913ba47487..bbcde8a658 100644
--- a/src/include/cpu/x86/mtrr.h
+++ b/src/include/cpu/x86/mtrr.h
@@ -96,6 +96,13 @@ static inline long x86_mtrr_rom_cache_var_index(void) { return -1; }
void set_var_mtrr(unsigned reg, unsigned base, unsigned size, unsigned type);
#endif
+/* Align up to next power of 2, suitable for ROMCC and assembler too.
+ * Range of result 256kB to 128MB is good enough here.
+ */
+#define _POW2_MASK(x) ((x>>1)|(x>>2)|(x>>3)|(x>>4)|(x>>5)| \
+ (x>>6)|(x>>7)|(x>>8)|((1<<18)-1))
+#define _ALIGN_UP_POW2(x) ((x + _POW2_MASK(x)) & ~_POW2_MASK(x))
+
#if !defined(CONFIG_RAMTOP)
# error "CONFIG_RAMTOP not defined"
#endif
@@ -104,11 +111,32 @@ void set_var_mtrr(unsigned reg, unsigned base, unsigned size, unsigned type);
# error "CONFIG_XIP_ROM_SIZE is not a power of 2"
#endif
-#if ((CONFIG_CACHE_ROM_SIZE & (CONFIG_CACHE_ROM_SIZE -1)) != 0)
-# error "CONFIG_CACHE_ROM_SIZE is not a power of 2"
+/* Select CACHE_ROM_SIZE to use with MTRR setup. For most cases this
+ * resolves to a suitable CONFIG_ROM_SIZE but some odd cases need to
+ * use CONFIG_CACHE_ROM_SIZE_OVERRIDE in the mainboard Kconfig.
+ */
+#if (CONFIG_CACHE_ROM_SIZE_OVERRIDE != 0)
+# define CACHE_ROM_SIZE CONFIG_CACHE_ROM_SIZE_OVERRIDE
+#else
+# if ((CONFIG_ROM_SIZE & (CONFIG_ROM_SIZE-1)) == 0)
+# define CACHE_ROM_SIZE CONFIG_ROM_SIZE
+# else
+# define CACHE_ROM_SIZE _ALIGN_UP_POW2(CONFIG_ROM_SIZE)
+# if (CACHE_ROM_SIZE < CONFIG_ROM_SIZE) || (CACHE_ROM_SIZE >= (2 * CONFIG_ROM_SIZE))
+# error "CACHE_ROM_SIZE is not optimal."
+# endif
+# endif
+#endif
+
+#if ((CACHE_ROM_SIZE & (CACHE_ROM_SIZE-1)) != 0)
+# error "CACHE_ROM_SIZE is not a power of 2."
#endif
-#define CACHE_ROM_BASE (((1<<20) - (CONFIG_CACHE_ROM_SIZE>>12))<<12)
+#define CACHE_ROM_BASE (((1<<20) - (CACHE_ROM_SIZE>>12))<<12)
+
+#if ((CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE) * 1UL > CACHE_ROM_BASE * 1UL)
+# error "CAR region (WB) and flash (WP) regions overlap."
+#endif
#if (CONFIG_RAMTOP & (CONFIG_RAMTOP - 1)) != 0
# error "CONFIG_RAMTOP must be a power of 2"