Home | History | Annotate | Download | only in hdt
      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 <stdio.h>
     30 #include <string.h>
     31 #include <stdlib.h>
     32 #include <errno.h>
     33 
     34 #include "hdt-cli.h"
     35 #include "hdt-common.h"
     36 
     37 static void show_dmi_modules(int argc __unused, char **argv __unused,
     38 			     struct s_hardware *hardware)
     39 {
     40     char available_dmi_commands[1024];
     41     reset_more_printf();
     42     memset(available_dmi_commands, 0, sizeof(available_dmi_commands));
     43 
     44     more_printf("Available DMI modules on your system:\n");
     45     if (hardware->dmi.base_board.filled == true)
     46 	more_printf("\t%s\n", CLI_DMI_BASE_BOARD);
     47     if (hardware->dmi.battery.filled == true)
     48 	more_printf("\t%s\n", CLI_DMI_BATTERY);
     49     if (hardware->dmi.bios.filled == true)
     50 	more_printf("\t%s\n", CLI_DMI_BIOS);
     51     if (hardware->dmi.chassis.filled == true)
     52 	more_printf("\t%s\n", CLI_DMI_CHASSIS);
     53     for (int i = 0; i < hardware->dmi.memory_count; i++) {
     54 	if (hardware->dmi.memory[i].filled == true) {
     55 	    more_printf("\tbank <number>\n");
     56 	    break;
     57 	}
     58     }
     59     for (int i = 0; i < hardware->dmi.memory_module_count; i++) {
     60 	if (hardware->dmi.memory_module[i].filled == true) {
     61 	    more_printf("\tmodule <number>\n");
     62 	    break;
     63 	}
     64     }
     65     if (hardware->dmi.processor.filled == true)
     66 	more_printf("\t%s\n", CLI_DMI_PROCESSOR);
     67     if (hardware->dmi.system.filled == true)
     68 	more_printf("\t%s\n", CLI_DMI_SYSTEM);
     69     if (hardware->dmi.ipmi.filled == true)
     70 	more_printf("\t%s\n", CLI_DMI_IPMI);
     71     if (hardware->dmi.cache_count)
     72 	more_printf("\t%s\n", CLI_DMI_CACHE);
     73     if (strlen(hardware->dmi.oem_strings))
     74 	more_printf("\t%s\n", CLI_DMI_OEM);
     75     if (hardware->dmi.hardware_security.filled)
     76 	more_printf("\t%s\n", CLI_DMI_SECURITY);
     77 }
     78 
     79 static void show_dmi_base_board(int argc __unused, char **argv __unused,
     80 				struct s_hardware *hardware)
     81 {
     82     if (hardware->dmi.base_board.filled == false) {
     83 	more_printf("base_board information not found on your system, see "
     84 		    "`show list' to see which module is available.\n");
     85 	return;
     86     }
     87     reset_more_printf();
     88     more_printf("Base board\n");
     89     more_printf(" Manufacturer : %s\n", hardware->dmi.base_board.manufacturer);
     90     more_printf(" Product Name : %s\n", hardware->dmi.base_board.product_name);
     91     more_printf(" Version      : %s\n", hardware->dmi.base_board.version);
     92     more_printf(" Serial       : %s\n", hardware->dmi.base_board.serial);
     93     more_printf(" Asset Tag    : %s\n", hardware->dmi.base_board.asset_tag);
     94     more_printf(" Location     : %s\n", hardware->dmi.base_board.location);
     95     more_printf(" Type         : %s\n", hardware->dmi.base_board.type);
     96     for (int i = 0; i < BASE_BOARD_NB_ELEMENTS; i++) {
     97 	if (((bool *) (&hardware->dmi.base_board.features))[i] == true) {
     98 	    more_printf(" %s\n", base_board_features_strings[i]);
     99 	}
    100     }
    101 
    102     for (unsigned int i = 0;
    103 	 i <
    104 	 sizeof hardware->dmi.base_board.devices_information /
    105 	 sizeof *hardware->dmi.base_board.devices_information; i++) {
    106 	if (strlen(hardware->dmi.base_board.devices_information[i].type)) {
    107 	    more_printf("On Board Device #%u Information\n", i)
    108 		more_printf("  Type        : %s\n",
    109 			    hardware->dmi.base_board.devices_information[i].
    110 			    type);
    111 	    more_printf("  Status      : %s\n",
    112 			hardware->dmi.base_board.devices_information[i].
    113 			status ? "Enabled" : "Disabled");
    114 	    more_printf("  Description : %s\n",
    115 			hardware->dmi.base_board.devices_information[i].
    116 			description);
    117 	}
    118     }
    119 }
    120 
    121 static void show_dmi_system(int argc __unused, char **argv __unused,
    122 			    struct s_hardware *hardware)
    123 {
    124     if (hardware->dmi.system.filled == false) {
    125 	more_printf("system information not found on your system, see "
    126 		    "`show list' to see which module is available.\n");
    127 	return;
    128     }
    129     reset_more_printf();
    130     more_printf("System\n");
    131     more_printf(" Manufacturer : %s\n", hardware->dmi.system.manufacturer);
    132     more_printf(" Product Name : %s\n", hardware->dmi.system.product_name);
    133     more_printf(" Version      : %s\n", hardware->dmi.system.version);
    134     more_printf(" Serial       : %s\n", hardware->dmi.system.serial);
    135     more_printf(" UUID         : %s\n", hardware->dmi.system.uuid);
    136     more_printf(" Wakeup Type  : %s\n", hardware->dmi.system.wakeup_type);
    137     more_printf(" SKU Number   : %s\n", hardware->dmi.system.sku_number);
    138     more_printf(" Family       : %s\n", hardware->dmi.system.family);
    139 
    140     if (strlen(hardware->dmi.system.configuration_options)) {
    141 	more_printf("System Configuration Options\n");
    142 	more_printf("%s\n", hardware->dmi.system.configuration_options);
    143     }
    144 
    145     if (hardware->dmi.system.system_reset.filled) {
    146 	more_printf("System Reset\n");
    147 	more_printf("  Status               : %s\n",
    148 		    (hardware->dmi.system.system_reset.
    149 		     status ? "Enabled" : "Disabled"));
    150 	more_printf("  Watchdog Timer       : %s\n",
    151 		    (hardware->dmi.system.system_reset.
    152 		     watchdog ? "Present" : "Not Present"));
    153 	if (strlen(hardware->dmi.system.system_reset.boot_option))
    154 	    more_printf("  Boot Option          : %s\n",
    155 			hardware->dmi.system.system_reset.boot_option);
    156 	if (strlen(hardware->dmi.system.system_reset.boot_option_on_limit))
    157 	    more_printf("  Boot Option On Limit : %s\n",
    158 			hardware->dmi.system.system_reset.boot_option_on_limit);
    159 	if (strlen(hardware->dmi.system.system_reset.reset_count))
    160 	    more_printf("  Reset Count          : %s\n",
    161 			hardware->dmi.system.system_reset.reset_count);
    162 	if (strlen(hardware->dmi.system.system_reset.reset_limit))
    163 	    more_printf("  Reset Limit          : %s\n",
    164 			hardware->dmi.system.system_reset.reset_limit);
    165 	if (strlen(hardware->dmi.system.system_reset.timer_interval))
    166 	    more_printf("  Timer Interval       : %s\n",
    167 			hardware->dmi.system.system_reset.timer_interval);
    168 	if (strlen(hardware->dmi.system.system_reset.timeout))
    169 	    more_printf("  Timeout              : %s\n",
    170 			hardware->dmi.system.system_reset.timeout);
    171     }
    172 
    173     more_printf("System Boot Information\n");
    174     more_printf(" Status       : %s\n",
    175 		hardware->dmi.system.system_boot_status);
    176 }
    177 
    178 static void show_dmi_bios(int argc __unused, char **argv __unused,
    179 			  struct s_hardware *hardware)
    180 {
    181     if (hardware->dmi.bios.filled == false) {
    182 	more_printf("bios information not found on your system, see "
    183 		    "`show list' to see which module is available.\n");
    184 	return;
    185     }
    186     reset_more_printf();
    187     more_printf("BIOS\n");
    188     more_printf(" Vendor            : %s\n", hardware->dmi.bios.vendor);
    189     more_printf(" Version           : %s\n", hardware->dmi.bios.version);
    190     more_printf(" Release Date      : %s\n", hardware->dmi.bios.release_date);
    191     more_printf(" Bios Revision     : %s\n", hardware->dmi.bios.bios_revision);
    192     if (strlen(hardware->dmi.bios.firmware_revision))
    193 	more_printf(" Firmware Revision : %s\n",
    194 		    hardware->dmi.bios.firmware_revision);
    195     more_printf(" Address           : 0x%04X0\n", hardware->dmi.bios.address);
    196     more_printf(" Runtime address   : %u %s\n",
    197 		hardware->dmi.bios.runtime_size,
    198 		hardware->dmi.bios.runtime_size_unit);
    199     more_printf(" Rom size          : %u %s\n", hardware->dmi.bios.rom_size,
    200 		hardware->dmi.bios.rom_size_unit);
    201 
    202     for (int i = 0; i < BIOS_CHAR_NB_ELEMENTS; i++) {
    203 	if (((bool *) (&hardware->dmi.bios.characteristics))[i] == true) {
    204 	    more_printf(" %s\n", bios_charac_strings[i]);
    205 	}
    206     }
    207     for (int i = 0; i < BIOS_CHAR_X1_NB_ELEMENTS; i++) {
    208 	if (((bool *) (&hardware->dmi.bios.characteristics_x1))[i] == true) {
    209 	    more_printf(" %s\n", bios_charac_x1_strings[i]);
    210 	}
    211     }
    212 
    213     for (int i = 0; i < BIOS_CHAR_X2_NB_ELEMENTS; i++) {
    214 	if (((bool *) (&hardware->dmi.bios.characteristics_x2))[i] == true) {
    215 	    more_printf(" %s\n", bios_charac_x2_strings[i]);
    216 	}
    217     }
    218 
    219 }
    220 
    221 static void show_dmi_chassis(int argc __unused, char **argv __unused,
    222 			     struct s_hardware *hardware)
    223 {
    224     if (hardware->dmi.chassis.filled == false) {
    225 	more_printf("chassis information not found on your system, see "
    226 		    "`show list' to see which module is available.\n");
    227 	return;
    228     }
    229     reset_more_printf();
    230     more_printf("Chassis\n");
    231     more_printf(" Manufacturer       : %s\n",
    232 		hardware->dmi.chassis.manufacturer);
    233     more_printf(" Type               : %s\n", hardware->dmi.chassis.type);
    234     more_printf(" Lock               : %s\n", hardware->dmi.chassis.lock);
    235     more_printf(" Version            : %s\n", hardware->dmi.chassis.version);
    236     more_printf(" Serial             : %s\n", hardware->dmi.chassis.serial);
    237     more_printf(" Asset Tag          : %s\n",
    238 		del_multi_spaces(hardware->dmi.chassis.asset_tag));
    239     more_printf(" Boot up state      : %s\n",
    240 		hardware->dmi.chassis.boot_up_state);
    241     more_printf(" Power supply state : %s\n",
    242 		hardware->dmi.chassis.power_supply_state);
    243     more_printf(" Thermal state      : %s\n",
    244 		hardware->dmi.chassis.thermal_state);
    245     more_printf(" Security Status    : %s\n",
    246 		hardware->dmi.chassis.security_status);
    247     more_printf(" OEM Information    : %s\n",
    248 		hardware->dmi.chassis.oem_information);
    249     more_printf(" Height             : %u\n", hardware->dmi.chassis.height);
    250     more_printf(" NB Power Cords     : %u\n",
    251 		hardware->dmi.chassis.nb_power_cords);
    252 }
    253 
    254 static void show_dmi_ipmi(int argc __unused, char **argv __unused,
    255 			  struct s_hardware *hardware)
    256 {
    257     if (hardware->dmi.ipmi.filled == false) {
    258 	more_printf("IPMI module not available\n");
    259 	return;
    260     }
    261     reset_more_printf();
    262     more_printf("IPMI\n");
    263     more_printf(" Interface Type     : %s\n",
    264 		hardware->dmi.ipmi.interface_type);
    265     more_printf(" Specification Ver. : %u.%u\n",
    266 		hardware->dmi.ipmi.major_specification_version,
    267 		hardware->dmi.ipmi.minor_specification_version);
    268     more_printf(" I2C Slave Address  : 0x%02x\n",
    269 		hardware->dmi.ipmi.I2C_slave_address);
    270     more_printf(" Nv Storage Address : %u\n", hardware->dmi.ipmi.nv_address);
    271     uint32_t high = hardware->dmi.ipmi.base_address >> 32;
    272     uint32_t low = hardware->dmi.ipmi.base_address & 0xFFFF;
    273     more_printf(" Base Address       : %08X%08X\n", high, (low & ~1));
    274     more_printf(" IRQ                : %d\n", hardware->dmi.ipmi.irq);
    275 }
    276 
    277 static void show_dmi_battery(int argc __unused, char **argv __unused,
    278 			     struct s_hardware *hardware)
    279 {
    280     if (hardware->dmi.battery.filled == false) {
    281 	more_printf("battery information not found on your system, see "
    282 		    "`show list' to see which module is available.\n");
    283 	return;
    284     }
    285     reset_more_printf();
    286     more_printf("Battery \n");
    287     more_printf(" Vendor             : %s\n",
    288 		hardware->dmi.battery.manufacturer);
    289     more_printf(" Manufacture Date   : %s\n",
    290 		hardware->dmi.battery.manufacture_date);
    291     more_printf(" Serial             : %s\n", hardware->dmi.battery.serial);
    292     more_printf(" Name               : %s\n", hardware->dmi.battery.name);
    293     more_printf(" Chemistry          : %s\n", hardware->dmi.battery.chemistry);
    294     more_printf(" Design Capacity    : %s\n",
    295 		hardware->dmi.battery.design_capacity);
    296     more_printf(" Design Voltage     : %s\n",
    297 		hardware->dmi.battery.design_voltage);
    298     more_printf(" SBDS               : %s\n", hardware->dmi.battery.sbds);
    299     more_printf(" SBDS Manuf. Date   : %s\n",
    300 		hardware->dmi.battery.sbds_manufacture_date);
    301     more_printf(" SBDS Chemistry     : %s\n",
    302 		hardware->dmi.battery.sbds_chemistry);
    303     more_printf(" Maximum Error      : %s\n",
    304 		hardware->dmi.battery.maximum_error);
    305     more_printf(" OEM Info           : %s\n", hardware->dmi.battery.oem_info);
    306 }
    307 
    308 static void show_dmi_cpu(int argc __unused, char **argv __unused,
    309 			 struct s_hardware *hardware)
    310 {
    311     if (hardware->dmi.processor.filled == false) {
    312 	more_printf("processor information not found on your system, see "
    313 		    "`show list' to see which module is available.\n");
    314 	return;
    315     }
    316     reset_more_printf();
    317     more_printf("CPU\n");
    318     more_printf(" Socket Designation : %s\n",
    319 		hardware->dmi.processor.socket_designation);
    320     more_printf(" Type               : %s\n", hardware->dmi.processor.type);
    321     more_printf(" Family             : %s\n", hardware->dmi.processor.family);
    322     more_printf(" Manufacturer       : %s\n",
    323 		hardware->dmi.processor.manufacturer);
    324     more_printf(" Version            : %s\n", hardware->dmi.processor.version);
    325     more_printf(" External Clock     : %u\n",
    326 		hardware->dmi.processor.external_clock);
    327     more_printf(" Max Speed          : %u\n",
    328 		hardware->dmi.processor.max_speed);
    329     more_printf(" Current Speed      : %u\n",
    330 		hardware->dmi.processor.current_speed);
    331     more_printf(" Cpu Type           : %u\n",
    332 		hardware->dmi.processor.signature.type);
    333     more_printf(" Cpu Family         : %u\n",
    334 		hardware->dmi.processor.signature.family);
    335     more_printf(" Cpu Model          : %u\n",
    336 		hardware->dmi.processor.signature.model);
    337     more_printf(" Cpu Stepping       : %u\n",
    338 		hardware->dmi.processor.signature.stepping);
    339     more_printf(" Cpu Minor Stepping : %u\n",
    340 		hardware->dmi.processor.signature.minor_stepping);
    341     more_printf("Voltage             : %d.%02d\n",
    342                 hardware->dmi.processor.voltage_mv / 1000,
    343                 hardware->dmi.processor.voltage_mv -
    344                 ((hardware->dmi.processor.voltage_mv / 1000) * 1000));
    345     more_printf(" Status             : %s\n", hardware->dmi.processor.status);
    346     more_printf(" Upgrade            : %s\n", hardware->dmi.processor.upgrade);
    347     more_printf(" Cache L1 Handle    : %s\n", hardware->dmi.processor.cache1);
    348     more_printf(" Cache L2 Handle    : %s\n", hardware->dmi.processor.cache2);
    349     more_printf(" Cache L3 Handle    : %s\n", hardware->dmi.processor.cache3);
    350     more_printf(" Serial             : %s\n", hardware->dmi.processor.serial);
    351     more_printf(" Part Number        : %s\n",
    352 		hardware->dmi.processor.part_number);
    353     if (hardware->dmi.processor.core_count != 0)
    354         more_printf(" Cores Count        : %d\n", hardware->dmi.processor.core_count);
    355     if (hardware->dmi.processor.core_enabled != 0)
    356         more_printf(" Cores Enabled      : %d\n", hardware->dmi.processor.core_enabled);
    357     if (hardware->dmi.processor.thread_count != 0)
    358         more_printf(" Threads Count      : %d\n", hardware->dmi.processor.thread_count);
    359 
    360     more_printf(" ID                 : %s\n", hardware->dmi.processor.id);
    361     for (int i = 0; i < PROCESSOR_FLAGS_ELEMENTS; i++) {
    362 	if (((bool *) (&hardware->dmi.processor.cpu_flags))[i] == true) {
    363 	    more_printf(" %s\n", cpu_flags_strings[i]);
    364 	}
    365     }
    366 }
    367 
    368 void show_dmi_memory_bank(int argc, char **argv, struct s_hardware *hardware)
    369 {
    370     int bank = -1;
    371 
    372     /* Sanitize arguments */
    373     if (argc > 0)
    374 	bank = strtol(argv[0], (char **)NULL, 10);
    375 
    376     if (errno == ERANGE || bank < 0) {
    377 	more_printf("This bank number is incorrect\n");
    378 	return;
    379     }
    380 
    381     if ((bank >= hardware->dmi.memory_count) || (bank < 0)) {
    382 	more_printf("Bank %d number doesn't exist\n", bank);
    383 	return;
    384     }
    385     if (hardware->dmi.memory[bank].filled == false) {
    386 	more_printf("Bank %d doesn't contain any information\n", bank);
    387 	return;
    388     }
    389 
    390     reset_more_printf();
    391     more_printf("Memory Bank %d\n", bank);
    392     more_printf(" Form Factor  : %s\n", hardware->dmi.memory[bank].form_factor);
    393     more_printf(" Type         : %s\n", hardware->dmi.memory[bank].type);
    394     more_printf(" Type Detail  : %s\n", hardware->dmi.memory[bank].type_detail);
    395     more_printf(" Speed        : %s\n", hardware->dmi.memory[bank].speed);
    396     more_printf(" Size         : %s\n", hardware->dmi.memory[bank].size);
    397     more_printf(" Device Set   : %s\n", hardware->dmi.memory[bank].device_set);
    398     more_printf(" Device Loc.  : %s\n",
    399 		hardware->dmi.memory[bank].device_locator);
    400     more_printf(" Bank Locator : %s\n",
    401 		hardware->dmi.memory[bank].bank_locator);
    402     more_printf(" Total Width  : %s\n", hardware->dmi.memory[bank].total_width);
    403     more_printf(" Data Width   : %s\n", hardware->dmi.memory[bank].data_width);
    404     more_printf(" Error        : %s\n", hardware->dmi.memory[bank].error);
    405     more_printf(" Vendor       : %s\n",
    406 		hardware->dmi.memory[bank].manufacturer);
    407     more_printf(" Serial       : %s\n", hardware->dmi.memory[bank].serial);
    408     more_printf(" Asset Tag    : %s\n", hardware->dmi.memory[bank].asset_tag);
    409     more_printf(" Part Number  : %s\n", hardware->dmi.memory[bank].part_number);
    410 }
    411 
    412 static void show_dmi_cache(int argc, char **argv, struct s_hardware *hardware)
    413 {
    414     if (!hardware->dmi.cache_count) {
    415 	more_printf("cache information not found on your system, see "
    416 		    "`show list' to see which module is available.\n");
    417 	return;
    418     }
    419 
    420     int cache = strtol(argv[0], NULL, 10);
    421 
    422     if (argc != 1 || cache > hardware->dmi.cache_count) {
    423 	more_printf("show cache [0-%d]\n", hardware->dmi.cache_count - 1);
    424 	return;
    425     }
    426 
    427     reset_more_printf();
    428 
    429     more_printf("Cache Information #%d\n", cache);
    430     more_printf("  Socket Designation    : %s\n",
    431 		hardware->dmi.cache[cache].socket_designation);
    432     more_printf("  Configuration         : %s\n",
    433 		hardware->dmi.cache[cache].configuration);
    434     more_printf("  Operational Mode      : %s\n",
    435 		hardware->dmi.cache[cache].mode);
    436     more_printf("  Location              : %s\n",
    437 		hardware->dmi.cache[cache].location);
    438     more_printf("  Installed Size        : %u KB",
    439 		hardware->dmi.cache[cache].installed_size);
    440     more_printf("\n");
    441     more_printf("  Maximum Size          : %u KB",
    442 		hardware->dmi.cache[cache].max_size);
    443     more_printf("\n");
    444     more_printf("  Supported SRAM Types  : %s",
    445 		hardware->dmi.cache[cache].supported_sram_types);
    446     more_printf("\n");
    447     more_printf("  Installed SRAM Type   : %s",
    448 		hardware->dmi.cache[cache].installed_sram_types);
    449     more_printf("\n");
    450     more_printf("  Speed                 : %u ns",
    451 		hardware->dmi.cache[cache].speed);
    452     more_printf("\n");
    453     more_printf("  Error Correction Type : %s\n",
    454 		hardware->dmi.cache[cache].error_correction_type);
    455     more_printf("  System Type           : %s\n",
    456 		hardware->dmi.cache[cache].system_type);
    457     more_printf("  Associativity         : %s\n",
    458 		hardware->dmi.cache[cache].associativity);
    459 }
    460 
    461 void show_dmi_memory_module(int argc, char **argv, struct s_hardware *hardware)
    462 {
    463     int module = -1;
    464 
    465     /* Sanitize arguments */
    466     if (argc > 0)
    467 	module = strtol(argv[0], (char **)NULL, 10);
    468 
    469     if (errno == ERANGE || module < 0) {
    470 	more_printf("This module number is incorrect\n");
    471 	return;
    472     }
    473 
    474     if ((module >= hardware->dmi.memory_module_count) || (module < 0)) {
    475 	more_printf("Module number %d doesn't exist\n", module);
    476 	return;
    477     }
    478 
    479     if (hardware->dmi.memory_module[module].filled == false) {
    480 	more_printf("Module %d doesn't contain any information\n", module);
    481 	return;
    482     }
    483 
    484     reset_more_printf();
    485     more_printf("Memory Module %d\n", module);
    486     more_printf(" Socket Designation : %s\n",
    487 		hardware->dmi.memory_module[module].socket_designation);
    488     more_printf(" Bank Connections   : %s\n",
    489 		hardware->dmi.memory_module[module].bank_connections);
    490     more_printf(" Current Speed      : %s\n",
    491 		hardware->dmi.memory_module[module].speed);
    492     more_printf(" Type               : %s\n",
    493 		hardware->dmi.memory_module[module].type);
    494     more_printf(" Installed Size     : %s\n",
    495 		hardware->dmi.memory_module[module].installed_size);
    496     more_printf(" Enabled Size       : %s\n",
    497 		hardware->dmi.memory_module[module].enabled_size);
    498     more_printf(" Error Status       : %s\n",
    499 		hardware->dmi.memory_module[module].error_status);
    500 }
    501 
    502 void main_show_dmi(int argc __unused, char **argv __unused,
    503 		   struct s_hardware *hardware)
    504 {
    505 
    506     if (hardware->is_dmi_valid == false) {
    507 	more_printf("No valid DMI table found, exiting.\n");
    508 	return;
    509     }
    510     reset_more_printf();
    511     more_printf("DMI Table version %u.%u found\n",
    512 		hardware->dmi.dmitable.major_version,
    513 		hardware->dmi.dmitable.minor_version);
    514 
    515     show_dmi_modules(0, NULL, hardware);
    516 }
    517 
    518 void show_dmi_memory_modules(int argc __unused, char **argv __unused,
    519 			     struct s_hardware *hardware)
    520 {
    521     /* Do we have so display unpopulated banks ? */
    522     int show_free_banks = 1;
    523 
    524     more_printf("Memory Size   : %lu MB (%lu KB)\n",
    525 		(hardware->detected_memory_size + (1 << 9)) >> 10,
    526 		hardware->detected_memory_size);
    527 
    528     if ((hardware->dmi.memory_count <= 0)
    529 	&& (hardware->dmi.memory_module_count <= 0)) {
    530 	more_printf("No memory bank found\n");
    531 	return;
    532     }
    533 
    534     /* Sanitize arguments */
    535     if (argc > 0) {
    536 	/* When we display a summary, there is no need to show the unpopulated banks
    537 	 * The first argv is set to define this behavior
    538 	 */
    539 	show_free_banks = strtol(argv[0], NULL, 10);
    540 	if (errno == ERANGE || show_free_banks < 0 || show_free_banks > 1)
    541 	    goto usage;
    542     }
    543 
    544     reset_more_printf();
    545     /* If type 17 is available */
    546     if (hardware->dmi.memory_count > 0) {
    547 	char bank_number[255];
    548 	more_printf("Memory Banks\n");
    549 	for (int i = 0; i < hardware->dmi.memory_count; i++) {
    550 	    if (hardware->dmi.memory[i].filled == true) {
    551 		memset(bank_number, 0, sizeof(bank_number));
    552 		snprintf(bank_number, sizeof(bank_number), "%d ", i);
    553 		if (show_free_banks == false) {
    554 		    if (strncmp(hardware->dmi.memory[i].size, "Free", 4))
    555 			more_printf(" bank %02d      : %s %s@%s\n",
    556 				    i, hardware->dmi.memory[i].size,
    557 				    hardware->dmi.memory[i].type,
    558 				    hardware->dmi.memory[i].speed);
    559 		} else {
    560 		    more_printf(" bank %02d      : %s %s@%s\n", i,
    561 				hardware->dmi.memory[i].size,
    562 				hardware->dmi.memory[i].type,
    563 				hardware->dmi.memory[i].speed);
    564 		}
    565 	    }
    566 	}
    567     } else if (hardware->dmi.memory_module_count > 0) {
    568 	/* Let's use type 6 as a fallback of type 17 */
    569 	more_printf("Memory Modules\n");
    570 	for (int i = 0; i < hardware->dmi.memory_module_count; i++) {
    571 	    if (hardware->dmi.memory_module[i].filled == true) {
    572 		more_printf(" module %02d    : %s %s@%s\n", i,
    573 			    hardware->dmi.memory_module[i].enabled_size,
    574 			    hardware->dmi.memory_module[i].type,
    575 			    hardware->dmi.memory_module[i].speed);
    576 	    }
    577 	}
    578     }
    579 
    580     return;
    581     //printf("Type 'show bank<bank_number>' for more details.\n");
    582 
    583 usage:
    584     more_printf("show memory <clear screen? <show free banks?>>\n");
    585     return;
    586 }
    587 
    588 void show_dmi_oem_strings(int argc __unused, char **argv __unused,
    589 			  struct s_hardware *hardware)
    590 {
    591     reset_more_printf();
    592 
    593     if (strlen(hardware->dmi.oem_strings))
    594 	more_printf("OEM Strings\n%s", hardware->dmi.oem_strings);
    595 }
    596 
    597 void show_dmi_hardware_security(int argc __unused, char **argv __unused,
    598 				struct s_hardware *hardware)
    599 {
    600     reset_more_printf();
    601 
    602     if (!hardware->dmi.hardware_security.filled)
    603 	return;
    604 
    605     more_printf("Hardware Security\n");
    606     more_printf("  Power-On Password Status      : %s\n",
    607 		hardware->dmi.hardware_security.power_on_passwd_status);
    608     more_printf("  Keyboard Password Status      : %s\n",
    609 		hardware->dmi.hardware_security.keyboard_passwd_status);
    610     more_printf("  Administrator Password Status : %s\n",
    611 		hardware->dmi.hardware_security.administrator_passwd_status);
    612     more_printf("  Front Panel Reset Status      : %s\n",
    613 		hardware->dmi.hardware_security.front_panel_reset_status);
    614 }
    615 
    616 struct cli_callback_descr list_dmi_show_modules[] = {
    617     {
    618      .name = CLI_DMI_BASE_BOARD,
    619      .exec = show_dmi_base_board,
    620      .nomodule = false,
    621      },
    622     {
    623      .name = CLI_DMI_BIOS,
    624      .exec = show_dmi_bios,
    625      .nomodule = false,
    626      },
    627     {
    628      .name = CLI_DMI_BATTERY,
    629      .exec = show_dmi_battery,
    630      .nomodule = false,
    631      },
    632     {
    633      .name = CLI_DMI_CHASSIS,
    634      .exec = show_dmi_chassis,
    635      .nomodule = false,
    636      },
    637     {
    638      .name = CLI_DMI_MEMORY,
    639      .exec = show_dmi_memory_modules,
    640      .nomodule = false,
    641      },
    642     {
    643      .name = CLI_DMI_MEMORY_BANK,
    644      .exec = show_dmi_memory_bank,
    645      .nomodule = false,
    646      },
    647     {
    648      .name = "module",
    649      .exec = show_dmi_memory_module,
    650      .nomodule = false,
    651      },
    652     {
    653      .name = CLI_DMI_PROCESSOR,
    654      .exec = show_dmi_cpu,
    655      .nomodule = false,
    656      },
    657     {
    658      .name = CLI_DMI_SYSTEM,
    659      .exec = show_dmi_system,
    660      .nomodule = false,
    661      },
    662     {
    663      .name = CLI_DMI_OEM,
    664      .exec = show_dmi_oem_strings,
    665      .nomodule = false,
    666      },
    667     {
    668      .name = CLI_DMI_SECURITY,
    669      .exec = show_dmi_hardware_security,
    670      .nomodule = false,
    671      },
    672     {
    673      .name = CLI_DMI_IPMI,
    674      .exec = show_dmi_ipmi,
    675      .nomodule = false,
    676      },
    677     {
    678      .name = CLI_DMI_CACHE,
    679      .exec = show_dmi_cache,
    680      .nomodule = false,
    681      },
    682     {
    683      .name = CLI_DMI_LIST,
    684      .exec = show_dmi_modules,
    685      .nomodule = false,
    686      },
    687     {
    688      .name = NULL,
    689      .exec = NULL,
    690      .nomodule = false,
    691      },
    692 };
    693 
    694 struct cli_module_descr dmi_show_modules = {
    695     .modules = list_dmi_show_modules,
    696     .default_callback = main_show_dmi,
    697 };
    698 
    699 struct cli_mode_descr dmi_mode = {
    700     .mode = DMI_MODE,
    701     .name = CLI_DMI,
    702     .default_modules = NULL,
    703     .show_modules = &dmi_show_modules,
    704     .set_modules = NULL,
    705 };
    706