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

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

unix.superglobalmegacorp.com

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