• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------- *
2  *
3  *   Copyright 2009 Erwan Velu - All Rights Reserved
4  *
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
12  *   conditions:
13  *
14  *   The above copyright notice and this permission notice shall
15  *   be included in all copies or substantial portions of the Software.
16  *
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.
25  *
26  * -----------------------------------------------------------------------
27  */
28 
29 #include <memory.h>
30 #include "hdt-menu.h"
31 #define E820MAX 128
32 
33 /* Compute the e820 submenu */
compute_e820(struct s_my_menu * menu)34 static void compute_e820(struct s_my_menu *menu)
35 {
36     char buffer[MENULEN + 1];
37     char statbuffer[STATLEN + 1];
38 
39     sprintf(buffer, " e820 information ");
40     menu->items_count = 0;
41     menu->menu = add_menu(buffer, -1);
42 
43     struct e820entry map[E820MAX];
44     int count = 0;
45     char type[14];
46 
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,
53 	     memory_size);
54     add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
55     add_item("", "", OPT_SEP, "", 0);
56 
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);
66 	menu->items_count++;
67     }
68 }
69 
70 /* Compute the e801 submenu */
compute_e801(struct s_my_menu * menu)71 static void compute_e801(struct s_my_menu *menu)
72 {
73     char buffer[MENULEN + 1];
74     char statbuffer[STATLEN + 1];
75 
76     sprintf(buffer, " e801 information ");
77     menu->items_count = 0;
78     menu->menu = add_menu(buffer, -1);
79 
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);
85 	menu->items_count++;
86     } else {
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);
93 
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);
100 
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);
106 
107     }
108     menu->items_count++;
109 }
110 
111 /* Compute the 88 submenu */
compute_88(struct s_my_menu * menu)112 static void compute_88(struct s_my_menu *menu)
113 {
114     char buffer[MENULEN + 1];
115     char statbuffer[STATLEN + 1];
116 
117     sprintf(buffer, " 88 information ");
118     menu->items_count = 0;
119     menu->menu = add_menu(buffer, -1);
120 
121     int mem_size = 0;
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);
126 	menu->items_count++;
127     } else {
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);
133     }
134     menu->items_count++;
135 }
136 
137 /* Compute the Memory submenu */
compute_memory_module(struct s_my_menu * menu,s_dmi * dmi,int slot_number)138 static void compute_memory_module(struct s_my_menu *menu, s_dmi * dmi,
139 				  int slot_number)
140 {
141     int i = slot_number;
142     char buffer[MENULEN + 1];
143     char statbuffer[STATLEN + 1];
144 
145     sprintf(buffer, " Bank <%d> ", i);
146     menu->items_count = 0;
147     menu->menu = add_menu(buffer, -1);
148 
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);
154     menu->items_count++;
155 
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);
159     menu->items_count++;
160 
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);
166     menu->items_count++;
167 
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);
172     menu->items_count++;
173 
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);
177     menu->items_count++;
178 
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);
184     menu->items_count++;
185 
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);
191     menu->items_count++;
192 
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);
198     menu->items_count++;
199 
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);
205     menu->items_count++;
206 
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);
212     menu->items_count++;
213 
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);
217     menu->items_count++;
218 
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);
224     menu->items_count++;
225 
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);
230     menu->items_count++;
231 
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);
237     menu->items_count++;
238 
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);
244     menu->items_count++;
245 
246 }
247 
248 /* Compute the Memory submenu when type 6 is used*/
compute_memory_module_type6(struct s_my_menu * menu,s_dmi * dmi,int slot_number)249 static void compute_memory_module_type6(struct s_my_menu *menu, s_dmi * dmi,
250 					int slot_number)
251 {
252     int i = slot_number;
253     char buffer[MENULEN + 1];
254     char statbuffer[STATLEN + 1];
255 
256     sprintf(buffer, " Bank <%d> ", i);
257     menu->items_count = 0;
258     menu->menu = add_menu(buffer, -1);
259 
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);
265     menu->items_count++;
266 
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);
272     menu->items_count++;
273 
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);
279     menu->items_count++;
280 
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);
286     menu->items_count++;
287 
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);
293     menu->items_count++;
294 
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);
300     menu->items_count++;
301 
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);
307     menu->items_count++;
308 
309 }
310 
311 /* Compute the Memory menu */
compute_memory(struct s_hdt_menu * menu,s_dmi * dmi,struct s_hardware * hardware)312 void compute_memory(struct s_hdt_menu *menu, s_dmi * dmi,
313 		    struct s_hardware *hardware)
314 {
315     char buffer[MENULEN + 1];
316     int i = 0;
317     int memory_count = 0;
318 
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);
324 	}
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);
330 	}
331     }
332 
333     compute_e820(&(menu->memory_sub_menu[++i]));
334     compute_e801(&(menu->memory_sub_menu[++i]));
335     compute_88(&(menu->memory_sub_menu[++i]));
336 
337     menu->memory_menu.menu = add_menu(" Memory ", -1);
338     menu->memory_menu.items_count = 0;
339 
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++;
345 
346     add_item("", "", OPT_SEP, "", 0);
347 
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++;
353     } else
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++;
359 	}
360 
361     add_item("", "", OPT_SEP, "", 0);
362 
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++;
367 
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++;
372 
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++;
377 
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);
382 }
383