diff -Nur pc-bios.orig/bios-pq/0002_smbios_report_4g.patch pc-bios/bios-pq/0002_smbios_report_4g.patch --- pc-bios.orig/bios-pq/0002_smbios_report_4g.patch 1969-12-31 21:00:00.000000000 -0300 +++ pc-bios/bios-pq/0002_smbios_report_4g.patch 2009-01-19 23:18:46.000000000 -0200 @@ -0,0 +1,32 @@ +kvm: bios: update SMBIOS table to report memory above 4G + +Signed-off-by: Alex Williamson
+Signed-off-by: Avi Kivity + +From: Alex Williamson + +Index: bochs/bios/rombios32.c +=================================================================== +--- bochs.orig/bios/rombios32.c ++++ bochs/bios/rombios32.c +@@ -2081,7 +2081,8 @@ void smbios_init(void) + { + unsigned cpu_num, nr_structs = 0, max_struct_size = 0; + char *start, *p, *q; +- int memsize = ram_size / (1024 * 1024); ++ int memsize = (ram_end == ram_size) ? ram_size / (1024 * 1024) : ++ (ram_end - (1ull << 32) + ram_size) / (1024 * 1024); + + #ifdef BX_USE_EBDA_TABLES + ebda_cur_addr = align(ebda_cur_addr, 16); +@@ -2108,8 +2109,8 @@ void smbios_init(void) + add_struct(smbios_type_4_init(p, cpu_num)); + add_struct(smbios_type_16_init(p, memsize)); + add_struct(smbios_type_17_init(p, memsize)); +- add_struct(smbios_type_19_init(p, memsize)); +- add_struct(smbios_type_20_init(p, memsize)); ++ add_struct(smbios_type_19_init(p, ram_end / (1024 * 1024))); ++ add_struct(smbios_type_20_init(p, ram_end / (1024 * 1024))); + add_struct(smbios_type_32_init(p)); + add_struct(smbios_type_127_init(p)); + diff -Nur pc-bios.orig/bios-pq/0003_mptable_unconditional.patch pc-bios/bios-pq/0003_mptable_unconditional.patch --- pc-bios.orig/bios-pq/0003_mptable_unconditional.patch 1969-12-31 21:00:00.000000000 -0300 +++ pc-bios/bios-pq/0003_mptable_unconditional.patch 2009-01-19 23:18:46.000000000 -0200 @@ -0,0 +1,23 @@ +kvm: bios: generate mptable unconditionally + +VMware ESX requires an mptable even for uniprocessor guests. + +Signed-off-by: Avi Kivity +From: Avi Kivity + +Index: bochs/bios/rombios32.c +=================================================================== +--- bochs.orig/bios/rombios32.c ++++ bochs/bios/rombios32.c +@@ -970,11 +970,6 @@ static void mptable_init(void) + int ioapic_id, i, len; + int mp_config_table_size; + +-#ifdef BX_QEMU +- if (smp_cpus <= 1) +- return; +-#endif +- + #ifdef BX_USE_EBDA_TABLES + mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE); + #else diff -Nur pc-bios.orig/bios-pq/0004_mtrr_up.patch pc-bios/bios-pq/0004_mtrr_up.patch --- pc-bios.orig/bios-pq/0004_mtrr_up.patch 1969-12-31 21:00:00.000000000 -0300 +++ pc-bios/bios-pq/0004_mtrr_up.patch 2009-01-19 23:18:46.000000000 -0200 @@ -0,0 +1,119 @@ +kvm: bios: add mtrr support + +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(); + } + + /****************************************************/ diff -Nur pc-bios.orig/bios-pq/0005_mtrr_smp.patch pc-bios/bios-pq/0005_mtrr_smp.patch --- pc-bios.orig/bios-pq/0005_mtrr_smp.patch 1969-12-31 21:00:00.000000000 -0300 +++ pc-bios/bios-pq/0005_mtrr_smp.patch 2009-01-19 23:18:46.000000000 -0200 @@ -0,0 +1,125 @@ +kvm: bios: smp mtrr support + +Signed-off-by: Avi Kivity + +From: Avi Kivity + +Index: bochs/bios/rombios.h +=================================================================== +--- bochs.orig/bios/rombios.h ++++ bochs/bios/rombios.h +@@ -56,6 +56,7 @@ + #define ACPI_DATA_SIZE 0x00010000L + #define PM_IO_BASE 0xb000 + #define SMB_IO_BASE 0xb100 ++#define SMP_MSR_ADDR 0xf010 + + // Define the application NAME + #if defined(BX_QEMU) +Index: bochs/bios/rombios32.c +=================================================================== +--- bochs.orig/bios/rombios32.c ++++ bochs/bios/rombios32.c +@@ -472,6 +472,23 @@ void qemu_cfg_read(uint8_t *buf, int len + } + #endif + ++void init_smp_msrs(void) ++{ ++ *(uint32_t *)SMP_MSR_ADDR = 0; ++} ++ ++void wrmsr_smp(uint32_t index, uint64_t val) ++{ ++ static struct { uint32_t ecx, eax, edx; } *p = (void *)SMP_MSR_ADDR; ++ ++ wrmsr(index, val); ++ p->ecx = index; ++ p->eax = val; ++ p->edx = val >> 32; ++ ++p; ++ p->ecx = 0; ++} ++ + void uuid_probe(void) + { + #ifdef BX_QEMU +@@ -519,32 +536,32 @@ void setup_mtrr(void) + for (i = 0; i < 8; ++i) + if (ram_size >= 65536 * (i + 1)) + u.valb[i] = 6; +- wrmsr(MSR_MTRRfix64K_00000, u.val); ++ wrmsr_smp(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); ++ wrmsr_smp(MSR_MTRRfix16K_80000, u.val); ++ wrmsr_smp(MSR_MTRRfix16K_A0000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_C0000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_C8000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_D0000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_D8000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_E0000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_E8000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_F0000, 0); ++ wrmsr_smp(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); ++ wrmsr_smp(MTRRphysBase_MSR(i), vbase | 6); ++ wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); + vbase += vmask + 1; + } +- wrmsr(MSR_MTRRdefType, 0xc00); ++ wrmsr_smp(MSR_MTRRdefType, 0xc00); + } + + void ram_probe(void) +@@ -2263,6 +2280,8 @@ void rombios32_init(uint32_t *s3_resume_ + qemu_cfg_port = qemu_cfg_port_probe(); + #endif + ++ init_smp_msrs(); ++ + ram_probe(); + + cpu_probe(); +Index: bochs/bios/rombios32start.S +=================================================================== +--- bochs.orig/bios/rombios32start.S ++++ bochs/bios/rombios32start.S +@@ -49,6 +49,18 @@ _start: + smp_ap_boot_code_start: + xor %ax, %ax + mov %ax, %ds ++ ++ mov $SMP_MSR_ADDR, %ebx ++11: ++ mov 0(%ebx), %ecx ++ test %ecx, %ecx ++ jz 12f ++ mov 4(%ebx), %eax ++ mov 8(%ebx), %edx ++ wrmsr ++ add $12, %ebx ++ jmp 11b ++12: + lock incw smp_cpus + 1: + hlt diff -Nur pc-bios.orig/bios-pq/0006_mtrr_above_4g.patch pc-bios/bios-pq/0006_mtrr_above_4g.patch --- pc-bios.orig/bios-pq/0006_mtrr_above_4g.patch 1969-12-31 21:00:00.000000000 -0300 +++ pc-bios/bios-pq/0006_mtrr_above_4g.patch 2009-01-19 23:18:46.000000000 -0200 @@ -0,0 +1,61 @@ +kvm: bios: extend MTRRs to above 4G + +When I try to boot guests using a recent Linux kernel (2.6.26+), memory +above 3.5G gets thrown away with an error like this: + +WARNING: BIOS bug: CPU MTRRs don't cover all of memory, losing 4608MB of RAM + +This extends MTRRs to cover all of memory. + +Signed-off-by: Alex Williamson +Signed-off-by: Avi Kivity + +From: Alex Williamson + +Index: bochs/bios/rombios32.c +=================================================================== +--- bochs.orig/bios/rombios32.c ++++ bochs/bios/rombios32.c +@@ -427,6 +427,7 @@ uint32_t cpuid_signature; + uint32_t cpuid_features; + uint32_t cpuid_ext_features; + unsigned long ram_size; ++uint64_t above4g_ram_size; + uint8_t bios_uuid[16]; + #ifdef BX_USE_EBDA_TABLES + unsigned long ebda_cur_addr; +@@ -561,6 +562,14 @@ void setup_mtrr(void) + wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); + vbase += vmask + 1; + } ++ for (vbase = 1ull << 32; i < vcnt && vbase < above4g_ram_size; ++i) { ++ vmask = (1ull << 40) - 1; ++ while (vbase + vmask + 1 > above4g_ram_size) ++ vmask >>= 1; ++ wrmsr_smp(MTRRphysBase_MSR(i), vbase | 6); ++ wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); ++ vbase += vmask + 1; ++ } + wrmsr_smp(MSR_MTRRdefType, 0xc00); + } + +@@ -572,11 +581,19 @@ void ram_probe(void) + else + ram_size = (cmos_readb(0x30) | (cmos_readb(0x31) << 8)) * 1024 + + 1 * 1024 * 1024; ++ if (cmos_readb(0x5b) | cmos_readb(0x5c) | cmos_readb(0x5d)) ++ above4g_ram_size = ((uint64_t)cmos_readb(0x5b) << 16) | ++ ((uint64_t)cmos_readb(0x5c) << 24) | ((uint64_t)cmos_readb(0x5d) << 32); ++ ++ if (above4g_ram_size) ++ above4g_ram_size += 1ull << 32; ++ + BX_INFO("ram_size=0x%08lx\n", ram_size); + #ifdef BX_USE_EBDA_TABLES + ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380; + BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr); + #endif ++ BX_INFO("top of ram %ldMB\n", above4g_ram_size >> 20); + setup_mtrr(); + } + diff -Nur pc-bios.orig/bios-pq/0007_mtrr_above_4g_clean.patch pc-bios/bios-pq/0007_mtrr_above_4g_clean.patch --- pc-bios.orig/bios-pq/0007_mtrr_above_4g_clean.patch 1969-12-31 21:00:00.000000000 -0300 +++ pc-bios/bios-pq/0007_mtrr_above_4g_clean.patch 2009-01-19 23:18:46.000000000 -0200 @@ -0,0 +1,57 @@ +kvm: bios: cleanup/consolidate above 4G memory parsing + +Signed-off-by: Alex Williamson +Signed-off-by: Avi Kivity + +From: Alex Williamson + +Index: bochs/bios/rombios32.c +=================================================================== +--- bochs.orig/bios/rombios32.c ++++ bochs/bios/rombios32.c +@@ -427,7 +427,7 @@ uint32_t cpuid_signature; + uint32_t cpuid_features; + uint32_t cpuid_ext_features; + unsigned long ram_size; +-uint64_t above4g_ram_size; ++uint64_t ram_end; + uint8_t bios_uuid[16]; + #ifdef BX_USE_EBDA_TABLES + unsigned long ebda_cur_addr; +@@ -562,9 +562,9 @@ void setup_mtrr(void) + wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); + vbase += vmask + 1; + } +- for (vbase = 1ull << 32; i < vcnt && vbase < above4g_ram_size; ++i) { ++ for (vbase = 1ull << 32; i < vcnt && vbase < ram_end; ++i) { + vmask = (1ull << 40) - 1; +- while (vbase + vmask + 1 > above4g_ram_size) ++ while (vbase + vmask + 1 > ram_end) + vmask >>= 1; + wrmsr_smp(MTRRphysBase_MSR(i), vbase | 6); + wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); +@@ -582,18 +582,19 @@ void ram_probe(void) + ram_size = (cmos_readb(0x30) | (cmos_readb(0x31) << 8)) * 1024 + + 1 * 1024 * 1024; + if (cmos_readb(0x5b) | cmos_readb(0x5c) | cmos_readb(0x5d)) +- above4g_ram_size = ((uint64_t)cmos_readb(0x5b) << 16) | +- ((uint64_t)cmos_readb(0x5c) << 24) | ((uint64_t)cmos_readb(0x5d) << 32); ++ ram_end = (((uint64_t)cmos_readb(0x5b) << 16) | ++ ((uint64_t)cmos_readb(0x5c) << 24) | ++ ((uint64_t)cmos_readb(0x5d) << 32)) + (1ull << 32); ++ else ++ ram_end = ram_size; + +- if (above4g_ram_size) +- above4g_ram_size += 1ull << 32; ++ BX_INFO("end of ram=%ldMB\n", ram_end >> 20); + + BX_INFO("ram_size=0x%08lx\n", ram_size); + #ifdef BX_USE_EBDA_TABLES + ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380; + BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr); + #endif +- BX_INFO("top of ram %ldMB\n", above4g_ram_size >> 20); + setup_mtrr(); + } + diff -Nur pc-bios.orig/bios-pq/0008_mtrr_default.patch pc-bios/bios-pq/0008_mtrr_default.patch --- pc-bios.orig/bios-pq/0008_mtrr_default.patch 1969-12-31 21:00:00.000000000 -0300 +++ pc-bios/bios-pq/0008_mtrr_default.patch 2009-01-19 23:18:46.000000000 -0200 @@ -0,0 +1,52 @@ +kvm: bios: switch MTRRs to cover only the PCI range and default to WB + +This matches how some bare metal machines report MTRRs and avoids +the problem of running out of MTRRs to cover all of RAM. + +Signed-off-by: Alex Williamson +Signed-off-by: Avi Kivity + +From: Alex Williamson + +Index: bochs/bios/rombios32.c +=================================================================== +--- bochs.orig/bios/rombios32.c ++++ bochs/bios/rombios32.c +@@ -525,7 +525,6 @@ void setup_mtrr(void) + uint8_t valb[8]; + uint64_t val; + } u; +- uint64_t vbase, vmask; + + mtrr_cap = rdmsr(MSR_MTRRcap); + vcnt = mtrr_cap & 0xff; +@@ -552,25 +551,10 @@ void setup_mtrr(void) + wrmsr_smp(MSR_MTRRfix4K_E8000, 0); + wrmsr_smp(MSR_MTRRfix4K_F0000, 0); + wrmsr_smp(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_smp(MTRRphysBase_MSR(i), vbase | 6); +- wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); +- vbase += vmask + 1; +- } +- for (vbase = 1ull << 32; i < vcnt && vbase < ram_end; ++i) { +- vmask = (1ull << 40) - 1; +- while (vbase + vmask + 1 > ram_end) +- vmask >>= 1; +- wrmsr_smp(MTRRphysBase_MSR(i), vbase | 6); +- wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); +- vbase += vmask + 1; +- } +- wrmsr_smp(MSR_MTRRdefType, 0xc00); ++ /* Mark 3.5-4GB as UC, anything not specified defaults to WB */ ++ wrmsr_smp(MTRRphysBase_MSR(0), 0xe0000000ull | 0); ++ wrmsr_smp(MTRRphysMask_MSR(0), ~(0x20000000ull - 1) | 0x800); ++ wrmsr_smp(MSR_MTRRdefType, 0xc06); + } + + void ram_probe(void) diff -Nur pc-bios.orig/bios-pq/0009_smbios_16gb.patch pc-bios/bios-pq/0009_smbios_16gb.patch --- pc-bios.orig/bios-pq/0009_smbios_16gb.patch 1969-12-31 21:00:00.000000000 -0300 +++ pc-bios/bios-pq/0009_smbios_16gb.patch 2009-01-19 23:18:46.000000000 -0200 @@ -0,0 +1,183 @@ +kvm: bios: resolve memory device roll over reporting issues with >32G guests + +The field within the Memory Device type 17 is only a word with the MSB being +used to report MB/KB. Thereby, a guest with 32G and greater would report +incorrect memory device information rolling over to 0. + +This presents more than one memory device and associated memory structures +if the memory is larger than 16G + +Signed-off-by: Bill Rieske