- unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
- char *start, *p, *q;
-
- bios_table_cur_addr = ALIGN(bios_table_cur_addr, 16);
- start = (void *)(bios_table_cur_addr);
-
- p = (char *)start + sizeof(struct smbios_entry_point);
-
-#define add_struct(fn) { \
- q = (fn); \
- nr_structs++; \
- if ((q - p) > max_struct_size) \
- max_struct_size = q - p; \
- p = q; \
-}
-
- add_struct(smbios_type_0_init(p));
- add_struct(smbios_type_1_init(p));
- add_struct(smbios_type_3_init(p));
- int smp_cpus = smp_probe();
- 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));
- add_struct(smbios_type_17_init(p));
- add_struct(smbios_type_19_init(p));
- add_struct(smbios_type_20_init(p));
- add_struct(smbios_type_32_init(p));
- add_struct(smbios_type_127_init(p));
+ char *start = malloc_high(2048); // XXX - determine real size
+ if (! start) {
+ dprintf(1, "No memory for smbios tables\n");
+ return;
+ }
+
+ u32 nr_structs = 0, max_struct_size = 0;
+ char *q, *p = start, *end = start + 2048 - sizeof(struct smbios_type_127);
+
+#define add_struct(type, args...) \
+ do { \
+ if (!qemu_cfg_smbios_load_external(type, &p, &nr_structs, \
+ &max_struct_size, end)) { \
+ q = smbios_init_type_##type(args); \
+ nr_structs++; \
+ if ((q - p) > max_struct_size) \
+ max_struct_size = q - p; \
+ p = q; \
+ } \
+ } while (0)
+
+ add_struct(0, p);
+ add_struct(1, p);
+ add_struct(3, p);
+
+ int cpu_num;
+ for (cpu_num = 1; cpu_num <= MaxCountCPUs; cpu_num++)
+ add_struct(4, p, cpu_num);
+ u64 memsize = RamSizeOver4G;
+ if (memsize)
+ memsize += 0x100000000ull;
+ else
+ memsize = RamSize;
+ memsize = memsize / (1024 * 1024);
+ int nr_mem_devs = (memsize + 0x3fff) >> 14;
+ add_struct(16, p, memsize, nr_mem_devs);
+ int i;
+ for (i = 0; i < nr_mem_devs; i++) {
+ u32 dev_memsize = ((i == (nr_mem_devs - 1))
+ ? (((memsize-1) & 0x3fff)+1) : 0x4000);
+ add_struct(17, p, dev_memsize, i);
+ add_struct(19, p, dev_memsize, i);
+ add_struct(20, p, dev_memsize, i);
+ }
+
+ add_struct(32, p);
+ /* Add any remaining provided entries before the end marker */
+ for (i = 0; i < 256; i++)
+ qemu_cfg_smbios_load_external(i, &p, &nr_structs, &max_struct_size,
+ end);
+ add_struct(127, p);