Update PC BIOS to latest bits from Bochs

A number of patches were merged since we last pulled.

Thanks to Marcelo Tosatti for rebasing the existing patches and testing.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6589 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
aliguori 2009-02-11 14:55:47 +00:00
parent 2edd089f8a
commit 7217e12403
11 changed files with 33 additions and 436 deletions

View file

@ -6,19 +6,43 @@ Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Index: bochs/bios/rombios32.c
===================================================================
--- bochs.orig/bios/rombios32.c
+++ bochs/bios/rombios32.c
@@ -2081,7 +2081,8 @@ void smbios_init(void)
diff --git a/bios/rombios32.c b/bios/rombios32.c
index 3269be5..9587288 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -429,6 +429,7 @@ uint32_t cpuid_signature;
uint32_t cpuid_features;
uint32_t cpuid_ext_features;
unsigned long ram_size;
+uint64_t ram_end;
uint8_t bios_uuid[16];
#ifdef BX_USE_EBDA_TABLES
unsigned long ebda_cur_addr;
@@ -571,6 +572,13 @@ void ram_probe(void)
ram_size = (cmos_readb(0x30) | (cmos_readb(0x31) << 8)) * 1024 +
1 * 1024 * 1024;
BX_INFO("ram_size=0x%08lx\n", ram_size);
+ if (cmos_readb(0x5b) | cmos_readb(0x5c) | cmos_readb(0x5d))
+ 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;
+ BX_INFO("end of ram=%ldMB\n", ram_end >> 20);
#ifdef BX_USE_EBDA_TABLES
ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380;
BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
@@ -2174,7 +2182,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)
@@ -2201,8 +2210,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));
@ -28,6 +52,4 @@ Index: bochs/bios/rombios32.c
+ 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));

View file

@ -1,120 +0,0 @@
add mtrr support (Avi Kivity)
program mtrrs for cpu 0. Doesn't support >=4G at the moment.
Signed-off-by: Avi Kivity <avi@qumranet.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
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();
}
/****************************************************/

View file

@ -1,126 +0,0 @@
smp mtrr support (Avi Kivity)
Signed-off-by: Avi Kivity <avi@qumranet.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
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

View file

@ -1,62 +0,0 @@
extend MTRRs to above 4G (Alex Williamson)
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 <alex.williamson@hp.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
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();
}

View file

@ -1,58 +0,0 @@
cleanup/consolidate above 4G memory parsing (Alex Williamson)
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
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();
}

View file

@ -1,54 +0,0 @@
switch MTRRs to cover only the PCI range and default to WB (Alex Williamson)
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 <alex.williamson@hp.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
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)

View file

@ -1 +1 @@
36989b0d2e785ac9e5d6e8a226dbdeb82e876bfd
04387139e3b5ac97b5633cd40b3d87cdf45efd6c

View file

@ -1,10 +1,5 @@
0001_bx-qemu.patch
0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch
0003_kvm-bios-generate-mptable-unconditionally.patch
0004_kvm-bios-add-mtrr-support.patch
0005_kvm-bios-smp-mtrr-support.patch
0006_kvm-bios-extend-mtrrs-to-above-4g.patch
0007_kvm-bios-cleanup-consolidate-above-4g-memory-parsing.patch
0008_kvm-bios-switch-mtrrs-to-cover-only-the-pci-range-and--default-to-wb.patch
0009_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch
0010_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch
0004_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch
0005_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch

Binary file not shown.