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

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
1.1.1.4   root        9: #include "xen.h" // usingXen
1.1       root       10: 
                     11: #define MSR_MTRRcap                    0x000000fe
                     12: #define MSR_MTRRfix64K_00000           0x00000250
                     13: #define MSR_MTRRfix16K_80000           0x00000258
                     14: #define MSR_MTRRfix16K_A0000           0x00000259
                     15: #define MSR_MTRRfix4K_C0000            0x00000268
                     16: #define MSR_MTRRfix4K_C8000            0x00000269
                     17: #define MSR_MTRRfix4K_D0000            0x0000026a
                     18: #define MSR_MTRRfix4K_D8000            0x0000026b
                     19: #define MSR_MTRRfix4K_E0000            0x0000026c
                     20: #define MSR_MTRRfix4K_E8000            0x0000026d
                     21: #define MSR_MTRRfix4K_F0000            0x0000026e
                     22: #define MSR_MTRRfix4K_F8000            0x0000026f
                     23: #define MSR_MTRRdefType                0x000002ff
                     24: 
                     25: #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
                     26: #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
                     27: 
1.1.1.2   root       28: #define MTRR_MEMTYPE_UC 0
                     29: #define MTRR_MEMTYPE_WC 1
                     30: #define MTRR_MEMTYPE_WT 4
                     31: #define MTRR_MEMTYPE_WP 5
                     32: #define MTRR_MEMTYPE_WB 6
                     33: 
1.1       root       34: void mtrr_setup(void)
                     35: {
1.1.1.4   root       36:     if (!CONFIG_MTRR_INIT || CONFIG_COREBOOT || usingXen())
1.1       root       37:         return;
                     38: 
                     39:     u32 eax, ebx, ecx, edx, cpuid_features;
                     40:     cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
                     41:     if (!(cpuid_features & CPUID_MTRR))
                     42:         return;
                     43:     if (!(cpuid_features & CPUID_MSR))
                     44:         return;
                     45: 
                     46:     dprintf(3, "init mtrr\n");
                     47: 
1.1.1.2   root       48:     u32 mtrr_cap = rdmsr(MSR_MTRRcap);
                     49:     int vcnt = mtrr_cap & 0xff;
                     50:     int fix = mtrr_cap & 0x100;
                     51:     if (!vcnt || !fix)
                     52:        return;
                     53: 
                     54:     // Disable MTRRs
                     55:     wrmsr_smp(MSR_MTRRdefType, 0);
                     56: 
                     57:     // Set fixed MTRRs
                     58:     union u64b {
1.1       root       59:         u8 valb[8];
                     60:         u64 val;
                     61:     } u;
                     62:     u.val = 0;
1.1.1.2   root       63:     int i;
                     64:     for (i = 0; i < 8; i++)
                     65:         if (RamSize >= 65536 * (i + 1))
                     66:             u.valb[i] = MTRR_MEMTYPE_WB;
1.1       root       67:     wrmsr_smp(MSR_MTRRfix64K_00000, u.val);
                     68:     u.val = 0;
1.1.1.2   root       69:     for (i = 0; i < 8; i++)
                     70:         if (RamSize >= 0x80000 + 16384 * (i + 1))
                     71:             u.valb[i] = MTRR_MEMTYPE_WB;
1.1       root       72:     wrmsr_smp(MSR_MTRRfix16K_80000, u.val);
1.1.1.2   root       73:     wrmsr_smp(MSR_MTRRfix16K_A0000, 0);   // 0xA0000-0xC0000 is uncached
                     74:     int j;
                     75:     for (j = 0; j < 8; j++) {
                     76:         u.val = 0;
                     77:         for (i = 0; i < 8; i++)
                     78:             if (RamSize >= 0xC0000 + j * 0x8000 + 4096 * (i + 1))
                     79:                 u.valb[i] = MTRR_MEMTYPE_WP;
                     80:         wrmsr_smp(MSR_MTRRfix4K_C0000 + j, u.val);
                     81:     }
1.1       root       82: 
1.1.1.2   root       83:     // Set variable MTRRs
1.1       root       84:     int phys_bits = 36;
                     85:     cpuid(0x80000000u, &eax, &ebx, &ecx, &edx);
                     86:     if (eax >= 0x80000008) {
1.1.1.5 ! root       87:         /* Get physical bits from leaf 0x80000008 (if available) */
        !            88:         cpuid(0x80000008u, &eax, &ebx, &ecx, &edx);
        !            89:         phys_bits = eax & 0xff;
1.1       root       90:     }
                     91:     u64 phys_mask = ((1ull << phys_bits) - 1);
1.1.1.2   root       92:     for (i=0; i<vcnt; i++) {
                     93:         wrmsr_smp(MTRRphysBase_MSR(i), 0);
                     94:         wrmsr_smp(MTRRphysMask_MSR(i), 0);
                     95:     }
                     96:     /* Mark 3.5-4GB as UC, anything not specified defaults to WB */
                     97:     wrmsr_smp(MTRRphysBase_MSR(0), BUILD_MAX_HIGHMEM | MTRR_MEMTYPE_UC);
                     98:     wrmsr_smp(MTRRphysMask_MSR(0)
                     99:               , (-((1ull<<32)-BUILD_MAX_HIGHMEM) & phys_mask) | 0x800);
1.1       root      100: 
1.1.1.2   root      101:     // Enable fixed and variable MTRRs; set default type.
                    102:     wrmsr_smp(MSR_MTRRdefType, 0xc00 | MTRR_MEMTYPE_WB);
1.1       root      103: }

unix.superglobalmegacorp.com

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