Annotation of qemu/roms/seabios/src/mtrr.c, revision 1.1.1.1

1.1       root        1: // Initialize MTRRs - mostly useful on KVM.
                      2: //
                      3: // Copyright (C) 2006 Fabrice Bellard
                      4: //
                      5: // This file may be distributed under the terms of the GNU LGPLv3 license.
                      6: 
                      7: #include "util.h" // dprintf
                      8: #include "biosvar.h" // GET_EBDA
                      9: 
                     10: #define MSR_MTRRcap                    0x000000fe
                     11: #define MSR_MTRRfix64K_00000           0x00000250
                     12: #define MSR_MTRRfix16K_80000           0x00000258
                     13: #define MSR_MTRRfix16K_A0000           0x00000259
                     14: #define MSR_MTRRfix4K_C0000            0x00000268
                     15: #define MSR_MTRRfix4K_C8000            0x00000269
                     16: #define MSR_MTRRfix4K_D0000            0x0000026a
                     17: #define MSR_MTRRfix4K_D8000            0x0000026b
                     18: #define MSR_MTRRfix4K_E0000            0x0000026c
                     19: #define MSR_MTRRfix4K_E8000            0x0000026d
                     20: #define MSR_MTRRfix4K_F0000            0x0000026e
                     21: #define MSR_MTRRfix4K_F8000            0x0000026f
                     22: #define MSR_MTRRdefType                0x000002ff
                     23: 
                     24: #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
                     25: #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
                     26: 
                     27: void mtrr_setup(void)
                     28: {
                     29:     if (CONFIG_COREBOOT)
                     30:         return;
                     31: 
                     32:     u32 eax, ebx, ecx, edx, cpuid_features;
                     33:     cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
                     34:     if (!(cpuid_features & CPUID_MTRR))
                     35:         return;
                     36:     if (!(cpuid_features & CPUID_MSR))
                     37:         return;
                     38: 
                     39:     dprintf(3, "init mtrr\n");
                     40: 
                     41:     int i, vcnt, fix, wc;
                     42:     u32 ram_size = GET_GLOBAL(RamSize);
                     43:     u32 mtrr_cap;
                     44:     union {
                     45:         u8 valb[8];
                     46:         u64 val;
                     47:     } u;
                     48: 
                     49:     mtrr_cap = rdmsr(MSR_MTRRcap);
                     50:     vcnt = mtrr_cap & 0xff;
                     51:     fix = mtrr_cap & 0x100;
                     52:     wc = mtrr_cap & 0x400;
                     53:     if (!vcnt || !fix)
                     54:        return;
                     55:     u.val = 0;
                     56:     for (i = 0; i < 8; ++i)
                     57:         if (ram_size >= 65536 * (i + 1))
                     58:             u.valb[i] = 6;
                     59:     wrmsr_smp(MSR_MTRRfix64K_00000, u.val);
                     60:     u.val = 0;
                     61:     for (i = 0; i < 8; ++i)
                     62:         if (ram_size >= 65536 * 8 + 16384 * (i + 1))
                     63:             u.valb[i] = 6;
                     64:     wrmsr_smp(MSR_MTRRfix16K_80000, u.val);
                     65:     wrmsr_smp(MSR_MTRRfix16K_A0000, 0);
                     66:     wrmsr_smp(MSR_MTRRfix4K_C0000, 0);
                     67:     wrmsr_smp(MSR_MTRRfix4K_C8000, 0);
                     68:     wrmsr_smp(MSR_MTRRfix4K_D0000, 0);
                     69:     wrmsr_smp(MSR_MTRRfix4K_D8000, 0);
                     70:     wrmsr_smp(MSR_MTRRfix4K_E0000, 0);
                     71:     wrmsr_smp(MSR_MTRRfix4K_E8000, 0);
                     72:     wrmsr_smp(MSR_MTRRfix4K_F0000, 0);
                     73:     wrmsr_smp(MSR_MTRRfix4K_F8000, 0);
                     74:     /* Mark 3.5-4GB as UC, anything not specified defaults to WB */
                     75:     wrmsr_smp(MTRRphysBase_MSR(0), 0xe0000000ull | 0);
                     76: 
                     77:     int phys_bits = 36;
                     78:     cpuid(0x80000000u, &eax, &ebx, &ecx, &edx);
                     79:     if (eax >= 0x80000008) {
                     80:             /* Get physical bits from leaf 0x80000008 (if available) */
                     81:             cpuid(0x80000008u, &eax, &ebx, &ecx, &edx);
                     82:             phys_bits = eax & 0xff;
                     83:     }
                     84:     u64 phys_mask = ((1ull << phys_bits) - 1);
                     85:     wrmsr_smp(MTRRphysMask_MSR(0), (~(0x20000000ull - 1) & phys_mask) | 0x800);
                     86: 
                     87:     wrmsr_smp(MSR_MTRRdefType, 0xc06);
                     88: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.