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 SMBIOS_BUILD_TABLE_PRE_SIZE(tbl_type, tbl_handle, tbl_required, \ 31 sizeof(struct smbios_type_##tbl_type))\ 32 33 #define SMBIOS_BUILD_TABLE_PRE_SIZE(tbl_type, tbl_handle, \ 34 tbl_required, tbl_len) \ 35 struct smbios_type_##tbl_type *t; \ 36 size_t t_off; /* table offset into smbios_tables */ \ 37 int str_index = 0; \ 38 do { \ 39 /* should we skip building this table ? */ \ 40 if (smbios_skip_table(tbl_type, tbl_required)) { \ 41 return; \ 42 } \ 43 \ 44 /* use offset of table t within smbios_tables */ \ 45 /* (pointer must be updated after each realloc) */ \ 46 t_off = smbios_tables_len; \ 47 smbios_tables_len += tbl_len; \ 48 smbios_tables = g_realloc(smbios_tables, smbios_tables_len); \ 49 t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \ 50 \ 51 t->header.type = tbl_type; \ 52 t->header.length = tbl_len; \ 53 t->header.handle = cpu_to_le16(tbl_handle); \ 54 } while (0) 55 56 #define SMBIOS_TABLE_SET_STR(tbl_type, field, value) \ 57 do { \ 58 int len = (value != NULL) ? strlen(value) + 1 : 0; \ 59 if (len > 1) { \ 60 smbios_tables = g_realloc(smbios_tables, \ 61 smbios_tables_len + len); \ 62 memcpy(smbios_tables + smbios_tables_len, value, len); \ 63 smbios_tables_len += len; \ 64 /* update pointer post-realloc */ \ 65 t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \ 66 t->field = ++str_index; \ 67 } else { \ 68 t->field = 0; \ 69 } \ 70 } while (0) 71 72 #define SMBIOS_TABLE_SET_STR_LIST(tbl_type, value) \ 73 do { \ 74 int len = (value != NULL) ? strlen(value) + 1 : 0; \ 75 if (len > 1) { \ 76 smbios_tables = g_realloc(smbios_tables, \ 77 smbios_tables_len + len); \ 78 memcpy(smbios_tables + smbios_tables_len, value, len); \ 79 smbios_tables_len += len; \ 80 ++str_index; \ 81 } \ 82 } while (0) 83 84 #define SMBIOS_BUILD_TABLE_POST \ 85 do { \ 86 size_t term_cnt, t_size; \ 87 \ 88 /* add '\0' terminator (add two if no strings defined) */ \ 89 term_cnt = (str_index == 0) ? 2 : 1; \ 90 smbios_tables = g_realloc(smbios_tables, \ 91 smbios_tables_len + term_cnt); \ 92 memset(smbios_tables + smbios_tables_len, 0, term_cnt); \ 93 smbios_tables_len += term_cnt; \ 94 \ 95 /* update smbios max. element size */ \ 96 t_size = smbios_tables_len - t_off; \ 97 if (t_size > smbios_table_max) { \ 98 smbios_table_max = t_size; \ 99 } \ 100 \ 101 /* update smbios element count */ \ 102 smbios_table_cnt++; \ 103 } while (0) 104 105 /* IPMI SMBIOS firmware handling */ 106 void smbios_build_type_38_table(void); 107 108 #endif /* QEMU_SMBIOS_BUILD_H */ 109