10517cc98SCorey Minyard /* 20517cc98SCorey Minyard * SMBIOS Support 30517cc98SCorey Minyard * 40517cc98SCorey Minyard * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. 50517cc98SCorey Minyard * Copyright (C) 2013 Red Hat, Inc. 6*5aca89d1SPhilippe Mathieu-Daudé * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC 70517cc98SCorey Minyard * 80517cc98SCorey Minyard * Authors: 90517cc98SCorey Minyard * Alex Williamson <alex.williamson@hp.com> 100517cc98SCorey Minyard * Markus Armbruster <armbru@redhat.com> 110517cc98SCorey Minyard * 120517cc98SCorey Minyard * This work is licensed under the terms of the GNU GPL, version 2. See 130517cc98SCorey Minyard * the COPYING file in the top-level directory. 140517cc98SCorey Minyard * 150517cc98SCorey Minyard * Contributions after 2012-01-13 are licensed under the terms of the 160517cc98SCorey Minyard * GNU GPL, version 2 or (at your option) any later version. 170517cc98SCorey Minyard */ 180517cc98SCorey Minyard 190517cc98SCorey Minyard #ifndef QEMU_SMBIOS_BUILD_H 200517cc98SCorey Minyard #define QEMU_SMBIOS_BUILD_H 210517cc98SCorey Minyard 220517cc98SCorey Minyard bool smbios_skip_table(uint8_t type, bool required_table); 230517cc98SCorey Minyard 240517cc98SCorey Minyard extern uint8_t *smbios_tables; 250517cc98SCorey Minyard extern size_t smbios_tables_len; 260517cc98SCorey Minyard extern unsigned smbios_table_max; 270517cc98SCorey Minyard extern unsigned smbios_table_cnt; 280517cc98SCorey Minyard 290517cc98SCorey Minyard #define SMBIOS_BUILD_TABLE_PRE(tbl_type, tbl_handle, tbl_required) \ 300517cc98SCorey Minyard struct smbios_type_##tbl_type *t; \ 310517cc98SCorey Minyard size_t t_off; /* table offset into smbios_tables */ \ 320517cc98SCorey Minyard int str_index = 0; \ 330517cc98SCorey Minyard do { \ 340517cc98SCorey Minyard /* should we skip building this table ? */ \ 350517cc98SCorey Minyard if (smbios_skip_table(tbl_type, tbl_required)) { \ 360517cc98SCorey Minyard return; \ 370517cc98SCorey Minyard } \ 380517cc98SCorey Minyard \ 390517cc98SCorey Minyard /* use offset of table t within smbios_tables */ \ 400517cc98SCorey Minyard /* (pointer must be updated after each realloc) */ \ 410517cc98SCorey Minyard t_off = smbios_tables_len; \ 420517cc98SCorey Minyard smbios_tables_len += sizeof(*t); \ 430517cc98SCorey Minyard smbios_tables = g_realloc(smbios_tables, smbios_tables_len); \ 440517cc98SCorey Minyard t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \ 450517cc98SCorey Minyard \ 460517cc98SCorey Minyard t->header.type = tbl_type; \ 470517cc98SCorey Minyard t->header.length = sizeof(*t); \ 480517cc98SCorey Minyard t->header.handle = cpu_to_le16(tbl_handle); \ 490517cc98SCorey Minyard } while (0) 500517cc98SCorey Minyard 510517cc98SCorey Minyard #define SMBIOS_TABLE_SET_STR(tbl_type, field, value) \ 520517cc98SCorey Minyard do { \ 530517cc98SCorey Minyard int len = (value != NULL) ? strlen(value) + 1 : 0; \ 540517cc98SCorey Minyard if (len > 1) { \ 550517cc98SCorey Minyard smbios_tables = g_realloc(smbios_tables, \ 560517cc98SCorey Minyard smbios_tables_len + len); \ 570517cc98SCorey Minyard memcpy(smbios_tables + smbios_tables_len, value, len); \ 580517cc98SCorey Minyard smbios_tables_len += len; \ 590517cc98SCorey Minyard /* update pointer post-realloc */ \ 600517cc98SCorey Minyard t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \ 610517cc98SCorey Minyard t->field = ++str_index; \ 620517cc98SCorey Minyard } else { \ 630517cc98SCorey Minyard t->field = 0; \ 640517cc98SCorey Minyard } \ 650517cc98SCorey Minyard } while (0) 660517cc98SCorey Minyard 672d6dcbf9SDaniel P. Berrange #define SMBIOS_TABLE_SET_STR_LIST(tbl_type, value) \ 682d6dcbf9SDaniel P. Berrange do { \ 692d6dcbf9SDaniel P. Berrange int len = (value != NULL) ? strlen(value) + 1 : 0; \ 702d6dcbf9SDaniel P. Berrange if (len > 1) { \ 712d6dcbf9SDaniel P. Berrange smbios_tables = g_realloc(smbios_tables, \ 722d6dcbf9SDaniel P. Berrange smbios_tables_len + len); \ 732d6dcbf9SDaniel P. Berrange memcpy(smbios_tables + smbios_tables_len, value, len); \ 742d6dcbf9SDaniel P. Berrange smbios_tables_len += len; \ 752d6dcbf9SDaniel P. Berrange ++str_index; \ 762d6dcbf9SDaniel P. Berrange } \ 772d6dcbf9SDaniel P. Berrange } while (0) 782d6dcbf9SDaniel P. Berrange 790517cc98SCorey Minyard #define SMBIOS_BUILD_TABLE_POST \ 800517cc98SCorey Minyard do { \ 810517cc98SCorey Minyard size_t term_cnt, t_size; \ 820517cc98SCorey Minyard \ 830517cc98SCorey Minyard /* add '\0' terminator (add two if no strings defined) */ \ 840517cc98SCorey Minyard term_cnt = (str_index == 0) ? 2 : 1; \ 850517cc98SCorey Minyard smbios_tables = g_realloc(smbios_tables, \ 860517cc98SCorey Minyard smbios_tables_len + term_cnt); \ 870517cc98SCorey Minyard memset(smbios_tables + smbios_tables_len, 0, term_cnt); \ 880517cc98SCorey Minyard smbios_tables_len += term_cnt; \ 890517cc98SCorey Minyard \ 900517cc98SCorey Minyard /* update smbios max. element size */ \ 910517cc98SCorey Minyard t_size = smbios_tables_len - t_off; \ 920517cc98SCorey Minyard if (t_size > smbios_table_max) { \ 930517cc98SCorey Minyard smbios_table_max = t_size; \ 940517cc98SCorey Minyard } \ 950517cc98SCorey Minyard \ 960517cc98SCorey Minyard /* update smbios element count */ \ 970517cc98SCorey Minyard smbios_table_cnt++; \ 980517cc98SCorey Minyard } while (0) 990517cc98SCorey Minyard 100*5aca89d1SPhilippe Mathieu-Daudé /* IPMI SMBIOS firmware handling */ 101*5aca89d1SPhilippe Mathieu-Daudé void smbios_build_type_38_table(void); 102*5aca89d1SPhilippe Mathieu-Daudé 1030517cc98SCorey Minyard #endif /* QEMU_SMBIOS_BUILD_H */ 104