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 | |