smbios support large memory guests
PATCH 1/1 smbios support large memory guests
This reports more than one memory device if the memory for the guest is larger than 16G.
Signed-off-by Bill Rieske <[email protected]>
tools/firmware/hvmloader/smbios.c +32 -19
@@ -56,11 +56,11 @@ static void *static void *smbios_type_16_init (void *start,uint32_t memory_size_mb);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);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);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);static void *smbios_type_32_init (void *start); static void *
@@ -89,9 +89,11 @@ write_smbios_tables(void *start, uint8_t uuid[16], char *xen_version, uint32_t xen_major_version, uint32_t xen_minor_version) { + uint64_t devmemsize;unsigned cpu_num, nr_structs =0 , max_struct_size =0 ;char *p, *q;char cpu_manufacturer[15 ]; +int i;get_cpu_manufacturer (cpu_manufacturer,15 );
@@ -112,9 +114,15 @@ write_smbios_tables(void *start,for ( cpu_num =1 ; cpu_num <= vcpus; cpu_num++ )do_struct (smbios_type_4_init (p, cpu_num, cpu_manufacturer));do_struct (smbios_type_16_init (p, memsize)); -do_struct (smbios_type_17_init (p, memsize)); -do_struct (smbios_type_19_init (p, memsize)); -do_struct (smbios_type_20_init (p, memsize)); +for ( i=0 ; memsize; memsize -= devmemsize ) + { + devmemsize = (memsize <0x4000 ) ? memsize :0x4000 ; +/* more than 1 of each type needed if memsize */ +/* represents greater than 16G */ +do_struct (smbios_type_17_init (p, devmemsize,i)); +do_struct (smbios_type_19_init (p, devmemsize,i)); +do_struct (smbios_type_20_init (p, devmemsize,i++)); + }do_struct (smbios_type_32_init (p));do_struct (smbios_type_127_init (p));
@@ -456,7 +464,8 @@ 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 = ( memsize <=0x4000 )?1 : + ( memsize %0x4000 )? (memsize >>14 )+1 :memsize >>14 ; start +=sizeof (struct smbios_type_16 ); *((uint16_t *)start) =0 ;
@@ -465,15 +474,16 @@ 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) { +char buf[16 ];struct smbios_type_17 *p = (struct smbios_type_17 *)start;memset (p,0 ,sizeof (*p)); 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 ;
@@ -489,8 +499,11 @@ smbios_type_17_init(void *start, uint32_ p->type_detail =0 ; start +=sizeof (struct smbios_type_17 ); -strcpy ((char *)start,"DIMM 1" ); - start +=strlen ("DIMM 1" ) +1 ; +strcpy ((char *)start,"DIMM " ); + start +=strlen ("DIMM " ); +itoa (buf, instance); +strcpy ((char *)start, buf); + start +=strlen (buf) +1 ; *((uint8_t *)start) =0 ;return start+1 ;
@@ -498,7 +511,7 @@ 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;
@@ -506,10 +519,10 @@ smbios_type_19_init(void *start, uint32_ 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-1 ) *1024 ; + p->starting_address = instance*0x4000 ; + p->ending_address = (( memory_size_mb+instance*0x4000 )-1 )*1024 ; p->memory_array_handle =0x1000 ; p->partition_width =1 ;
@@ -528,11 +541,11 @@ smbios_type_20_init(void *start, uint32_ 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-1 )*1024 ; - p->memory_device_handle =0x1100 ; + p->starting_address = instance*0x4000 ; + p->ending_address = (( memory_size_mb+instance*0x4000 ) -1 )*1024 ; + p->memory_device_handle =0x1100 +instance; p->memory_array_mapped_address_handle =0x1300 ; p->partition_row_position =1 ; p->interleave_position =0 ;
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel
Quoted 5 lines · Bill Rieske
This reports more than one memory device if the memory for the guest is larger than 16G.
Signed-off-by Bill Rieske <[email protected]>
It's not a great start that this patch cannot possibly compile.
-- Keir
Quoted 10 lines · Keir Fraser
Quoted 6 lines · Bill Rieske
This reports more than one memory device if the memory for the guest is larger
than 16G.Signed-off-by Bill Rieske <[email protected]>It's not a great start that this patch cannot possibly compile.
Also the starting_address computations are bogus, since the field is in kilobytes not megabytes. I will fix this patch up as necessary and apply it.
-- Keir