From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LWzEJ-0002xh-Dn for qemu-devel@nongnu.org; Tue, 10 Feb 2009 15:29:15 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LWzEG-0002vs-St for qemu-devel@nongnu.org; Tue, 10 Feb 2009 15:29:15 -0500 Received: from [199.232.76.173] (port=41689 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LWzEG-0002vd-L1 for qemu-devel@nongnu.org; Tue, 10 Feb 2009 15:29:12 -0500 Received: from mx2.redhat.com ([66.187.237.31]:39844) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LWzEG-0005Vc-0R for qemu-devel@nongnu.org; Tue, 10 Feb 2009 15:29:12 -0500 Date: Tue, 10 Feb 2009 18:28:11 -0200 From: Marcelo Tosatti Subject: Re: [Qemu-devel] Re: [Bochs-developers] [PATCH] Read additional ACPI tables from a VM Message-ID: <20090210202811.GA32355@amt.cnet> References: <20090209143017.GG28969@redhat.com> <336692845B5F4E10A22861C218D4EEBF@FSCPC> <20090209210027.GA13234@redhat.com> <4990A014.1040202@codemonkey.ws> <20090210072006.GB13234@redhat.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="SUOF0GtieIMvvwua" Content-Disposition: inline In-Reply-To: <20090210072006.GB13234@redhat.com> 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, Anthony Liguori Cc: bochs-developers@lists.sourceforge.net, Sebastian Herbszt --SUOF0GtieIMvvwua Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Tue, Feb 10, 2009 at 09:20:06AM +0200, Gleb Natapov wrote: > On Mon, Feb 09, 2009 at 03:28:52PM -0600, Anthony Liguori wrote: > > Gleb Natapov wrote: > >>>> + > >>>> +static int acpi_load_table(int i, uint32_t addr, uint16_t *len) > >>>> +{ > >>>> + qemu_cfg_read((uint8_t*)len, sizeof(*len)); > >>>> + > >>>> + if (!*len) > >>>> + return -1; > >>>> + > >>>> + qemu_cfg_read((uint8_t*)addr, *len); > >>>> + return 0; > >>>> +} > >>>> #endif > >>>> > >>>> void init_smp_msrs(void) > >>>> > >>> Can you please diff against bochs cvs? > >>> > >>> > >> Will do. This patch was initially intended to go to qemu patch series so I > >> did it against patched bios source. > > > > I'm happy to update to a more recent BIOS snapshot... > > > >> And unpatched bochs bios does not > >> boot linux with qemu. IRQ routing problem or something. > >> > > > > Unless upstream Bochs has regressed. Did you apply the other patches in > > the QEMU series? Some are no longer needed I think. > > > With all qemu patches IRQ problem goes away. (One qemu patch conflicts with > the last bochs commit so I reverted it before applying qemu series). Ugh, I was getting "GRUB Error 16: Inconsistent filesystem structure" which appeared to be caused by 864034d9a3190e0c2c10382ae015b5b5fd16718a. But now its magically working again. Or not? Anthony, attached are updated patches + series to sync with Bochs. Please give it a try. --SUOF0GtieIMvvwua Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="0001_bx-qemu.patch" --- bochs-2.3.7.orig/bios/rombios.h +++ bochs-2.3.7/bios/rombios.h @@ -19,7 +19,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /* define it to include QEMU specific code */ -//#define BX_QEMU +#define BX_QEMU #ifndef LEGACY # define BX_ROMBIOS32 1 --SUOF0GtieIMvvwua Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch" update SMBIOS table to report memory above 4G (Alex Williamson) Signed-off-by: Alex Williamson Signed-off-by: Avi Kivity Signed-off-by: Anthony Liguori Index: bochs/bios/rombios32.c =================================================================== --- bochs.orig/bios/rombios32.c +++ bochs/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; @@ -570,6 +571,14 @@ 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)) + 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); + BX_INFO("ram_size=0x%08lx\n", ram_size); #ifdef BX_USE_EBDA_TABLES ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380; @@ -2174,7 +2183,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); @@ -2201,8 +2211,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)); --SUOF0GtieIMvvwua Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="0003_kvm-bios-generate-mptable-unconditionally.patch" generate mptable unconditionally (Avi Kivity) VMware ESX requires an mptable even for uniprocessor guests. Signed-off-by: Avi Kivity Signed-off-by: Anthony Liguori 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 --SUOF0GtieIMvvwua Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="0004_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch" resolve memory device roll over reporting issues with >32G guests (Bill Rieske) 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 Signed-off-by: Avi Kivity Signed-off-by: Anthony Liguori Index: bochs/bios/rombios32.c =================================================================== --- bochs.orig/bios/rombios32.c +++ bochs/bios/rombios32.c @@ -381,6 +381,17 @@ int vsnprintf(char *buf, int buflen, con return buf - buf0; } +int snprintf(char * buf, size_t size, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i=vsnprintf(buf,size,fmt,args); + va_end(args); + return i; +} + void bios_printf(int flags, const char *fmt, ...) { va_list ap; @@ -2039,7 +2050,7 @@ smbios_type_4_init(void *start, unsigned /* Type 16 -- Physical Memory Array */ static void * -smbios_type_16_init(void *start, uint32_t memsize) +smbios_type_16_init(void *start, uint32_t memsize, int nr_mem_devs) { struct smbios_type_16 *p = (struct smbios_type_16*)start; @@ -2052,7 +2063,7 @@ smbios_type_16_init(void *start, uint32_ p->error_correction = 0x01; /* other */ p->maximum_capacity = memsize * 1024; p->memory_error_information_handle = 0xfffe; /* none provided */ - p->number_of_memory_devices = 1; + p->number_of_memory_devices = nr_mem_devs; start += sizeof(struct smbios_type_16); *((uint16_t *)start) = 0; @@ -2062,20 +2073,19 @@ smbios_type_16_init(void *start, uint32_ /* Type 17 -- Memory Device */ static void * -smbios_type_17_init(void *start, uint32_t memory_size_mb) +smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance) { struct smbios_type_17 *p = (struct smbios_type_17 *)start; p->header.type = 17; p->header.length = sizeof(struct smbios_type_17); - p->header.handle = 0x1100; + p->header.handle = 0x1100 + instance; p->physical_memory_array_handle = 0x1000; p->total_width = 64; p->data_width = 64; - /* truncate memory_size_mb to 16 bits and clear most significant - bit [indicates size in MB] */ - p->size = (uint16_t) memory_size_mb & 0x7fff; +/* TODO: should assert in case something is wrong ASSERT((memory_size_mb & ~0x7fff) == 0); */ + p->size = memory_size_mb; p->form_factor = 0x09; /* DIMM */ p->device_set = 0; p->device_locator_str = 1; @@ -2084,8 +2094,8 @@ smbios_type_17_init(void *start, uint32_ p->type_detail = 0; start += sizeof(struct smbios_type_17); - memcpy((char *)start, "DIMM 1", 7); - start += 7; + snprintf(start, 8, "DIMM %d", instance); + start += strlen(start) + 1; *((uint8_t *)start) = 0; return start+1; @@ -2093,16 +2103,16 @@ smbios_type_17_init(void *start, uint32_ /* Type 19 -- Memory Array Mapped Address */ static void * -smbios_type_19_init(void *start, uint32_t memory_size_mb) +smbios_type_19_init(void *start, uint32_t memory_size_mb, int instance) { struct smbios_type_19 *p = (struct smbios_type_19 *)start; p->header.type = 19; p->header.length = sizeof(struct smbios_type_19); - p->header.handle = 0x1300; + p->header.handle = 0x1300 + instance; - p->starting_address = 0; - p->ending_address = (memory_size_mb * 1024) - 1; + p->starting_address = instance << 24; + p->ending_address = p->starting_address + (memory_size_mb << 10) - 1; p->memory_array_handle = 0x1000; p->partition_width = 1; @@ -2114,18 +2124,18 @@ smbios_type_19_init(void *start, uint32_ /* Type 20 -- Memory Device Mapped Address */ static void * -smbios_type_20_init(void *start, uint32_t memory_size_mb) +smbios_type_20_init(void *start, uint32_t memory_size_mb, int instance) { struct smbios_type_20 *p = (struct smbios_type_20 *)start; p->header.type = 20; p->header.length = sizeof(struct smbios_type_20); - p->header.handle = 0x1400; + p->header.handle = 0x1400 + instance; - p->starting_address = 0; - p->ending_address = (memory_size_mb * 1024) - 1; - p->memory_device_handle = 0x1100; - p->memory_array_mapped_address_handle = 0x1300; + p->starting_address = instance << 24; + p->ending_address = p->starting_address + (memory_size_mb << 10) - 1; + p->memory_device_handle = 0x1100 + instance; + p->memory_array_mapped_address_handle = 0x1300 + instance; p->partition_row_position = 1; p->interleave_position = 0; p->interleaved_data_depth = 0; @@ -2176,6 +2186,7 @@ void smbios_init(void) char *start, *p, *q; int memsize = (ram_end == ram_size) ? ram_size / (1024 * 1024) : (ram_end - (1ull << 32) + ram_size) / (1024 * 1024); + int i, nr_mem_devs; #ifdef BX_USE_EBDA_TABLES ebda_cur_addr = align(ebda_cur_addr, 16); @@ -2187,23 +2198,32 @@ void smbios_init(void) p = (char *)start + sizeof(struct smbios_entry_point); -#define add_struct(fn) { \ +#define add_struct(fn) do{ \ q = (fn); \ nr_structs++; \ if ((q - p) > max_struct_size) \ max_struct_size = q - p; \ p = q; \ -} +}while (0) add_struct(smbios_type_0_init(p)); add_struct(smbios_type_1_init(p)); add_struct(smbios_type_3_init(p)); for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++) 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, ram_end / (1024 * 1024))); - add_struct(smbios_type_20_init(p, ram_end / (1024 * 1024))); + + /* Each 'memory device' covers up to 16GB of address space. */ + nr_mem_devs = (memsize + 0x3fff) >> 14; + add_struct(smbios_type_16_init(p, memsize, nr_mem_devs)); + for ( i = 0; i < nr_mem_devs; i++ ) + { + uint32_t dev_memsize = ((i == (nr_mem_devs - 1)) + ? (memsize & 0x3fff) : 0x4000); + add_struct(smbios_type_17_init(p, dev_memsize, i)); + add_struct(smbios_type_19_init(p, dev_memsize, i)); + add_struct(smbios_type_20_init(p, dev_memsize, i)); + } + add_struct(smbios_type_32_init(p)); add_struct(smbios_type_127_init(p)); --SUOF0GtieIMvvwua Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="0005_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch" fix smbios memory device length boundary condition (Bill Rieske) dev_memsize ends up 0 when it shouldn't be on 16G boundary conditions. Signed-off-by: Bill Rieske Signed-off-by: Avi Kivity Signed-off-by: Anthony Liguori Index: bochs/bios/rombios32.c =================================================================== --- bochs.orig/bios/rombios32.c +++ bochs/bios/rombios32.c @@ -2218,7 +2218,7 @@ void smbios_init(void) for ( i = 0; i < nr_mem_devs; i++ ) { uint32_t dev_memsize = ((i == (nr_mem_devs - 1)) - ? (memsize & 0x3fff) : 0x4000); + ? (((memsize-1) & 0x3fff)+1) : 0x4000); add_struct(smbios_type_17_init(p, dev_memsize, i)); add_struct(smbios_type_19_init(p, dev_memsize, i)); add_struct(smbios_type_20_init(p, dev_memsize, i)); --SUOF0GtieIMvvwua Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=series 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-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch 0005_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch --SUOF0GtieIMvvwua--