1 /* 2 * SMBIOS Support 3 * 4 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. 5 * Copyright (C) 2013 Red Hat, Inc. 6 * 7 * Authors: 8 * Alex Williamson <alex.williamson@hp.com> 9 * Markus Armbruster <armbru@redhat.com> 10 * 11 * This work is licensed under the terms of the GNU GPL, version 2. See 12 * the COPYING file in the top-level directory. 13 * 14 * Contributions after 2012-01-13 are licensed under the terms of the 15 * GNU GPL, version 2 or (at your option) any later version. 16 */ 17 18 #ifndef QEMU_SMBIOS_BUILD_H 19 #define QEMU_SMBIOS_BUILD_H 20 21 bool smbios_skip_table(uint8_t type, bool required_table); 22 23 extern uint8_t *smbios_tables; 24 extern size_t smbios_tables_len; 25 extern unsigned smbios_table_max; 26 extern unsigned smbios_table_cnt; 27 28 #define SMBIOS_BUILD_TABLE_PRE(tbl_type, tbl_handle, tbl_required) \ 29 struct smbios_type_##tbl_type *t; \ 30 size_t t_off; /* table offset into smbios_tables */ \ 31 int str_index = 0; \ 32 do { \ 33 /* should we skip building this table ? */ \ 34 if (smbios_skip_table(tbl_type, tbl_required)) { \ 35 return; \ 36 } \ 37 \ 38 /* use offset of table t within smbios_tables */ \ 39 /* (pointer must be updated after each realloc) */ \ 40 t_off = smbios_tables_len; \ 41 smbios_tables_len += sizeof(*t); \ 42 smbios_tables = g_realloc(smbios_tables, smbios_tables_len); \ 43 t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \ 44 \ 45 t->header.type = tbl_type; \ 46 t->header.length = sizeof(*t); \ 47 t->header.handle = cpu_to_le16(tbl_handle); \ 48 } while (0) 49 50 #define SMBIOS_TABLE_SET_STR(tbl_type, field, value) \ 51 do { \ 52 int len = (value != NULL) ? strlen(value) + 1 : 0; \ 53 if (len > 1) { \ 54 smbios_tables = g_realloc(smbios_tables, \ 55 smbios_tables_len + len); \ 56 memcpy(smbios_tables + smbios_tables_len, value, len); \ 57 smbios_tables_len += len; \ 58 /* update pointer post-realloc */ \ 59 t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \ 60 t->field = ++str_index; \ 61 } else { \ 62 t->field = 0; \ 63 } \ 64 } while (0) 65 66 #define SMBIOS_BUILD_TABLE_POST \ 67 do { \ 68 size_t term_cnt, t_size; \ 69 \ 70 /* add '\0' terminator (add two if no strings defined) */ \ 71 term_cnt = (str_index == 0) ? 2 : 1; \ 72 smbios_tables = g_realloc(smbios_tables, \ 73 smbios_tables_len + term_cnt); \ 74 memset(smbios_tables + smbios_tables_len, 0, term_cnt); \ 75 smbios_tables_len += term_cnt; \ 76 \ 77 /* update smbios max. element size */ \ 78 t_size = smbios_tables_len - t_off; \ 79 if (t_size > smbios_table_max) { \ 80 smbios_table_max = t_size; \ 81 } \ 82 \ 83 /* update smbios element count */ \ 84 smbios_table_cnt++; \ 85 } while (0) 86 87 #endif /* QEMU_SMBIOS_BUILD_H */ 88