1 /* ----------------------------------------------------------------------- * 2 * 3 * Pportions of this file taken from the dmidecode project 4 * 5 * Copyright (C) 2000-2002 Alan Cox <alan (at) redhat.com> 6 * Copyright (C) 2002-2008 Jean Delvare <khali (at) 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 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 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 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 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 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 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 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 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 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 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 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 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 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