1 #include <console/console.h>
2 #include <device/device.h>
3 #include <cpu/x86/mtrr.h>
4 #include <cpu/amd/mtrr.h>
5 #include <cpu/x86/cache.h>
6 #include <cpu/x86/msr.h>
8 static unsigned long resk(uint64_t value)
10 unsigned long resultk;
11 if (value < (1ULL << 42)) {
12 resultk = value >> 10;
20 void amd_setup_mtrrs(void)
22 unsigned long mmio_basek, tomk;
27 /* Disable the access to AMD RdDram and WrDram extension bits */
28 msr = rdmsr(SYSCFG_MSR);
29 msr.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
30 wrmsr(SYSCFG_MSR, msr);
34 /* Except for the PCI MMIO hole just before 4GB there are no
35 * significant holes in the address space, so just account
36 * for those two and move on.
38 mmio_basek = tomk = 0;
39 for(dev = all_devices; dev; dev = dev->next) {
40 struct resource *res, *last;
41 last = &dev->resource[dev->resources];
42 for(res = &dev->resource[0]; res < last; res++) {
44 if (!(res->flags & IORESOURCE_MEM) ||
45 (!(res->flags & IORESOURCE_CACHEABLE))) {
48 topk = resk(res->base + res->size);
52 if ((topk < 4*1024*1024) && (mmio_basek < topk)) {
57 if (mmio_basek > tomk) {
60 /* Round mmio_basek down to the nearst size that will fit in TOP_MEM */
61 mmio_basek = mmio_basek & ~TOP_MEM_MASK_KB;
62 /* Round tomk up to the next greater size that will fit in TOP_MEM */
63 tomk = (tomk + TOP_MEM_MASK_KB) & ~TOP_MEM_MASK_KB;
68 msr.hi = mmio_basek >> 22;
69 msr.lo = mmio_basek << 10;
77 /* zero the IORR's before we enable to prevent
78 * undefined side effects.
81 for(i = IORR_FIRST; i <= IORR_LAST; i++) {
85 msr = rdmsr(SYSCFG_MSR);
86 msr.lo |= SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_TOM2En;
87 wrmsr(SYSCFG_MSR, msr);