• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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