From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LP6QB-0008DQ-L8 for qemu-devel@nongnu.org; Mon, 19 Jan 2009 21:32:55 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LP6QA-0008CM-8J for qemu-devel@nongnu.org; Mon, 19 Jan 2009 21:32:55 -0500 Received: from [199.232.76.173] (port=56955 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LP6QA-0008CG-3o for qemu-devel@nongnu.org; Mon, 19 Jan 2009 21:32:54 -0500 Received: from mx2.redhat.com ([66.187.237.31]:39303) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LP6Q9-0001Ol-Je for qemu-devel@nongnu.org; Mon, 19 Jan 2009 21:32:53 -0500 Message-Id: <20090120023057.646292685@amt.cnet> Date: Tue, 20 Jan 2009 00:30:43 -0200 From: Marcelo Tosatti References: <20090120023040.623163208@amt.cnet> Content-Disposition: inline; filename=0004_mtrr_up.patch Subject: [Qemu-devel] [patch 3/9] kvm: bios: add mtrr support Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, bochs-developers@lists.sourceforge.net Cc: Anthony Liguori , Avi Kivity program mtrrs for cpu 0. Doesn't support >=4G at the moment. Signed-off-by: Avi Kivity From: Avi Kivity Index: bochs/bios/rombios32.c =================================================================== --- bochs.orig/bios/rombios32.c +++ bochs/bios/rombios32.c @@ -64,6 +64,23 @@ typedef unsigned long long uint64_t; #define BIOS_TMP_STORAGE 0x00030000 /* 64 KB used to copy the BIOS to shadow RAM */ +#define MSR_MTRRcap 0x000000fe +#define MSR_MTRRfix64K_00000 0x00000250 +#define MSR_MTRRfix16K_80000 0x00000258 +#define MSR_MTRRfix16K_A0000 0x00000259 +#define MSR_MTRRfix4K_C0000 0x00000268 +#define MSR_MTRRfix4K_C8000 0x00000269 +#define MSR_MTRRfix4K_D0000 0x0000026a +#define MSR_MTRRfix4K_D8000 0x0000026b +#define MSR_MTRRfix4K_E0000 0x0000026c +#define MSR_MTRRfix4K_E8000 0x0000026d +#define MSR_MTRRfix4K_F0000 0x0000026e +#define MSR_MTRRfix4K_F8000 0x0000026f +#define MSR_MTRRdefType 0x000002ff + +#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg)) +#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1) + static inline void outl(int addr, int val) { asm volatile ("outl %1, %w0" : : "d" (addr), "a" (val)); @@ -135,6 +152,19 @@ static inline void putc(int c) outb(INFO_PORT, c); } +static uint64_t rdmsr(unsigned index) +{ + unsigned long long ret; + + asm ("rdmsr" : "=A"(ret) : "c"(index)); + return ret; +} + +static void wrmsr(unsigned index, uint64_t val) +{ + asm volatile ("wrmsr" : : "c"(index), "A"(val)); +} + static inline int isdigit(int c) { return c >= '0' && c <= '9'; @@ -469,6 +499,54 @@ static int cmos_readb(int addr) return inb(0x71); } +void setup_mtrr(void) +{ + int i, vcnt, fix, wc; + uint32_t mtrr_cap; + union { + uint8_t valb[8]; + uint64_t val; + } u; + uint64_t vbase, vmask; + + mtrr_cap = rdmsr(MSR_MTRRcap); + vcnt = mtrr_cap & 0xff; + fix = mtrr_cap & 0x100; + wc = mtrr_cap & 0x400; + if (!vcnt || !fix) + return; + u.val = 0; + for (i = 0; i < 8; ++i) + if (ram_size >= 65536 * (i + 1)) + u.valb[i] = 6; + wrmsr(MSR_MTRRfix64K_00000, u.val); + u.val = 0; + for (i = 0; i < 8; ++i) + if (ram_size >= 65536 * 8 + 16384 * (i + 1)) + u.valb[i] = 6; + wrmsr(MSR_MTRRfix16K_80000, u.val); + wrmsr(MSR_MTRRfix16K_A0000, 0); + wrmsr(MSR_MTRRfix4K_C0000, 0); + wrmsr(MSR_MTRRfix4K_C8000, 0); + wrmsr(MSR_MTRRfix4K_D0000, 0); + wrmsr(MSR_MTRRfix4K_D8000, 0); + wrmsr(MSR_MTRRfix4K_E0000, 0); + wrmsr(MSR_MTRRfix4K_E8000, 0); + wrmsr(MSR_MTRRfix4K_F0000, 0); + wrmsr(MSR_MTRRfix4K_F8000, 0); + vbase = 0; + --vcnt; /* leave one mtrr for VRAM */ + for (i = 0; i < vcnt && vbase < ram_size; ++i) { + vmask = (1ull << 40) - 1; + while (vbase + vmask + 1 > ram_size) + vmask >>= 1; + wrmsr(MTRRphysBase_MSR(i), vbase | 6); + wrmsr(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); + vbase += vmask + 1; + } + wrmsr(MSR_MTRRdefType, 0xc00); +} + void ram_probe(void) { if (cmos_readb(0x34) | cmos_readb(0x35)) @@ -482,6 +560,7 @@ void ram_probe(void) ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380; BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr); #endif + setup_mtrr(); } /****************************************************/