1 /* ----------------------------------------------------------------------- *
3 * Copyright 2009 Erwan Velu - All Rights Reserved
5 * Permission is hereby granted, free of charge, to any person
6 * obtaining a copy of this software and associated documentation
7 * files (the "Software"), to deal in the Software without
8 * restriction, including without limitation the rights to use,
9 * copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom
11 * the Software is furnished to do so, subject to the following
14 * The above copyright notice and this permission notice shall
15 * be included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
26 * -----------------------------------------------------------------------
33 /* Compute the e820 submenu */
34 static void compute_e820(struct s_my_menu
*menu
)
36 char buffer
[MENULEN
+ 1];
37 char statbuffer
[STATLEN
+ 1];
39 sprintf(buffer
, " e820 Physical RAM map ");
40 menu
->items_count
= 0;
41 menu
->menu
= add_menu(buffer
, -1);
43 struct e820entry map
[E820MAX
];
47 detect_memory_e820(map
, E820MAX
, &count
);
48 unsigned long memory_size
= memsize_e820(map
, count
);
49 snprintf(buffer
, sizeof buffer
, "Detected Memory - %lu MiB (%lu KiB)",
50 memory_size
>> 10, memory_size
);
51 snprintf(statbuffer
, sizeof statbuffer
,
52 "Detected Memory : %lu MiB (%lu KiB)", memory_size
>> 10,
54 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
55 add_item("", "", OPT_SEP
, "", 0);
57 for (int j
= 0; j
< count
; j
++) {
58 get_type(map
[j
].type
, type
, 14);
59 snprintf(buffer
, sizeof buffer
,
60 "%016llx - %016llx (%s)",
61 map
[j
].addr
, map
[j
].size
, remove_spaces(type
));
62 snprintf(statbuffer
, sizeof statbuffer
,
63 "%016llx - %016llx (%s)",
64 map
[j
].addr
, map
[j
].size
, remove_spaces(type
));
65 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
70 /* Compute the e801 submenu */
71 static void compute_e801(struct s_my_menu
*menu
)
73 char buffer
[MENULEN
+ 1];
74 char statbuffer
[STATLEN
+ 1];
76 sprintf(buffer
, " e801 information ");
77 menu
->items_count
= 0;
78 menu
->menu
= add_menu(buffer
, -1);
80 int mem_low
, mem_high
= 0;
81 if (detect_memory_e801(&mem_low
, &mem_high
)) {
82 snprintf(buffer
, sizeof buffer
, "%s", "e801 output is bogus");
83 snprintf(statbuffer
, sizeof statbuffer
, "%s", "e801 output is bogus");
84 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
87 snprintf(buffer
, sizeof buffer
, "Detected Memory : %d MiB (%d KiB)",
88 (mem_high
>> 4) + (mem_low
>> 10), mem_low
+ (mem_high
<< 6));
89 snprintf(statbuffer
, sizeof statbuffer
,
90 "Detected Memory : %d MiB (%d KiB)",
91 (mem_high
>> 4) + (mem_low
>> 10), mem_low
+ (mem_high
<< 6));
92 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
94 add_item("", "", OPT_SEP
, "", 0);
95 snprintf(buffer
, sizeof buffer
, "Low Memory : %d KiB (%d MiB)",
96 mem_low
, mem_low
>> 10);
97 snprintf(statbuffer
, sizeof statbuffer
, "Low Memory : %d KiB (%d MiB)",
98 mem_low
, mem_low
>> 10);
99 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
101 snprintf(buffer
, sizeof buffer
, "High Memory : %d KiB (%d MiB)",
102 mem_high
<< 6, mem_high
>> 4);
103 snprintf(statbuffer
, sizeof statbuffer
, "High Memory : %d KiB (%d MiB)",
104 mem_high
<< 6, mem_high
>> 4);
105 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
111 /* Compute the 88 submenu */
112 static void compute_88(struct s_my_menu
*menu
)
114 char buffer
[MENULEN
+ 1];
115 char statbuffer
[STATLEN
+ 1];
117 sprintf(buffer
, " 88 information ");
118 menu
->items_count
= 0;
119 menu
->menu
= add_menu(buffer
, -1);
122 if (detect_memory_88(&mem_size
)) {
123 snprintf(buffer
, sizeof buffer
, "%s", "88 output is bogus");
124 snprintf(statbuffer
, sizeof statbuffer
, "%s", "88 output is bogus");
125 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
128 snprintf(buffer
, sizeof buffer
, "Detected Memory : %d MiB (%d KiB)",
129 mem_size
>> 10, mem_size
);
130 snprintf(statbuffer
, sizeof statbuffer
,
131 "Detected Memory : %d MiB (%d KiB)", mem_size
>> 10, mem_size
);
132 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
137 /* Compute the Memory submenu */
138 static void compute_memory_module(struct s_my_menu
*menu
, s_dmi
* dmi
,
142 char buffer
[MENULEN
+ 1];
143 char statbuffer
[STATLEN
+ 1];
145 sprintf(buffer
, " Bank <%d> ", i
);
146 menu
->items_count
= 0;
147 menu
->menu
= add_menu(buffer
, -1);
149 snprintf(buffer
, sizeof buffer
, "Form Factor : %s",
150 dmi
->memory
[i
].form_factor
);
151 snprintf(statbuffer
, sizeof statbuffer
, "Form Factor: %s",
152 dmi
->memory
[i
].form_factor
);
153 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
156 snprintf(buffer
, sizeof buffer
, "Type : %s", dmi
->memory
[i
].type
);
157 snprintf(statbuffer
, sizeof statbuffer
, "Type: %s", dmi
->memory
[i
].type
);
158 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
161 snprintf(buffer
, sizeof buffer
, "Type Details : %s",
162 dmi
->memory
[i
].type_detail
);
163 snprintf(statbuffer
, sizeof statbuffer
, "Type Details: %s",
164 dmi
->memory
[i
].type_detail
);
165 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
168 snprintf(buffer
, sizeof buffer
, "Speed : %s", dmi
->memory
[i
].speed
);
169 snprintf(statbuffer
, sizeof statbuffer
, "Speed (Mhz): %s",
170 dmi
->memory
[i
].speed
);
171 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
174 snprintf(buffer
, sizeof buffer
, "Size : %s", dmi
->memory
[i
].size
);
175 snprintf(statbuffer
, sizeof statbuffer
, "Size: %s", dmi
->memory
[i
].size
);
176 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
179 snprintf(buffer
, sizeof buffer
, "Device Set : %s",
180 dmi
->memory
[i
].device_set
);
181 snprintf(statbuffer
, sizeof statbuffer
, "Device Set: %s",
182 dmi
->memory
[i
].device_set
);
183 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
186 snprintf(buffer
, sizeof buffer
, "Device Loc. : %s",
187 dmi
->memory
[i
].device_locator
);
188 snprintf(statbuffer
, sizeof statbuffer
, "Device Location: %s",
189 dmi
->memory
[i
].device_locator
);
190 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
193 snprintf(buffer
, sizeof buffer
, "Bank Locator : %s",
194 dmi
->memory
[i
].bank_locator
);
195 snprintf(statbuffer
, sizeof statbuffer
, "Bank Locator: %s",
196 dmi
->memory
[i
].bank_locator
);
197 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
200 snprintf(buffer
, sizeof buffer
, "Total Width : %s",
201 dmi
->memory
[i
].total_width
);
202 snprintf(statbuffer
, sizeof statbuffer
, "Total bit Width: %s",
203 dmi
->memory
[i
].total_width
);
204 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
207 snprintf(buffer
, sizeof buffer
, "Data Width : %s",
208 dmi
->memory
[i
].data_width
);
209 snprintf(statbuffer
, sizeof statbuffer
, "Data bit Width: %s",
210 dmi
->memory
[i
].data_width
);
211 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
214 snprintf(buffer
, sizeof buffer
, "Error : %s", dmi
->memory
[i
].error
);
215 snprintf(statbuffer
, sizeof statbuffer
, "Error: %s", dmi
->memory
[i
].error
);
216 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
219 snprintf(buffer
, sizeof buffer
, "Vendor : %s",
220 dmi
->memory
[i
].manufacturer
);
221 snprintf(statbuffer
, sizeof statbuffer
, "Vendor: %s",
222 dmi
->memory
[i
].manufacturer
);
223 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
226 snprintf(buffer
, sizeof buffer
, "Serial : %s", dmi
->memory
[i
].serial
);
227 snprintf(statbuffer
, sizeof statbuffer
, "Serial: %s",
228 dmi
->memory
[i
].serial
);
229 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
232 snprintf(buffer
, sizeof buffer
, "Asset Tag : %s",
233 dmi
->memory
[i
].asset_tag
);
234 snprintf(statbuffer
, sizeof statbuffer
, "Asset Tag: %s",
235 dmi
->memory
[i
].asset_tag
);
236 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
239 snprintf(buffer
, sizeof buffer
, "Part Number : %s",
240 dmi
->memory
[i
].part_number
);
241 snprintf(statbuffer
, sizeof statbuffer
, "Part Number: %s",
242 dmi
->memory
[i
].part_number
);
243 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
248 /* Compute the Memory submenu when type 6 is used*/
249 static void compute_memory_module_type6(struct s_my_menu
*menu
, s_dmi
* dmi
,
253 char buffer
[MENULEN
+ 1];
254 char statbuffer
[STATLEN
+ 1];
256 sprintf(buffer
, " Bank <%d> ", i
);
257 menu
->items_count
= 0;
258 menu
->menu
= add_menu(buffer
, -1);
260 snprintf(buffer
, sizeof buffer
, "Socket Designation : %s",
261 dmi
->memory_module
[i
].socket_designation
);
262 snprintf(statbuffer
, sizeof statbuffer
, "Socket Designation : %s",
263 dmi
->memory_module
[i
].socket_designation
);
264 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
267 snprintf(buffer
, sizeof buffer
, "Bank Connections : %s",
268 dmi
->memory_module
[i
].bank_connections
);
269 snprintf(statbuffer
, sizeof statbuffer
, "Bank Connections: %s",
270 dmi
->memory_module
[i
].bank_connections
);
271 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
274 snprintf(buffer
, sizeof buffer
, "Type : %s",
275 dmi
->memory_module
[i
].type
);
276 snprintf(statbuffer
, sizeof statbuffer
, "Type : %s",
277 dmi
->memory_module
[i
].type
);
278 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
281 snprintf(buffer
, sizeof buffer
, "Current Speed : %s",
282 dmi
->memory_module
[i
].speed
);
283 snprintf(statbuffer
, sizeof statbuffer
, "Current Speed : %s",
284 dmi
->memory_module
[i
].speed
);
285 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
288 snprintf(buffer
, sizeof buffer
, "Installed Size : %s",
289 dmi
->memory_module
[i
].installed_size
);
290 snprintf(statbuffer
, sizeof statbuffer
, "Installed Size : %s",
291 dmi
->memory_module
[i
].installed_size
);
292 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
295 snprintf(buffer
, sizeof buffer
, "Enabled Size : %s",
296 dmi
->memory_module
[i
].enabled_size
);
297 snprintf(statbuffer
, sizeof statbuffer
, "Enabled Size : %s",
298 dmi
->memory_module
[i
].enabled_size
);
299 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
302 snprintf(buffer
, sizeof buffer
, "Error Status : %s",
303 dmi
->memory_module
[i
].error_status
);
304 snprintf(statbuffer
, sizeof statbuffer
, "Error Status : %s",
305 dmi
->memory_module
[i
].error_status
);
306 add_item(buffer
, statbuffer
, OPT_INACTIVE
, NULL
, 0);
311 /* Compute the Memory menu */
312 void compute_memory(struct s_hdt_menu
*menu
, s_dmi
* dmi
,
313 struct s_hardware
*hardware
)
315 char buffer
[MENULEN
+ 1];
317 int memory_count
= 0;
319 /* If memory type 17 is available */
320 if (dmi
->memory_count
> 0) {
321 memory_count
= dmi
->memory_count
;
322 for (i
= 0; i
< dmi
->memory_count
; i
++) {
323 compute_memory_module(&(menu
->memory_sub_menu
[i
]), dmi
, i
);
325 } else if (dmi
->memory_module_count
> 0) {
326 memory_count
= dmi
->memory_module_count
;
327 /* Memory Type 17 isn't available, let's fallback on type 6 */
328 for (i
= 0; i
< dmi
->memory_module_count
; i
++) {
329 compute_memory_module_type6(&(menu
->memory_sub_menu
[i
]), dmi
, i
);
333 compute_e820(&(menu
->memory_sub_menu
[++i
]));
334 compute_e801(&(menu
->memory_sub_menu
[++i
]));
335 compute_88(&(menu
->memory_sub_menu
[++i
]));
337 menu
->memory_menu
.menu
= add_menu(" Memory ", -1);
338 menu
->memory_menu
.items_count
= 0;
340 snprintf(buffer
, sizeof(buffer
), " %lu MB detected ",
341 (hardware
->detected_memory_size
+ (1 << 9)) >> 10);
342 add_item(buffer
, "Detected Memory", OPT_INACTIVE
, NULL
,
343 menu
->memory_sub_menu
[0].menu
);
344 menu
->memory_menu
.items_count
++;
346 add_item("", "", OPT_SEP
, "", 0);
348 if (memory_count
== 0) {
349 snprintf(buffer
, sizeof buffer
, " No memory bank detected ");
350 add_item(buffer
, "Memory Bank", OPT_INACTIVE
, NULL
,
351 menu
->memory_sub_menu
[1].menu
);
352 menu
->memory_menu
.items_count
++;
354 for (i
= 0; i
< memory_count
; i
++) {
355 snprintf(buffer
, sizeof buffer
, " Bank <%d> ", i
);
356 add_item(buffer
, "Memory Bank", OPT_SUBMENU
, NULL
,
357 menu
->memory_sub_menu
[i
].menu
);
358 menu
->memory_menu
.items_count
++;
361 add_item("", "", OPT_SEP
, "", 0);
363 snprintf(buffer
, sizeof buffer
, " e820 ");
364 add_item(buffer
, "e820 mapping", OPT_SUBMENU
, NULL
,
365 menu
->memory_sub_menu
[++i
].menu
);
366 menu
->memory_menu
.items_count
++;
368 snprintf(buffer
, sizeof buffer
, " e801 ");
369 add_item(buffer
, "e801 information", OPT_SUBMENU
, NULL
,
370 menu
->memory_sub_menu
[++i
].menu
);
371 menu
->memory_menu
.items_count
++;
373 snprintf(buffer
, sizeof buffer
, " 88 ");
374 add_item(buffer
, "88 information", OPT_SUBMENU
, NULL
,
375 menu
->memory_sub_menu
[++i
].menu
);
376 menu
->memory_menu
.items_count
++;
378 add_item("", "", OPT_SEP
, "", 0);
379 printf("MENU: Memory menu done (%d items)\n",
380 menu
->memory_menu
.items_count
);
381 add_item("Run Test", "Run Test", OPT_RUN
, hardware
->memtest_label
, 0);