From 5e8857158cba3b375ca5f2a64b1bf7c06a4571f2 Mon Sep 17 00:00:00 2001 From: Regia König Date: Mon, 7 Jun 2021 16:53:44 +0200 Subject: Move dmi.c into /bios and /efi dir. The whole open_dmit() function must be rewritten. --- efi_memtest/memtest86+/bios/dmi.c | 485 ++++++++++++++++++++++++++++++++++++ efi_memtest/memtest86+/controller.c | 42 +++- efi_memtest/memtest86+/dmi.c | 443 -------------------------------- efi_memtest/memtest86+/efi/dmi.c | 485 ++++++++++++++++++++++++++++++++++++ efi_memtest/memtest86+/efi/init.c | 26 +- 5 files changed, 1016 insertions(+), 465 deletions(-) create mode 100644 efi_memtest/memtest86+/bios/dmi.c delete mode 100644 efi_memtest/memtest86+/dmi.c create mode 100644 efi_memtest/memtest86+/efi/dmi.c diff --git a/efi_memtest/memtest86+/bios/dmi.c b/efi_memtest/memtest86+/bios/dmi.c new file mode 100644 index 0000000..688d067 --- /dev/null +++ b/efi_memtest/memtest86+/bios/dmi.c @@ -0,0 +1,485 @@ +/* dmi.c using the DMI from SMBIOS to read information about the hardware's + * memory devices capabilities and where they are mapped into the address space + * + * Copyright (c) Joachim Deguara, AMD 2006 + * + * Release under the GPL version 2 + * ---------------------------------------------------- + * Memtest86+ V4.00 - Added compliance with SMBIOS Spec V2.6.1 + */ + +#include "Uefi.h" +#include "Library/UefiLib.h" + +extern EFI_SYSTEM_TABLE *gST; + +#include "test.h" +#include "stdint.h" + +#include "logger.h" + +#define round_up(x,y) (((x) + (y) - 1) & ~((y)-1)) +#define round_down(x,y) ((x) & ~((y)-1)) + +extern short logflag; +extern short log_mem_ctrl; + +struct dmi_eps { + uint8_t anchor[4]; + int8_t checksum; + uint8_t length; + uint8_t majorversion; + uint8_t minorversion; + uint16_t maxstructsize; + uint8_t revision; + uint8_t pad[5]; + uint8_t intanchor[5]; + int8_t intchecksum; + uint16_t tablelength; + uint32_t tableaddress; + uint16_t numstructs; + uint8_t SMBIOSrev; +} __attribute__((packed)); + +struct tstruct_header{ + uint8_t type; + uint8_t length; + uint16_t handle; +} __attribute__((packed)); + +struct system_map { + struct tstruct_header header; + uint8_t manufacturer; + uint8_t productname; + uint8_t version; + uint8_t serialnumber; + uint8_t uuidbytes[16]; + uint8_t wut; +} __attribute__((packed)); + +struct cpu_map { + struct tstruct_header header; + uint8_t cpu_socket; + uint8_t cpu_type; + uint8_t cpu_family; + uint8_t cpu_manufacturer; + uint32_t cpu_id; + uint8_t cpu_version; + uint8_t cpu_voltage; + uint16_t ext_clock; + uint16_t max_speed; + uint16_t cur_speed; + uint8_t cpu_status; + uint8_t cpu_upgrade; + uint16_t l1_handle; + uint16_t l2_handle; + uint16_t l3_handle; + uint8_t cpu_serial; + uint8_t cpu_asset_tag; + uint8_t cpu_part_number; + uint8_t core_count; + uint8_t core_enabled; + uint8_t thread_count; + uint16_t cpu_specs; + uint16_t cpu_family_2; +} __attribute__((packed)); + +struct mem_dev { + struct tstruct_header header; + uint16_t pma_handle; + uint16_t err_handle; + uint16_t tot_width; + uint16_t dat_width; + uint16_t size; + uint8_t form; + uint8_t set; + uint8_t dev_locator; + uint8_t bank_locator; + uint8_t type; + uint16_t typedetail; + uint16_t speed; + uint8_t manufacturer; + uint8_t serialnum; + uint8_t asset; + uint8_t partnum; + uint8_t attributes; + uint8_t ext_size; + uint8_t conf_ram_speed; + uint8_t min_voltage; + uint8_t max_votage; + uint8_t conf_voltage; +} __attribute__((packed)); + +struct md_map{ + struct tstruct_header header; + uint32_t start; + uint32_t end; + uint16_t md_handle; + uint16_t mama_handle; + uint8_t row_pos; + uint8_t interl_pos; + uint8_t interl_depth; +} __attribute__((packed)); + +struct pma{ + struct tstruct_header header; + uint8_t location; + uint8_t use; + uint8_t ecc; + uint32_t capacity; + uint16_t errhandle; + uint16_t numdevs; +} __attribute__((packed)); + +static char *form_factors[] = { + "?", + "Other", "Unknown", "SIMM", "SIP", "Chip", "DIP", "ZIP", + "Proprietary Card", "DIMM", "TSOP", "Row of chips", "RIMM", + "SODIMM", "SRIMM", "FB-DIMM", "Die" +}; + + +static char *memory_types[] = { + "?", + "Other", "????", "DRAM", "EDRAM", "VRAM", "SRAM", "RAM", + "ROM", "FLASH", "EEPROM", "FEPROM", "EPROM", "CDRAM", "3DRAM", + "SDRAM", "SGRAM", "RDRAM", "DDR", "DDR2", "DDR2 FB", "RSVD", + "RSVD","RSVD","DDR3","FBD2", "DDR4", "LPDDR", "LPDDR2", "LPDDR3", + "LPDDR4", "LNVD", "HBM", "HBM2", "DDR5", "LPDDR5" +}; + + +struct mem_dev * mem_devs[MAX_DMI_MEMDEVS]; +int mem_devs_count=0; +struct md_map * md_maps[MAX_DMI_MEMDEVS]; +struct system_map * dmi_system_info; +struct cpu_map * dmi_cpu_info; +int md_maps_count=0; +int dmi_err_cnts[MAX_DMI_MEMDEVS]; +short dmi_initialized=0; + +char * get_tstruct_string(struct tstruct_header *header, int n){ + if(n<1) + return 0; + char * a = (char *)header + header->length; + n--; + do{ + if (!*a) + n--; + if (!n && *a) + return a; + a++; + }while (!(*a==0 && *(a-1)==0)); + return 0; +} + +int open_dmi(void) { + +} + +/*int open_dmi(void){ + char *dmi, *dmi_search_start, *dmi_start; + int found=0; + struct dmi_eps *eps; + char *table_start; + int tstruct_count=0; + dmi_search_start = (char *)DMI_SEARCH_START; + + //find anchor + for(dmi = dmi_search_start; dmi < dmi_search_start + 0xf0000; dmi +=16){ + if( *dmi == '_' && + *(dmi+1) == 'S' && + *(dmi+2) == 'M' && + *(dmi+3) == '_'){ + found =1; + break; + } + } + if (!found) { + print_log("open_dmi(): dmi not found", 25); + return -1; + } + dmi_start=dmi; + eps=(struct dmi_eps *)dmi; + + //check checksum + int8_t checksum=0; + for (; dmi < dmi_start + eps->length; dmi++) + checksum += *dmi; + if (checksum){ + return -1; + } + + //we need at least revision 2.1 of SMBIOS + if ( eps->majorversion < 2 && + eps->minorversion < 1){ + return -1; + } + + table_start=(char *)(uintptr_t)eps->tableaddress; + dmi=table_start; +//look at all structs + while(dmi < table_start + eps->tablelength){ + struct tstruct_header *header = (struct tstruct_header *)dmi; + + if (header->type == 17) + mem_devs[mem_devs_count++] = (struct mem_dev *)dmi; + + // Mem Dev Map + if (header->type == 20) + md_maps[md_maps_count++] = (struct md_map *)dmi; + + // MB_SPEC + if (header->type == 2) + { + dmi_system_info = (struct system_map *)dmi; + } + + // CPU_SPEC + if (header->type == 4) + { + dmi_cpu_info = (struct cpu_map *)dmi; + } + + dmi+=header->length; + + while( ! (*dmi == 0 && *(dmi+1) == 0 ) ) + dmi++; + dmi+=2; + + if (++tstruct_count > eps->numstructs) + return -1; + } + return 0; +}*/ + +void init_dmi(void){ + + if (logflag) print_log("init_dmi() started", 18); + + int i; + for(i=0; i < MAX_DMI_MEMDEVS; i++) + dmi_err_cnts[i]=0; + open_dmi(); + dmi_initialized=1; +} + +void print_dmi_startup_info(void) +{ + + if (logflag) print_log("print_dmi_startup_info() started", 32); + + char *string1; + char *string2; + char *string3; + int dmicol = 78; + int slength; + int sl1, sl2, sl3; + + if(!dmi_initialized) { init_dmi(); } + + string1 = get_tstruct_string(&dmi_system_info->header,dmi_system_info->manufacturer); + sl1 = mt86_strlen(string1); + string2 = get_tstruct_string(&dmi_system_info->header,dmi_system_info->productname); + sl2 = mt86_strlen(string2); + string3 = get_tstruct_string(&dmi_cpu_info->header,dmi_cpu_info->cpu_socket); + sl3 = mt86_strlen(string3); + + if (logflag && log_mem_ctrl) { + char log[61] = "print_dmi_startup_info(): manufacturer = "; + int length = 41; + string_to_charr(string1, log, &length); + print_log(log, length); + } + + if (logflag && log_mem_ctrl) { + char log[16] = "sl1 = "; + int length = 6; + int_to_charr(sl1, log, &length); + print_log(log, length); + } + + if (logflag && log_mem_ctrl) { + char log[60] = "print_dmi_startup_info(): productname = "; + int length = 40; + string_to_charr(string2, log, &length); + print_log(log, length); + } + + if (logflag && log_mem_ctrl) { + char log[59] = "print_dmi_startup_info(): cpu_socket = "; + int length = 39; + string_to_charr(string3, log, &length); + print_log(log, length); + } + + slength = sl1 + sl2; + if(sl3 > 2) { slength += sl3 + 4; } else { slength++; } + + if(sl1 && sl2) + { + //dmicol -= slength; // right align + dmicol = 39 - slength/2; // center align + cprint(LINE_DMI, dmicol, string1); + dmicol += sl1 + 1; + cprint(LINE_DMI, dmicol, string2); + dmicol += sl2 + 1; + + if(sl3 > 2){ + cprint(LINE_DMI, dmicol, "("); + dmicol++; + cprint(LINE_DMI, dmicol, string3); + dmicol += sl3; + cprint(LINE_DMI, dmicol, ")"); + } + } +} + +void print_dmi_info(void){ + int i,j,page; + char * string=0; + + if(!dmi_initialized) + init_dmi(); + + if (mem_devs_count == 0){ + cprint(POP2_Y+1, POP2_X+2, "No valid DMI Memory Devices info found"); + while (get_key() == 0); + return; + } + + for(page=1; page <= 1 + (mem_devs_count-1)/8; page++){ + pop2clear(); + cprint(POP2_Y+1, POP2_X+2, "DMI Memory Device Info (page "); + itoa(string,page); + cprint(POP2_Y+1, POP2_X+32, string); + cprint(POP2_Y+1, POP2_X+33, "/"); + itoa(string,1 + (mem_devs_count-1)/8); + cprint(POP2_Y+1, POP2_X+34, string); + cprint(POP2_Y+1, POP2_X+35, ")"); + + cprint(POP2_Y+3, POP2_X+4, "Location Size(MB) Speed(MHz) Type Form"); + cprint(POP2_Y+4, POP2_X+4, "--------------------------------------------------------------"); + + for(i=8*(page-1); iheader), mem_devs[i]->dev_locator)); + + if (mem_devs[i]->size == 0){ + cprint(yof, POP2_X+4+18, "Empty"); + }else if (mem_devs[i]->size == 0xFFFF){ + cprint(yof, POP2_X+4+18, "Unknown"); + }else if (mem_devs[i]->size == 0x7FFF){ + // SMBIOS 2.7+ + size_in_mb = mem_devs[i]->ext_size; + itoa(string, size_in_mb); + cprint(yof, POP2_X+4+18, string); + }else{ + size_in_mb = 0xFFFF & mem_devs[i]->size; + if (mem_devs[i]->size & 0x8000) + size_in_mb <<= 10; + itoa(string, size_in_mb); + cprint(yof, POP2_X+4+18, string); + } + + //this is the only field that needs to be SMBIOS 2.3+ + if ( mem_devs[i]->speed && + mem_devs[i]->header.length > 21){ + itoa(string, mem_devs[i]->speed); + cprint(yof, POP2_X+4+27, string); + }else{ + cprint(yof, POP2_X+4+27, "Unknown"); + } + cprint(yof, POP2_X+4+37, memory_types[mem_devs[i]->type]); + cprint(yof, POP2_X+4+44, form_factors[mem_devs[i]->form]); + + //print mappings + int mapped=0,of=0; + cprint(yof+1, POP2_X+6,"mapped to: "); + for(j=0; jheader.handle != md_maps[j]->md_handle) + continue; + if (mapped++){ + cprint(yof+1, POP2_X+17+of, ","); + of++; + } + hprint3(yof+1, POP2_X+17+of, md_maps[j]->start>>22, 4); + of += 4; + hprint3(yof+1, POP2_X+17+of, md_maps[j]->start<<10, 8); + of += 8; + cprint(yof+1, POP2_X+17+of, "-"); + of++; + hprint3(yof+1, POP2_X+17+of, md_maps[j]->end>>22, 4); + of += 4; + hprint3(yof+1, POP2_X+17+of, ((md_maps[j]->end+1)<<10) - 1, 8); + of += 8; + if(md_maps[j]->end == 0) { hprint3(yof+1, POP2_X+17+of-8,0,8); } + } + if (!mapped) + { + cprint(yof+1, POP2_X+17, "No mapping (Interleaved Device)"); + } + + } + + wait_keyup(); + while (get_key() == 0); + } +} + +//return 1 if the list of bad memory devices changes, 0 otherwise, -1 if no mapped +int add_dmi_err(ulong adr){ + int i,j,found=-1; + + if(!dmi_initialized) + init_dmi(); + + for(i=0; i < md_maps_count; i++){ + if ( adr < (md_maps[i]->start<<10) || + adr > (md_maps[i]->end<<10) ) + continue; + + //matching map found, now check find corresponding dev + for(j=0; j < mem_devs_count; j++){ + if (mem_devs[j]->header.handle != md_maps[i]->md_handle) + continue; + if (dmi_err_cnts[j]){ + found=0; + }else{ + found = dmi_err_cnts[j] = 1; + } + } + } + + return found; +} + +void print_dmi_err(void){ + int i,count,of; + char *string; + + scroll(); + + cprint(vv->msg_line, 0,"Bad Memory Devices: "); + of=20; + for ( i=count=0; i < MAX_DMI_MEMDEVS; i++){ + if (!dmi_err_cnts[i]) + continue; + struct mem_dev *md = mem_devs[i]; + if(count++){ + cprint(vv->msg_line, of, ", "); + of+=2; + } + string=get_tstruct_string((struct tstruct_header *)md,md->dev_locator); + if (mt86_strlen(string) + of > 80){ + scroll(); + of=7; + } + cprint(vv->msg_line, of, string); + of += mt86_strlen(string); + } +} diff --git a/efi_memtest/memtest86+/controller.c b/efi_memtest/memtest86+/controller.c index 5437956..c81c357 100644 --- a/efi_memtest/memtest86+/controller.c +++ b/efi_memtest/memtest86+/controller.c @@ -123,7 +123,7 @@ void coretemp(void) void print_cpu_line(float dram_freq, float fsb_freq, int ram_type) { - if (1) print_log("print_cpu_line", 14); + if (logflag) print_log("print_cpu_line() started.", 25); int cur_col = COL_SPEC; @@ -134,9 +134,9 @@ void print_cpu_line(float dram_freq, float fsb_freq, int ram_type) cprint(LINE_CPU, cur_col, "MHz ("); cur_col += 5; - if (1) { - char log[21] = "ram_type = "; - int length = 11; + if (logflag && log_mem_ctrl) { + char log[39] = "print_cpu_line(): ram_type = "; + int length = 29; int_to_charr(ram_type, log, &length); print_log(log, length); } @@ -156,9 +156,14 @@ void print_cpu_line(float dram_freq, float fsb_freq, int ram_type) cprint(LINE_CPU, cur_col, "DDR3-"); cur_col += 5; break; - } + } - while(1); + if (logflag && log_mem_ctrl) { + char log[50] = "print_cpu_line(): dram_freq = "; + int length = 30; + int_to_charr(dram_freq, log, &length); + print_log(log, length); + } if(dram_freq < 500) { @@ -171,6 +176,13 @@ void print_cpu_line(float dram_freq, float fsb_freq, int ram_type) cprint(LINE_CPU, cur_col, ")"); cur_col++; + if (logflag && log_mem_ctrl) { + char log[49] = "print_cpu_line(): fsb_freq = "; + int length = 29; + int_to_charr(fsb_freq, log, &length); + print_log(log, length); + } + if(fsb_freq > 10) { cprint(LINE_CPU, cur_col, " - BCLK: "); @@ -252,7 +264,7 @@ void print_ram_line(float cas, int rcd, int rp, int ras, int chan) static void poll_fsb_nothing(void) { - print_log("poll_fsb_nothing", 16); + if (logflag) print_log("poll_fsb_nothing", 16); char *name; @@ -290,6 +302,9 @@ static void poll_nothing(void) static void setup_wmr(void) { + + if (logflag) print_log("setup_wmr() started.", 20); + ulong dev0; // Activate MMR I/O @@ -4181,7 +4196,7 @@ static void print_memory_controller(void) // TODO REMOVE /* Print advanced caracteristics */ - col2 = 0; +/* col2 = 0; if (logflag && log_mem_ctrl) { char log[23] = "ctrl.index = "; @@ -4196,7 +4211,7 @@ static void print_memory_controller(void) poll_fsb_ivb(); //controllers[127].poll_fsb(); - print_log("print_controller(): 2nd", 23); + print_log("print_controller(): 2nd", 23);*/ // TODO REMOVE UNTIL HERE @@ -4384,7 +4399,7 @@ void find_controller(void) print_log(log, length); } - // controllers[ctrl.index].setup_ecc(); + controllers[127].setup_ecc(); /* Don't enable ECC polling by default unless it has * been well tested. @@ -4392,6 +4407,13 @@ void find_controller(void) // TODO this function contains a variable 'COL_ECC' which is defined nowhere // set_ecc_polling(-1); print_memory_controller(); + + if (logflag && log_mem_ctrl) { + char log[40] = "find_controller(): imc_type = "; + int length = 30; + int_to_charr(imc_type, log, &length); + print_log(log, length); + } if(imc_type) { print_dmi_startup_info(); } diff --git a/efi_memtest/memtest86+/dmi.c b/efi_memtest/memtest86+/dmi.c deleted file mode 100644 index a450de1..0000000 --- a/efi_memtest/memtest86+/dmi.c +++ /dev/null @@ -1,443 +0,0 @@ -/* dmi.c using the DMI from SMBIOS to read information about the hardware's - * memory devices capabilities and where they are mapped into the address space - * - * Copyright (c) Joachim Deguara, AMD 2006 - * - * Release under the GPL version 2 - * ---------------------------------------------------- - * Memtest86+ V4.00 - Added compliance with SMBIOS Spec V2.6.1 - */ - - -#include "test.h" -#include "stdint.h" - -#include "logger.h" - -#define round_up(x,y) (((x) + (y) - 1) & ~((y)-1)) -#define round_down(x,y) ((x) & ~((y)-1)) - -struct dmi_eps { - uint8_t anchor[4]; - int8_t checksum; - uint8_t length; - uint8_t majorversion; - uint8_t minorversion; - uint16_t maxstructsize; - uint8_t revision; - uint8_t pad[5]; - uint8_t intanchor[5]; - int8_t intchecksum; - uint16_t tablelength; - uint32_t tableaddress; - uint16_t numstructs; - uint8_t SMBIOSrev; -} __attribute__((packed)); - -struct tstruct_header{ - uint8_t type; - uint8_t length; - uint16_t handle; -} __attribute__((packed)); - -struct system_map { - struct tstruct_header header; - uint8_t manufacturer; - uint8_t productname; - uint8_t version; - uint8_t serialnumber; - uint8_t uuidbytes[16]; - uint8_t wut; -} __attribute__((packed)); - -struct cpu_map { - struct tstruct_header header; - uint8_t cpu_socket; - uint8_t cpu_type; - uint8_t cpu_family; - uint8_t cpu_manufacturer; - uint32_t cpu_id; - uint8_t cpu_version; - uint8_t cpu_voltage; - uint16_t ext_clock; - uint16_t max_speed; - uint16_t cur_speed; - uint8_t cpu_status; - uint8_t cpu_upgrade; - uint16_t l1_handle; - uint16_t l2_handle; - uint16_t l3_handle; - uint8_t cpu_serial; - uint8_t cpu_asset_tag; - uint8_t cpu_part_number; - uint8_t core_count; - uint8_t core_enabled; - uint8_t thread_count; - uint16_t cpu_specs; - uint16_t cpu_family_2; -} __attribute__((packed)); - -struct mem_dev { - struct tstruct_header header; - uint16_t pma_handle; - uint16_t err_handle; - uint16_t tot_width; - uint16_t dat_width; - uint16_t size; - uint8_t form; - uint8_t set; - uint8_t dev_locator; - uint8_t bank_locator; - uint8_t type; - uint16_t typedetail; - uint16_t speed; - uint8_t manufacturer; - uint8_t serialnum; - uint8_t asset; - uint8_t partnum; - uint8_t attributes; - uint8_t ext_size; - uint8_t conf_ram_speed; - uint8_t min_voltage; - uint8_t max_votage; - uint8_t conf_voltage; -} __attribute__((packed)); - -struct md_map{ - struct tstruct_header header; - uint32_t start; - uint32_t end; - uint16_t md_handle; - uint16_t mama_handle; - uint8_t row_pos; - uint8_t interl_pos; - uint8_t interl_depth; -} __attribute__((packed)); - -struct pma{ - struct tstruct_header header; - uint8_t location; - uint8_t use; - uint8_t ecc; - uint32_t capacity; - uint16_t errhandle; - uint16_t numdevs; -} __attribute__((packed)); - -static char *form_factors[] = { - "?", - "Other", "Unknown", "SIMM", "SIP", "Chip", "DIP", "ZIP", - "Proprietary Card", "DIMM", "TSOP", "Row of chips", "RIMM", - "SODIMM", "SRIMM", "FB-DIMM", "Die" -}; - - -static char *memory_types[] = { - "?", - "Other", "????", "DRAM", "EDRAM", "VRAM", "SRAM", "RAM", - "ROM", "FLASH", "EEPROM", "FEPROM", "EPROM", "CDRAM", "3DRAM", - "SDRAM", "SGRAM", "RDRAM", "DDR", "DDR2", "DDR2 FB", "RSVD", - "RSVD","RSVD","DDR3","FBD2", "DDR4", "LPDDR", "LPDDR2", "LPDDR3", - "LPDDR4", "LNVD", "HBM", "HBM2", "DDR5", "LPDDR5" -}; - - -struct mem_dev * mem_devs[MAX_DMI_MEMDEVS]; -int mem_devs_count=0; -struct md_map * md_maps[MAX_DMI_MEMDEVS]; -struct system_map * dmi_system_info; -struct cpu_map * dmi_cpu_info; -int md_maps_count=0; -int dmi_err_cnts[MAX_DMI_MEMDEVS]; -short dmi_initialized=0; - -char * get_tstruct_string(struct tstruct_header *header, int n){ - if(n<1) - return 0; - char * a = (char *)header + header->length; - n--; - do{ - if (!*a) - n--; - if (!n && *a) - return a; - a++; - }while (!(*a==0 && *(a-1)==0)); - return 0; -} - - -int open_dmi(void){ - char *dmi, *dmi_search_start, *dmi_start; - int found=0; - struct dmi_eps *eps; - char *table_start; - int tstruct_count=0; - dmi_search_start = (char *)DMI_SEARCH_START; - - //find anchor - for(dmi = dmi_search_start; dmi < dmi_search_start + 0xf0000; dmi +=16){ - if( *dmi == '_' && - *(dmi+1) == 'S' && - *(dmi+2) == 'M' && - *(dmi+3) == '_'){ - found =1; - break; - } - } - if (!found) { - return -1; - } - dmi_start=dmi; - eps=(struct dmi_eps *)dmi; - - //check checksum - int8_t checksum=0; - for (; dmi < dmi_start + eps->length; dmi++) - checksum += *dmi; - if (checksum){ - return -1; - } - - //we need at least revision 2.1 of SMBIOS - if ( eps->majorversion < 2 && - eps->minorversion < 1){ - return -1; - } - - table_start=(char *)(uintptr_t)eps->tableaddress; - dmi=table_start; -//look at all structs - while(dmi < table_start + eps->tablelength){ - struct tstruct_header *header = (struct tstruct_header *)dmi; - - if (header->type == 17) - mem_devs[mem_devs_count++] = (struct mem_dev *)dmi; - - // Mem Dev Map - if (header->type == 20) - md_maps[md_maps_count++] = (struct md_map *)dmi; - - // MB_SPEC - if (header->type == 2) - { - dmi_system_info = (struct system_map *)dmi; - } - - // CPU_SPEC - if (header->type == 4) - { - dmi_cpu_info = (struct cpu_map *)dmi; - } - - dmi+=header->length; - - while( ! (*dmi == 0 && *(dmi+1) == 0 ) ) - dmi++; - dmi+=2; - - if (++tstruct_count > eps->numstructs) - return -1; - } - return 0; -} - -void init_dmi(void){ - int i; - for(i=0; i < MAX_DMI_MEMDEVS; i++) - dmi_err_cnts[i]=0; - open_dmi(); - dmi_initialized=1; -} - -void print_dmi_startup_info(void) -{ - - if (1) print_log("print_dmi_startup_info", 22); - - char *string1; - char *string2; - char *string3; - int dmicol = 78; - int slength; - int sl1, sl2, sl3; - - if(!dmi_initialized) { init_dmi(); } - - string1 = get_tstruct_string(&dmi_system_info->header,dmi_system_info->manufacturer); - sl1 = mt86_strlen(string1); - string2 = get_tstruct_string(&dmi_system_info->header,dmi_system_info->productname); - sl2 = mt86_strlen(string2); - string3 = get_tstruct_string(&dmi_cpu_info->header,dmi_cpu_info->cpu_socket); - sl3 = mt86_strlen(string3); - - slength = sl1 + sl2; - if(sl3 > 2) { slength += sl3 + 4; } else { slength++; } - - if(sl1 && sl2) - { - //dmicol -= slength; // right align - dmicol = 39 - slength/2; // center align - cprint(LINE_DMI, dmicol, string1); - dmicol += sl1 + 1; - cprint(LINE_DMI, dmicol, string2); - dmicol += sl2 + 1; - - if(sl3 > 2){ - cprint(LINE_DMI, dmicol, "("); - dmicol++; - cprint(LINE_DMI, dmicol, string3); - dmicol += sl3; - cprint(LINE_DMI, dmicol, ")"); - } - } -} - -void print_dmi_info(void){ - int i,j,page; - char * string=0; - - if(!dmi_initialized) - init_dmi(); - - if (mem_devs_count == 0){ - cprint(POP2_Y+1, POP2_X+2, "No valid DMI Memory Devices info found"); - while (get_key() == 0); - return; - } - - for(page=1; page <= 1 + (mem_devs_count-1)/8; page++){ - pop2clear(); - cprint(POP2_Y+1, POP2_X+2, "DMI Memory Device Info (page "); - itoa(string,page); - cprint(POP2_Y+1, POP2_X+32, string); - cprint(POP2_Y+1, POP2_X+33, "/"); - itoa(string,1 + (mem_devs_count-1)/8); - cprint(POP2_Y+1, POP2_X+34, string); - cprint(POP2_Y+1, POP2_X+35, ")"); - - cprint(POP2_Y+3, POP2_X+4, "Location Size(MB) Speed(MHz) Type Form"); - cprint(POP2_Y+4, POP2_X+4, "--------------------------------------------------------------"); - - for(i=8*(page-1); iheader), mem_devs[i]->dev_locator)); - - if (mem_devs[i]->size == 0){ - cprint(yof, POP2_X+4+18, "Empty"); - }else if (mem_devs[i]->size == 0xFFFF){ - cprint(yof, POP2_X+4+18, "Unknown"); - }else if (mem_devs[i]->size == 0x7FFF){ - // SMBIOS 2.7+ - size_in_mb = mem_devs[i]->ext_size; - itoa(string, size_in_mb); - cprint(yof, POP2_X+4+18, string); - }else{ - size_in_mb = 0xFFFF & mem_devs[i]->size; - if (mem_devs[i]->size & 0x8000) - size_in_mb <<= 10; - itoa(string, size_in_mb); - cprint(yof, POP2_X+4+18, string); - } - - //this is the only field that needs to be SMBIOS 2.3+ - if ( mem_devs[i]->speed && - mem_devs[i]->header.length > 21){ - itoa(string, mem_devs[i]->speed); - cprint(yof, POP2_X+4+27, string); - }else{ - cprint(yof, POP2_X+4+27, "Unknown"); - } - cprint(yof, POP2_X+4+37, memory_types[mem_devs[i]->type]); - cprint(yof, POP2_X+4+44, form_factors[mem_devs[i]->form]); - - //print mappings - int mapped=0,of=0; - cprint(yof+1, POP2_X+6,"mapped to: "); - for(j=0; jheader.handle != md_maps[j]->md_handle) - continue; - if (mapped++){ - cprint(yof+1, POP2_X+17+of, ","); - of++; - } - hprint3(yof+1, POP2_X+17+of, md_maps[j]->start>>22, 4); - of += 4; - hprint3(yof+1, POP2_X+17+of, md_maps[j]->start<<10, 8); - of += 8; - cprint(yof+1, POP2_X+17+of, "-"); - of++; - hprint3(yof+1, POP2_X+17+of, md_maps[j]->end>>22, 4); - of += 4; - hprint3(yof+1, POP2_X+17+of, ((md_maps[j]->end+1)<<10) - 1, 8); - of += 8; - if(md_maps[j]->end == 0) { hprint3(yof+1, POP2_X+17+of-8,0,8); } - } - if (!mapped) - { - cprint(yof+1, POP2_X+17, "No mapping (Interleaved Device)"); - } - - } - - wait_keyup(); - while (get_key() == 0); - } -} - -//return 1 if the list of bad memory devices changes, 0 otherwise, -1 if no mapped -int add_dmi_err(ulong adr){ - int i,j,found=-1; - - if(!dmi_initialized) - init_dmi(); - - for(i=0; i < md_maps_count; i++){ - if ( adr < (md_maps[i]->start<<10) || - adr > (md_maps[i]->end<<10) ) - continue; - - //matching map found, now check find corresponding dev - for(j=0; j < mem_devs_count; j++){ - if (mem_devs[j]->header.handle != md_maps[i]->md_handle) - continue; - if (dmi_err_cnts[j]){ - found=0; - }else{ - found = dmi_err_cnts[j] = 1; - } - } - } - - return found; -} - -void print_dmi_err(void){ - int i,count,of; - char *string; - - scroll(); - - cprint(vv->msg_line, 0,"Bad Memory Devices: "); - of=20; - for ( i=count=0; i < MAX_DMI_MEMDEVS; i++){ - if (!dmi_err_cnts[i]) - continue; - struct mem_dev *md = mem_devs[i]; - if(count++){ - cprint(vv->msg_line, of, ", "); - of+=2; - } - string=get_tstruct_string((struct tstruct_header *)md,md->dev_locator); - if (mt86_strlen(string) + of > 80){ - scroll(); - of=7; - } - cprint(vv->msg_line, of, string); - of += mt86_strlen(string); - } -} diff --git a/efi_memtest/memtest86+/efi/dmi.c b/efi_memtest/memtest86+/efi/dmi.c new file mode 100644 index 0000000..df1eade --- /dev/null +++ b/efi_memtest/memtest86+/efi/dmi.c @@ -0,0 +1,485 @@ +/* dmi.c using the DMI from SMBIOS to read information about the hardware's + * memory devices capabilities and where they are mapped into the address space + * + * Copyright (c) Joachim Deguara, AMD 2006 + * + * Release under the GPL version 2 + * ---------------------------------------------------- + * Memtest86+ V4.00 - Added compliance with SMBIOS Spec V2.6.1 + */ + +#include "Uefi.h" +#include "Library/UefiLib.h" + +extern EFI_SYSTEM_TABLE *gST; + +#include "test.h" +#include "stdint.h" + +#include "logger.h" + +#define round_up(x,y) (((x) + (y) - 1) & ~((y)-1)) +#define round_down(x,y) ((x) & ~((y)-1)) + +extern short logflag; +extern short log_mem_ctrl; + +struct dmi_eps { + uint8_t anchor[4]; + int8_t checksum; + uint8_t length; + uint8_t majorversion; + uint8_t minorversion; + uint16_t maxstructsize; + uint8_t revision; + uint8_t pad[5]; + uint8_t intanchor[5]; + int8_t intchecksum; + uint16_t tablelength; + uint32_t tableaddress; + uint16_t numstructs; + uint8_t SMBIOSrev; +} __attribute__((packed)); + +struct tstruct_header{ + uint8_t type; + uint8_t length; + uint16_t handle; +} __attribute__((packed)); + +struct system_map { + struct tstruct_header header; + uint8_t manufacturer; + uint8_t productname; + uint8_t version; + uint8_t serialnumber; + uint8_t uuidbytes[16]; + uint8_t wut; +} __attribute__((packed)); + +struct cpu_map { + struct tstruct_header header; + uint8_t cpu_socket; + uint8_t cpu_type; + uint8_t cpu_family; + uint8_t cpu_manufacturer; + uint32_t cpu_id; + uint8_t cpu_version; + uint8_t cpu_voltage; + uint16_t ext_clock; + uint16_t max_speed; + uint16_t cur_speed; + uint8_t cpu_status; + uint8_t cpu_upgrade; + uint16_t l1_handle; + uint16_t l2_handle; + uint16_t l3_handle; + uint8_t cpu_serial; + uint8_t cpu_asset_tag; + uint8_t cpu_part_number; + uint8_t core_count; + uint8_t core_enabled; + uint8_t thread_count; + uint16_t cpu_specs; + uint16_t cpu_family_2; +} __attribute__((packed)); + +struct mem_dev { + struct tstruct_header header; + uint16_t pma_handle; + uint16_t err_handle; + uint16_t tot_width; + uint16_t dat_width; + uint16_t size; + uint8_t form; + uint8_t set; + uint8_t dev_locator; + uint8_t bank_locator; + uint8_t type; + uint16_t typedetail; + uint16_t speed; + uint8_t manufacturer; + uint8_t serialnum; + uint8_t asset; + uint8_t partnum; + uint8_t attributes; + uint8_t ext_size; + uint8_t conf_ram_speed; + uint8_t min_voltage; + uint8_t max_votage; + uint8_t conf_voltage; +} __attribute__((packed)); + +struct md_map{ + struct tstruct_header header; + uint32_t start; + uint32_t end; + uint16_t md_handle; + uint16_t mama_handle; + uint8_t row_pos; + uint8_t interl_pos; + uint8_t interl_depth; +} __attribute__((packed)); + +struct pma{ + struct tstruct_header header; + uint8_t location; + uint8_t use; + uint8_t ecc; + uint32_t capacity; + uint16_t errhandle; + uint16_t numdevs; +} __attribute__((packed)); + +static char *form_factors[] = { + "?", + "Other", "Unknown", "SIMM", "SIP", "Chip", "DIP", "ZIP", + "Proprietary Card", "DIMM", "TSOP", "Row of chips", "RIMM", + "SODIMM", "SRIMM", "FB-DIMM", "Die" +}; + + +static char *memory_types[] = { + "?", + "Other", "????", "DRAM", "EDRAM", "VRAM", "SRAM", "RAM", + "ROM", "FLASH", "EEPROM", "FEPROM", "EPROM", "CDRAM", "3DRAM", + "SDRAM", "SGRAM", "RDRAM", "DDR", "DDR2", "DDR2 FB", "RSVD", + "RSVD","RSVD","DDR3","FBD2", "DDR4", "LPDDR", "LPDDR2", "LPDDR3", + "LPDDR4", "LNVD", "HBM", "HBM2", "DDR5", "LPDDR5" +}; + + +struct mem_dev * mem_devs[MAX_DMI_MEMDEVS]; +int mem_devs_count=0; +struct md_map * md_maps[MAX_DMI_MEMDEVS]; +struct system_map * dmi_system_info; +struct cpu_map * dmi_cpu_info; +int md_maps_count=0; +int dmi_err_cnts[MAX_DMI_MEMDEVS]; +short dmi_initialized=0; + +char * get_tstruct_string(struct tstruct_header *header, int n){ + if(n<1) + return 0; + char * a = (char *)header + header->length; + n--; + do{ + if (!*a) + n--; + if (!n && *a) + return a; + a++; + }while (!(*a==0 && *(a-1)==0)); + return 0; +} + +int open_dmi(void) { + return 0; +} + +/*int open_dmi(void){ + char *dmi, *dmi_search_start, *dmi_start; + int found=0; + struct dmi_eps *eps; + char *table_start; + int tstruct_count=0; + dmi_search_start = (char *)DMI_SEARCH_START; + + //find anchor + for(dmi = dmi_search_start; dmi < dmi_search_start + 0xf0000; dmi +=16){ + if( *dmi == '_' && + *(dmi+1) == 'S' && + *(dmi+2) == 'M' && + *(dmi+3) == '_'){ + found =1; + break; + } + } + if (!found) { + print_log("open_dmi(): dmi not found", 25); + return -1; + } + dmi_start=dmi; + eps=(struct dmi_eps *)dmi; + + //check checksum + int8_t checksum=0; + for (; dmi < dmi_start + eps->length; dmi++) + checksum += *dmi; + if (checksum){ + return -1; + } + + //we need at least revision 2.1 of SMBIOS + if ( eps->majorversion < 2 && + eps->minorversion < 1){ + return -1; + } + + table_start=(char *)(uintptr_t)eps->tableaddress; + dmi=table_start; +//look at all structs + while(dmi < table_start + eps->tablelength){ + struct tstruct_header *header = (struct tstruct_header *)dmi; + + if (header->type == 17) + mem_devs[mem_devs_count++] = (struct mem_dev *)dmi; + + // Mem Dev Map + if (header->type == 20) + md_maps[md_maps_count++] = (struct md_map *)dmi; + + // MB_SPEC + if (header->type == 2) + { + dmi_system_info = (struct system_map *)dmi; + } + + // CPU_SPEC + if (header->type == 4) + { + dmi_cpu_info = (struct cpu_map *)dmi; + } + + dmi+=header->length; + + while( ! (*dmi == 0 && *(dmi+1) == 0 ) ) + dmi++; + dmi+=2; + + if (++tstruct_count > eps->numstructs) + return -1; + } + return 0; +}*/ + +void init_dmi(void){ + + if (logflag) print_log("init_dmi() started", 18); + + int i; + for(i=0; i < MAX_DMI_MEMDEVS; i++) + dmi_err_cnts[i]=0; + open_dmi(); + dmi_initialized=1; +} + +void print_dmi_startup_info(void) +{ + + if (logflag) print_log("print_dmi_startup_info() started", 32); + + char *string1; + char *string2; + char *string3; + int dmicol = 78; + int slength; + int sl1, sl2, sl3; + + if(!dmi_initialized) { init_dmi(); } + + string1 = get_tstruct_string(&dmi_system_info->header,dmi_system_info->manufacturer); + sl1 = mt86_strlen(string1); + string2 = get_tstruct_string(&dmi_system_info->header,dmi_system_info->productname); + sl2 = mt86_strlen(string2); + string3 = get_tstruct_string(&dmi_cpu_info->header,dmi_cpu_info->cpu_socket); + sl3 = mt86_strlen(string3); + + if (logflag && log_mem_ctrl) { + char log[61] = "print_dmi_startup_info(): manufacturer = "; + int length = 41; + string_to_charr(string1, log, &length); + print_log(log, length); + } + + if (logflag && log_mem_ctrl) { + char log[16] = "sl1 = "; + int length = 6; + int_to_charr(sl1, log, &length); + print_log(log, length); + } + + if (logflag && log_mem_ctrl) { + char log[60] = "print_dmi_startup_info(): productname = "; + int length = 40; + string_to_charr(string2, log, &length); + print_log(log, length); + } + + if (logflag && log_mem_ctrl) { + char log[59] = "print_dmi_startup_info(): cpu_socket = "; + int length = 39; + string_to_charr(string3, log, &length); + print_log(log, length); + } + + slength = sl1 + sl2; + if(sl3 > 2) { slength += sl3 + 4; } else { slength++; } + + if(sl1 && sl2) + { + //dmicol -= slength; // right align + dmicol = 39 - slength/2; // center align + cprint(LINE_DMI, dmicol, string1); + dmicol += sl1 + 1; + cprint(LINE_DMI, dmicol, string2); + dmicol += sl2 + 1; + + if(sl3 > 2){ + cprint(LINE_DMI, dmicol, "("); + dmicol++; + cprint(LINE_DMI, dmicol, string3); + dmicol += sl3; + cprint(LINE_DMI, dmicol, ")"); + } + } +} + +void print_dmi_info(void){ + int i,j,page; + char * string=0; + + if(!dmi_initialized) + init_dmi(); + + if (mem_devs_count == 0){ + cprint(POP2_Y+1, POP2_X+2, "No valid DMI Memory Devices info found"); + while (get_key() == 0); + return; + } + + for(page=1; page <= 1 + (mem_devs_count-1)/8; page++){ + pop2clear(); + cprint(POP2_Y+1, POP2_X+2, "DMI Memory Device Info (page "); + itoa(string,page); + cprint(POP2_Y+1, POP2_X+32, string); + cprint(POP2_Y+1, POP2_X+33, "/"); + itoa(string,1 + (mem_devs_count-1)/8); + cprint(POP2_Y+1, POP2_X+34, string); + cprint(POP2_Y+1, POP2_X+35, ")"); + + cprint(POP2_Y+3, POP2_X+4, "Location Size(MB) Speed(MHz) Type Form"); + cprint(POP2_Y+4, POP2_X+4, "--------------------------------------------------------------"); + + for(i=8*(page-1); iheader), mem_devs[i]->dev_locator)); + + if (mem_devs[i]->size == 0){ + cprint(yof, POP2_X+4+18, "Empty"); + }else if (mem_devs[i]->size == 0xFFFF){ + cprint(yof, POP2_X+4+18, "Unknown"); + }else if (mem_devs[i]->size == 0x7FFF){ + // SMBIOS 2.7+ + size_in_mb = mem_devs[i]->ext_size; + itoa(string, size_in_mb); + cprint(yof, POP2_X+4+18, string); + }else{ + size_in_mb = 0xFFFF & mem_devs[i]->size; + if (mem_devs[i]->size & 0x8000) + size_in_mb <<= 10; + itoa(string, size_in_mb); + cprint(yof, POP2_X+4+18, string); + } + + //this is the only field that needs to be SMBIOS 2.3+ + if ( mem_devs[i]->speed && + mem_devs[i]->header.length > 21){ + itoa(string, mem_devs[i]->speed); + cprint(yof, POP2_X+4+27, string); + }else{ + cprint(yof, POP2_X+4+27, "Unknown"); + } + cprint(yof, POP2_X+4+37, memory_types[mem_devs[i]->type]); + cprint(yof, POP2_X+4+44, form_factors[mem_devs[i]->form]); + + //print mappings + int mapped=0,of=0; + cprint(yof+1, POP2_X+6,"mapped to: "); + for(j=0; jheader.handle != md_maps[j]->md_handle) + continue; + if (mapped++){ + cprint(yof+1, POP2_X+17+of, ","); + of++; + } + hprint3(yof+1, POP2_X+17+of, md_maps[j]->start>>22, 4); + of += 4; + hprint3(yof+1, POP2_X+17+of, md_maps[j]->start<<10, 8); + of += 8; + cprint(yof+1, POP2_X+17+of, "-"); + of++; + hprint3(yof+1, POP2_X+17+of, md_maps[j]->end>>22, 4); + of += 4; + hprint3(yof+1, POP2_X+17+of, ((md_maps[j]->end+1)<<10) - 1, 8); + of += 8; + if(md_maps[j]->end == 0) { hprint3(yof+1, POP2_X+17+of-8,0,8); } + } + if (!mapped) + { + cprint(yof+1, POP2_X+17, "No mapping (Interleaved Device)"); + } + + } + + wait_keyup(); + while (get_key() == 0); + } +} + +//return 1 if the list of bad memory devices changes, 0 otherwise, -1 if no mapped +int add_dmi_err(ulong adr){ + int i,j,found=-1; + + if(!dmi_initialized) + init_dmi(); + + for(i=0; i < md_maps_count; i++){ + if ( adr < (md_maps[i]->start<<10) || + adr > (md_maps[i]->end<<10) ) + continue; + + //matching map found, now check find corresponding dev + for(j=0; j < mem_devs_count; j++){ + if (mem_devs[j]->header.handle != md_maps[i]->md_handle) + continue; + if (dmi_err_cnts[j]){ + found=0; + }else{ + found = dmi_err_cnts[j] = 1; + } + } + } + + return found; +} + +void print_dmi_err(void){ + int i,count,of; + char *string; + + scroll(); + + cprint(vv->msg_line, 0,"Bad Memory Devices: "); + of=20; + for ( i=count=0; i < MAX_DMI_MEMDEVS; i++){ + if (!dmi_err_cnts[i]) + continue; + struct mem_dev *md = mem_devs[i]; + if(count++){ + cprint(vv->msg_line, of, ", "); + of+=2; + } + string=get_tstruct_string((struct tstruct_header *)md,md->dev_locator); + if (mt86_strlen(string) + of > 80){ + scroll(); + of=7; + } + cprint(vv->msg_line, of, string); + of += mt86_strlen(string); + } +} diff --git a/efi_memtest/memtest86+/efi/init.c b/efi_memtest/memtest86+/efi/init.c index 9ed5e89..ef09f48 100644 --- a/efi_memtest/memtest86+/efi/init.c +++ b/efi_memtest/memtest86+/efi/init.c @@ -291,18 +291,7 @@ void init(void) { /*initialise_cpus();*/ - /* Find Memory Specs */ - if(vv->fail_safe & 1) - { - cprint(LINE_CPU, COL_SPEC, " **** FAIL SAFE **** FAIL SAFE **** "); // TODO should be printed AFTER prnt_mainscreen - cprint(LINE_RAM, COL_SPEC, " No detection, same reliability "); - } else { - find_controller(); - // get_spd_spec(); - if(num_cpus <= 16 && !(vv->fail_safe & 4)) { - //coretemp(); - } - } /* + /* if(vv->check_temp > 0 && !(vv->fail_safe & 4)) { @@ -329,6 +318,19 @@ void init(void) { */ print_mainscreen(); + /* Find Memory Specs */ + if(vv->fail_safe & 1) + { + cprint(LINE_CPU, COL_SPEC, " **** FAIL SAFE **** FAIL SAFE **** "); // TODO should be printed AFTER prnt_mainscreen + cprint(LINE_RAM, COL_SPEC, " No detection, same reliability "); + } else { + find_controller(); + // get_spd_spec(); + if(num_cpus <= 16 && !(vv->fail_safe & 4)) { + //coretemp(); + } + } + } /* Get cache sizes for most AMD and Intel CPUs, exceptions for old CPUs are -- cgit v1.2.3-55-g7522