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. 60517cc98SCorey Minyard * 70517cc98SCorey Minyard * Authors: 80517cc98SCorey Minyard * Alex Williamson <alex.williamson@hp.com> 90517cc98SCorey Minyard * Markus Armbruster <armbru@redhat.com> 100517cc98SCorey Minyard * 110517cc98SCorey Minyard * This work is licensed under the terms of the GNU GPL, version 2. See 120517cc98SCorey Minyard * the COPYING file in the top-level directory. 130517cc98SCorey Minyard * 140517cc98SCorey Minyard * Contributions after 2012-01-13 are licensed under the terms of the 150517cc98SCorey Minyard * GNU GPL, version 2 or (at your option) any later version. 160517cc98SCorey Minyard */ 170517cc98SCorey Minyard 180517cc98SCorey Minyard #ifndef QEMU_SMBIOS_BUILD_H 190517cc98SCorey Minyard #define QEMU_SMBIOS_BUILD_H 200517cc98SCorey Minyard 210517cc98SCorey Minyard bool smbios_skip_table(uint8_t type, bool required_table); 220517cc98SCorey Minyard 230517cc98SCorey Minyard extern uint8_t *smbios_tables; 240517cc98SCorey Minyard extern size_t smbios_tables_len; 250517cc98SCorey Minyard extern unsigned smbios_table_max; 260517cc98SCorey Minyard extern unsigned smbios_table_cnt; 270517cc98SCorey Minyard 280517cc98SCorey Minyard #define SMBIOS_BUILD_TABLE_PRE(tbl_type, tbl_handle, tbl_required) \ 290517cc98SCorey Minyard struct smbios_type_##tbl_type *t; \ 300517cc98SCorey Minyard size_t t_off; /* table offset into smbios_tables */ \ 310517cc98SCorey Minyard int str_index = 0; \ 320517cc98SCorey Minyard do { \ 330517cc98SCorey Minyard /* should we skip building this table ? */ \ 340517cc98SCorey Minyard if (smbios_skip_table(tbl_type, tbl_required)) { \ 350517cc98SCorey Minyard return; \ 360517cc98SCorey Minyard } \ 370517cc98SCorey Minyard \ 380517cc98SCorey Minyard /* use offset of table t within smbios_tables */ \ 390517cc98SCorey Minyard /* (pointer must be updated after each realloc) */ \ 400517cc98SCorey Minyard t_off = smbios_tables_len; \ 410517cc98SCorey Minyard smbios_tables_len += sizeof(*t); \ 420517cc98SCorey Minyard smbios_tables = g_realloc(smbios_tables, smbios_tables_len); \ 430517cc98SCorey Minyard t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \ 440517cc98SCorey Minyard \ 450517cc98SCorey Minyard t->header.type = tbl_type; \ 460517cc98SCorey Minyard t->header.length = sizeof(*t); \ 470517cc98SCorey Minyard t->header.handle = cpu_to_le16(tbl_handle); \ 480517cc98SCorey Minyard } while (0) 490517cc98SCorey Minyard 500517cc98SCorey Minyard #define SMBIOS_TABLE_SET_STR(tbl_type, field, value) \ 510517cc98SCorey Minyard do { \ 520517cc98SCorey Minyard int len = (value != NULL) ? strlen(value) + 1 : 0; \ 530517cc98SCorey Minyard if (len > 1) { \ 540517cc98SCorey Minyard smbios_tables = g_realloc(smbios_tables, \ 550517cc98SCorey Minyard smbios_tables_len + len); \ 560517cc98SCorey Minyard memcpy(smbios_tables + smbios_tables_len, value, len); \ 570517cc98SCorey Minyard smbios_tables_len += len; \ 580517cc98SCorey Minyard /* update pointer post-realloc */ \ 590517cc98SCorey Minyard t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \ 600517cc98SCorey Minyard t->field = ++str_index; \ 610517cc98SCorey Minyard } else { \ 620517cc98SCorey Minyard t->field = 0; \ 630517cc98SCorey Minyard } \ 640517cc98SCorey Minyard } while (0) 650517cc98SCorey Minyard 66*2d6dcbf9SDaniel P. Berrange #define SMBIOS_TABLE_SET_STR_LIST(tbl_type, value) \ 67*2d6dcbf9SDaniel P. Berrange do { \ 68*2d6dcbf9SDaniel P. Berrange int len = (value != NULL) ? strlen(value) + 1 : 0; \ 69*2d6dcbf9SDaniel P. Berrange if (len > 1) { \ 70*2d6dcbf9SDaniel P. Berrange smbios_tables = g_realloc(smbios_tables, \ 71*2d6dcbf9SDaniel P. Berrange smbios_tables_len + len); \ 72*2d6dcbf9SDaniel P. Berrange memcpy(smbios_tables + smbios_tables_len, value, len); \ 73*2d6dcbf9SDaniel P. Berrange smbios_tables_len += len; \ 74*2d6dcbf9SDaniel P. Berrange ++str_index; \ 75*2d6dcbf9SDaniel P. Berrange } \ 76*2d6dcbf9SDaniel P. Berrange } while (0) 77*2d6dcbf9SDaniel P. Berrange 780517cc98SCorey Minyard #define SMBIOS_BUILD_TABLE_POST \ 790517cc98SCorey Minyard do { \ 800517cc98SCorey Minyard size_t term_cnt, t_size; \ 810517cc98SCorey Minyard \ 820517cc98SCorey Minyard /* add '\0' terminator (add two if no strings defined) */ \ 830517cc98SCorey Minyard term_cnt = (str_index == 0) ? 2 : 1; \ 840517cc98SCorey Minyard smbios_tables = g_realloc(smbios_tables, \ 850517cc98SCorey Minyard smbios_tables_len + term_cnt); \ 860517cc98SCorey Minyard memset(smbios_tables + smbios_tables_len, 0, term_cnt); \ 870517cc98SCorey Minyard smbios_tables_len += term_cnt; \ 880517cc98SCorey Minyard \ 890517cc98SCorey Minyard /* update smbios max. element size */ \ 900517cc98SCorey Minyard t_size = smbios_tables_len - t_off; \ 910517cc98SCorey Minyard if (t_size > smbios_table_max) { \ 920517cc98SCorey Minyard smbios_table_max = t_size; \ 930517cc98SCorey Minyard } \ 940517cc98SCorey Minyard \ 950517cc98SCorey Minyard /* update smbios element count */ \ 960517cc98SCorey Minyard smbios_table_cnt++; \ 970517cc98SCorey Minyard } while (0) 980517cc98SCorey Minyard 990517cc98SCorey Minyard #endif /* QEMU_SMBIOS_BUILD_H */ 100