Annotation of qemu/roms/seabios/src/mtrr.c, revision 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.