diff options
Diffstat (limited to 'memtestEDK/Memtest/SingleComponents/spd.c')
-rw-r--r-- | memtestEDK/Memtest/SingleComponents/spd.c | 541 |
1 files changed, 0 insertions, 541 deletions
diff --git a/memtestEDK/Memtest/SingleComponents/spd.c b/memtestEDK/Memtest/SingleComponents/spd.c deleted file mode 100644 index 197db56..0000000 --- a/memtestEDK/Memtest/SingleComponents/spd.c +++ /dev/null @@ -1,541 +0,0 @@ -/* - * MemTest86+ V5 Specific code (GPL V2.0) - * By Samuel DEMEULEMEESTER, sdemeule@memtest.org - * http://www.canardpc.com - http://www.memtest.org - */ - - -#include "test.h" -#include "io.h" -#include "pci.h" -#include "msr.h" -#include "spd.h" -#include "screen_buffer.h" -#include "jedec_id.h" - -#define NULL 0 - -#define SMBHSTSTS smbusbase -#define SMBHSTCNT smbusbase + 2 -#define SMBHSTCMD smbusbase + 3 -#define SMBHSTADD smbusbase + 4 -#define SMBHSTDAT smbusbase + 5 - -extern void wait_keyup(); - -int smbdev, smbfun; -unsigned short smbusbase; -unsigned char spd_raw[256]; -char s[] = {'/', 0, '-', 0, '\\', 0, '|', 0}; - -static void ich5_get_smb(void) -{ - unsigned long x; - int result; - result = pci_conf_read(0, smbdev, smbfun, 0x20, 2, &x); - if (result == 0) smbusbase = (unsigned short) x & 0xFFFE; -} - -static void piix4_get_smb(void) -{ - unsigned long x; - int result; - - result = pci_conf_read(0, smbdev, smbfun, 0x08, 1, &x); - - if(x < 0x40){ - // SB600/700 - result = pci_conf_read(0, smbdev, smbfun, 0x90, 2, &x); - if (result == 0) smbusbase = (unsigned short) x & 0xFFFE; - } else { - // SB800 - sb800_get_smb(); - } -} - -void sb800_get_smb(void) -{ - int lbyte, hbyte; - - __outb(AMD_SMBUS_BASE_REG + 1, AMD_INDEX_IO_PORT); - lbyte = __inb(AMD_DATA_IO_PORT); - __outb(AMD_SMBUS_BASE_REG, AMD_INDEX_IO_PORT); - hbyte = __inb(AMD_DATA_IO_PORT); - - smbusbase = lbyte; - smbusbase <<= 8; - smbusbase += hbyte; - smbusbase &= 0xFFE0; - - if (smbusbase == 0xFFE0) { smbusbase = 0; } -} - -unsigned char ich5_smb_read_byte(unsigned char adr, unsigned char cmd) -{ - int l1, h1, l2, h2; - unsigned long long t; - __outb(0x1f, SMBHSTSTS); // reset SMBus Controller - __outb(0xff, SMBHSTDAT); - while(__inb(SMBHSTSTS) & 0x01); // wait until ready - __outb(cmd, SMBHSTCMD); - __outb((adr << 1) | 0x01, SMBHSTADD); - __outb(0x48, SMBHSTCNT); - rdtsc(l1, h1); - //cprint(POP2_Y, POP2_X + 16, s + cmd % 8); // progress bar - while (!(__inb(SMBHSTSTS) & 0x02)) { // wait til command finished - rdtsc(l2, h2); - t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / vv->clks_msec; - if (t > 10) break; // break after 10ms - } - return __inb(SMBHSTDAT); -} - -static int ich5_read_spd(int dimmadr) -{ - int x; - spd_raw[0] = ich5_smb_read_byte(0x50 + dimmadr, 0); - if (spd_raw[0] == 0xff) return -1; // no spd here - for (x = 1; x < 256; x++) { - spd_raw[x] = ich5_smb_read_byte(0x50 + dimmadr, (unsigned char) x); - } - return 0; -} - -static void us15w_get_smb(void) -{ - unsigned long x; - int result; - result = pci_conf_read(0, 0x1f, 0, 0x40, 2, &x); - if (result == 0) smbusbase = (unsigned short) x & 0xFFC0; -} - -unsigned char us15w_smb_read_byte(unsigned char adr, unsigned char cmd) -{ - int l1, h1, l2, h2; - unsigned long long t; - //__outb(0x00, smbusbase + 1); // reset SMBus Controller - //__outb(0x00, smbusbase + 6); - //while((__inb(smbusbase + 1) & 0x08) != 0); // wait until ready - __outb(0x02, smbusbase + 0); // Byte read - __outb(cmd, smbusbase + 5); // Command - __outb(0x07, smbusbase + 1); // Clear status - __outb((adr << 1) | 0x01, smbusbase + 4); // DIMM address - __outb(0x12, smbusbase + 0); // Start - //while (((__inb(smbusbase + 1) & 0x08) == 0)) {} // wait til busy - rdtsc(l1, h1); - cprint(POP2_Y, POP2_X + 16, s + cmd % 8); // progress bar - while (((__inb(smbusbase + 1) & 0x01) == 0) || - ((__inb(smbusbase + 1) & 0x08) != 0)) { // wait til command finished - rdtsc(l2, h2); - t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / vv->clks_msec; - if (t > 10) break; // break after 10ms - } - return __inb(smbusbase + 6); -} - -static int us15w_read_spd(int dimmadr) -{ - int x; - spd_raw[0] = us15w_smb_read_byte(0x50 + dimmadr, 0); - if (spd_raw[0] == 0xff) return -1; // no spd here - for (x = 1; x < 256; x++) { - spd_raw[x] = us15w_smb_read_byte(0x50 + dimmadr, (unsigned char) x); - } - return 0; -} - -struct pci_smbus_controller { - unsigned vendor; - unsigned device; - char *name; - void (*get_adr)(void); - int (*read_spd)(int dimmadr); -}; - -static struct pci_smbus_controller smbcontrollers[] = - { - // Intel SMBUS - {0x8086, 0x9C22, "Intel HSW-ULT", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x8C22, "Intel HSW", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x1E22, "Intel Z77", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x1C22, "Intel P67", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x3B30, "Intel P55", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x3A60, "Intel ICH10B", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x3A30, "Intel ICH10R", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x2930, "Intel ICH9", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x283E, "Intel ICH8", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x27DA, "Intel ICH7", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x266A, "Intel ICH6", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x24D3, "Intel ICH5", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x24C3, "Intel ICH4", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x25A4, "Intel 6300ESB", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x269B, "Intel ESB2", ich5_get_smb, ich5_read_spd}, - {0x8086, 0x8119, "Intel US15W", us15w_get_smb, us15w_read_spd}, - {0x8086, 0x5032, "Intel EP80579", ich5_get_smb, ich5_read_spd}, - - // AMD SMBUS - {0x1002, 0x4385, "AMD SB600/700", piix4_get_smb, ich5_read_spd}, - {0x1022, 0x780B, "AMD SB800/900", sb800_get_smb, ich5_read_spd}, - {0, 0, "", NULL, NULL} - }; - -int find_smb_controller(void) -{ - int i = 0; - unsigned long valuev, valued; - - for (smbdev = 0; smbdev < 32; smbdev++) { - for (smbfun = 0; smbfun < 8; smbfun++) { - pci_conf_read(0, smbdev, smbfun, 0, 2, &valuev); - if (valuev != 0xFFFF) { // if there is something look what's it.. - for (i = 0; smbcontrollers[i].vendor > 0; i++) { // check if this is a known smbus controller - if (valuev == smbcontrollers[i].vendor) { - pci_conf_read(0, smbdev, smbfun, 2, 2, &valued); // read the device id - if (valued == smbcontrollers[i].device) { - return i; - } - } - } - } - } - } - return -1; -} - -void get_spd_spec(void) -{ - int index; - int h, i, j, z; - int k = 0; - int module_size; - int curcol; - int temp_nbd; - int tck; - - index = find_smb_controller(); - - if (index == -1) - { - // Unknown SMBUS Controller, exit - return; - } - - smbcontrollers[index].get_adr(); - cprint(LINE_SPD-2, 0, "Memory SPD Informations"); - cprint(LINE_SPD-1, 0, "--------------------------"); - - for (j = 0; j < 8; j++) { - if (smbcontrollers[index].read_spd(j) == 0) { - curcol = 1; - if(spd_raw[2] == 0x0b){ - // We are here if DDR3 present - - // First print slot#, module capacity - cprint(LINE_SPD+k, curcol, " - Slot :"); - dprint(LINE_SPD+k, curcol+8, k, 1, 0); - - module_size = get_ddr3_module_size(spd_raw[4] & 0xF, spd_raw[8] & 0x7, spd_raw[7] & 0x7, spd_raw[7] >> 3); - temp_nbd = getnum(module_size); curcol += 12; - dprint(LINE_SPD+k, curcol, module_size, temp_nbd, 0); curcol += temp_nbd; - cprint(LINE_SPD+k, curcol, " MB"); curcol += 4; - - // If XMP is supported, check Tck in XMP reg - if(spd_raw[176] == 0x0C && spd_raw[177] == 0x4A && spd_raw[12]) - { - tck = spd_raw[186]; - } else { - tck = spd_raw[12]; - } - - // Then module jedec speed - switch(tck) - { - default: - cprint(LINE_SPD+k, curcol, "DDR3-????"); - break; - case 20: - cprint(LINE_SPD+k, curcol, "DDR3-800"); - curcol--; - break; - case 15: - cprint(LINE_SPD+k, curcol, "DDR3-1066"); - break; - case 12: - cprint(LINE_SPD+k, curcol, "DDR3-1333"); - break; - case 10: - cprint(LINE_SPD+k, curcol, "DDR3-1600"); - break; - case 9: - cprint(LINE_SPD+k, curcol, "DDR3-1866"); - break; - case 8: - cprint(LINE_SPD+k, curcol, "DDR3-2133"); - break; - case 7: - cprint(LINE_SPD+k, curcol, "DDR3-2400"); - break; - case 6: - cprint(LINE_SPD+k, curcol, "DDR3-2533"); - break; - case 5: - cprint(LINE_SPD+k, curcol, "DDR3-2666"); - break; - } - - curcol += 10; - - if((spd_raw[8] >> 3) == 1) { cprint(LINE_SPD+k, curcol, "ECC"); curcol += 4; } - - // Then print module infos (manufacturer & part number) - spd_raw[117] &= 0x0F; // Parity odd or even - for (i = 0; jep106[i].cont_code < 9; i++) { - if (spd_raw[117] == jep106[i].cont_code && spd_raw[118] == jep106[i].hex_byte) { - // We are here if a Jedec manufacturer is detected - cprint(LINE_SPD+k, curcol, "-"); curcol += 2; - cprint(LINE_SPD+k, curcol, jep106[i].name); - for(z = 0; jep106[i].name[z] != '\0'; z++) { curcol++; } - curcol++; - // Display module serial number - for (h = 128; h < 146; h++) { - cprint(LINE_SPD+k, curcol, convert_hex_to_char(spd_raw[h])); - curcol++; - } - - // Detect Week and Year of Manufacturing (Think to upgrade after 2015 !!!) - if(curcol <= 72 && spd_raw[120] > 3 && spd_raw[120] < 16 && spd_raw[121] < 55) - { - cprint(LINE_SPD+k, curcol, "(W"); - dprint(LINE_SPD+k, curcol+2, spd_raw[121], 2, 0); - if(spd_raw[121] < 10) { cprint(LINE_SPD+k, curcol+2, "0"); } - cprint(LINE_SPD+k, curcol+4, "'"); - dprint(LINE_SPD+k, curcol+5, spd_raw[120], 2, 0); - if(spd_raw[120] < 10) { cprint(LINE_SPD+k, curcol+5, "0"); } - cprint(LINE_SPD+k, curcol+7, ")"); - curcol += 9; - } - - // Detect XMP Memory - if(spd_raw[176] == 0x0C && spd_raw[177] == 0x4A) - { - cprint(LINE_SPD+k, curcol, "*XMP*"); - } - } - } - } - // We enter this function if DDR2 is detected - if(spd_raw[2] == 0x08){ - // First print slot#, module capacity - cprint(LINE_SPD+k, curcol, " - Slot :"); - dprint(LINE_SPD+k, curcol+8, k, 1, 0); - - module_size = get_ddr2_module_size(spd_raw[31], spd_raw[5]); - temp_nbd = getnum(module_size); curcol += 12; - dprint(LINE_SPD+k, curcol, module_size, temp_nbd, 0); curcol += temp_nbd; - cprint(LINE_SPD+k, curcol, " MB"); curcol += 4; - - // Then module jedec speed - float ddr2_speed, byte1, byte2; - - byte1 = (spd_raw[9] >> 4) * 10; - byte2 = spd_raw[9] & 0xF; - - ddr2_speed = 1 / (byte1 + byte2) * 10000 * 2; - - temp_nbd = getnum(ddr2_speed); - cprint(LINE_SPD+k, curcol, "DDR2-"); curcol += 5; - dprint(LINE_SPD+k, curcol, ddr2_speed, temp_nbd, 0); curcol += temp_nbd; - - if((spd_raw[11] >> 1) == 1) { cprint(LINE_SPD+k, curcol+1, "ECC"); curcol += 4; } - - // Then print module infos (manufacturer & part number) - int ccode = 0; - - for(i = 64; i < 72; i++) - { - if(spd_raw[i] == 0x7F) { ccode++; } - } - - curcol++; - - for (i = 0; jep106[i].cont_code < 9; i++) { - if (ccode == jep106[i].cont_code && spd_raw[64+ccode] == jep106[i].hex_byte) { - // We are here if a Jedec manufacturer is detected - cprint(LINE_SPD+k, curcol, "-"); curcol += 2; - cprint(LINE_SPD+k, curcol, jep106[i].name); - for(z = 0; jep106[i].name[z] != '\0'; z++) { curcol++; } - curcol++; - // Display module serial number - for (h = 73; h < 91; h++) { - cprint(LINE_SPD+k, curcol, convert_hex_to_char(spd_raw[h])); - curcol++; - } - } - } - } - k++; - } - } -} - -void show_spd(void) -{ - int index; - int i, j; - int flag = 0; - pop2up(); - wait_keyup(); - index = find_smb_controller(); - if (index == -1) { - cprint(POP2_Y, POP2_X+1, "SMBus Controller not known"); - while (!get_key()); - wait_keyup(); - pop2down(); - return; - } - else cprint(POP2_Y, POP2_X+1, "SPD Data: Slot"); - smbcontrollers[index].get_adr(); - for (j = 0; j < 16; j++) { - if (smbcontrollers[index].read_spd(j) == 0) { - dprint(POP2_Y, POP2_X + 15, j, 2, 0); - for (i = 0; i < 256; i++) { - hprint2(2 + POP2_Y + i / 16, 3 + POP2_X + (i % 16) * 3, spd_raw[i], 2); - } - flag = 0; - while(!flag) { - if (get_key()) flag++; - } - wait_keyup(); - } - } - pop2down(); -} - -int get_ddr3_module_size(int sdram_capacity, int prim_bus_width, int sdram_width, int ranks) -{ - int module_size; - - switch(sdram_capacity) - { - case 0: - module_size = 256; - break; - case 1: - module_size = 512; - break; - default: - case 2: - module_size = 1024; - break; - case 3: - module_size = 2048; - break; - case 4: - module_size = 4096; - break; - case 5: - module_size = 8192; - break; - case 6: - module_size = 16384; - break; - } - - module_size /= 8; - - switch(prim_bus_width) - { - case 0: - module_size *= 8; - break; - case 1: - module_size *= 16; - break; - case 2: - module_size *= 32; - break; - case 3: - module_size *= 64; - break; - } - - switch(sdram_width) - { - case 0: - module_size /= 4; - break; - case 1: - module_size /= 8; - break; - case 2: - module_size /= 16; - break; - case 3: - module_size /= 32; - break; - - } - - module_size *= (ranks + 1); - - return module_size; -} - - -int get_ddr2_module_size(int rank_density_byte, int rank_num_byte) -{ - int module_size; - - switch(rank_density_byte) - { - case 1: - module_size = 1024; - break; - case 2: - module_size = 2048; - break; - case 4: - module_size = 4096; - break; - case 8: - module_size = 8192; - break; - case 16: - module_size = 16384; - break; - case 32: - module_size = 128; - break; - case 64: - module_size = 256; - break; - default: - case 128: - module_size = 512; - break; - } - - module_size *= (rank_num_byte & 7) + 1; - - return module_size; - -} - - -struct ascii_map { - unsigned hex_code; - char *name; -}; - - -char* convert_hex_to_char(unsigned hex_org) { - static char buf[2] = " "; - if (hex_org >= 0x20 && hex_org < 0x80) { - buf[0] = hex_org; - } else { - //buf[0] = '\0'; - buf[0] = ' '; - } - - return buf; -} |