diff options
author | Regia König | 2021-06-07 16:53:44 +0200 |
---|---|---|
committer | Regia König | 2021-06-07 16:53:44 +0200 |
commit | 5e8857158cba3b375ca5f2a64b1bf7c06a4571f2 (patch) | |
tree | 59589e3157d627c420bcbf26d964cb5bdb8322e3 | |
parent | Clean up logging information (diff) | |
download | memtest86-5e8857158cba3b375ca5f2a64b1bf7c06a4571f2.tar.gz memtest86-5e8857158cba3b375ca5f2a64b1bf7c06a4571f2.tar.xz memtest86-5e8857158cba3b375ca5f2a64b1bf7c06a4571f2.zip |
Move dmi.c into /bios and /efi dir. The whole open_dmit() function must be rewritten.
-rw-r--r-- | efi_memtest/memtest86+/bios/dmi.c (renamed from efi_memtest/memtest86+/dmi.c) | 48 | ||||
-rw-r--r-- | efi_memtest/memtest86+/controller.c | 42 | ||||
-rw-r--r-- | efi_memtest/memtest86+/efi/dmi.c | 485 | ||||
-rw-r--r-- | efi_memtest/memtest86+/efi/init.c | 26 |
4 files changed, 576 insertions, 25 deletions
diff --git a/efi_memtest/memtest86+/dmi.c b/efi_memtest/memtest86+/bios/dmi.c index a450de1..688d067 100644 --- a/efi_memtest/memtest86+/dmi.c +++ b/efi_memtest/memtest86+/bios/dmi.c @@ -8,6 +8,10 @@ * 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" @@ -17,6 +21,9 @@ #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; @@ -166,8 +173,11 @@ char * get_tstruct_string(struct tstruct_header *header, int n){ return 0; } +int open_dmi(void) { + +} -int open_dmi(void){ +/*int open_dmi(void){ char *dmi, *dmi_search_start, *dmi_start; int found=0; struct dmi_eps *eps; @@ -186,6 +196,7 @@ int open_dmi(void){ } } if (!found) { + print_log("open_dmi(): dmi not found", 25); return -1; } dmi_start=dmi; @@ -240,9 +251,12 @@ int open_dmi(void){ 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; @@ -253,7 +267,7 @@ void init_dmi(void){ void print_dmi_startup_info(void) { - if (1) print_log("print_dmi_startup_info", 22); + if (logflag) print_log("print_dmi_startup_info() started", 32); char *string1; char *string2; @@ -271,6 +285,34 @@ void print_dmi_startup_info(void) 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++; } 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+/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); i<mem_devs_count && i<8*page; i++){ + int size_in_mb; + int yof; + + yof = POP2_Y+5+2*(i-8*(page-1)); + cprint(yof, POP2_X+4, get_tstruct_string(&(mem_devs[i]->header), 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; j<md_maps_count; j++) + { + if (mem_devs[i]->header.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 |