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