1 /* ----------------------------------------------------------------------- *
2 *
3 * Pportions of this file taken from the dmidecode project
4 *
5 * Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
6 * Copyright (C) 2002-2008 Jean Delvare <khali@linux-fr.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * For the avoidance of doubt the "preferred form" of this code is one which
23 * is in an open unpatent encumbered format. Where cryptographic key signing
24 * forms part of the process of creating an executable the information
25 * including keys needed to generate an equivalently functional executable
26 * are deemed to be part of the source code.
27 */
28
29 #include <dmi/dmi.h>
30 #include <stdio.h>
31
dmi_memory_array_error_handle(uint16_t code,char * array)32 void dmi_memory_array_error_handle(uint16_t code, char *array)
33 {
34 if (code == 0xFFFE)
35 sprintf(array, "%s", "Not Provided");
36 else if (code == 0xFFFF)
37 sprintf(array, "%s", "No Error");
38 else
39 sprintf(array, "0x%04X", code);
40 }
41
dmi_memory_device_width(uint16_t code,char * width)42 void dmi_memory_device_width(uint16_t code, char *width)
43 {
44 /*
45 * 3.3.18 Memory Device (Type 17)
46 * If no memory module is present, width may be 0
47 */
48 if (code == 0xFFFF || code == 0)
49 sprintf(width, "%s", "Unknown");
50 else
51 sprintf(width, "%u bits", code);
52 }
53
dmi_memory_device_size(uint16_t code,char * size)54 void dmi_memory_device_size(uint16_t code, char *size)
55 {
56 if (code == 0)
57 sprintf(size, "%s", "Free");
58 else if (code == 0xFFFF)
59 sprintf(size, "%s", "Unknown");
60 else {
61 if (code & 0x8000)
62 sprintf(size, "%u kB", code & 0x7FFF);
63 else
64 sprintf(size, "%u MB", code);
65 }
66 }
67
dmi_memory_device_form_factor(uint8_t code)68 const char *dmi_memory_device_form_factor(uint8_t code)
69 {
70 /* 3.3.18.1 */
71 static const char *form_factor[] = {
72 "Other", /* 0x01 */
73 "Unknown",
74 "SIMM",
75 "SIP",
76 "Chip",
77 "DIP",
78 "ZIP",
79 "Proprietary Card",
80 "DIMM",
81 "TSOP",
82 "Row Of Chips",
83 "RIMM",
84 "SODIMM",
85 "SRIMM",
86 "FB-DIMM" /* 0x0F */
87 };
88
89 if (code >= 0x01 && code <= 0x0F)
90 return form_factor[code - 0x01];
91 return out_of_spec;
92 }
93
dmi_memory_device_set(uint8_t code,char * set)94 void dmi_memory_device_set(uint8_t code, char *set)
95 {
96 if (code == 0)
97 sprintf(set, "%s", "None");
98 else if (code == 0xFF)
99 sprintf(set, "%s", "Unknown");
100 else
101 sprintf(set, "%u", code);
102 }
103
dmi_memory_device_type(uint8_t code)104 const char *dmi_memory_device_type(uint8_t code)
105 {
106 /* 3.3.18.2 */
107 static const char *type[] = {
108 "Other", /* 0x01 */
109 "Unknown",
110 "DRAM",
111 "EDRAM",
112 "VRAM",
113 "SRAM",
114 "RAM",
115 "ROM",
116 "Flash",
117 "EEPROM",
118 "FEPROM",
119 "EPROM",
120 "CDRAM",
121 "3DRAM",
122 "SDRAM",
123 "SGRAM",
124 "RDRAM",
125 "DDR",
126 "DDR2",
127 "DDR2 FB-DIMM", /* 0x14 */
128 NULL,
129 NULL,
130 NULL,
131 "DDR3", /* 0x18 */
132 "FBD2" /* 0x19 */
133 };
134
135 if (code >= 0x01 && code <= 0x19)
136 return type[code - 0x01];
137 return out_of_spec;
138 }
139
dmi_memory_device_type_detail(uint16_t code,char * type_detail,int sizeof_type_detail)140 void dmi_memory_device_type_detail(uint16_t code, char *type_detail, int sizeof_type_detail)
141 {
142 /* 3.3.18.3 */
143 static const char *detail[] = {
144 "Other", /* 1 */
145 "Unknown",
146 "Fast-paged",
147 "Static Column",
148 "Pseudo-static",
149 "RAMBus",
150 "Synchronous",
151 "CMOS",
152 "EDO",
153 "Window DRAM",
154 "Cache DRAM",
155 "Non-Volatile" /* 12 */
156 };
157
158 if ((code & 0x1FFE) == 0)
159 sprintf(type_detail, "%s", "None");
160 else {
161 int i;
162
163 for (i = 1; i <= 12; i++)
164 if (code & (1 << i))
165 snprintf(type_detail, sizeof_type_detail, "%s", detail[i - 1]);
166 }
167 }
168
dmi_memory_device_speed(uint16_t code,char * speed)169 void dmi_memory_device_speed(uint16_t code, char *speed)
170 {
171 if (code == 0)
172 sprintf(speed, "%s", "Unknown");
173 else
174 sprintf(speed, "%u MHz", code);
175 }
176
177 /*
178 * 3.3.7 Memory Module Information (Type 6)
179 */
180
dmi_memory_module_types(uint16_t code,const char * sep,char * type,int sizeof_type)181 void dmi_memory_module_types(uint16_t code, const char *sep, char *type, int sizeof_type)
182 {
183 /* 3.3.7.1 */
184 static const char *types[] = {
185 "Other", /* 0 */
186 "Unknown",
187 "Standard",
188 "FPM",
189 "EDO",
190 "Parity",
191 "ECC",
192 "SIMM",
193 "DIMM",
194 "Burst EDO",
195 "SDRAM" /* 10 */
196 };
197
198 if ((code & 0x07FF) == 0)
199 sprintf(type, "%s", "None");
200 else {
201 int i;
202
203 for (i = 0; i <= 10; i++)
204 if (code & (1 << i))
205 snprintf(type, sizeof_type, "%s%s%s", type, sep, types[i]);
206 }
207 }
208
dmi_memory_module_connections(uint8_t code,char * connection,int sizeof_connection)209 void dmi_memory_module_connections(uint8_t code, char *connection, int sizeof_connection)
210 {
211 if (code == 0xFF)
212 sprintf(connection, "%s", "None");
213 else {
214 if ((code & 0xF0) != 0xF0)
215 sprintf(connection, "%u ", code >> 4);
216 if ((code & 0x0F) != 0x0F)
217 snprintf(connection, sizeof_connection, "%s%u", connection, code & 0x0F);
218 }
219 }
220
dmi_memory_module_speed(uint8_t code,char * speed)221 void dmi_memory_module_speed(uint8_t code, char *speed)
222 {
223 if (code == 0)
224 sprintf(speed, "%s", "Unknown");
225 else
226 sprintf(speed, "%u ns", code);
227 }
228
dmi_memory_module_size(uint8_t code,char * size,int sizeof_size)229 void dmi_memory_module_size(uint8_t code, char *size, int sizeof_size)
230 {
231 /* 3.3.7.2 */
232 switch (code & 0x7F) {
233 case 0x7D:
234 sprintf(size, "%s", "Not Determinable");
235 break;
236 case 0x7E:
237 sprintf(size, "%s", "Disabled");
238 break;
239 case 0x7F:
240 sprintf(size, "%s", "Not Installed");
241 return;
242 default:
243 sprintf(size, "%u MB", 1 << (code & 0x7F));
244 }
245
246 if (code & 0x80)
247 snprintf(size, sizeof_size, "%s %s", size, "(Double-bank Connection)");
248 else
249 snprintf(size, sizeof_size, "%s %s", size, "(Single-bank Connection)");
250 }
251
dmi_memory_module_error(uint8_t code,const char * prefix,char * error)252 void dmi_memory_module_error(uint8_t code, const char *prefix, char *error)
253 {
254 if (code & (1 << 2))
255 sprintf(error, "%s", "See Event Log\n");
256 else {
257 if ((code & 0x03) == 0)
258 sprintf(error, "%s", "OK\n");
259 if (code & (1 << 0))
260 sprintf(error, "%sUncorrectable Errors\n", prefix);
261 if (code & (1 << 1))
262 sprintf(error, "%sCorrectable Errors\n", prefix);
263 }
264 }
265