diff options
author | Michael Brown | 2009-09-22 22:20:42 +0200 |
---|---|---|
committer | Michael Brown | 2012-07-09 16:41:42 +0200 |
commit | 1abd405570a2692adcc3bef3845bfb9178a1d952 (patch) | |
tree | e00898ca6512883677073335334add8e3b22b33d | |
parent | [import] Import version 2.11 (diff) | |
download | memtest86-1abd405570a2692adcc3bef3845bfb9178a1d952.tar.gz memtest86-1abd405570a2692adcc3bef3845bfb9178a1d952.tar.xz memtest86-1abd405570a2692adcc3bef3845bfb9178a1d952.zip |
[import] Import version 4.00
http://www.memtest.org/download/4.00/memtest86+-4.00.tar.gz
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | changelog | 25 | ||||
-rw-r--r-- | config.c | 32 | ||||
-rw-r--r-- | config.h | 3 | ||||
-rw-r--r-- | controller.c | 171 | ||||
-rw-r--r-- | cpuid.c | 258 | ||||
-rw-r--r-- | cpuid.h | 217 | ||||
-rw-r--r-- | dmi.c | 11 | ||||
-rw-r--r-- | error.c | 26 | ||||
-rw-r--r-- | init.c | 195 | ||||
-rw-r--r-- | jedec_id.h | 887 | ||||
-rw-r--r-- | lib.c | 44 | ||||
-rw-r--r-- | main.c | 230 | ||||
-rwxr-xr-x | makedos.sh | 10 | ||||
-rwxr-xr-x | makeiso.sh | 6 | ||||
-rw-r--r-- | memsize.c | 141 | ||||
-rw-r--r-- | memtest.exe | bin | 0 -> 161064 bytes | |||
-rw-r--r-- | memtest_shared.lds | 1 | ||||
-rw-r--r-- | mt86+_loader | bin | 784 -> 784 bytes | |||
-rw-r--r-- | mt86+_loader.asm | 4 | ||||
-rw-r--r-- | pci.c | 13 | ||||
-rwxr-xr-x[-rw-r--r--] | precomp.bin | bin | 116508 -> 160280 bytes | |||
-rw-r--r-- | smp.c | 440 | ||||
-rw-r--r-- | smp.h | 265 | ||||
-rw-r--r-- | spd.c | 407 | ||||
-rw-r--r-- | spd.h | 13 | ||||
-rw-r--r-- | stdint.h | 8 | ||||
-rw-r--r-- | test.c | 125 | ||||
-rw-r--r-- | test.h | 20 |
30 files changed, 3134 insertions, 429 deletions
@@ -11,11 +11,11 @@ FDISK=/dev/fd0 AS=as -32 CC=gcc -CFLAGS= -Wall -march=i486 -m32 -Os -fomit-frame-pointer -fno-builtin -ffreestanding -fPIC +CFLAGS= -Wall -march=i486 -m32 -O2 -fomit-frame-pointer -fno-builtin -ffreestanding -fPIC OBJS= head.o reloc.o main.o test.o init.o lib.o patn.o screen_buffer.o \ - config.o linuxbios.o memsize.o pci.o controller.o random.o extra.o \ - spd.o error.o dmi.o + config.o linuxbios.o memsize.o pci.o controller.o random.o spd.o \ + error.o dmi.o cpuid.o all: memtest.bin memtest @@ -55,6 +55,9 @@ test.o: test.c clean: rm -f *.o *.s *.iso memtest.bin memtest memtest_shared memtest_shared.bin +asm: + @./makedos.sh + iso: make all ./makeiso.sh @@ -1,4 +1,4 @@ -Memtest86++ v2.10
+Memtest86++ v4.00
====================
Table of Contents
@@ -1,10 +1,19 @@ -Memtest86+ V2.11 changelog
+Memtest86+ V4.00 changelog
--------------------------
- - Added support for Intel Core i5 (Lynnfield) CPU
- - Added support for Intel P55 Southbridge
- - Added support for Intel PM45/GM45/GM47 Mobile chipset
- - Added support for Intel GL40/GS45 Mobile chipset
- - Corrected DDR2/DDR3 detection on Intel x35/x45
- - Corrected detection on some Core i7 CPU
- - Various bug fixes
+ - Major Architectural changes
+ - First pass twice faster (reduced iterations)
+ - Detect DDR2/3 brands and part numbers
+ - Corrected detection for Intel "Lynnfield" CPU
+ - Added detection for Intel "Clarkdale" CPU
+ - Added detection for Intel "Gulftown" CPU
+ - Corrected detection for AMD 45nm K10 CPU
+ - Added detection for AMD "Magny-Cours" CPU
+ - Solved crash with AMD Geode LX
+ - Added detection for Intel XMP Memory
+ - Added for CPU w/ 0.5/1.5/3/6/12/16/18/24MB L3
+ - Added "clean" DMI detection for DDR3/FBDIMM2
+ - Better detection of Integrated Memory Ctrl
+ - Complies with SMBIOS 2.6.1 specs
+ - Fixed compilation issues with gcc 4.2+
+ - Many others bug fixes
@@ -3,7 +3,7 @@ * Released under version 2 of the Gnu Public License. * By Chris Brady * ---------------------------------------------------- - * MemTest86+ V2.00 Specific code (GPL V2.0) + * MemTest86+ V4.00 Specific code (GPL V2.0) * By Samuel DEMEULEMEESTER, sdemeule@memtest.org * http://www.x86-secret.com - http://www.memtest.org */ @@ -17,6 +17,7 @@ extern int bail, beepmode; extern struct tseq tseq[]; extern short e820_nr; extern char memsz_mode; +extern int find_ticks_for_pass(); //void performance(); char save[2][POP_H][POP_W]; @@ -71,7 +72,7 @@ void get_config() bail++; } v->testsel = -1; - find_ticks(); + find_ticks_for_pass(); sflag++; cprint(LINE_INFO, COL_TST, "Std"); break; @@ -95,7 +96,7 @@ void get_config() } v->testsel = i; } - find_ticks(); + find_ticks_for_pass(); sflag++; bail++; cprint(LINE_INFO, COL_TST, "#"); @@ -107,7 +108,7 @@ void get_config() v->test = -1; } v->testsel = 9; - find_ticks(); + find_ticks_for_pass(); sflag++; bail++; cprint(LINE_INFO, COL_TST, "#"); @@ -120,7 +121,7 @@ void get_config() v->test = -1; } v->testsel = 9+1; - find_ticks(); + find_ticks_for_pass(); sflag++; bail++; cprint(LINE_INFO, COL_TST, "#"); @@ -163,7 +164,7 @@ void get_config() bail++; } adj_mem(); - find_ticks(); + find_ticks_for_pass(); sflag++; break; case 3: @@ -183,7 +184,7 @@ void get_config() bail++; } adj_mem(); - find_ticks(); + find_ticks_for_pass(); sflag++; break; case 4: @@ -193,7 +194,7 @@ void get_config() v->test--; bail++; adj_mem(); - find_ticks(); + find_ticks_for_pass(); sflag++; break; case 11: @@ -210,14 +211,9 @@ void get_config() popclear(); cprint(POP_Y+1, POP_X+2, "Memory Sizing:"); cprint(POP_Y+3, POP_X+6, "(1) BIOS - Std"); - if (e820_nr) { - cprint(POP_Y+4, POP_X+6, "(2) BIOS - All"); - cprint(POP_Y+5, POP_X+6, "(3) Probe"); - cprint(POP_Y+6, POP_X+6, "(0) Continue"); - cprint(POP_Y+2+memsz_mode, POP_X+5, ">"); - } else { - cprint(POP_Y+4, POP_X+6, "(3) Probe"); + cprint(POP_Y+4, POP_X+6, "(2) Probe"); cprint(POP_Y+5, POP_X+6, "(0) Continue"); + if(!e820_nr){ if (memsz_mode == SZ_MODE_BIOS) { cprint(POP_Y+3, POP_X+5, ">"); } else { @@ -234,12 +230,6 @@ void get_config() break; case 3: - memsz_mode = SZ_MODE_BIOS_RES; - wait_keyup(); - restart(); - - break; - case 4: memsz_mode = SZ_MODE_PROBE; wait_keyup(); restart(); @@ -27,6 +27,9 @@ /* BEEP_END_NO_ERROR - Beep at end of each pass without error. Default off, Change to 1 to enable */ #define BEEP_END_NO_ERROR 0 +/* FIRST_PASS_HALF_ITERATIONS - First pass twice faster / half iterations. Change to 0 to disable */ +#define FIRST_PASS_HALF_ITERATIONS 1 + /* SCRN_DEBUG - extra check for SCREEN_BUFFER */ /* #define SCRN_DEBUG */ diff --git a/controller.c b/controller.c index f57618e..948785b 100644 --- a/controller.c +++ b/controller.c @@ -3,7 +3,7 @@ * Released under version 2 of the Gnu Public License. * By Chris Brady, cbrady@sgi.com * ---------------------------------------------------- - * MemTest86+ V2.11 Specific code (GPL V2.0) + * MemTest86+ V4.00 Specific code (GPL V2.0) * By Samuel DEMEULEMEESTER, sdemeule@memtest.org * http://www.canardpc.com - http://www.memtest.org */ @@ -13,11 +13,14 @@ #include "test.h" #include "pci.h" #include "controller.h" +#include "spd.h" +#include "test.h" int col, col2; int nhm_bus = 0x3F; extern ulong extclock; +extern unsigned long imc_type; extern struct cpu_ident cpu_id; #define rdmsr(msr,val1,val2) \ @@ -80,6 +83,7 @@ struct pci_memory_controller { void (*poll_errors)(void); }; + void print_timings_info(float cas, int rcd, int rp, int ras) { /* Now, we could print some additionnals timings infos) */ @@ -199,8 +203,8 @@ static void setup_nhm(void) pci_conf_read( possible_nhm_bus[i], 3, 4, 0x00, 2, &vid); pci_conf_read( possible_nhm_bus[i], 3, 4, 0x02, 2, &did); vid &= 0xFFFF; - did &= 0xFFFF; - if(vid == 0x8086 && did == 0x2C1C) { + did &= 0xFF00; + if(vid == 0x8086 && did == 0x2C00) { nhm_bus = possible_nhm_bus[i]; } } @@ -282,6 +286,7 @@ static void setup_k10(void) unsigned int mcgsth; unsigned long mcanb; unsigned long dramcl; + ulong msr_low, msr_high; /* All AMD64 support Chipkill */ ctrl.cap = ECC_CHIPKILL; @@ -302,7 +307,13 @@ static void setup_k10(void) /* Clear any previous error */ pci_conf_read(0, 24, 3, 0x4C, 4, &mcanb); - pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7FFFFFFF ); + pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7FFFFFFF ); + + /* Enable ECS */ + rdmsr(0xC001001F, msr_low, msr_high); + wrmsr(0xC001001F, msr_low, (msr_high | 0x4000)); + rdmsr(0xC001001F, msr_low, msr_high); + } static void poll_amd64(void) @@ -1258,6 +1269,29 @@ static void poll_fsb_k10(void) { unsigned long dramchr; unsigned long mainPllId; double dramclock; + unsigned long pns_low; + unsigned long pns_high; + unsigned long msr_psn; + + + /* If ECC not enabled : display CPU name as IMC */ + if(ctrl.mode == ECC_NONE) + { + cprint(LINE_CPU+5, 0, "IMC : "); + for(msr_psn = 0; msr_psn < 5; msr_psn++) + { + rdmsr(0xC0010030+msr_psn, pns_low, pns_high); + cprint(LINE_CPU+5, 6+(msr_psn*8), convert_hex_to_char(pns_low & 0xff)); + cprint(LINE_CPU+5, 7+(msr_psn*8), convert_hex_to_char((pns_low >> 8) & 0xff)); + cprint(LINE_CPU+5, 8+(msr_psn*8), convert_hex_to_char((pns_low >> 16) & 0xff)); + cprint(LINE_CPU+5, 9+(msr_psn*8), convert_hex_to_char((pns_low >> 24) & 0xff)); + cprint(LINE_CPU+5, 10+(msr_psn*8), convert_hex_to_char(pns_high & 0xff)); + cprint(LINE_CPU+5, 11+(msr_psn*8), convert_hex_to_char((pns_high >> 8) & 0xff)); + cprint(LINE_CPU+5, 12+(msr_psn*8), convert_hex_to_char((pns_high >> 16) & 0xff)); + cprint(LINE_CPU+5, 13+(msr_psn*8), convert_hex_to_char((pns_high >> 24) & 0xff)); + } + cprint(LINE_CPU+5, 41, "(ECC : Disabled)"); + } /* First, we need the clock ratio */ pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); @@ -2020,15 +2054,15 @@ static void poll_fsb_nhm(void) { fsb = ((extclock /1000) / coef); /* Print FSB */ - cprint(LINE_CPU+5, col +1, "/ FSB : "); - col += 9; + cprint(LINE_CPU+5, col +1, "/ BCLK : "); + col += 10; dprint(LINE_CPU+5, col, fsb, 3,0); col += 3; cprint(LINE_CPU+5, col +1, "MHz"); col += 4; /* Print QPI Speed (if ECC not supported) */ - if(ctrl.mode == ECC_NONE) { + if(ctrl.mode == ECC_NONE && cpu_id.model == 10) { pci_conf_read(nhm_bus, 2, 1, 0x50, 2, &qpi_pll_status); qpi_speed = (qpi_pll_status & 0x7F) * ((extclock / 1000) / coef) * 2; cprint(LINE_CPU+5, col +1, "/ QPI : "); @@ -2167,9 +2201,9 @@ static void poll_timings_i925(void) { //Determine DDR or DDR-II if ((drc & 3) == 2) { - cprint(LINE_CPU+5, col +1, "- Type : DDR-II"); + cprint(LINE_CPU+5, col +1, "- Type : DDR2"); } else { - cprint(LINE_CPU+5, col +1, "- Type : DDR-I"); + cprint(LINE_CPU+5, col +1, "- Type : DDR1"); } // Now, detect timings @@ -2682,11 +2716,11 @@ static void poll_timings_amd64(void) { // Print 64 or 128 bits mode if ((dramclr >> 11)&1) { - cprint(LINE_CPU+6, col2, " DDR-2 (128 bits)"); - col2 +=17; - } else { - cprint(LINE_CPU+6, col2, " DDR-2 (64 bits)"); + cprint(LINE_CPU+6, col2, " DDR2 (128 bits)"); col2 +=16; + } else { + cprint(LINE_CPU+6, col2, " DDR2 (64 bits)"); + col2 +=15; } } else { @@ -2720,11 +2754,11 @@ static void poll_timings_amd64(void) { // Print 64 or 128 bits mode if (((dramclr >> 16)&1) == 1) { - cprint(LINE_CPU+6, col2, " DDR-1 (128 bits)"); - col2 +=17; - } else { - cprint(LINE_CPU+6, col2, " DDR-1 (64 bits)"); + cprint(LINE_CPU+6, col2, " DDR1 (128 bits)"); col2 +=16; + } else { + cprint(LINE_CPU+6, col2, " DDR1 (64 bits)"); + col2 +=15; } } } @@ -2732,59 +2766,56 @@ static void poll_timings_amd64(void) { static void poll_timings_k10(void) { ulong dramtlr, dramclr, dramchr; - int temp; - int trcd, trp, tras ; - - cprint(LINE_CPU+6, col2 +1, "/ CAS : "); - col2 += 9; + ulong offset = 0; + int cas, rcd, rp, rc, ras; - pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr); - pci_conf_read(0, 24, 2, 0x110, 4, &dramclr); pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); - - // CAS Latency (tCAS) - temp = (dramtlr & 0x7) + 1; - dprint(LINE_CPU+6, col2, temp , 1 ,0); - cprint(LINE_CPU+6, col2 +1, "-"); col2 +=2; - // RAS-To-CAS (tRCD) - trcd = ((dramtlr >> 4) & 0x3) + 3; - dprint(LINE_CPU+6, col2, trcd , 1 ,0); - cprint(LINE_CPU+6, col2 +1, "-"); col2 +=2; - - // RAS Precharge (tRP) - trp = ((dramtlr >> 8) & 0x3) + 3; - dprint(LINE_CPU+6, col2, trp , 1 ,0); - cprint(LINE_CPU+6, col2 +1, "-"); col2 +=2; + // If Channel A not enabled, switch to channel B + if(((dramchr>>14) & 0x1)) + { + offset = 0x100; + pci_conf_read(0, 24, 2, 0x94+offset, 4, &dramchr); + } - // RAS Active to precharge (tRAS) - tras = ((dramtlr >> 12) & 0xF) + 3; - dprint(LINE_CPU+6, col2, tras, 1 ,0); - (tras < 10)?(col2 += 1):(col2 += 2); - cprint(LINE_CPU+6, col2, "-"); - col2 += 1; + pci_conf_read(0, 24, 2, 0x88+offset, 4, &dramtlr); + pci_conf_read(0, 24, 2, 0x110, 4, &dramclr); + + // CAS Latency (tCAS) + if(((dramchr >> 8)&1) || ((dramchr & 0x7) == 0x4)){ + // DDR3 or DDR2-1066 + cas = (dramtlr & 0xF) + 4; + rcd = ((dramtlr >> 4) & 0x7) + 5; + rp = ((dramtlr >> 7) & 0x7) + 5; + ras = ((dramtlr >> 12) & 0xF) + 15; + rc = ((dramtlr >> 16) & 0x1F) + 11; + } else { + // DDR2-800 or less + cas = (dramtlr & 0xF) + 1; + rcd = ((dramtlr >> 4) & 0x3) + 3; + rp = ((dramtlr >> 8) & 0x3) + 3; + ras = ((dramtlr >> 12) & 0xF) + 3; + rc = ((dramtlr >> 16) & 0x1F) + 11; + } - // Row Cycle Time (tRC) - trp = ((dramtlr >> 16) & 0x1F) + 11; - dprint(LINE_CPU+6, col2, trp , 1 ,0); - col2 +=2; + print_timings_info(cas, rcd, rp, ras); - cprint(LINE_CPU+6, col2+1, "/"); col2 +=2; + cprint(LINE_CPU+6, col2, "/"); col2++; //Print DDR2 or DDR3 if ((dramchr >> 8)&1) { - cprint(LINE_CPU+6, col2+1, "DDR-3"); + cprint(LINE_CPU+6, col2+1, "DDR3"); } else { - cprint(LINE_CPU+6, col2+1, "DDR-2"); + cprint(LINE_CPU+6, col2+1, "DDR2"); } - col2 += 6; + col2 += 5; // Print 64 or 128 bits mode - if ((dramclr >> 4)&1) { - cprint(LINE_CPU+6, col2+1, "(Dual)"); - } else { - cprint(LINE_CPU+6, col2+1, "(Single)"); - } + if ((dramclr >> 4)&1) { + cprint(LINE_CPU+6, col2+1, "(128 bits)"); + } else { + cprint(LINE_CPU+6, col2+1, "(64 bits)"); + } } @@ -2948,8 +2979,6 @@ static struct pci_memory_controller controllers[] = { { 0x1022, 0x7006, "AMD 751", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd751, poll_amd751 }, { 0x1022, 0x700c, "AMD 762", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd76x, poll_amd76x }, { 0x1022, 0x700e, "AMD 761", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd76x, poll_amd76x }, - { 0x1022, 0x0000, "AMD K8", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, - { 0x1022, 0x0000, "AMD K10", 0, poll_fsb_k10, poll_timings_k10, setup_k10, poll_nothing }, /* SiS */ { 0x1039, 0x0600, "SiS 600", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, @@ -3081,12 +3110,13 @@ static struct pci_memory_controller controllers[] = { { 0x8086, 0x5020, "Intel EP80579", 0, poll_fsb_p4, poll_timings_EP80579, setup_nothing, poll_nothing }, { 0x8086, 0x8100, "Intel US15W", 0, poll_fsb_us15w, poll_timings_us15w, setup_nothing, poll_nothing}, { 0x8086, 0x8101, "Intel UL11L/US15L", 0, poll_fsb_us15w, poll_timings_us15w, setup_nothing, poll_nothing}, - { 0x8086, 0x3400, "NHM IMC", 0, poll_fsb_nhm, poll_timings_nhm, setup_nhm, poll_nothing}, - { 0x8086, 0x3401, "NHM IMC", 0, poll_fsb_nhm, poll_timings_nhm, setup_nhm, poll_nothing}, - { 0x8086, 0x3402, "NHM IMC", 0, poll_fsb_nhm, poll_timings_nhm, setup_nhm, poll_nothing}, - { 0x8086, 0x3403, "NHM IMC", 0, poll_fsb_nhm, poll_timings_nhm, setup_nhm, poll_nothing}, - { 0x8086, 0x3404, "NHM IMC", 0, poll_fsb_nhm, poll_timings_nhm, setup_nhm, poll_nothing}, - { 0x8086, 0x3405, "NHM IMC", 0, poll_fsb_nhm, poll_timings_nhm, setup_nhm, poll_nothing} + + /* Integrated Memory Controllers */ + { 0xFFFF, 0x0001, "Core IMC", 0, poll_fsb_nhm, poll_timings_nhm, setup_nhm, poll_nothing}, + { 0xFFFF, 0x0002, "Core IMC2", 0, poll_fsb_nhm, poll_timings_nothing, setup_nhm, poll_nothing}, + { 0xFFFF, 0x0100, "AMD K8 IMC", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, + { 0xFFFF, 0x0101, "AMD K10 IMC", 0, poll_fsb_k10, poll_timings_k10, setup_k10, poll_nothing } + }; static void print_memory_controller(void) @@ -3155,7 +3185,6 @@ static void print_memory_controller(void) col += 9; } - /* Print advanced caracteristics */ col2 = 0; d = get_key(); @@ -3176,6 +3205,10 @@ void find_controller(void) int result; result = pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, PCI_VENDOR_ID, 2, &vendor); result = pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, PCI_DEVICE_ID, 2, &device); + + // Detect IMC by CPUID + if(imc_type) { vendor = 0xFFFF; device = imc_type; } + ctrl.index = 0; if (result == 0) { for(i = 1; i < sizeof(controllers)/sizeof(controllers[0]); i++) { @@ -3185,12 +3218,6 @@ void find_controller(void) } } } - - // AMD K8 use integrated mem controller, force detection - if (cpu_id.type == 15 && cpu_id.vend_id[0] == 'A') { ctrl.index = 4; } - - // Same thing for K10. Detect by cpu_id.model = 2, will change it to ext.cpuid > 10 later - if (cpu_id.type == 15 && cpu_id.vend_id[0] == 'A' && cpu_id.model == 2) { ctrl.index = 5; } controllers[ctrl.index].setup_ecc(); /* Don't enable ECC polling by default unless it has @@ -0,0 +1,258 @@ +/* + * cpuid.c -- + * + * Implements CPUID querying functions + * + */ +#include "cpuid.h" + +cpuid_t cpuid_data0; +cpuid_t cpuid_data80; + +unsigned num_logical_cpus = 1; // number of logical cpus per physical package +unsigned num_cores_per_package = 1; // number of cores in each physical cpu package +unsigned num_hyper_threads_per_core = 1; // number of hyper-threads per core + +void +cpuid_get(unsigned n, cpuid_t *data) +{ + data->eax = n; + GET_CPUID(data->eax, data->ebx, data->ecx, data->edx); +} + + +/* cpuid_get_vendor_string --- + * + * This function gets the vendor string from the processor's cpuid instruction + * and passes it back to the caller in an easy to use structure. + */ +cpuid_vendor_string_t +cpuid_get_vendor_string(void) +{ + static cpuid_vendor_string_t v; + + /* Note: the string gets passed in EBX-EDX-ECX, not the intuitive order. */ + v.uint32_array[0] = cpuid_data0.ebx; + v.uint32_array[1] = cpuid_data0.edx; + v.uint32_array[2] = cpuid_data0.ecx; + v.char_array[CPUID_VENDOR_STR_LENGTH-1] = '\0'; + return v; +} + + +/* cpuid_get_version --- + * + * This function reads the processors version information using CPUID and puts + * it into a union for easy use by the caller. + */ +cpuid_version_t +cpuid_get_version(void) +{ + cpuid_version_t v; + uint32_t junkEBX = 0, junkECX = 0, junkEDX = 0; + v.flat = 0x1; + GET_CPUID(v.flat, junkEBX, junkECX, junkEDX); + return v; +} + + +cpuid_feature_flags_t +cpuid_get_feature_flags(void) +{ + cpuid_feature_flags_t f; + uint32_t junkEAX = 0x1, junkEBX = 0; + GET_CPUID(junkEAX, junkEBX, f.uint32_array[1], f.uint32_array[0]); + return f; +} + + +/* + *----------------------------------------------------------------------------- + * + * cpuid_get_ext_feature_flags -- + * + * Passes back the caller the extended feature flags supported by + * this CPU. This can be used, among other things, to determine if the + * processor supports long mode. + * + * Results: + * Returns TRUE if the processor supports the extended feature flags + * CPUID node, and FALSE otherwise. + * + * Side effects: + * Calls CPUID a couple of times. + * + *----------------------------------------------------------------------------- + */ + +bool +cpuid_get_ext_feature_flags(cpuid_ext_feature_flags_t *f) // OUT: Flags for this CPU +{ + uint32_t eax, ebx, ecx; + + if (cpuid_data80.eax < 0x80000001) { + // Extended feature flags not supported on this CPU + return FALSE; + } + eax = CPUID_EXTENDED_FEATURE; + GET_CPUID(eax, ebx, ecx, f->flat); + return TRUE; +} + +#define CHAR_TO_INT(a,b,c,d) ((a) + (b) * 0x100 + (c) * 0x10000 + (d) * 0x1000000) + +bool +cpuid_is_vendor_amd(void) +{ + return cpuid_data0.ebx == CHAR_TO_INT('A', 'u', 't', 'h') + && cpuid_data0.edx == CHAR_TO_INT('e', 'n', 't', 'i') + && cpuid_data0.ecx == CHAR_TO_INT('c', 'A', 'M', 'D'); +} + + +bool +cpuid_is_vendor_intel(void) +{ + return cpuid_data0.ebx == CHAR_TO_INT('G', 'e', 'n', 'u') + && cpuid_data0.edx == CHAR_TO_INT('i', 'n', 'e', 'I') + && cpuid_data0.ecx == CHAR_TO_INT('n', 't', 'e', 'l'); +} + + +/* + *----------------------------------------------------------------------------- + * + * cpuid_is_family_p4 -- + * + * Returns TRUE if the processor we're running on is an Intel processor + * of the P4 family. + * + * Results: + * The obvious. + * + *----------------------------------------------------------------------------- + */ + +bool +cpuid_is_family_p4(void) +{ + cpuid_version_t v = cpuid_get_version(); + + return cpuid_is_vendor_intel() && v.bits.family == CPUID_FAMILY_EXTENDED && + v.bits.extendedFamily == CPUID_EXTENDED_FAMILY_PENTIUM4; +} + + +/* + *----------------------------------------------------------------------------- + * + * cpuid_is_family_p6 -- + * + * Returns TRUE if the processor we're running on belongs to the P6 family. + * + * Results: + * The obvious. + * + *----------------------------------------------------------------------------- + */ + +bool +cpuid_is_family_p6(void) +{ + cpuid_version_t v = cpuid_get_version(); + + return cpuid_is_vendor_intel() && v.bits.family == CPUID_FAMILY_P6; +} + + +/* + *----------------------------------------------------------------------------- + * + * cpuid_is_family_opteron -- + * + * Returns TRUE if the processor we're running on belongs to the + * Opteron family. + * + *----------------------------------------------------------------------------- + */ + +bool +cpuid_is_family_opteron(void) +{ + cpuid_version_t v = cpuid_get_version(); + return cpuid_is_vendor_amd() && CPUID_FAMILY_IS_OPTERON(v.flat); +} + + +/* + *----------------------------------------------------------------------------- + * + * cpuid_init -- + * + * Executes CPUID and caches values in cpuid_data0 abd cpuid_data80. + * + *----------------------------------------------------------------------------- + */ +void +cpuid_init(void) +{ + //bool htt = FALSE; + cpuid_t id1; + + /* First get the basic cpuid information on what the + * type of the processor is , i.e intel or amd etc + * and how much of extra cpuid information is available + * with the processor + */ + cpuid_data0.eax = 0; + GET_CPUID(cpuid_data0.eax, cpuid_data0.ebx, + cpuid_data0.ecx, cpuid_data0.edx); + + + /* Find out if hyper-threading is available and there is more than one + * logical processor. See section 7.6.3 in Intel IA-32 volume III. + */ + cpuid_get(1, &id1); + + if (cpuid_is_vendor_intel()) { + if (cpuid_is_family_p6()) { + // Extended CPUID features not supported on PIII + return; + } + if (cpuid_is_family_p4()) { + /* + * Multi-core processors have the HT feature bit set (even if they + * don't support HT). + * The number of HT is the total number, not per-core number. + * The number of cores is off by 1, i.e. single-core reports 0. + */ + //htt = id1.edx & CPUID_FEATURE_COMMON_ID1EDX_HT; + if (id1.edx & CPUID_FEATURE_COMMON_ID1EDX_HT) { + num_hyper_threads_per_core = (id1.ebx >> 16) & 0xff; + if (cpuid_max_func() >= 4) { + cpuid_t id4; + cpuid_get(4, &id4); + num_cores_per_package = ((id4.eax >> 26) & 0x3f) + 1; + num_hyper_threads_per_core /= num_cores_per_package; + } + } + } + } else if (cpuid_is_vendor_amd()) { + cpuid_data80.eax = 0x80000000; + GET_CPUID(cpuid_data80.eax, cpuid_data80.ebx, + cpuid_data80.ecx, cpuid_data80.edx); + if (cpuid_max_ext_func() >= 0x80000008) { + /* Number of cores is reported in extended function 0x80000008 + * For legacy multi-core support, AMD CPUs report the number of + * cores as hyper-threads. Adjust the numbers to reflect that there + * are no threads. + */ + cpuid_t id88; + cpuid_get(0x80000008, &id88); + num_cores_per_package = id88.ecx & 0xff; + num_hyper_threads_per_core = 1; + } + } else { + /* Unknown cpu type. we use the defaults */ + } +} @@ -0,0 +1,217 @@ +/* + * cpuid.h -- + * + * contains the data structures required for CPUID + * implementation. + * + */ + +#ifndef _CPUID_H_ +#define _CPUID_H_ +#include "stdint.h" +#include "defs.h" +#include "smp.h" + +#define CPUID_EXTENDED_BASE 0x80000000 +#define CPUID_EXTENDED_FEATURE 0x80000001 +#define CPUID_EXTENDED_BRAND1 0x80000002 +#define CPUID_EXTENDED_BRAND2 0x80000003 +#define CPUID_EXTENDED_BRAND3 0x80000004 + +#define CPUID_VENDOR_LENGTH 3 /* 3 GPRs hold vendor ID */ +#define CPUID_VENDOR_STR_LENGTH (CPUID_VENDOR_LENGTH * sizeof(uint32_t) + 1) +#define CPUID_BRAND_LENGTH 12 /* 12 GPRs hold vendor ID */ +#define CPUID_BRAND_STR_LENGTH (CPUID_BRAND_LENGTH * sizeof(uint32_t) + 1) + +#define CPUID_FAMILY(_eax) (((_eax) >> 8) & 0xf) +/* Intel CPU Family */ +#define CPUID_FAMILY_486 4 +#define CPUID_FAMILY_P5 5 +#define CPUID_FAMILY_P6 6 +#define CPUID_FAMILY_EXTENDED 15 + +#define CPUID_EXTENDED_FAMILY(_eax) (((_eax) >> 20) & 0xff) +#define CPUID_EXTENDED_FAMILY_PENTIUM4 0 +#define CPUID_EXTENDED_FAMILY_OPTERON 0 + + +#define CPUID_FAMILY_IS_OPTERON(_eax) \ + (CPUID_FAMILY(_eax) == CPUID_FAMILY_EXTENDED && \ + CPUID_EXTENDED_FAMILY(_eax) == CPUID_EXTENDED_FAMILY_OPTERON) +#define CPUID_FEATURE_COMMON_ID1EDX_HT 0x10000000 /* 28 */ + + +typedef struct { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; +} cpuid_t; + +/* cached CPUID data for CPUID(0) and CPUID(0x80000000) */ +extern cpuid_t cpuid_data0; +extern cpuid_t cpuid_data80; + + +static inline unsigned +cpuid_max_func() +{ + return cpuid_data0.eax; +} + + +static inline unsigned +cpuid_max_ext_func() +{ + return cpuid_data80.eax; +} + + +/* Typedef for storing the CPUID Vendor String */ +typedef union { + /* Note: the extra byte in the char array is for '\0'. */ + char char_array[CPUID_VENDOR_STR_LENGTH]; + uint32_t uint32_array[CPUID_VENDOR_LENGTH]; +} cpuid_vendor_string_t; + +/* Typedef for storing the CPUID Brand String */ +typedef union { + /* Note: the extra byte in the char array is for '\0'. */ + char char_array[CPUID_BRAND_STR_LENGTH]; + uint32_t uint32_array[CPUID_BRAND_LENGTH]; +} cpuid_brand_string_t; + +/* Typedef for storing CPUID Version */ +typedef union { + uint32_t flat; + struct { + uint32_t stepping:4; /* Bit 0 */ + uint32_t model:4; + uint32_t family:4; + uint32_t processorType:2; + uint32_t reserved1514:2; + uint32_t extendedModel:4; + uint32_t extendedFamily:8; + uint32_t reserved3128:4; /* Bit 31 */ + } bits; +} cpuid_version_t; + +/* Typedef for storing CPUID Processor Information */ +typedef union { + uint32_t flat; + struct { + uint32_t brandIndex:8; /* Bit 0 */ + uint32_t cflushLineSize:8; + uint32_t logicalProcessorCount:8; + uint32_t apicID:8; /* Bit 31 */ + } bits; +} cpuid_proc_info_t; + +/* Typedef for storing CPUID Feature flags */ +typedef union { + uint64_t flat; + uint32_t uint32_array[2]; + struct { + uint32_t fpu:1; /* Bit 0 */ + uint32_t vme:1; + uint32_t de:1; + uint32_t pse:1; + uint32_t tsc:1; + uint32_t msr:1; + uint32_t pae:1; + uint32_t mce:1; + uint32_t cx8:1; + uint32_t apic:1; + uint32_t reserved10:1; + uint32_t sep:1; + uint32_t mtrr:1; + uint32_t pge:1; + uint32_t mca:1; + uint32_t cmov:1; + uint32_t pat:1; + uint32_t pse36:1; + uint32_t psn:1; + uint32_t cflush:1; + uint32_t reserved20:1; + uint32_t ds:1; + uint32_t acpi:1; + uint32_t mmx:1; + uint32_t fxsr:1; + uint32_t sse:1; + uint32_t sse2:1; + uint32_t ss:1; + uint32_t htt:1; + uint32_t tm:1; + uint32_t reserved30:1; + uint32_t pbe:1; /* Bit 31 */ + uint32_t sse3:1; /* Bit 32 */ + uint32_t reserved3433:2; + uint32_t monitor:1; + uint32_t dscpl:1; + uint32_t reserved3937:3; + uint32_t tm2:1; + uint32_t reserved41:1; + uint32_t cnxtid:1; + uint32_t reserved4443:2; + uint32_t cmpxchg16b:1; + uint32_t reserved6346:18; /* Bit 63 */ + } bits; +} cpuid_feature_flags_t; + +/* Feature flags returned by extended CPUID node function 8000_0001. */ +typedef union { + uint64_t flat; + uint32_t uint32_array[2]; + struct { + uint32_t fpu:1; /* Bit 0 */ + uint32_t vme:1; + uint32_t de:1; + uint32_t pse:1; + uint32_t tsc:1; + uint32_t msr:1; + uint32_t pae:1; + uint32_t mce:1; + uint32_t cx8:1; + uint32_t apic:1; + uint32_t reserved10:1; + uint32_t sep:1; + uint32_t mtrr:1; + uint32_t pge:1; + uint32_t mca:1; + uint32_t cmov:1; + uint32_t pat:1; + uint32_t pse36:1; + uint32_t reserved1918:2; + uint32_t nx:1; + uint32_t reserved21:1; + uint32_t mmxamd:1; + uint32_t mmx:1; + uint32_t fxsr:1; + uint32_t ffxsr:1; + uint32_t reserved26:1; + uint32_t rdtscp:1; + uint32_t reserved28:1; + uint32_t lm:1; + uint32_t threedeenowext:1; + uint32_t threedeenow:1; /* Bit 31 */ + uint32_t lahf:1; /* Bit 32 */ + uint32_t cmplegacy:1; + uint32_t reserved3534:2; + uint32_t cr8avail:1; + uint32_t reserved6337:27; /* Bit 63 */ + } bits; +} cpuid_ext_feature_flags_t; + +void cpuid_get(unsigned n, cpuid_t *data); +cpuid_vendor_string_t cpuid_get_vendor_string(void); +cpuid_version_t cpuid_get_version(void); +cpuid_feature_flags_t cpuid_get_feature_flags(void); +bool cpuid_get_ext_feature_flags(cpuid_ext_feature_flags_t *f); +bool cpuid_is_vendor_amd(void); +bool cpuid_is_vendor_intel(void); +bool cpuid_is_family_p6(void); +bool cpuid_is_family_p4(void); +bool cpuid_is_family_opteron(void); +void cpuid_init(void); + +#endif @@ -5,8 +5,7 @@ * * Release under the GPL version 2 * ---------------------------------------------------- - * Memtest86+ V1.70 - Added compliance with SMBIOS Spec V2.5 - * - Support for FB-DIMM + * Memtest86+ V4.00 - Added compliance with SMBIOS Spec V2.6.1 */ @@ -89,15 +88,13 @@ static char *form_factors[] = { "SODIMM", "SRIMM", "FB-DIMM" }; -// Slot 1 is "Other", according to SMBIOS 2.6. -// BTW, SMBIOS 2.6 doesn't yet recognize DDR3 and I replaced Other to DDR3 -// Need fix as soon as SMBIOS will take DDR3 into consideration static char *memory_types[] = { "?", - "DDR3", "Unknown", "DRAM", "EDRAM", "VRAM", "SRAM", "RAM", + "Other", "Unknown", "DRAM", "EDRAM", "VRAM", "SRAM", "RAM", "ROM", "FLASH", "EEPROM", "FEPROM", "EPROM", "CDRAM", "3DRAM", - "SDRAM", "SGRAM", "RDRAM", "DDR", "DDR2", "DDR2 FB" + "SDRAM", "SGRAM", "RDRAM", "DDR", "DDR2", "DDR2 FB", "RSVD", + "RSVD","RSVD","DDR3","FBD2" }; @@ -4,7 +4,7 @@ * Released under version 2 of the Gnu Public License. * By Chris Brady, cbrady@sgi.com * ---------------------------------------------------- - * MemTest86+ V2.01 Specific code (GPL V2.0) + * MemTest86+ V4.00 Specific code (GPL V2.0) * By Samuel DEMEULEMEESTER, sdemeule@memtest.org * http://www.canardpc.com - http://www.memtest.org */ @@ -13,6 +13,7 @@ #include "config.h" #include <sys/io.h> #include "dmi.h" +#define NULL 0 extern int test_ticks, nticks, beepmode; extern struct tseq tseq[]; @@ -158,7 +159,7 @@ void common_err( ulong *adr, ulong good, ulong bad, ulong xor, int type) hprint2(LINE_HEADER+1, 33, offset, 3); cprint(LINE_HEADER+1, 36, " - . MB"); dprint(LINE_HEADER+1, 39, mb, 5, 0); - dprint(LINE_HEADER+1, 45, ((page & 0xF)*10)/16, 1, 0); + dprint(LINE_HEADER+1, 45, ((page & 0xFF)*10)/256, 1, 0); page = v->erri.high_addr.page; offset = v->erri.high_addr.offset; mb = page >> 8; @@ -166,7 +167,7 @@ void common_err( ulong *adr, ulong good, ulong bad, ulong xor, int type) hprint2(LINE_HEADER+2, 33, offset, 3); cprint(LINE_HEADER+2, 36, " - . MB"); dprint(LINE_HEADER+2, 39, mb, 5, 0); - dprint(LINE_HEADER+2, 45, ((page & 0xF)*10)/16, 1, 0); + dprint(LINE_HEADER+2, 45, ((page & 0xFF)*10)/256, 1, 0); hprint(LINE_HEADER+3, 25, v->erri.ebits); dprint(LINE_HEADER+4, 25, n, 2, 1); dprint(LINE_HEADER+4, 34, v->erri.min_bits, 2, 1); @@ -228,7 +229,7 @@ void common_err( ulong *adr, ulong good, ulong bad, ulong xor, int type) hprint2(v->msg_line, 19, offset, 3); cprint(v->msg_line, 22, " - . MB"); dprint(v->msg_line, 25, mb, 5, 0); - dprint(v->msg_line, 31, ((page & 0xF)*10)/16, 1, 0); + dprint(v->msg_line, 31, ((page & 0xFF)*10)/256, 1, 0); if (type == 3) { /* ECC error */ @@ -439,7 +440,15 @@ void do_tick(void) nticks++; v->total_ticks++; - pct = 100*nticks/test_ticks; + if (test_ticks) { + pct = 100*nticks/test_ticks; + if (pct > 100) { + pct = 100; + } + } else { + pct = 0; + } + dprint(1, COL_MID+4, pct, 3, 0); i = (BAR_SIZE * pct) / 100; while (i > v->tptr) { @@ -450,7 +459,12 @@ void do_tick(void) v->tptr++; } - pct = 100*v->total_ticks/v->pass_ticks; + if (v->pass_ticks) { + pct = 100*v->total_ticks/v->pass_ticks; + if (pct > 100) { pct = 100; } + } else { + pct = 0; + } dprint(0, COL_MID+4, pct, 3, 0); i = (BAR_SIZE * pct) / 100; while (i > v->pptr) { @@ -3,7 +3,7 @@ * Released under version 2 of the Gnu Public License. * By Chris Brady, cbrady@sgi.com * ---------------------------------------------------- - * MemTest86+ V2.11 Specific code (GPL V2.0) + * MemTest86+ V4.00 Specific code (GPL V2.0) * By Samuel DEMEULEMEESTER, sdemeule@memtest.org * http://www.canardpc.com - http://www.memtest.org */ @@ -14,6 +14,7 @@ #include "controller.h" #include "pci.h" #include "io.h" +#include "spd.h" #define rdmsr(msr,val1,val2) \ __asm__ __volatile__("rdmsr" \ @@ -31,6 +32,7 @@ ulong st_low, st_high; ulong end_low, end_high; ulong cal_low, cal_high; ulong extclock; +unsigned long imc_type = 0; int l1_cache, l2_cache, l3_cache; int tsc_invariable = 0; @@ -63,7 +65,7 @@ static void display_init(void) for(i=0, pp=(char *)(SCREEN_ADR+1); i<TITLE_WIDTH; i++, pp+=2) { *pp = 0x20; } - cprint(0, 0, " Memtest86 v2.11 "); + cprint(0, 0, " Memtest86 v4.00 "); for(i=0, pp=(char *)(SCREEN_ADR+1); i<2; i++, pp+=30) { *pp = 0xA4; @@ -133,7 +135,7 @@ void init(void) v->erri.ebits = 0; v->erri.hdr_flag = 0; v->erri.tbits = 0; - for (i=0; tseq[i].msg != NULL; i++) { + for (i=0; tseq[i].msg != 0; i++) { tseq[i].errors = 0; } if (dmi_initialized) { @@ -153,9 +155,12 @@ void init(void) cpu_type(); - /* Find the memory controller (inverted from standard) */ + /* Find the memory controller */ find_controller(); + /* Find Memory Specs */ + get_spd_spec(); + if (v->rdtsc) { cacheable(); cprint(LINE_TIME, COL_TIME+4, ": :"); @@ -181,7 +186,6 @@ void init(void) // v->printmode=PRINTMODE_SUMMARY; v->printmode=PRINTMODE_ADDRESSES; v->numpatn=0; - find_ticks(); } @@ -443,6 +447,14 @@ void cpu_type(void) l2_cache = (cpu_id.cache_info[11] << 8); l2_cache += cpu_id.cache_info[10]; break; + case 10: + cprint(LINE_CPU, 0, "AMD Geode LX"); + off = 12; + l1_cache = cpu_id.cache_info[3]; + l1_cache += cpu_id.cache_info[7]; + l2_cache = (cpu_id.cache_info[11] << 8); + l2_cache += cpu_id.cache_info[10]; + break; case 13: cprint(LINE_CPU, 0, "AMD K6-III+"); off = 11; @@ -511,59 +523,77 @@ void cpu_type(void) l1_cache = cpu_id.cache_info[3]; l2_cache = (cpu_id.cache_info[11] << 8); l2_cache += cpu_id.cache_info[10]; - switch(cpu_id.model) { - default: - cprint(LINE_CPU, 0, "AMD K8"); - off = 6; - break; - case 1: - case 5: - if (((cpu_id.ext >> 16) & 0xF) != 0) { - cprint(LINE_CPU, 0, "AMD Opteron (0.09)"); - } else { - cprint(LINE_CPU, 0, "AMD Opteron (0.13)"); - } - off = 18; - break; - case 3: - case 11: - cprint(LINE_CPU, 0, "Athlon 64 X2"); - off = 12; - break; - case 8: - cprint(LINE_CPU, 0, "Turion 64 X2"); - off = 12; - break; - case 4: - case 7: - case 9: - case 12: - case 14: - case 15: - if (((cpu_id.ext >> 16) & 0xF) != 0) { - if (l2_cache > 256) { - cprint(LINE_CPU, 0, "Athlon 64 (0.09)"); + imc_type = 0x0100; + if(((cpu_id.ext >> 16) & 0xFF) < 0x10) { + // Here if CPUID.EXT < 0x10h (old K8/K10) + switch(cpu_id.model) { + default: + cprint(LINE_CPU, 0, "AMD K8"); + off = 6; + break; + case 1: + case 5: + if (((cpu_id.ext >> 16) & 0xF) != 0) { + cprint(LINE_CPU, 0, "AMD Opteron (0.09)"); } else { - cprint(LINE_CPU, 0, "Sempron (0.09)"); + cprint(LINE_CPU, 0, "AMD Opteron (0.13)"); } - } else { - if (l2_cache > 256) { - cprint(LINE_CPU, 0, "Athlon 64 (0.13)"); + off = 18; + break; + case 3: + case 11: + cprint(LINE_CPU, 0, "Athlon 64 X2"); + off = 12; + break; + case 8: + cprint(LINE_CPU, 0, "Turion 64 X2"); + off = 12; + break; + case 4: + case 7: + case 12: + case 14: + case 15: + if (((cpu_id.ext >> 16) & 0xF) != 0) { + if (l2_cache > 256) { + cprint(LINE_CPU, 0, "Athlon 64 (0.09)"); + } else { + cprint(LINE_CPU, 0, "Sempron (0.09)"); + } } else { - cprint(LINE_CPU, 0, "Sempron (0.13)"); - } + if (l2_cache > 256) { + cprint(LINE_CPU, 0, "Athlon 64 (0.13)"); + } else { + cprint(LINE_CPU, 0, "Sempron (0.13)"); + } + } + off = 16; + break; } - off = 16; break; - case 2: + } else { + // Here if CPUID.EXT >= 0x10h (new K10) l3_cache = (cpu_id.cache_info[15] << 8); l3_cache += (cpu_id.cache_info[14] >> 2); l3_cache *= 512; - cprint(LINE_CPU, 0, "AMD K10 CPU @"); - off = 13; - break; + imc_type = 0x0101; + switch(cpu_id.model) { + default: + case 2: + cprint(LINE_CPU, 0, "AMD K10 (65nm) @"); + off = 16; + break; + case 4: + cprint(LINE_CPU, 0, "AMD K10 (45nm) @"); + off = 16; + break; + case 9: + cprint(LINE_CPU, 0, "AMD Magny-Cours"); + off = 15; + break; + } + break; } - break; } break; @@ -697,25 +727,54 @@ void cpu_type(void) case 0x4e: l2_cache = 6144; break; + case 0x22: + case 0xd0: + l3_cache = 512; + case 0x23: case 0xd1: case 0xd6: l3_cache = 1024; break; + case 0xdc: + l3_cache = 1536; + break; + case 0x25: case 0xd2: case 0xd7: - case 0xdc: case 0xe2: l3_cache = 2048; break; - case 0xd8: case 0xdd: + l3_cache = 3072; + break; + case 0x29: + case 0x46: + case 0xd8: case 0xe3: l3_cache = 4096; break; + case 0x4a: case 0xde: + l3_cache = 6144; + break; + case 0x47: + case 0x4b: case 0xe4: l3_cache = 8192; break; + case 0x4c: + case 0xea: + l3_cache = 12288; + break; + case 0x4d: + l3_cache = 16374; + break; + case 0xeb: + l3_cache = 18432; + break; + case 0xec: + l3_cache = 24576; + break; } } @@ -755,10 +814,17 @@ void cpu_type(void) off = 10; break; case 5: - if (((cpu_id.ext >> 16) & 0xF) != 0) { - cprint(LINE_CPU, 0, "Intel EP80579"); - if (l2_cache == 0) { l2_cache = 256; } - off = 13; + if ((cpu_id.ext >> 16) & 0xF) { + if(((cpu_id.ext >> 16) & 0xF) > 1) { + cprint(LINE_CPU, 0, "Intel Core i3/i5"); + tsc_invariable = 1; + imc_type = 0x0002; + off = 16; + } else { + cprint(LINE_CPU, 0, "Intel EP80579"); + if (l2_cache == 0) { l2_cache = 256; } + off = 13; + } } else { if (l2_cache == 0) { cprint(LINE_CPU, 0, "Celeron"); @@ -811,6 +877,7 @@ void cpu_type(void) case 10: if (((cpu_id.ext >> 16) & 0xF) != 0) { tsc_invariable = 1; + imc_type = 0x0001; cprint(LINE_CPU, 0, "Intel Core i7"); off = 13; } else { @@ -819,9 +886,16 @@ void cpu_type(void) } break; case 12: - l1_cache = 24; - cprint(LINE_CPU, 0, "Atom (0.045)"); - off = 12; + if (((cpu_id.ext >> 16) & 0xF) > 1) { + cprint(LINE_CPU, 0, "Intel Core i9"); + tsc_invariable = 1; + imc_type = 0x0002; + off = 13; + } else { + l1_cache = 24; + cprint(LINE_CPU, 0, "Atom (0.045)"); + off = 12; + } break; case 13: if (l2_cache == 1024) { @@ -834,8 +908,9 @@ void cpu_type(void) case 14: if (((cpu_id.ext >> 16) & 0xF) != 0) { tsc_invariable = 1; - cprint(LINE_CPU, 0, "Intel Core i5"); - off = 13; + imc_type = 0x0001; + cprint(LINE_CPU, 0, "Intel Core i5/i7"); + off = 16; } else { cprint(LINE_CPU, 0, "Intel Core"); off = 10; diff --git a/jedec_id.h b/jedec_id.h new file mode 100644 index 0000000..6694c17 --- /dev/null +++ b/jedec_id.h @@ -0,0 +1,887 @@ +/* MemTest86+ V4.00 Specific code (GPL V2.0)
+ * By Samuel DEMEULEMEESTER, sdemeule@memtest.org
+ * http://www.canardpc.com - http://www.memtest.org
+ */
+
+struct spd_jedec_manufacturer {
+ unsigned cont_code;
+ unsigned hex_byte;
+ char *name;
+};
+
+struct spd_jedec_manufacturer jep106[] = {
+ { 0, 0x01, "AMD"},
+ { 0, 0x02, "AMI"},
+ { 0, 0x83, "Fairchild"},
+ { 0, 0x04, "Fujitsu"},
+ { 0, 0x85, "GTE"},
+ { 0, 0x86, "Harris"},
+ { 0, 0x07, "Hitachi"},
+ { 0, 0x08, "Inmos"},
+ { 0, 0x89, "Intel"},
+ { 0, 0x8a, "I.T.T."},
+ { 0, 0x0b, "Intersil"},
+ { 0, 0x8c, "Monolithic Memories"},
+ { 0, 0x0d, "Mostek"},
+ { 0, 0x0e, "Freescale (Motorola)"},
+ { 0, 0x8f, "National"},
+ { 0, 0x10, "NEC"},
+ { 0, 0x91, "RCA"},
+ { 0, 0x92, "Raytheon"},
+ { 0, 0x13, "Conexant (Rockwell)"},
+ { 0, 0x94, "Seeq"},
+ { 0, 0x15, "NXP (Philips)"},
+ { 0, 0x16, "Synertek"},
+ { 0, 0x97, "Texas Instruments"},
+ { 0, 0x98, "Toshiba"},
+ { 0, 0x19, "Xicor"},
+ { 0, 0x1a, "Zilog"},
+ { 0, 0x9b, "Eurotechnique"},
+ { 0, 0x1c, "Mitsubishi"},
+ { 0, 0x9d, "Lucent (AT&T)"},
+ { 0, 0x9e, "Exel"},
+ { 0, 0x1f, "Atmel"},
+ { 0, 0x20, "SGS/Thomson"},
+ { 0, 0xa1, "Lattice Semi."},
+ { 0, 0xa2, "NCR"},
+ { 0, 0x23, "Wafer Scale Integration"},
+ { 0, 0xa4, "IBM"},
+ { 0, 0x25, "Tristar"},
+ { 0, 0x26, "Visic"},
+ { 0, 0xa7, "Intl. CMOS Technology"},
+ { 0, 0xa8, "SSSI"},
+ { 0, 0x29, "MicrochipTechnology"},
+ { 0, 0x2a, "Ricoh"},
+ { 0, 0xab, "VLSI"},
+ { 0, 0x2c, "Micron Technology"},
+ { 0, 0xad, "Hynix Semiconductor"},
+ { 0, 0xae, "OKI Semiconductor"},
+ { 0, 0x2f, "ACTEL"},
+ { 0, 0xb0, "Sharp"},
+ { 0, 0x31, "Catalyst"},
+ { 0, 0x32, "Panasonic"},
+ { 0, 0xb3, "IDT"},
+ { 0, 0x34, "Cypress"},
+ { 0, 0xb5, "DEC"},
+ { 0, 0xb6, "LSI Logic"},
+ { 0, 0x37, "Zarlink (Plessey)"},
+ { 0, 0x38, "UTMC"},
+ { 0, 0xb9, "Thinking Machine"},
+ { 0, 0xba, "Thomson CSF"},
+ { 0, 0x3b, "Integrated CMOS (Vertex)"},
+ { 0, 0xbc, "Honeywell"},
+ { 0, 0x3d, "Tektronix"},
+ { 0, 0x3e, "Sun Microsystems"},
+ { 0, 0xbf, "SST"},
+ { 0, 0x40, "ProMos/Mosel Vitelic"},
+ { 0, 0xc1, "Infineon (Siemens)"},
+ { 0, 0xc2, "Macronix"},
+ { 0, 0x43, "Xerox"},
+ { 0, 0xc4, "Plus Logic"},
+ { 0, 0x45, "SanDisk"},
+ { 0, 0x46, "Elan Circuit Tech."},
+ { 0, 0xc7, "European Silicon Str."},
+ { 0, 0xc8, "Apple Computer"},
+ { 0, 0x49, "Xilinx"},
+ { 0, 0x4a, "Compaq"},
+ { 0, 0xcb, "Protocol Engines"},
+ { 0, 0x4c, "SCI"},
+ { 0, 0xcd, "Seiko Instruments"},
+ { 0, 0xce, "Samsung"},
+ { 0, 0x4f, "I3 Design System"},
+ { 0, 0xd0, "Klic"},
+ { 0, 0x51, "Crosspoint Solutions"},
+ { 0, 0x52, "Alliance Semiconductor"},
+ { 0, 0xd3, "Tandem"},
+ { 0, 0x54, "Hewlett-Packard"},
+ { 0, 0xd5, "Intg. Silicon Solutions"},
+ { 0, 0xd6, "Brooktree"},
+ { 0, 0x57, "New Media"},
+ { 0, 0x58, "MHS Electronic"},
+ { 0, 0xd9, "Performance Semi."},
+ { 0, 0xda, "Winbond Electronic"},
+ { 0, 0x5b, "Kawasaki Steel"},
+ { 0, 0xdc, "Bright Micro"},
+ { 0, 0x5d, "TECMAR"},
+ { 0, 0x5e, "Exar"},
+ { 0, 0xdf, "PCMCIA"},
+ { 0, 0xe0, "LG Semi (Goldstar)"},
+ { 0, 0x61, "Northern Telecom"},
+ { 0, 0x62, "Sanyo"},
+ { 0, 0xe3, "Array Microsystems"},
+ { 0, 0x64, "Crystal Semiconductor"},
+ { 0, 0xe5, "Analog Devices"},
+ { 0, 0xe6, "PMC-Sierra"},
+ { 0, 0x67, "Asparix"},
+ { 0, 0x68, "Convex Computer"},
+ { 0, 0xe9, "Quality Semiconductor"},
+ { 0, 0xea, "Nimbus Technology"},
+ { 0, 0x6b, "Transwitch"},
+ { 0, 0xec, "Micronas (ITT Intermetall)"},
+ { 0, 0x6d, "Cannon"},
+ { 0, 0x6e, "Altera"},
+ { 0, 0xef, "NEXCOM"},
+ { 0, 0x70, "QUALCOMM"},
+ { 0, 0xf1, "Sony"},
+ { 0, 0xf2, "Cray Research"},
+ { 0, 0x73, "AMS(Austria Micro)"},
+ { 0, 0xf4, "Vitesse"},
+ { 0, 0x75, "Aster Electronics"},
+ { 0, 0x76, "Bay Networks (Synoptic)"},
+ { 0, 0xf7, "Zentrum/ZMD"},
+ { 0, 0xf8, "TRW"},
+ { 0, 0x79, "Thesys"},
+ { 0, 0x7a, "Solbourne Computer"},
+ { 0, 0xfb, "Allied-Signal"},
+ { 0, 0x7c, "Dialog"},
+ { 0, 0xfd, "Media Vision"},
+ { 0, 0xfe, "Numonyx"},
+ { 1, 0x01, "Cirrus Logic"},
+ { 1, 0x02, "National Instruments"},
+ { 1, 0x83, "ILC Data Device"},
+ { 1, 0x04, "Alcatel Mietec"},
+ { 1, 0x85, "Micro Linear"},
+ { 1, 0x86, "Univ. of NC"},
+ { 1, 0x07, "JTAG Technologies"},
+ { 1, 0x08, "BAE Systems (Loral)"},
+ { 1, 0x89, "Nchip"},
+ { 1, 0x8a, "Galileo Tech"},
+ { 1, 0x0b, "Bestlink Systems"},
+ { 1, 0x8c, "Graychip"},
+ { 1, 0x0d, "GENNUM"},
+ { 1, 0x0e, "VideoLogic"},
+ { 1, 0x8f, "Robert Bosch"},
+ { 1, 0x10, "Chip Express"},
+ { 1, 0x91, "DATARAM"},
+ { 1, 0x92, "United Microelectronics Corp."},
+ { 1, 0x13, "TCSI"},
+ { 1, 0x94, "Smart Modular"},
+ { 1, 0x15, "Hughes Aircraft"},
+ { 1, 0x16, "Lanstar Semiconductor"},
+ { 1, 0x97, "Qlogic"},
+ { 1, 0x98, "Kingston"},
+ { 1, 0x19, "Music Semi"},
+ { 1, 0x1a, "Ericsson Components"},
+ { 1, 0x9b, "SpaSE"},
+ { 1, 0x1c, "Eon Silicon Devices"},
+ { 1, 0x9d, "Programmable Micro Corp"},
+ { 1, 0x9e, "DoD"},
+ { 1, 0x1f, "Integ. Memories Tech."},
+ { 1, 0x20, "Corollary"},
+ { 1, 0xa1, "Dallas Semiconductor"},
+ { 1, 0xa2, "Omnivision"},
+ { 1, 0x23, "EIV(Switzerland)"},
+ { 1, 0xa4, "Novatel Wireless"},
+ { 1, 0x25, "Zarlink (Mitel)"},
+ { 1, 0x26, "Clearpoint"},
+ { 1, 0xa7, "Cabletron"},
+ { 1, 0xa8, "STEC (Silicon Tech)"},
+ { 1, 0x29, "Vanguard"},
+ { 1, 0x2a, "Hagiwara Sys-Com"},
+ { 1, 0xab, "Vantis"},
+ { 1, 0x2c, "Celestica"},
+ { 1, 0xad, "Century"},
+ { 1, 0xae, "Hal Computers"},
+ { 1, 0x2f, "Rohm Company"},
+ { 1, 0xb0, "Juniper Networks"},
+ { 1, 0x31, "Libit Signal Processing"},
+ { 1, 0x32, "Mushkin Enhanced Memory"},
+ { 1, 0xb3, "Tundra Semiconductor"},
+ { 1, 0x34, "Adaptec"},
+ { 1, 0xb5, "LightSpeed Semi."},
+ { 1, 0xb6, "ZSP Corp."},
+ { 1, 0x37, "AMIC Technology"},
+ { 1, 0x38, "Adobe Systems"},
+ { 1, 0xb9, "Dynachip"},
+ { 1, 0xba, "PNY Electronics"},
+ { 1, 0x3b, "Newport Digital"},
+ { 1, 0xbc, "MMC Networks"},
+ { 1, 0x3d, "T Square"},
+ { 1, 0x3e, "Seiko Epson"},
+ { 1, 0xbf, "Broadcom"},
+ { 1, 0x40, "Viking Components"},
+ { 1, 0xc1, "V3 Semiconductor"},
+ { 1, 0xc2, "Flextronics (Orbit Semiconductor)"},
+ { 1, 0x43, "Suwa Electronics"},
+ { 1, 0xc4, "Transmeta"},
+ { 1, 0x45, "Micron CMS"},
+ { 1, 0x46, "American Computer & Digital Components"},
+ { 1, 0xc7, "Enhance 3000"},
+ { 1, 0xc8, "Tower Semiconductor"},
+ { 1, 0x49, "CPU Design"},
+ { 1, 0x4a, "Price Point"},
+ { 1, 0xcb, "Maxim Integrated Product"},
+ { 1, 0x4c, "Tellabs"},
+ { 1, 0xcd, "Centaur Technology"},
+ { 1, 0xce, "Unigen"},
+ { 1, 0x4f, "Transcend Information"},
+ { 1, 0xd0, "Memory Card Technology"},
+ { 1, 0x51, "CKD"},
+ { 1, 0x52, "Capital Instruments"},
+ { 1, 0xd3, "Aica Kogyo"},
+ { 1, 0x54, "Linvex Technology"},
+ { 1, 0xd5, "MSC Vertriebs"},
+ { 1, 0xd6, "AKM Company"},
+ { 1, 0x57, "Dynamem"},
+ { 1, 0x58, "NERA ASA"},
+ { 1, 0xd9, "GSI Technology"},
+ { 1, 0xda, "Dane-Elec (C Memory)"},
+ { 1, 0x5b, "Acorn Computers"},
+ { 1, 0xdc, "Lara Technology"},
+ { 1, 0x5d, "Oak Technology"},
+ { 1, 0x5e, "Itec Memory"},
+ { 1, 0xdf, "Tanisys Technology"},
+ { 1, 0xe0, "Truevision"},
+ { 1, 0x61, "Wintec Industries"},
+ { 1, 0x62, "Super PC Memory"},
+ { 1, 0xe3, "MGV Memory"},
+ { 1, 0x64, "Galvantech"},
+ { 1, 0xe5, "Gadzoox Networks"},
+ { 1, 0xe6, "Multi Dimensional Cons."},
+ { 1, 0x67, "GateField"},
+ { 1, 0x68, "Integrated Memory System"},
+ { 1, 0xe9, "Triscend"},
+ { 1, 0xea, "XaQti"},
+ { 1, 0x6b, "Goldenram"},
+ { 1, 0xec, "Clear Logic"},
+ { 1, 0x6d, "Cimaron Communications"},
+ { 1, 0x6e, "Nippon Steel Semi. Corp."},
+ { 1, 0xef, "Advantage Memory"},
+ { 1, 0x70, "AMCC"},
+ { 1, 0xf1, "LeCroy"},
+ { 1, 0xf2, "Yamaha"},
+ { 1, 0x73, "Digital Microwave"},
+ { 1, 0xf4, "NetLogic Microsystems"},
+ { 1, 0x75, "MIMOS Semiconductor"},
+ { 1, 0x76, "Advanced Fibre"},
+ { 1, 0xf7, "BF Goodrich Data."},
+ { 1, 0xf8, "Epigram"},
+ { 1, 0x79, "Acbel Polytech"},
+ { 1, 0x7a, "Apacer Technology"},
+ { 1, 0xfb, "Admor Memory"},
+ { 1, 0x7c, "FOXCONN"},
+ { 1, 0xfd, "Quadratics Superconductor"},
+ { 1, 0xfe, "3COM"},
+ { 2, 0x01, "Camintonn"},
+ { 2, 0x02, "ISOA"},
+ { 2, 0x83, "Agate Semiconductor"},
+ { 2, 0x04, "ADMtek"},
+ { 2, 0x85, "HYPERTEC"},
+ { 2, 0x86, "Adhoc Technologies"},
+ { 2, 0x07, "MOSAID Technologies"},
+ { 2, 0x08, "Ardent Technologies"},
+ { 2, 0x89, "Switchcore"},
+ { 2, 0x8a, "Cisco Systems"},
+ { 2, 0x0b, "Allayer Technologies"},
+ { 2, 0x8c, "WorkX AG (Wichman)"},
+ { 2, 0x0d, "Oasis Semiconductor"},
+ { 2, 0x0e, "Novanet Semiconductor"},
+ { 2, 0x8f, "E-M Solutions"},
+ { 2, 0x10, "Power General"},
+ { 2, 0x91, "Advanced Hardware Arch."},
+ { 2, 0x92, "Inova Semiconductors"},
+ { 2, 0x13, "Telocity"},
+ { 2, 0x94, "Delkin Devices"},
+ { 2, 0x15, "Symagery Microsystems"},
+ { 2, 0x16, "C-Port"},
+ { 2, 0x97, "SiberCore Technologies"},
+ { 2, 0x98, "Southland Microsystems"},
+ { 2, 0x19, "Malleable Technologies"},
+ { 2, 0x1a, "Kendin Communications"},
+ { 2, 0x9b, "Great Technology Microcomputer"},
+ { 2, 0x1c, "Sanmina"},
+ { 2, 0x9d, "HADCO"},
+ { 2, 0x9e, "Corsair"},
+ { 2, 0x1f, "Actrans System"},
+ { 2, 0x20, "ALPHA Technologies"},
+ { 2, 0xa1, "Silicon Laboratories (Cygnal)"},
+ { 2, 0xa2, "Artesyn Technologies"},
+ { 2, 0x23, "Align Manufacturing"},
+ { 2, 0xa4, "Peregrine Semiconductor"},
+ { 2, 0x25, "Chameleon Systems"},
+ { 2, 0x26, "Aplus Flash Technology"},
+ { 2, 0xa7, "MIPS Technologies"},
+ { 2, 0xa8, "Chrysalis ITS"},
+ { 2, 0x29, "ADTEC"},
+ { 2, 0x2a, "Kentron Technologies"},
+ { 2, 0xab, "Win Technologies"},
+ { 2, 0x2c, "Tachyon Semiconductor (ASIC)"},
+ { 2, 0xad, "Extreme Packet Devices"},
+ { 2, 0xae, "RF Micro Devices"},
+ { 2, 0x2f, "Siemens AG"},
+ { 2, 0xb0, "Sarnoff"},
+ { 2, 0x31, "Itautec SA"},
+ { 2, 0x32, "Radiata"},
+ { 2, 0xb3, "Benchmark Elect. (AVEX)"},
+ { 2, 0x34, "Legend"},
+ { 2, 0xb5, "SpecTek"},
+ { 2, 0xb6, "Hi/fn"},
+ { 2, 0x37, "Enikia"},
+ { 2, 0x38, "SwitchOn Networks"},
+ { 2, 0xb9, "AANetcom"},
+ { 2, 0xba, "Micro Memory Bank"},
+ { 2, 0x3b, "ESS Technology"},
+ { 2, 0xbc, "Virata"},
+ { 2, 0x3d, "Excess Bandwidth"},
+ { 2, 0x3e, "West Bay Semiconductor"},
+ { 2, 0xbf, "DSP Group"},
+ { 2, 0x40, "Newport Communications"},
+ { 2, 0xc1, "Chip2Chip"},
+ { 2, 0xc2, "Phobos"},
+ { 2, 0x43, "Intellitech"},
+ { 2, 0xc4, "Nordic VLSI ASA"},
+ { 2, 0x45, "Ishoni Networks"},
+ { 2, 0x46, "Silicon Spice"},
+ { 2, 0xc7, "Alchemy Semiconductor"},
+ { 2, 0xc8, "Agilent Technologies"},
+ { 2, 0x49, "Centillium Communications"},
+ { 2, 0x4a, "W.L. Gore"},
+ { 2, 0xcb, "HanBit Electronics"},
+ { 2, 0x4c, "GlobeSpan"},
+ { 2, 0xcd, "Element 14"},
+ { 2, 0xce, "Pycon"},
+ { 2, 0x4f, "Saifun Semiconductors"},
+ { 2, 0xd0, "Sibyte,"},
+ { 2, 0x51, "MetaLink Technologies"},
+ { 2, 0x52, "Feiya Technology"},
+ { 2, 0xd3, "I & C Technology"},
+ { 2, 0x54, "Shikatronics"},
+ { 2, 0xd5, "Elektrobit"},
+ { 2, 0xd6, "Megic"},
+ { 2, 0x57, "Com-Tier"},
+ { 2, 0x58, "Malaysia Micro Solutions"},
+ { 2, 0xd9, "Hyperchip"},
+ { 2, 0xda, "Gemstone Communications"},
+ { 2, 0x5b, "Anadigm (Anadyne)"},
+ { 2, 0xdc, "3ParData"},
+ { 2, 0x5d, "Mellanox Technologies"},
+ { 2, 0x5e, "Tenx Technologies"},
+ { 2, 0xdf, "Helix AG"},
+ { 2, 0xe0, "Domosys"},
+ { 2, 0x61, "Skyup Technology"},
+ { 2, 0x62, "HiNT"},
+ { 2, 0xe3, "Chiaro"},
+ { 2, 0x64, "MDT Technologies"},
+ { 2, 0xe5, "Exbit Technology A/S"},
+ { 2, 0xe6, "Integrated Technology Express"},
+ { 2, 0x67, "AVED Memory"},
+ { 2, 0x68, "Legerity"},
+ { 2, 0xe9, "Jasmine Networks"},
+ { 2, 0xea, "Caspian Networks"},
+ { 2, 0x6b, "nCUBE"},
+ { 2, 0xec, "Silicon Access Networks"},
+ { 2, 0x6d, "FDK"},
+ { 2, 0x6e, "High Bandwidth Access"},
+ { 2, 0xef, "MultiLink Technology"},
+ { 2, 0x70, "BRECIS"},
+ { 2, 0xf1, "World Wide Packets"},
+ { 2, 0xf2, "APW"},
+ { 2, 0x73, "Chicory Systems"},
+ { 2, 0xf4, "Xstream Logic"},
+ { 2, 0x75, "Fast-Chip"},
+ { 2, 0x76, "Zucotto Wireless"},
+ { 2, 0xf7, "Realchip"},
+ { 2, 0xf8, "Galaxy Power"},
+ { 2, 0x79, "eSilicon"},
+ { 2, 0x7a, "Morphics Technology"},
+ { 2, 0xfb, "Accelerant Networks"},
+ { 2, 0x7c, "Silicon Wave"},
+ { 2, 0xfd, "SandCraft"},
+ { 2, 0xfe, "Elpida"},
+ { 3, 0x01, "Solectron"},
+ { 3, 0x02, "Optosys Technologies"},
+ { 3, 0x83, "Buffalo (Formerly Melco)"},
+ { 3, 0x04, "TriMedia Technologies"},
+ { 3, 0x85, "Cyan Technologies"},
+ { 3, 0x86, "Global Locate"},
+ { 3, 0x07, "Optillion"},
+ { 3, 0x08, "Terago Communications"},
+ { 3, 0x89, "Ikanos Communications"},
+ { 3, 0x8a, "Preton Technology"},
+ { 3, 0x0b, "Nanya Technology"},
+ { 3, 0x8c, "Elite Flash Storage"},
+ { 3, 0x0d, "Mysticom"},
+ { 3, 0x0e, "LightSand Communications"},
+ { 3, 0x8f, "ATI Technologies"},
+ { 3, 0x10, "Agere Systems"},
+ { 3, 0x91, "NeoMagic"},
+ { 3, 0x92, "AuroraNetics"},
+ { 3, 0x13, "Golden Empire"},
+ { 3, 0x94, "Mushkin"},
+ { 3, 0x15, "Tioga Technologies"},
+ { 3, 0x16, "Netlist"},
+ { 3, 0x97, "TeraLogic"},
+ { 3, 0x98, "Cicada Semiconductor"},
+ { 3, 0x19, "Centon Electronics"},
+ { 3, 0x1a, "Tyco Electronics"},
+ { 3, 0x9b, "Magis Works"},
+ { 3, 0x1c, "Zettacom"},
+ { 3, 0x9d, "Cogency Semiconductor"},
+ { 3, 0x9e, "Chipcon AS"},
+ { 3, 0x1f, "Aspex Technology"},
+ { 3, 0x20, "F5 Networks"},
+ { 3, 0xa1, "Programmable Silicon Solutions"},
+ { 3, 0xa2, "ChipWrights"},
+ { 3, 0x23, "Acorn Networks"},
+ { 3, 0xa4, "Quicklogic"},
+ { 3, 0x25, "Kingmax Semiconductor"},
+ { 3, 0x26, "BOPS"},
+ { 3, 0xa7, "Flasys"},
+ { 3, 0xa8, "BitBlitz Communications"},
+ { 3, 0x29, "eMemory Technology"},
+ { 3, 0x2a, "Procket Networks"},
+ { 3, 0xab, "Purple Ray"},
+ { 3, 0x2c, "Trebia Networks"},
+ { 3, 0xad, "Delta Electronics"},
+ { 3, 0xae, "Onex Communications"},
+ { 3, 0x2f, "Ample Communications"},
+ { 3, 0xb0, "Memory Experts Intl"},
+ { 3, 0x31, "Astute Networks"},
+ { 3, 0x32, "Azanda Network Devices"},
+ { 3, 0xb3, "Dibcom"},
+ { 3, 0x34, "Tekmos"},
+ { 3, 0xb5, "API NetWorks"},
+ { 3, 0xb6, "Bay Microsystems"},
+ { 3, 0x37, "Firecron"},
+ { 3, 0x38, "Resonext Communications"},
+ { 3, 0xb9, "Tachys Technologies"},
+ { 3, 0xba, "Equator Technology"},
+ { 3, 0x3b, "Concept Computer"},
+ { 3, 0xbc, "SILCOM"},
+ { 3, 0x3d, "3Dlabs"},
+ { 3, 0x3e, "c?t Magazine"},
+ { 3, 0xbf, "Sanera Systems"},
+ { 3, 0x40, "Silicon Packets"},
+ { 3, 0xc1, "Viasystems Group"},
+ { 3, 0xc2, "Simtek"},
+ { 3, 0x43, "Semicon Devices Singapore"},
+ { 3, 0xc4, "Satron Handelsges"},
+ { 3, 0x45, "Improv Systems"},
+ { 3, 0x46, "INDUSYS"},
+ { 3, 0xc7, "Corrent"},
+ { 3, 0xc8, "Infrant Technologies"},
+ { 3, 0x49, "Ritek Corp"},
+ { 3, 0x4a, "empowerTel Networks"},
+ { 3, 0xcb, "Hypertec"},
+ { 3, 0x4c, "Cavium Networks"},
+ { 3, 0xcd, "PLX Technology"},
+ { 3, 0xce, "Massana Design"},
+ { 3, 0x4f, "Intrinsity"},
+ { 3, 0xd0, "Valence Semiconductor"},
+ { 3, 0x51, "Terawave Communications"},
+ { 3, 0x52, "IceFyre Semiconductor"},
+ { 3, 0xd3, "Primarion"},
+ { 3, 0x54, "Picochip Designs"},
+ { 3, 0xd5, "Silverback Systems"},
+ { 3, 0xd6, "Jade Star Technologies"},
+ { 3, 0x57, "Pijnenburg Securealink"},
+ { 3, 0x58, "takeMS International AG"},
+ { 3, 0xd9, "Cambridge Silicon Radio"},
+ { 3, 0xda, "Swissbit"},
+ { 3, 0x5b, "Nazomi Communications"},
+ { 3, 0xdc, "eWave System"},
+ { 3, 0x5d, "Rockwell Collins"},
+ { 3, 0x5e, "Picocel Co. (Paion)"},
+ { 3, 0xdf, "Alphamosaic"},
+ { 3, 0xe0, "Sandburst"},
+ { 3, 0x61, "SiCon Video"},
+ { 3, 0x62, "NanoAmp Solutions"},
+ { 3, 0xe3, "Ericsson Technology"},
+ { 3, 0x64, "PrairieComm"},
+ { 3, 0xe5, "Mitac International"},
+ { 3, 0xe6, "Layer N Networks"},
+ { 3, 0x67, "MtekVision (Atsana)"},
+ { 3, 0x68, "Allegro Networks"},
+ { 3, 0xe9, "Marvell Semiconductors"},
+ { 3, 0xea, "Netergy Microelectronic"},
+ { 3, 0x6b, "NVIDIA"},
+ { 3, 0xec, "Internet Machines"},
+ { 3, 0x6d, "Peak Electronics"},
+ { 3, 0x6e, "Litchfield Communication"},
+ { 3, 0xef, "Accton Technology"},
+ { 3, 0x70, "Teradiant Networks"},
+ { 3, 0xf1, "Scaleo Chip"},
+ { 3, 0xf2, "Cortina Systems"},
+ { 3, 0x73, "RAM Components"},
+ { 3, 0xf4, "Raqia Networks"},
+ { 3, 0x75, "ClearSpeed"},
+ { 3, 0x76, "Matsushita Battery"},
+ { 3, 0xf7, "Xelerated"},
+ { 3, 0xf8, "SimpleTech"},
+ { 3, 0x79, "Utron Technology"},
+ { 3, 0x7a, "Astec International"},
+ { 3, 0xfb, "AVM"},
+ { 3, 0x7c, "Redux Communications"},
+ { 3, 0xfd, "Dot Hill Systems"},
+ { 3, 0xfe, "TeraChip"},
+ { 4, 0x01, "T-RAM"},
+ { 4, 0x02, "Innovics Wireless"},
+ { 4, 0x83, "Teknovus"},
+ { 4, 0x04, "KeyEye Communications"},
+ { 4, 0x85, "Runcom Technologies"},
+ { 4, 0x86, "RedSwitch"},
+ { 4, 0x07, "Dotcast"},
+ { 4, 0x08, "Silicon Mountain Memory"},
+ { 4, 0x89, "Signia Technologies"},
+ { 4, 0x8a, "Pixim"},
+ { 4, 0x0b, "Galazar Networks"},
+ { 4, 0x8c, "White Electronic Designs"},
+ { 4, 0x0d, "Patriot Scientific"},
+ { 4, 0x0e, "Neoaxiom"},
+ { 4, 0x8f, "3Y Power Technology"},
+ { 4, 0x10, "Scaleo Chip"},
+ { 4, 0x91, "Potentia Power Systems"},
+ { 4, 0x92, "C-guys"},
+ { 4, 0x13, "Digital Communications Technology"},
+ { 4, 0x94, "Silicon-Based Technology"},
+ { 4, 0x15, "Fulcrum Microsystems"},
+ { 4, 0x16, "Positivo Informatica"},
+ { 4, 0x97, "XIOtech"},
+ { 4, 0x98, "PortalPlayer"},
+ { 4, 0x19, "Zhiying Software"},
+ { 4, 0x1a, "ParkerVision"},
+ { 4, 0x9b, "Phonex Broadband"},
+ { 4, 0x1c, "Skyworks Solutions"},
+ { 4, 0x9d, "Entropic Communications"},
+ { 4, 0x9e, "Pacific Force Technology"},
+ { 4, 0x1f, "Zensys A/S"},
+ { 4, 0x20, "Legend Silicon Corp."},
+ { 4, 0xa1, "Sci-worx"},
+ { 4, 0xa2, "SMSC (Standard Microsystems)"},
+ { 4, 0x23, "Renesas Technology"},
+ { 4, 0xa4, "Raza Microelectronics"},
+ { 4, 0x25, "Phyworks"},
+ { 4, 0x26, "MediaTek"},
+ { 4, 0xa7, "Non-cents Productions"},
+ { 4, 0xa8, "US Modular"},
+ { 4, 0x29, "Wintegra"},
+ { 4, 0x2a, "Mathstar"},
+ { 4, 0xab, "StarCore"},
+ { 4, 0x2c, "Oplus Technologies"},
+ { 4, 0xad, "Mindspeed"},
+ { 4, 0xae, "Just Young Computer"},
+ { 4, 0x2f, "Radia Communications"},
+ { 4, 0xb0, "OCZ"},
+ { 4, 0x31, "Emuzed"},
+ { 4, 0x32, "LOGIC Devices"},
+ { 4, 0xb3, "Inphi"},
+ { 4, 0x34, "Quake Technologies"},
+ { 4, 0xb5, "Vixel"},
+ { 4, 0xb6, "SolusTek"},
+ { 4, 0x37, "Kongsberg Maritime"},
+ { 4, 0x38, "Faraday Technology"},
+ { 4, 0xb9, "Altium"},
+ { 4, 0xba, "Insyte"},
+ { 4, 0x3b, "ARM"},
+ { 4, 0xbc, "DigiVision"},
+ { 4, 0x3d, "Vativ Technologies"},
+ { 4, 0x3e, "Endicott Interconnect Technologies"},
+ { 4, 0xbf, "Pericom"},
+ { 4, 0x40, "Bandspeed"},
+ { 4, 0xc1, "LeWiz Communications"},
+ { 4, 0xc2, "CPU Technology"},
+ { 4, 0x43, "Ramaxel Technology"},
+ { 4, 0xc4, "DSP Group"},
+ { 4, 0x45, "Axis Communications"},
+ { 4, 0x46, "Legacy Electronics"},
+ { 4, 0xc7, "Chrontel"},
+ { 4, 0xc8, "Powerchip Semiconductor"},
+ { 4, 0x49, "MobilEye Technologies"},
+ { 4, 0x4a, "Excel Semiconductor"},
+ { 4, 0xcb, "A-DATA Technology"},
+ { 4, 0x4c, "VirtualDigm"},
+ { 4, 0xcd, "G Skill Intl"},
+ { 4, 0xce, "Quanta Computer"},
+ { 4, 0x4f, "Yield Microelectronics"},
+ { 4, 0xd0, "Afa Technologies"},
+ { 4, 0x51, "KINGBOX Technology Co."},
+ { 4, 0x52, "Ceva"},
+ { 4, 0xd3, "iStor Networks"},
+ { 4, 0x54, "Advance Modules"},
+ { 4, 0xd5, "Microsoft"},
+ { 4, 0xd6, "Open-Silicon"},
+ { 4, 0x57, "Goal Semiconductor"},
+ { 4, 0x58, "ARC International"},
+ { 4, 0xd9, "Simmtec"},
+ { 4, 0xda, "Metanoia"},
+ { 4, 0x5b, "Key Stream"},
+ { 4, 0xdc, "Lowrance Electronics"},
+ { 4, 0x5d, "Adimos"},
+ { 4, 0x5e, "SiGe Semiconductor"},
+ { 4, 0xdf, "Fodus Communications"},
+ { 4, 0xe0, "Credence Systems Corp."},
+ { 4, 0x61, "Genesis Microchip"},
+ { 4, 0x62, "Vihana"},
+ { 4, 0xe3, "WIS Technologies"},
+ { 4, 0x64, "GateChange Technologies"},
+ { 4, 0xe5, "High Density Devices AS"},
+ { 4, 0xe6, "Synopsys"},
+ { 4, 0x67, "Gigaram"},
+ { 4, 0x68, "Enigma Semiconductor"},
+ { 4, 0xe9, "Century Micro"},
+ { 4, 0xea, "Icera Semiconductor"},
+ { 4, 0x6b, "Mediaworks Integrated Systems"},
+ { 4, 0xec, "O?Neil Product Development"},
+ { 4, 0x6d, "Supreme Top Technology"},
+ { 4, 0x6e, "MicroDisplay"},
+ { 4, 0xef, "Team Group"},
+ { 4, 0x70, "Sinett"},
+ { 4, 0xf1, "Toshiba"},
+ { 4, 0xf2, "Tensilica"},
+ { 4, 0x73, "SiRF Technology"},
+ { 4, 0xf4, "Bacoc"},
+ { 4, 0x75, "SMaL Camera Technologies"},
+ { 4, 0x76, "Thomson SC"},
+ { 4, 0xf7, "Airgo Networks"},
+ { 4, 0xf8, "Wisair"},
+ { 4, 0x79, "SigmaTel"},
+ { 4, 0x7a, "Arkados"},
+ { 4, 0xfb, "Compete IT Co. KG"},
+ { 4, 0x7c, "Eudar Technology"},
+ { 4, 0xfd, "Focus Enhancements"},
+ { 4, 0xfe, "Xyratex"},
+ { 5, 0x01, "Specular Networks"},
+ { 5, 0x02, "Patriot Memory (PDP Systems)"},
+ { 5, 0x83, "U-Chip Technology Corp."},
+ { 5, 0x04, "Silicon Optix"},
+ { 5, 0x85, "Greenfield Networks"},
+ { 5, 0x86, "CompuRAM"},
+ { 5, 0x07, "Stargen"},
+ { 5, 0x08, "NetCell"},
+ { 5, 0x89, "Excalibrus Technologies"},
+ { 5, 0x8a, "SCM Microsystems"},
+ { 5, 0x0b, "Xsigo Systems"},
+ { 5, 0x8c, "CHIPS & Systems"},
+ { 5, 0x0d, "Tier"},
+ { 5, 0x0e, "CWRL Labs"},
+ { 5, 0x8f, "Teradici"},
+ { 5, 0x10, "Gigaram"},
+ { 5, 0x91, "g2 Microsystems"},
+ { 5, 0x92, "PowerFlash Semiconductor"},
+ { 5, 0x13, "P.A. Semi"},
+ { 5, 0x94, "NovaTech Solutions, S.A."},
+ { 5, 0x15, "c2 Microsystems"},
+ { 5, 0x16, "Level5 Networks"},
+ { 5, 0x97, "COS Memory AG"},
+ { 5, 0x98, "Innovasic Semiconductor"},
+ { 5, 0x19, "02IC Co."},
+ { 5, 0x1a, "Tabula,"},
+ { 5, 0x9b, "Crucial Technology"},
+ { 5, 0x1c, "Chelsio Communications"},
+ { 5, 0x9d, "Solarflare Communications"},
+ { 5, 0x9e, "Xambala"},
+ { 5, 0x1f, "EADS Astrium"},
+ { 5, 0x20, "Terra Semiconductor"},
+ { 5, 0xa1, "Imaging Works"},
+ { 5, 0xa2, "Astute Networks"},
+ { 5, 0x23, "Tzero"},
+ { 5, 0xa4, "Emulex"},
+ { 5, 0x25, "Power-One"},
+ { 5, 0x26, "Pulse~LINK"},
+ { 5, 0xa7, "Hon Hai Precision Industry"},
+ { 5, 0xa8, "White Rock Networks"},
+ { 5, 0x29, "Telegent Systems USA"},
+ { 5, 0x2a, "Atrua Technologies"},
+ { 5, 0xab, "Acbel Polytech"},
+ { 5, 0x2c, "eRide"},
+ { 5, 0xad, "ULi Electronics"},
+ { 5, 0xae, "Magnum Semiconductor"},
+ { 5, 0x2f, "neoOne Technology"},
+ { 5, 0xb0, "Connex Technology"},
+ { 5, 0x31, "Stream Processors"},
+ { 5, 0x32, "Focus Enhancements"},
+ { 5, 0xb3, "Telecis Wireless"},
+ { 5, 0x34, "uNav Microelectronics"},
+ { 5, 0xb5, "Tarari"},
+ { 5, 0xb6, "Ambric"},
+ { 5, 0x37, "Newport Media"},
+ { 5, 0x38, "VMTS"},
+ { 5, 0xb9, "Enuclia Semiconductor"},
+ { 5, 0xba, "Virtium Technology"},
+ { 5, 0x3b, "Solid State System Co."},
+ { 5, 0xbc, "Kian Tech LLC"},
+ { 5, 0x3d, "Artimi"},
+ { 5, 0x3e, "Power Quotient International"},
+ { 5, 0xbf, "Avago Technologies"},
+ { 5, 0x40, "ADTechnology"},
+ { 5, 0xc1, "Sigma Designs"},
+ { 5, 0xc2, "SiCortex"},
+ { 5, 0x43, "Ventura Technology Group"},
+ { 5, 0xc4, "eASIC"},
+ { 5, 0x45, "M.H.S. SAS"},
+ { 5, 0x46, "Micro Star International"},
+ { 5, 0xc7, "Rapport"},
+ { 5, 0xc8, "Makway International"},
+ { 5, 0x49, "Broad Reach Engineering Co."},
+ { 5, 0x4a, "Semiconductor Mfg Intl Corp"},
+ { 5, 0xcb, "SiConnect"},
+ { 5, 0x4c, "FCI USA"},
+ { 5, 0xcd, "Validity Sensors"},
+ { 5, 0xce, "Coney Technology Co."},
+ { 5, 0x4f, "Spans Logic"},
+ { 5, 0xd0, "Neterion"},
+ { 5, 0x51, "Qimonda"},
+ { 5, 0x52, "New Japan Radio Co."},
+ { 5, 0xd3, "Velogix"},
+ { 5, 0x54, "Montalvo Systems"},
+ { 5, 0xd5, "iVivity"},
+ { 5, 0xd6, "Walton Chaintech"},
+ { 5, 0x57, "AENEON"},
+ { 5, 0x58, "Lorom Industrial Co."},
+ { 5, 0xd9, "Radiospire Networks"},
+ { 5, 0xda, "Sensio Technologies"},
+ { 5, 0x5b, "Nethra Imaging"},
+ { 5, 0xdc, "Hexon Technology Pte"},
+ { 5, 0x5d, "CompuStocx (CSX)"},
+ { 5, 0x5e, "Methode Electronics"},
+ { 5, 0xdf, "Connect One"},
+ { 5, 0xe0, "Opulan Technologies"},
+ { 5, 0x61, "Septentrio NV"},
+ { 5, 0x62, "Goldenmars Technology"},
+ { 5, 0xe3, "Kreton"},
+ { 5, 0x64, "Cochlear"},
+ { 5, 0xe5, "Altair Semiconductor"},
+ { 5, 0xe6, "NetEffect"},
+ { 5, 0x67, "Spansion"},
+ { 5, 0x68, "Taiwan Semiconductor Mfg"},
+ { 5, 0xe9, "Emphany Systems"},
+ { 5, 0xea, "ApaceWave Technologies"},
+ { 5, 0x6b, "Mobilygen"},
+ { 5, 0xec, "Tego"},
+ { 5, 0x6d, "Cswitch"},
+ { 5, 0x6e, "Haier (Beijing) IC Design Co."},
+ { 5, 0xef, "MetaRAM"},
+ { 5, 0x70, "Axel Electronics Co."},
+ { 5, 0xf1, "Tilera"},
+ { 5, 0xf2, "Aquantia"},
+ { 5, 0x73, "Vivace Semiconductor"},
+ { 5, 0xf4, "Redpine Signals"},
+ { 5, 0x75, "Octalica"},
+ { 5, 0x76, "InterDigital Communications"},
+ { 5, 0xf7, "Avant Technology"},
+ { 5, 0xf8, "Asrock"},
+ { 5, 0x79, "Availink"},
+ { 5, 0x7a, "Quartics"},
+ { 5, 0xfb, "Element CXI"},
+ { 5, 0x7c, "Innovaciones Microelectronicas"},
+ { 5, 0xfd, "VeriSilicon Microelectronics"},
+ { 5, 0xfe, "W5 Networks"},
+ { 6, 0x01, "MOVEKING"},
+ { 6, 0x02, "Mavrix Technology"},
+ { 6, 0x83, "CellGuide"},
+ { 6, 0x04, "Faraday Technology"},
+ { 6, 0x85, "Diablo Technologies"},
+ { 6, 0x86, "Jennic"},
+ { 6, 0x07, "Octasic"},
+ { 6, 0x08, "Molex"},
+ { 6, 0x89, "3Leaf Networks"},
+ { 6, 0x8a, "Bright Micron Technology"},
+ { 6, 0x0b, "Netxen"},
+ { 6, 0x8c, "NextWave Broadband"},
+ { 6, 0x0d, "DisplayLink"},
+ { 6, 0x0e, "ZMOS Technology"},
+ { 6, 0x8f, "Tec-Hill"},
+ { 6, 0x10, "Multigig"},
+ { 6, 0x91, "Amimon"},
+ { 6, 0x92, "Euphonic Technologies"},
+ { 6, 0x13, "BRN Phoenix"},
+ { 6, 0x94, "InSilica"},
+ { 6, 0x15, "Ember"},
+ { 6, 0x16, "Avexir Technologies"},
+ { 6, 0x97, "Echelon"},
+ { 6, 0x98, "Edgewater Computer Systems"},
+ { 6, 0x19, "XMOS Semiconductor"},
+ { 6, 0x1a, "GENUSION"},
+ { 6, 0x9b, "Memory Corp NV"},
+ { 6, 0x1c, "SiliconBlue Technologies"},
+ { 6, 0x9d, "Rambus"},
+ { 6, 0x9e, "Andes Technology"},
+ { 6, 0x1f, "Coronis Systems"},
+ { 6, 0x20, "Achronix Semiconductor"},
+ { 6, 0xa1, "Siano Mobile Silicon"},
+ { 6, 0xa2, "Semtech"},
+ { 6, 0x23, "Pixelworks"},
+ { 6, 0xa4, "Gaisler Research AB"},
+ { 6, 0x25, "Teranetics"},
+ { 6, 0x26, "Toppan Printing Co."},
+ { 6, 0xa7, "Kingxcon"},
+ { 6, 0xa8, "Silicon Integrated Systems"},
+ { 6, 0x29, "I-O Data Device"},
+ { 6, 0x2a, "NDS Americas"},
+ { 6, 0xab, "Solomon Systech Limited"},
+ { 6, 0x2c, "On Demand Microelectronics"},
+ { 6, 0xad, "Amicus Wireless"},
+ { 6, 0xae, "SMARDTV SNC"},
+ { 6, 0x2f, "Comsys Communication"},
+ { 6, 0xb0, "Movidia"},
+ { 6, 0x31, "Javad GNSS"},
+ { 6, 0x32, "Montage Technology Group"},
+ { 6, 0xb3, "Trident Microsystems"},
+ { 6, 0x34, "Super Talent"},
+ { 6, 0xb5, "Optichron"},
+ { 6, 0xb6, "Future Waves UK"},
+ { 6, 0x37, "SiBEAM"},
+ { 6, 0x38, "Inicore,"},
+ { 6, 0xb9, "Virident Systems"},
+ { 6, 0xba, "M2000"},
+ { 6, 0x3b, "ZeroG Wireless"},
+ { 6, 0xbc, "Gingle Technology Co."},
+ { 6, 0x3d, "Space Micro"},
+ { 6, 0x3e, "Wilocity"},
+ { 6, 0xbf, "Novafora, Ic."},
+ { 6, 0x40, "iKoa"},
+ { 6, 0xc1, "ASint Technology"},
+ { 6, 0xc2, "Ramtron"},
+ { 6, 0x43, "Plato Networks"},
+ { 6, 0xc4, "IPtronics AS"},
+ { 6, 0x45, "Infinite-Memories"},
+ { 6, 0x46, "Parade Technologies"},
+ { 6, 0xc7, "Dune Networks"},
+ { 6, 0xc8, "GigaDevice Semiconductor"},
+ { 6, 0x49, "Modu"},
+ { 6, 0x4a, "CEITEC"},
+ { 6, 0xcb, "Northrop Grumman"},
+ { 6, 0x4c, "XRONET"},
+ { 6, 0xcd, "Sicon Semiconductor AB"},
+ { 6, 0xce, "Atla Electronics Co."},
+ { 6, 0x4f, "TOPRAM Technology"},
+ { 6, 0xd0, "Silego Technology"},
+ { 6, 0x51, "Kinglife"},
+ { 6, 0x52, "Ability Industries"},
+ { 6, 0xd3, "Silicon Power Computer & Communications"},
+ { 6, 0x54, "Augusta Technology"},
+ { 6, 0xd5, "Nantronics Semiconductors"},
+ { 6, 0xd6, "Hilscher Gesellschaft"},
+ { 6, 0x57, "Quixant"},
+ { 6, 0x58, "Percello"},
+ { 6, 0xd9, "NextIO"},
+ { 6, 0xda, "Scanimetrics"},
+ { 6, 0x5b, "FS-Semi Company"},
+ { 6, 0xdc, "Infinera"},
+ { 6, 0x5d, "SandForce"},
+ { 6, 0x5e, "Lexar Media"},
+ { 6, 0xdf, "Teradyne"},
+ { 6, 0xe0, "Memory Exchange Corp."},
+ { 6, 0x61, "Suzhou Smartek Electronics"},
+ { 6, 0x62, "Avantium"},
+ { 6, 0xe3, "ATP Electronics"},
+ { 6, 0x64, "Valens Semiconductor"},
+ { 6, 0xe5, "Agate Logic"},
+ { 6, 0xe6, "Netronome"},
+ { 6, 0x67, "Zenverge"},
+ { 6, 0x68, "N-trig"},
+ { 6, 0xe9, "SanMax Technologies"},
+ { 6, 0xea, "Contour Semiconductor"},
+ { 6, 0x6b, "TwinMOS"},
+ { 6, 0xec, "Silicon Systems"},
+ { 6, 0x6d, "V-Color Technology"},
+ { 6, 0x6e, "Certicom"},
+ { 6, 0xef, "JSC ICC Milandr"},
+ { 6, 0x70, "PhotoFast Global"},
+ { 6, 0xf1, "InnoDisk"},
+ { 6, 0xf2, "Muscle Power"},
+ { 6, 0x73, "Energy Micro"},
+ { 6, 0xf4, "Innofidei"},
+ { 9, 0xff, ""}
+};
+
@@ -3,7 +3,7 @@ * Released under version 2 of the Gnu Public License. * By Chris Brady, cbrady@sgi.com * ---------------------------------------------------- - * MemTest86+ V2.00 Specific code (GPL V2.0) + * MemTest86+ V4.00 Specific code (GPL V2.0) * By Samuel DEMEULEMEESTER, memtest@memtest.org * http://www.canardplus.com - http://www.memtest.org */ @@ -13,7 +13,9 @@ #include "test.h" #include "config.h" #include "screen_buffer.h" +#include "smp.h" +#define NULL 0 int slock = 0, lsr = 0; short serial_cons = SERIAL_CONSOLE_DEFAULT; @@ -62,6 +64,8 @@ char *codes[] = { }; struct eregs { + ulong ss; + ulong ds; ulong esp; ulong ebp; ulong esi; @@ -89,6 +93,19 @@ int memcmp(const void *s1, const void *s2, ulong count) return 0; } +void memcpy (void *dst, void *src, int len) +{ + char *s = (char*)src; + char *d = (char*)dst; + int i; + + if (len <= 0) { + return; + } + for (i = 0 ; i < len; i++) { + *d++ = *s++; + } +} int strncmp(const char *s1, const char *s2, ulong n) { signed char res = 0; while (n) { @@ -344,6 +361,25 @@ void dprint(int y, int x, ulong val, int len, int right) cprint(y,x,buf); } + +/* + * Get_number of digits + */ +int getnum(ulong val) +{ + int len = 0; + int i = 1; + + while(i <= val) + { + len++; + i *= 10; + } + + return len; + +} + /* * Print a hex number on screen at least digits long */ @@ -495,7 +531,10 @@ void inter(struct eregs *trap_regs) hprint(line+8, 25, trap_regs->ebp); cprint(line+9, 20, "esp: "); hprint(line+9, 25, trap_regs->esp); - + cprint(line+7, 0, " DS: "); + hprint(line+7, 7, trap_regs->ds); + cprint(line+8, 0, " SS: "); + hprint(line+8, 7, trap_regs->ss); cprint(line+1, 38, "Stack:"); for (i=0; i<12; i++) { hprint(line+2+i, 38, trap_regs->esp+(4*i)); @@ -1133,5 +1172,6 @@ put_lp(char c, short port) outb((LP_PSELECP | LP_PINITP), CONTROL(port)); lp_wait(DELAY); } + #endif @@ -3,7 +3,7 @@ * Released under version 2 of the Gnu Public License. * By Chris Brady * ---------------------------------------------------- - * MemTest86+ V2.01 Specific code (GPL V2.0) + * MemTest86+ V4.00 Specific code (GPL V2.0) * By Samuel DEMEULEMEESTER, sdemeule@memtest.org * http://www.canardpc.com - http://www.memtest.org */ @@ -17,17 +17,17 @@ extern void bzero(); const struct tseq tseq[] = { - {1, 5, 3, 0, 0, "[Address test, walking ones, uncached]"}, - {1, 6, 3, 2, 0, "[Address test, own address] "}, - {1, 0, 3, 14, 0, "[Moving inversions, ones & zeros] "}, - {1, 1, 2, 80, 0, "[Moving inversions, 8 bit pattern] "}, - {1, 10, 60, 300, 0, "[Moving inversions, random pattern] "}, - {1, 7, 64, 66, 0, "[Block move, 64 moves] "}, - {1, 2, 2, 320, 0, "[Moving inversions, 32 bit pattern] "}, - {1, 9, 40, 120, 0, "[Random number sequence] "}, - {1, 3, 2, 360, 0, "[Modulo 20, random pattern] "}, - {1, 8, 1, 2, 0, "[Bit fade test, 90 min, 2 patterns] "}, - {0, 0, 0, 0, 0, NULL} + {1, 5, 4, 0, "[Address test, walking ones] "}, + {1, 6, 4, 0, "[Address test, own address] "}, + {1, 0, 4, 0, "[Moving inversions, ones & zeros] "}, + {1, 1, 2, 0, "[Moving inversions, 8 bit pattern] "}, + {1, 10, 50, 0, "[Moving inversions, random pattern] "}, + {1, 7, 80, 0, "[Block move, 80 moves] "}, + {1, 2, 2, 0, "[Moving inversions, 32 bit pattern] "}, + {1, 9, 30, 0, "[Random number sequence] "}, + {1, 11, 6, 0, "[Modulo 20, Random pattern] "}, + {1, 8, 1, 0, "[Bit fade test, 90 min, 2 patterns] "}, + {0, 0, 0, 0, NULL} }; char firsttime = 0; @@ -44,6 +44,7 @@ int nticks; ulong high_test_adr = 0x200000; static int window = 0; +static int c_iter; static struct pmap windows[] = { { 0, 0x080000 }, @@ -101,8 +102,9 @@ static struct pmap windows[] = #error LOW_TEST_ADR must be below 640K #endif -static int find_ticks_for_test(unsigned long chunks, int test); -static void compute_segments(int win); +static int find_ticks_for_test(int ch, int test); +static int compute_segments(int win); +void find_ticks_for_pass(void); static void __run_at(unsigned long addr) { @@ -196,7 +198,11 @@ void do_test(void) if ((ulong)&_start != LOW_TEST_ADR) { restart(); } + init(); + + find_ticks_for_pass(); + windows[0].start = ( LOW_TEST_ADR + (_end - _start) + 4095) >> 12; @@ -279,6 +285,13 @@ void do_test(void) if (v->testsel >= 0) { v->test = v->testsel; } + + if (v->pass == 0) { + c_iter = tseq[v->test].iter/2; + } else { + c_iter = tseq[v->test].iter; + } + dprint(LINE_TST, COL_MID+6, v->test, 2, 1); cprint(LINE_TST, COL_MID+9, tseq[v->test].msg); set_cache(tseq[v->test].cache); @@ -297,105 +310,128 @@ void do_test(void) switch(tseq[v->test].pat) { /* Now do the testing according to the selected pattern */ - case 0: /* Moving inversions, all ones and zeros */ - case 4: + case 0: /* Moving inversions, all ones and zeros (test #2) */ + p1 = 0; + p2 = ~p1; + movinv1(c_iter,p1,p2); + BAILOUT; - if (tseq[v->test].pat == 1) - p0 = 0x80808080; - else - p0 = 0; - - for ( ; ; ) { - movinv1(tseq[v->test].iter,p0,~p0); - BAILOUT; - - /* Switch patterns */ - movinv1(tseq[v->test].iter,~p0,p0); - BAILOUT - if ( !((unsigned char)(p0 >>= 1) & 0x7F) ) - break; - } + /* Switch patterns */ + p2 = p1; + p1 = ~p2; + movinv1(c_iter,p1,p2); + BAILOUT; break; - - case 1: /* Moving inversions, 8 bit wide walking ones and zeros. */ + + case 1: /* Moving inversions, 8 bit walking ones and zeros (test #3) */ p0 = 0x80; for (i=0; i<8; i++, p0=p0>>1) { p1 = p0 | (p0<<8) | (p0<<16) | (p0<<24); p2 = ~p1; - movinv1(tseq[v->test].iter,p1,p2); + movinv1(c_iter,p1,p2); BAILOUT; /* Switch patterns */ p2 = p1; p1 = ~p2; - movinv1(tseq[v->test].iter,p1,p2); + movinv1(c_iter,p1,p2); BAILOUT } - break; - + break; - case 2: /* Moving inversions, 32 bit shifting pattern, very long */ + case 2: /* Moving inversions, 32 bit shifting pattern (test #6) */ for (i=0, p1=1; p1; p1=p1<<1, i++) { - movinv32(tseq[v->test].iter,p1, 1, 0x80000000, 0, i); + movinv32(c_iter,p1, 1, 0x80000000, 0, i); BAILOUT - movinv32(tseq[v->test].iter,~p1, 0xfffffffe, 0x7fffffff, 1, i); + movinv32(c_iter,~p1, 0xfffffffe, + 0x7fffffff, 1, i); BAILOUT } break; - case 3: /* Modulo 20, random */ - for (j=0; j<tseq[v->test].iter; j++) { - p1 = rand(); + case 3: /* Modulo 20 check, all ones and zeros (unused) */ + p1=0; + for (i=0; i<MOD_SZ; i++) { + p2 = ~p1; + modtst(i, c_iter, p1, p2); + BAILOUT + + /* Switch patterns */ + p2 = p1; + p1 = ~p2; + modtst(i, c_iter, p1,p2); + BAILOUT + } + break; + + case 4: /* Modulo 20 check, 8 bit pattern (unused) */ + p0 = 0x80; + for (j=0; j<8; j++, p0=p0>>1) { + p1 = p0 | (p0<<8) | (p0<<16) | (p0<<24); for (i=0; i<MOD_SZ; i++) { p2 = ~p1; - modtst(i, tseq[v->test].iter, p1, p2); + modtst(i, c_iter, p1, p2); BAILOUT /* Switch patterns */ p2 = p1; p1 = ~p2; - modtst(i, tseq[v->test].iter, p1, p2); + modtst(i, c_iter, p1, p2); BAILOUT } } break; - - case 5: /* Address test, walking ones */ + case 5: /* Address test, walking ones (test #0) */ addr_tst1(); BAILOUT; break; - case 6: /* Address test, own address */ + case 6: /* Address test, own address (test #1) */ addr_tst2(); BAILOUT; break; - case 7: /* Block move test */ - block_move(tseq[v->test].iter); + case 7: /* Block move (test #5) */ + block_move(c_iter); BAILOUT; break; - - case 8: /* Bit fade test */ + case 8: /* Bit fade test (test #9) */ if (window == 0 ) { bit_fade(); } BAILOUT; break; - - case 9: /* Random Data Sequence */ - for (i=0; i < tseq[v->test].iter; i++) { + case 9: /* Random Data Sequence (test #7) */ + for (i=0; i < c_iter; i++) { movinvr(); BAILOUT; } break; - case 10: /* Random Data */ - for (i=0; i < tseq[v->test].iter; i++) { + case 10: /* Random Data (test #4) */ + for (i=0; i < c_iter; i++) { p1 = rand(); p2 = ~p1; movinv1(2,p1,p2); BAILOUT; } break; + + case 11: /* Modulo 20 check, Random pattern (test #8) */ + for (j=0; j<c_iter; j++) { + p1 = rand(); + for (i=0; i<MOD_SZ; i++) { + p2 = ~p1; + modtst(i, 2, p1, p2); + BAILOUT + + /* Switch patterns */ + p2 = p1; + p1 = ~p2; + modtst(i, 2, p1, p2); + BAILOUT + } + } + break; } skip_window: if (bail) { @@ -458,8 +494,8 @@ void do_test(void) cprint(0, COL_MID+8, " "); if (v->ecount == 0 && v->testsel < 0) { - cprint(LINE_MSG, COL_MSG, - "Pass complete, no errors, press Esc to exit"); + cprint(LINE_MSG+5, 0, + " *****Pass complete, no errors, press Esc to exit***** "); if(BEEP_END_NO_ERROR) { beep(1000); beep(2000); @@ -494,9 +530,7 @@ void restart() run_at(LOW_TEST_ADR); } - -/* Compute the total number of ticks per pass */ -void find_ticks(void) +void find_ticks_for_pass(void) { int i, j, chunks; @@ -526,18 +560,62 @@ void find_ticks(void) } } -static int find_ticks_for_test(unsigned long chunks, int test) + +static int find_ticks_for_test(int ch, int test) { - int ticks; - ticks = chunks * tseq[test].ticks; - if (tseq[test].pat == 5) { - /* Address test, walking ones */ + int ticks=0, c; + + /* Set the number of iterations. We only do half of the iterations */ + /* on the first pass */ + if (v->pass == 0 && FIRST_PASS_HALF_ITERATIONS) { + c = tseq[test].iter/2; + } else { + c = tseq[test].iter; + } + + switch(tseq[test].pat) { + case 0: /* Moving inversions, all ones and zeros (test #2) */ + ticks = 2 + 4 * c; + break; + case 1: /* Moving inversions, 8 bit walking ones and zeros (test #3) */ + ticks = 24 + 24 * c; + break; + case 2: /* Moving inversions, 32 bit shifting pattern, very long */ + ticks = (1 + c * 2) * 80; + break; + case 3: /* Modulo 20 check, all ones and zeros (unused) */ + ticks = (2 + c) * 40; + break; + case 4: /* Modulo 20 check, 8 bit pattern (unused) */ + ticks = (2 + c) * 40 * 8; + break; + case 5: /* Address test, walking ones (test #0) */ ticks = 4; + break; + case 6: /* Address test, own address (test #1) */ + ticks = 2; + break; + case 7: /* Block move (test #5) */ + ticks = 2 + c; + break; + case 8: /* Bit fade test (test #9) */ + ticks = 1; + break; + case 9: /* Random Data Sequence (test #7) */ + ticks = 3 * c; + break; + case 10: /* Random Data (test #4) */ + ticks = c + 4 * c; + break; + case 11: /* Modulo 20 check, Random pattern (test #8) */ + ticks = 4 * 40 * c; + break; } - return ticks; + + return ticks*ch; } -static void compute_segments(int win) +static int compute_segments(int win) { unsigned long wstart, wend; int i; @@ -555,7 +633,7 @@ static void compute_segments(int win) wend = v->plim_upper; } if (wstart >= wend) { - return; + return(0); } /* List the segments being tested */ for (i=0; i< v->msegs; i++) { @@ -601,11 +679,11 @@ static void compute_segments(int win) cprint(LINE_SCROLL+(2*i+1), 44, "i="); hprint(LINE_SCROLL+(2*i+1), 46, i); - - cprint(LINE_SCROLL+(2*i+2), 0, + + cprint(LINE_SCROLL+(2*i+2), 0, " " " "); - cprint(LINE_SCROLL+(2*i+3), 0, + cprint(LINE_SCROLL+(2*i+3), 0, " " " "); #endif @@ -614,10 +692,12 @@ static void compute_segments(int win) v->map[segs].start = mapping(start); v->map[segs].end = emapping(end); #if 0 - cprint(LINE_SCROLL+(2*i+1), 54, " segs: "); - hprint(LINE_SCROLL+(2*i+1), 61, segs); + cprint(LINE_SCROLL+(2*i+1), 54, " sg: "); + hprint(LINE_SCROLL+(2*i+1), 61, sg); #endif segs++; } } + return (segs); } + diff --git a/makedos.sh b/makedos.sh new file mode 100755 index 0000000..adeb29d --- /dev/null +++ b/makedos.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [ -f memtest.bin ] +then +CSIZE="$(awk 'NR==16' mt86+_loader.asm | awk '{print $2}')"; +NSIZE="$(ls -l memtest.bin | awk '{print $5}')"; +sed "s/$CSIZE/$NSIZE/" mt86+_loader.asm > mt86+_loader.asm.new; +mv mt86+_loader.asm.new mt86+_loader.asm; +nasm mt86+_loader.asm; +fi @@ -37,9 +37,9 @@ cd cd echo -e "There is nothing to do here\r\r\nMemtest86+ is located on the bootsector of this CD\r\r\n" > README.TXT echo -e "Just boot from this CD and Memtest86+ will launch" >> README.TXT -mkisofs -A "MKISOFS 1.1.2" -p "Memtest86+ 2.11" -publisher "Samuel D. <sdemeule@memtest.org>" -b boot/memtest.img -c boot/boot.catalog -V "MT201" -o memtest.iso . -mv memtest.iso ../mt211.iso +mkisofs -A "MKISOFS 1.1.2" -p "Memtest86+ 4.00" -publisher "Samuel D. <sdemeule@memtest.org>" -b boot/memtest.img -c boot/boot.catalog -V "MT201" -o memtest.iso . +mv memtest.iso ../mt400.iso cd .. rm -rf cd -echo "Done! Memtest86+ ISO is mt211.iso" +echo "Done! Memtest86+ 4.00 ISO is mt400.iso" @@ -1,4 +1,4 @@ -/* memsize.c - MemTest-86 Version 3.2 +/* memsize.c - MemTest-86 Version 3.3 * * Released under version 2 of the Gnu Public License. * By Chris Brady @@ -21,11 +21,11 @@ extern volatile ulong *p; static void sort_pmap(void); static int check_ram(void); -static void memsize_bios(int res); -static void memsize_820(int res); +static void memsize_bios(void); +static void memsize_820(void); static void memsize_801(void); -static int sanitize_e820_map(struct e820entry *orig_map, struct e820entry *new_bios, - short old_nr, short res); +static int sanitize_e820_map(struct e820entry *orig_map, + struct e820entry *new_bios, short old_nr); static void memsize_linuxbios(); static void memsize_probe(void); static int check_ram(void); @@ -56,16 +56,12 @@ void mem_size(void) switch (memsz_mode) { case SZ_MODE_BIOS: /* Get the memory size from the BIOS */ - memsize_bios(0); - break; - case SZ_MODE_BIOS_RES: - /* Get the memory size from the BIOS, include reserved mem */ - memsize_bios(1); + memsize_bios(); break; case SZ_MODE_PROBE: /* Probe to find memory */ memsize_probe(); - cprint(LINE_INFO, COL_MMAP, " Probed "); + cprint(LINE_INFO, COL_MMAP, "Probed"); break; } /* Guarantee that pmap entries are in ascending order */ @@ -77,10 +73,10 @@ void mem_size(void) aprint(LINE_INFO, COL_RESERVED, v->reserved_pages); } -static void memsize_bios(int res) +static void memsize_bios() { if (firmware == FIRMWARE_PCBIOS) { - memsize_820(res); + memsize_820(); } else if (firmware == FIRMWARE_LINUXBIOS) { memsize_linuxbios(); @@ -105,7 +101,7 @@ static void sort_pmap(void) if (i != j) { struct pmap temp; temp = v->pmap[i]; - memmove(&v->pmap[j], &v->pmap[j+1], + memmove(&v->pmap[j], &v->pmap[j+1], (i -j)* sizeof(temp)); v->pmap[j] = temp; } @@ -129,16 +125,15 @@ static void memsize_linuxbios(void) n++; } v->msegs = n; - cprint(LINE_INFO, COL_MMAP, "LinuxBIOS"); + cprint(LINE_INFO, COL_MMAP, "LxBIOS"); } -static void memsize_820(int res) +static void memsize_820() { int i, n, nr; struct e820entry nm[E820MAX]; /* Clean up, adjust and copy the BIOS-supplied E820-map. */ - /* If the res arg is true reclassify reserved memory as E820_RAM */ - nr = sanitize_e820_map(e820, nm, e820_nr, res); + nr = sanitize_e820_map(e820, nm, e820_nr); /* If there is not a good 820 map use the BIOS 801/88 info */ if (nr < 1 || nr > E820MAX) { @@ -149,7 +144,7 @@ static void memsize_820(int res) /* Build the memory map for testing */ n = 0; for (i=0; i<nr; i++) { - if (nm[i].type == E820_RAM) { + if (nm[i].type == E820_RAM || nm[i].type == E820_ACPI) { unsigned long long start; unsigned long long end; start = nm[i].addr; @@ -169,24 +164,14 @@ static void memsize_820(int res) v->pmap[n].end = end >> 12; v->test_pages += v->pmap[n].end - v->pmap[n].start; n++; - } else { - /* If this is reserved memory starting at the top - * of memory then don't count it as reserved, since - * it is very unlikely to be real memory. - */ - if (nm[i].addr < 0xff000000) { - v->reserved_pages += nm[i].size >> 12; - } + } else if (nm[i].type == E820_NVS) { + v->reserved_pages += nm[i].size >> 12; } } v->msegs = n; - if (res) { - cprint(LINE_INFO, COL_MMAP, "e820-All"); - } else { - cprint(LINE_INFO, COL_MMAP, "e820-Std"); - } + cprint(LINE_INFO, COL_MMAP, " e820"); } - + static void memsize_801(void) { ulong mem_size; @@ -196,10 +181,10 @@ static void memsize_801(void) if (alt_mem_k < ext_mem_k) { mem_size = ext_mem_k; - cprint(LINE_INFO, COL_MMAP, "e88-Std "); + cprint(LINE_INFO, COL_MMAP, " e88"); } else { mem_size = alt_mem_k; - cprint(LINE_INFO, COL_MMAP, "e801-Std"); + cprint(LINE_INFO, COL_MMAP, " e801"); } /* First we map in the first 640k */ v->pmap[0].start = 0; @@ -216,12 +201,12 @@ static void memsize_801(void) /* * Sanitize the BIOS e820 map. * - * Some e820 responses include overlapping entries. The following + * Some e820 responses include overlapping entries. The following * replaces the original e820 map with a new one, removing overlaps. * */ static int sanitize_e820_map(struct e820entry *orig_map, struct e820entry *new_bios, - short old_nr, short res) + short old_nr) { struct change_member { struct e820entry *pbios; /* pointer to original bios entry */ @@ -284,22 +269,6 @@ static int sanitize_e820_map(struct e820entry *orig_map, struct e820entry *new_b for (i=0; i<old_nr; i++) { if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr) return 0; - if (res) { - /* If we want to test the reserved memory include - * everything except for reserved segments that start - * at the the top of memory - */ - if (biosmap[i].type == E820_RESERVED && - biosmap[i].addr > 0xff000000) { - continue; - } - biosmap[i].type = E820_RAM; - } else { - /* It is always be safe to test ACPI ram */ - if ( biosmap[i].type == E820_ACPI) { - biosmap[i].type = E820_RAM; - } - } } /* create pointers for initial change-point information (for sorting) */ @@ -374,7 +343,7 @@ static int sanitize_e820_map(struct e820entry *orig_map, struct e820entry *new_b /* move forward only if the new size was non-zero */ if (new_bios[new_bios_entry].size != 0) if (++new_bios_entry >= E820MAX) - break; /* no more space left for new bios entries */ + break; /* no more space left for new bios entries */ } if (current_type != 0) { new_bios[new_bios_entry].addr = change_point[chgidx]->addr; @@ -397,8 +366,8 @@ static void memsize_probe(void) * must be limited. The max address is found by checking for * memory wrap from 1MB to 4GB. */ p1 = (ulong)&magic; - m_lim = 0xfffffffc; - for (p2 = 0x100000; p2; p2 <<= 1) { + m_lim = 0xfffffffc; + for (p2 = 0x100000; p2; p2 <<= 1) { p = (ulong *)(p1 + p2); if (*p == 0x1234569) { m_lim = --p2; @@ -415,7 +384,7 @@ static void memsize_probe(void) v->pmap[i].start = ((ulong)&_end + (1 << 12) - 1) >> 12; p = (ulong *)(v->pmap[i].start << 12); - /* Limit search for memory to m_lim and make sure we don't + /* Limit search for memory to m_lim and make sure we don't * overflow the 32 bit size of p. */ while ((ulong)p < m_lim && (ulong)p >= (ulong)&_end) { /* @@ -482,34 +451,34 @@ fstart: * We then check that at least one bit changed in each byte before * believing that it really is memory. */ -static int check_ram(void) +static int check_ram(void) { - int s; - - p1 = *p; - - /* write the complement */ - *p = ~p1; - p2 = *p; - s = 0; - - /* Now make sure a bit changed in each byte */ - if ((0xff & p1) != (0xff & p2)) { - s++; - } - if ((0xff00 & p1) != (0xff00 & p2)) { - s++; - } - if ((0xff0000 & p1) != (0xff0000 & p2)) { - s++; - } - if ((0xff000000 & p1) != (0xff000000 & p2)) { - s++; - } - if (s == 4) { - /* RAM at this address */ - return 1; - } - - return 0; + int s; + + p1 = *p; + + /* write the complement */ + *p = ~p1; + p2 = *p; + s = 0; + + /* Now make sure a bit changed in each byte */ + if ((0xff & p1) != (0xff & p2)) { + s++; + } + if ((0xff00 & p1) != (0xff00 & p2)) { + s++; + } + if ((0xff0000 & p1) != (0xff0000 & p2)) { + s++; + } + if ((0xff000000 & p1) != (0xff000000 & p2)) { + s++; + } + if (s == 4) { + /* RAM at this address */ + return 1; + } + + return 0; } diff --git a/memtest.exe b/memtest.exe Binary files differnew file mode 100644 index 0000000..a79b407 --- /dev/null +++ b/memtest.exe diff --git a/memtest_shared.lds b/memtest_shared.lds index d4576a2..453916c 100644 --- a/memtest_shared.lds +++ b/memtest_shared.lds @@ -18,6 +18,7 @@ SECTIONS { .dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.hash : { *(.hash) }
+ .gnu.hash : { *(.gnu.hash) }
.dynamic : { *(.dynamic) }
.rel.text : { *(.rel.text .rel.text.*) }
diff --git a/mt86+_loader b/mt86+_loader Binary files differindex ee3d2ec..adac56e 100644 --- a/mt86+_loader +++ b/mt86+_loader diff --git a/mt86+_loader.asm b/mt86+_loader.asm index 29b0322..03cea01 100644 --- a/mt86+_loader.asm +++ b/mt86+_loader.asm @@ -12,8 +12,8 @@ ; The good thing is that you get a single file which can be ; compressed, for example with http://upx.sf.net/ (UPX). -%define fullsize (116508 + buffer - exeh) - ; 116508 is the size of memtest86+ V2.11, adjust as needed! +%define fullsize (160280 + buffer - exeh) + ; 160280 is the size of memtest86+ V4.00, adjust as needed! %define stacksize 2048 %define stackpara ((stacksize + 15) / 16) @@ -3,7 +3,7 @@ * Released under version 2 of the Gnu Public License. * By Chris Brady * ---------------------------------------------------- - * MemTest86+ V1.94 Specific code (GPL V2.0) + * MemTest86+ V4.00 Specific code (GPL V2.0) * By Samuel DEMEULEMEESTER, sdemeule@memtest.org * http://www.x86-secret.com - http://www.memtest.org */ @@ -25,17 +25,24 @@ static unsigned char pci_conf_type = PCI_CONF_TYPE_NONE; #define PCI_CONF2_ADDRESS(dev, reg) (unsigned short)(0xC000 | (dev << 8) | reg) +#define PCI_CONF3_ADDRESS(bus, dev, fn, reg) \ + (0x80000000 | (((reg >> 8) & 0xF) << 24) | (bus << 16) | ((dev & 0x1F) << 11) | (fn << 8) | (reg & 0xFF)) + int pci_conf_read(unsigned bus, unsigned dev, unsigned fn, unsigned reg, unsigned len, unsigned long *value) { int result; - if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255 && pci_conf_type != PCI_CONF_TYPE_1)) return -1; result = -1; switch(pci_conf_type) { case PCI_CONF_TYPE_1: - outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8); + if(reg < 256){ + outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8); + }else{ + outl(PCI_CONF3_ADDRESS(bus, dev, fn, reg), 0xCF8); + } switch(len) { case 1: *value = inb(0xCFC + (reg & 3)); result = 0; break; case 2: *value = inw(0xCFC + (reg & 2)); result = 0; break; diff --git a/precomp.bin b/precomp.bin Binary files differindex d7f7f2f..6603191 100644..100755 --- a/precomp.bin +++ b/precomp.bin @@ -0,0 +1,440 @@ +/* + * smp.c -- + * + * Implements support for SMP machines. For reasons of + * simplicity, we do not handle all possible cases allowed by the + * MP spec. For example, we expect an explicit MP configuration + * table and do not handle default configurations. We also expect + * an on-chip local apic and do not support an external 82489DX + * apic controller. + * + */ + +#include "stddef.h" +#include "smp.h" +#include "cpuid.h" +#include "test.h" +#define DELAY_FACTOR 1 +extern void memcpy(void *dst, void *src , int len); +extern void test_start(void); + +typedef struct { + bool started; +} ap_info_t; + +volatile apic_register_t *APIC = NULL; +unsigned number_of_cpus = 1; // There is at least one cpu, the BSP +/* CPU number to APIC ID mapping table. CPU 0 is the BSP. */ +static unsigned cpu_num_to_apic_id[MAX_CPUS]; +volatile ap_info_t AP[MAX_CPUS]; + +uint8_t +checksum(uint8_t *data, unsigned len) +{ + uint32_t sum = 0; + uint8_t *end = data + len; + while (data < end) { + sum += *data; + data++; + } + return (uint8_t)(sum % 0x100); +} + + +bool +read_mp_config_table(uintptr_t addr) +{ + mp_config_table_header_t *mpc = (mp_config_table_header_t*)addr; + uint8_t *tab_entry_ptr; + uint8_t *mpc_table_end; + extern unsigned num_hyper_threads_per_core; + + if (mpc->signature != MPCSignature) { + return FALSE; + } + if (checksum((uint8_t*)mpc, mpc->length) != 0) { + return FALSE; + } + + + /* FIXME: the uintptr_t cast here works around a compilation problem on + * AMD64, but it ignores the real problem, which is that lapic_addr + * is only 32 bits. Maybe that's OK, but it should be investigated. + */ + APIC = (volatile apic_register_t*)(uintptr_t)mpc->lapic_addr; + + tab_entry_ptr = ((uint8_t*)mpc) + sizeof(mp_config_table_header_t); + mpc_table_end = ((uint8_t*)mpc) + mpc->length; + while (tab_entry_ptr < mpc_table_end) { + switch (*tab_entry_ptr) { + case MP_PROCESSOR: { + mp_processor_entry_t *pe = (mp_processor_entry_t*)tab_entry_ptr; + + if (pe->cpu_flag & CPU_BOOTPROCESSOR) { + // BSP is CPU 0 + cpu_num_to_apic_id[0] = pe->apic_id; + } else if (number_of_cpus < MAX_CPUS) { + cpu_num_to_apic_id[number_of_cpus] = pe->apic_id; + number_of_cpus++; + } + if (num_hyper_threads_per_core > 1 ) { + cpu_num_to_apic_id[number_of_cpus] = pe->apic_id | 1; + number_of_cpus++; + } + + // we cannot handle non-local 82489DX apics + if ((pe->apic_ver & 0xf0) != 0x10) { + return 0; + } + + // we don't know what to do with disabled cpus + + tab_entry_ptr += sizeof(mp_processor_entry_t); + break; + } + case MP_BUS: { + tab_entry_ptr += sizeof(mp_bus_entry_t); + break; + } + case MP_IOAPIC: { + tab_entry_ptr += sizeof(mp_io_apic_entry_t); + break; + } + case MP_INTSRC: + tab_entry_ptr += sizeof(mp_interrupt_entry_t); + case MP_LINTSRC: + tab_entry_ptr += sizeof(mp_local_interrupt_entry_t); + break; + default: + return FALSE; + } + } + return TRUE; +} + + +floating_pointer_struct_t * +scan_for_floating_ptr_struct(uintptr_t addr, uint32_t length) +{ + floating_pointer_struct_t *fp; + uintptr_t end = addr + length; + + + fp = (floating_pointer_struct_t*)addr; + while ((uintptr_t)fp < end) { + if (fp->signature == FPSignature) { + if (fp->length == 1 && checksum((uint8_t*)fp, 16) == 0) { + return fp; + } + } + fp++; + } + return NULL; +} + +void PUT_MEM16(uintptr_t addr, uint16_t val) +{ + *((volatile uint16_t *)addr) = val; +} + +void PUT_MEM32(uintptr_t addr, uint32_t val) +{ + *((volatile uint32_t *)addr) = val; +} + +static void inline +APIC_WRITE(unsigned reg, uint32_t val) +{ + APIC[reg][0] = val; +} + +static inline uint32_t +APIC_READ(unsigned reg) +{ + return APIC[reg][0]; +} + + +static void +SEND_IPI(unsigned apic_id, unsigned trigger, unsigned level, unsigned mode, + uint8_t vector) +{ + uint32_t v; + + v = APIC_READ(APICR_ICRHI) & 0x00ffffff; + APIC_WRITE(APICR_ICRHI, v | (apic_id << 24)); + + v = APIC_READ(APICR_ICRLO) & ~0xcdfff; + v |= (APIC_DEST_DEST << APIC_ICRLO_DEST_OFFSET) + | (trigger << APIC_ICRLO_TRIGGER_OFFSET) + | (level << APIC_ICRLO_LEVEL_OFFSET) + | (mode << APIC_ICRLO_DELMODE_OFFSET) + | (vector); + APIC_WRITE(APICR_ICRLO, v); +} + + +// Silly way of busywaiting, but we don't have a timer +void delay(unsigned us) +{ + unsigned freq = 1000; // in MHz, assume 1GHz CPU speed + uint64_t cycles = us * freq; + uint64_t t0 = RDTSC(); + uint64_t t1; + volatile unsigned k; + + do { + for (k = 0; k < 1000; k++) continue; + t1 = RDTSC(); + } while (t1 - t0 < cycles); +} + +static inline void +memset (void *dst, + char value, + int len) +{ + int i; + for (i = 0 ; i < len ; i++ ) { + *((char *) dst + i) = value; + } +} + +void kick_cpu(unsigned cpu_num) +{ + unsigned num_sipi, apic_id; + apic_id = cpu_num_to_apic_id[cpu_num]; + + // clear the APIC ESR register + APIC_WRITE(APICR_ESR, 0); + APIC_READ(APICR_ESR); + + // asserting the INIT IPI + SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 1, APIC_DELMODE_INIT, 0); + delay(100000 / DELAY_FACTOR); + + // de-assert the INIT IPI + SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 0, APIC_DELMODE_INIT, 0); + + for (num_sipi = 0; num_sipi < 2; num_sipi++) { + unsigned timeout; + bool send_pending; + unsigned err; + + APIC_WRITE(APICR_ESR, 0); + + SEND_IPI(apic_id, 0, 0, APIC_DELMODE_STARTUP, (uint32_t)startup_32 >> 12); + + timeout = 0; + do { + delay(10); + timeout++; + send_pending = (APIC_READ(APICR_ICRLO) & APIC_ICRLO_STATUS_MASK) != 0; + } while (send_pending && timeout < 1000); + + if (send_pending) { + //cprint(LINE_STATUS+1, 0, "SMP: STARTUP IPI was never sent"); + } + + delay(100000 / DELAY_FACTOR); + + err = APIC_READ(APICR_ESR) & 0xef; + if (err) { + //cprint(LINE_STATUS+1, 0, "SMP: After STARTUP IPI: err = 0x"); + //hprint(LINE_STATUS+1, COL_MID, err); + } + } +} + +// These memory locations are used for the trampoline code and data. + +#define BOOTCODESTART 0x9000 +#define GDTPOINTERADDR 0x9100 +#define GDTADDR 0x9110 + +void boot_ap(unsigned cpu_num) +{ + unsigned num_sipi, apic_id; + extern uint8_t gdt; + extern uint8_t _ap_trampoline_start; + extern uint8_t _ap_trampoline_protmode; + unsigned len = &_ap_trampoline_protmode - &_ap_trampoline_start; + apic_id = cpu_num_to_apic_id[cpu_num]; + + + memcpy((uint8_t*)BOOTCODESTART, &_ap_trampoline_start, len); + + // Fixup the LGDT instruction to point to GDT pointer. + PUT_MEM16(BOOTCODESTART + 3, GDTPOINTERADDR); + + // Copy a pointer to the temporary GDT to addr GDTPOINTERADDR. + // The temporary gdt is at addr GDTADDR + PUT_MEM16(GDTPOINTERADDR, 4 * 8); + PUT_MEM32(GDTPOINTERADDR + 2, GDTADDR); + + // Copy the first 4 gdt entries from the currently used GDT to the + // temporary GDT. + memcpy((uint8_t *)GDTADDR, &gdt, 32); + + // clear the APIC ESR register + APIC_WRITE(APICR_ESR, 0); + APIC_READ(APICR_ESR); + + // asserting the INIT IPI + SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 1, APIC_DELMODE_INIT, 0); + delay(100000 / DELAY_FACTOR); + + // de-assert the INIT IPI + SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 0, APIC_DELMODE_INIT, 0); + + for (num_sipi = 0; num_sipi < 2; num_sipi++) { + unsigned timeout; + bool send_pending; + unsigned err; + + APIC_WRITE(APICR_ESR, 0); + + SEND_IPI(apic_id, 0, 0, APIC_DELMODE_STARTUP, BOOTCODESTART >> 12); + + timeout = 0; + do { + delay(10); + timeout++; + send_pending = (APIC_READ(APICR_ICRLO) & APIC_ICRLO_STATUS_MASK) != 0; + } while (send_pending && timeout < 1000); + + if (send_pending) { + //cprint(LINE_STATUS+1, 0, "SMP: STARTUP IPI was never sent"); + } + + delay(100000 / DELAY_FACTOR); + + err = APIC_READ(APICR_ESR) & 0xef; + if (err) { + //cprint(LINE_STATUS+1, 0, "SMP: After STARTUP IPI: err = 0x"); + // hprint(LINE_STATUS+1, COL_MID, err); + } + } +} + +void +smp_init_bsp() +{ + floating_pointer_struct_t *fp; + /* gets the details about the cpu, the type, the brand + * whether it is a multi-core package etc. + */ + cpuid_init(); + + memset(&AP, 0, sizeof AP); + + fp = scan_for_floating_ptr_struct(0x0, 0x400); + if (fp == NULL) { + fp = scan_for_floating_ptr_struct(639*0x400, 0x400); + } + if (fp == NULL) { + fp = scan_for_floating_ptr_struct(0xf0000, 0x10000); + } + if (fp == NULL) { + /* + * If it is an SMP machine we should know now, unless the + * configuration is in an EISA/MCA bus machine with an + * extended bios data area. + * + * there is a real-mode segmented pointer pointing to the + * 4K EBDA area at 0x40E, calculate and scan it here. + */ + unsigned int address = *(unsigned short *)0x40E; + address <<= 4; + if (address) { + fp = scan_for_floating_ptr_struct(address, 0x400); + } + } + + if (fp != NULL && fp->phys_addr != 0) { + if (!read_mp_config_table(fp->phys_addr)) { + //cprint(LINE_STATUS+1,0, "SMP: Error while parsing MP config table"); + } + } +/* + if (fp == NULL) { + cprint(LINE_STATUS+1,0,"SMP: No floating pointer structure found"); + } +*/ +} + +void +smp_init_aps() +{ + int cpuNum; + for(cpuNum = 0 ; cpuNum < MAX_CPUS ; cpuNum++) { + AP[cpuNum].started = FALSE; + } +} + +unsigned +my_apic_id() +{ + return (APIC[APICR_ID][0]) >> 24; +} + +void +smp_ap_booted(unsigned cpu_num) +{ + AP[cpu_num].started = TRUE; +} + +void +smp_boot_ap(unsigned cpu_num) +{ + unsigned timeout; + extern bool smp_mode; + boot_ap(cpu_num); + timeout = 0; + do { + delay(1000 / DELAY_FACTOR); + timeout++; + } while (!AP[cpu_num].started && timeout < 100000 / DELAY_FACTOR); + + if (!AP[cpu_num].started) { + //cprint(LINE_STATUS+1, 0, "SMP: Boot timeout for"); + //dprint(LINE_STATUS+1, COL_MID, cpu_num,2,1); + //cprint(LINE_STATUS+1, 26, "Turning off SMP"); + smp_mode = FALSE; + } +} + +unsigned +smp_num_cpus() +{ + return number_of_cpus; +} + +unsigned +smp_my_cpu_num() +{ + unsigned apicid = my_apic_id(); + unsigned i; + + for (i = 0; i < MAX_CPUS; i++) { + if (apicid == cpu_num_to_apic_id[i]) { + break; + } + } + if (i == MAX_CPUS) { + i = 0; + } + return i; +} + +volatile spinlock_t barr_lk={1}; +void barrier(volatile int *barr, int n) +{ + spin_lock(&barr_lk); + barr++; + spin_unlock(&barr_lk); + while((uint32_t)barr<n); + barr = 0; + return; +} + @@ -0,0 +1,265 @@ +/* ********************************************************** + * Copyright 2002 VMware, Inc. All rights reserved. -- VMware Confidential + * **********************************************************/ + + +#ifndef _SMP_H_ +#define _SMP_H_ +#include "stdint.h" +#include "defs.h" +#define MAX_CPUS 16 // "16 CPUs ought to be enough for everybody." + + +#define FPSignature ('_' | 'M' << 8 | 'P' << 16 | '_' << 24) + +typedef struct { + uint32_t signature; // "_MP_" + uint32_t phys_addr; + uint8_t length; + uint8_t spec_rev; + uint8_t checksum; + uint8_t feature[5]; +} floating_pointer_struct_t; + +#define MPCSignature ('P' | 'C' << 8 | 'M' << 16 | 'P' << 24) +typedef struct { + uint32_t signature; // "PCMP" + uint16_t length; + uint8_t spec_rev; + uint8_t checksum; + char oem[8]; + char productid[12]; + uint32_t oem_ptr; + uint16_t oem_size; + uint16_t oem_count; + uint32_t lapic_addr; + uint32_t reserved; +} mp_config_table_header_t; + +/* Followed by entries */ + +#define MP_PROCESSOR 0 +#define MP_BUS 1 +#define MP_IOAPIC 2 +#define MP_INTSRC 3 +#define MP_LINTSRC 4 + +typedef struct { + uint8_t type; /* MP_PROCESSOR */ + uint8_t apic_id; /* Local APIC number */ + uint8_t apic_ver; /* Its versions */ + uint8_t cpu_flag; +#define CPU_ENABLED 1 /* Processor is available */ +#define CPU_BOOTPROCESSOR 2 /* Processor is the BP */ + uint32_t cpu_signature; +#define CPU_STEPPING_MASK 0x0F +#define CPU_MODEL_MASK 0xF0 +#define CPU_FAMILY_MASK 0xF00 + uint32_t featureflag; /* CPUID feature value */ + uint32_t reserved[2]; +} mp_processor_entry_t; + + +typedef struct { + uint8_t type; // has value MP_BUS + uint8_t busid; + char bustype[6]; +} mp_bus_entry_t; + +#define BUSTYPE_EISA "EISA" +#define BUSTYPE_ISA "ISA" +#define BUSTYPE_INTERN "INTERN" +#define BUSTYPE_MCA "MCA" +#define BUSTYPE_VL "VL" +#define BUSTYPE_PCI "PCI" +#define BUSTYPE_PCMCIA "PCMCIA" + +/* We don't understand the others */ + +typedef struct { + uint8_t type; // set to MP_IOAPIC + uint8_t apicid; + uint8_t apicver; + uint8_t flags; +#define MPC_APIC_USABLE 0x01 + uint32_t apicaddr; +} mp_io_apic_entry_t; + + +typedef struct { + uint8_t type; + uint8_t irqtype; + uint16_t irqflag; + uint8_t srcbus; + uint8_t srcbusirq; + uint8_t dstapic; + uint8_t dstirq; +} mp_interrupt_entry_t; + +#define MP_INT_VECTORED 0 +#define MP_INT_NMI 1 +#define MP_INT_SMI 2 +#define MP_INT_EXTINT 3 + +#define MP_IRQDIR_DEFAULT 0 +#define MP_IRQDIR_HIGH 1 +#define MP_IRQDIR_LOW 3 + + +typedef struct { + uint8_t type; + uint8_t irqtype; + uint16_t irqflag; + uint8_t srcbusid; + uint8_t srcbusirq; + uint8_t destapic; +#define MP_APIC_ALL 0xFF + uint8_t destapiclint; +} mp_local_interrupt_entry_t; + +/* APIC definitions */ +/* + * APIC registers + */ +#define APICR_ID 0x02 +#define APICR_ESR 0x28 +#define APICR_ICRLO 0x30 +#define APICR_ICRHI 0x31 + +/* APIC destination shorthands */ +#define APIC_DEST_DEST 0 +#define APIC_DEST_LOCAL 1 +#define APIC_DEST_ALL_INC 2 +#define APIC_DEST_ALL_EXC 3 + +/* APIC IPI Command Register format */ +#define APIC_ICRHI_RESERVED 0x00ffffff +#define APIC_ICRHI_DEST_MASK 0xff000000 +#define APIC_ICRHI_DEST_OFFSET 24 + +#define APIC_ICRLO_RESERVED 0xfff32000 +#define APIC_ICRLO_DEST_MASK 0x000c0000 +#define APIC_ICRLO_DEST_OFFSET 18 +#define APIC_ICRLO_TRIGGER_MASK 0x00008000 +#define APIC_ICRLO_TRIGGER_OFFSET 15 +#define APIC_ICRLO_LEVEL_MASK 0x00004000 +#define APIC_ICRLO_LEVEL_OFFSET 14 +#define APIC_ICRLO_STATUS_MASK 0x00001000 +#define APIC_ICRLO_STATUS_OFFSET 12 +#define APIC_ICRLO_DESTMODE_MASK 0x00000800 +#define APIC_ICRLO_DESTMODE_OFFSET 11 +#define APIC_ICRLO_DELMODE_MASK 0x00000700 +#define APIC_ICRLO_DELMODE_OFFSET 8 +#define APIC_ICRLO_VECTOR_MASK 0x000000ff +#define APIC_ICRLO_VECTOR_OFFSET 0 + +/* APIC trigger types (edge/level) */ +#define APIC_TRIGGER_EDGE 0 +#define APIC_TRIGGER_LEVEL 1 + +/* APIC delivery modes */ +#define APIC_DELMODE_FIXED 0 +#define APIC_DELMODE_LOWEST 1 +#define APIC_DELMODE_SMI 2 +#define APIC_DELMODE_NMI 4 +#define APIC_DELMODE_INIT 5 +#define APIC_DELMODE_STARTUP 6 +#define APIC_DELMODE_EXTINT 7 +typedef uint32_t apic_register_t[4]; + +extern volatile apic_register_t *APIC; + +unsigned smp_num_cpus(); +unsigned smp_my_cpu_num(); + +void smp_init_bsp(void); +void smp_init_aps(void); + +void smp_boot_ap(unsigned cpu_num); +void smp_ap_booted(unsigned cpu_num); + +static inline void +__GET_CPUID(int ax, uint32_t *regs) +{ + __asm__ __volatile__("\t" + /* save ebx in case -fPIC is being used */ + "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" + : "=a" (regs[0]), "=D" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) + : "a" (ax) + : "memory" + ); +} + +#define GET_CPUID(_ax,_bx,_cx,_dx) { \ + uint32_t regs[4]; \ + __GET_CPUID(_ax,regs); \ + _ax = regs[0]; \ + _bx = regs[1]; \ + _cx = regs[2]; \ + _dx = regs[3]; \ +} + +/* + * Checked against the Intel manual and GCC --hpreg + * + * volatile because the tsc always changes without the compiler knowing it. + */ +static inline uint64_t +RDTSC(void) +{ + uint64_t tim; + + __asm__ __volatile__( + "rdtsc" + : "=A" (tim) + ); + + return tim; +} + +static inline uint64_t __GET_MSR(int cx) +{ + uint64_t msr; + + __asm__ __volatile__( + "rdmsr" + : "=A" (msr) + : "c" (cx) + ); + + return msr; +} + +#define __GCC_OUT(s, s2, port, val) do { \ + __asm__( \ + "out" #s " %" #s2 "1, %w0" \ + : \ + : "Nd" (port), "a" (val) \ + ); \ +} while (0) +#define OUTB(port, val) __GCC_OUT(b, b, port, val) + +typedef struct { + unsigned int slock; +} spinlock_t; + +static inline void spin_lock(volatile spinlock_t *lock) +{ + asm volatile("\n1:\t" + " ; lock;decb %0\n\t" + "jns 3f\n" + "2:\t" + "rep;nop\n\t" + "cmpb $0,%0\n\t" + "jle 2b\n\t" + "jmp 1b\n" + "3:\n\t" + : "+m" (lock->slock) : : "memory"); +} +static inline void spin_unlock(volatile spinlock_t *lock) +{ + asm volatile("movb $1,%0" : "+m" (lock->slock) :: "memory"); +} + + +#endif /* _SMP_H_ */ @@ -2,13 +2,22 @@ * added by Reto Sonderegger, 2004, reto@swissbit.com
*
* Released under version 2 of the Gnu Puclic License
+ * ----------------------------------------------------
+ * MemTest86+ V4.00 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
@@ -42,7 +51,7 @@ unsigned char ich5_smb_read_byte(unsigned char adr, unsigned char cmd) __outb((adr << 1) | 0x01, SMBHSTADD);
__outb(0x48, SMBHSTCNT);
rdtsc(l1, h1);
- cprint(POP2_Y, POP2_X + 16, s + cmd % 8); // progress bar
+ //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)) / v->clks_msec;
@@ -57,7 +66,7 @@ static int ich5_read_spd(int dimmadr) spd[0] = ich5_smb_read_byte(0x50 + dimmadr, 0);
if (spd[0] == 0xff) return -1; // no spd here
for (x = 1; x < 256; x++) {
- spd[x] = ich5_smb_read_byte(0x50 + dimmadr, (unsigned char) x);
+ spd[x] = ich5_smb_read_byte(0x50 + dimmadr, (unsigned char) x);
}
return 0;
}
@@ -136,24 +145,171 @@ 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;
+ 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;
+
+ 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[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[4] & 0xF, spd[8] & 0x7, spd[7] & 0x7, spd[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;
+
+ // Then module jedec speed
+ switch(spd[12])
+ {
+ default:
+ case 20:
+ cprint(LINE_SPD+k, curcol, "PC3-6400");
+ curcol += 8;
+ break;
+ case 15:
+ cprint(LINE_SPD+k, curcol, "PC3-8500");
+ curcol += 8;
+ break;
+ case 12:
+ cprint(LINE_SPD+k, curcol, "PC3-10600");
+ curcol += 9;
+ break;
+ case 10:
+ cprint(LINE_SPD+k, curcol, "PC3-12800");
+ curcol += 9;
+ break;
+ case 8:
+ cprint(LINE_SPD+k, curcol, "PC3-15000");
+ curcol += 9;
+ break;
+ case 6:
+ cprint(LINE_SPD+k, curcol, "PC3-16000");
+ curcol += 9;
+ break;
+ }
+
+ curcol++;
+
+ // Then print module infos (manufacturer & part number)
+ for (i = 0; jep106[i].cont_code < 9; i++) {
+ if (spd[117] == jep106[i].cont_code && spd[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(16+k, curcol, convert_hex_to_char(spd[h]));
+ curcol++;
+ }
+
+ // Detect XMP Memory
+ if(spd[176] == 0x0C && spd[177] == 0x4A)
+ {
+ cprint(LINE_SPD+k, curcol, "*XMP*");
+ }
+ }
+ }
+ }
+ // We enter this function if DDR2 is detected
+ if(spd[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[31], spd[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[9] >> 4) * 10;
+ byte2 = spd[9] & 0xF;
+
+ ddr2_speed = 1 / (byte1 + byte2) * 10000;
+
+ 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;
+
+ // Then print module infos (manufacturer & part number)
+ int ccode = 0;
+
+ for(i = 64; i < 72; i++)
+ {
+ if(spd[i] == 0x7F) { ccode++; }
+ }
+
+ curcol++;
+
+ for (i = 0; jep106[i].cont_code < 9; i++) {
+ if (ccode == jep106[i].cont_code && spd[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(16+k, curcol, convert_hex_to_char(spd[h]));
+ curcol++;
+ }
+
+ }
+ }
+
+ }
+ k++;
+ }
+ }
+}
+
+
void show_spd(void)
{
int index;
@@ -187,3 +343,222 @@ void show_spd(void) 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;
+};
+
+struct ascii_map amap[] = {
+{ 0x20, " "},
+{ 0x21, "!"},
+{ 0x22, "'"},
+{ 0x23, "#"},
+{ 0x24, "$"},
+{ 0x25, "%"},
+{ 0x26, "&"},
+{ 0x28, "("},
+{ 0x29, ")"},
+{ 0x2A, "*"},
+{ 0x2B, "+"},
+{ 0x2C, ","},
+{ 0x2D, "-"},
+{ 0x2E, "."},
+{ 0x30, "0"},
+{ 0x31, "1"},
+{ 0x32, "2"},
+{ 0x33, "3"},
+{ 0x34, "4"},
+{ 0x35, "5"},
+{ 0x36, "6"},
+{ 0x38, "8"},
+{ 0x39, "9"},
+{ 0x3A, ":"},
+{ 0x3B, ";"},
+{ 0x3C, "<"},
+{ 0x3D, "="},
+{ 0x3E, ">"},
+{ 0x40, "@"},
+{ 0x41, "A"},
+{ 0x42, "B"},
+{ 0x43, "C"},
+{ 0x44, "D"},
+{ 0x45, "E"},
+{ 0x46, "F"},
+{ 0x47, "G"},
+{ 0x48, "H"},
+{ 0x49, "I"},
+{ 0x4A, "J"},
+{ 0x4B, "K"},
+{ 0x4C, "L"},
+{ 0x4D, "M"},
+{ 0x4E, "N"},
+{ 0x4F, "O"},
+{ 0x50, "P"},
+{ 0x51, "Q"},
+{ 0x52, "R"},
+{ 0x53, "S"},
+{ 0x54, "T"},
+{ 0x55, "U"},
+{ 0x56, "V"},
+{ 0x57, "W"},
+{ 0x58, "X"},
+{ 0x59, "Y"},
+{ 0x5A, "Z"},
+{ 0x5B, "["},
+{ 0x5C, "-"},
+{ 0x5D, "]"},
+{ 0x5E, "^"},
+{ 0x60, "`"},
+{ 0x61, "a"},
+{ 0x62, "b"},
+{ 0x63, "c"},
+{ 0x64, "d"},
+{ 0x65, "e"},
+{ 0x66, "f"},
+{ 0x68, "h"},
+{ 0x69, "i"},
+{ 0x6A, "j"},
+{ 0x6B, "k"},
+{ 0x6C, "l"},
+{ 0x6D, "m"},
+{ 0x6E, "n"},
+{ 0x6F, "o"},
+{ 0x70, "p"},
+{ 0x71, "q"},
+{ 0x72, "r"},
+{ 0x73, "s"},
+{ 0x74, "t"},
+{ 0x75, "u"},
+{ 0x76, "v"},
+{ 0x78, "x"},
+{ 0x79, "y"},
+{ 0x7A, "z"},
+{ 0x7B, "{"},
+{ 0x7C, "|"},
+{ 0x7D, "}"},
+{ 0x7E, "~"},
+{ 0, ""}
+};
+
+char* convert_hex_to_char(unsigned hex_org){
+ int i;
+
+ for (i = 0; amap[i].hex_code > 0; i++) {
+ if (hex_org == amap[i].hex_code) {
+ return amap[i].name;
+ }
+ }
+ return "";
+}
+
@@ -0,0 +1,13 @@ +/* + * MemTest86+ V3.00 Specific code (GPL V2.0) + * By Samuel DEMEULEMEESTER, sdemeule@memtest.org + * http://www.canardpc.com - http://www.memtest.org + */ + +void get_spd_spec(void); +int get_ddr2_module_size(int rank_density_byte, int rank_num_byte); +int get_ddr3_module_size(int sdram_capacity, int prim_bus_width, int sdram_width, int ranks); +char* convert_hex_to_char(unsigned hex_org); +#define LINE_SPD 16 + + @@ -48,5 +48,13 @@ typedef unsigned int uintptr_t; typedef long long int intmax_t; typedef unsigned long long uintmax_t; +typedef char bool; +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif #endif /* I386_STDINT_H */ @@ -4,7 +4,7 @@ * Released under version 2 of the Gnu Public License. * By Chris Brady, cbrady@sgi.com * ---------------------------------------------------- - * MemTest86+ V2.01 Specific code (GPL V2.0) + * MemTest86+ V3.00 Specific code (GPL V2.0) * By Samuel DEMEULEMEESTER, sdemeule@memtest.org * http://www.canardpc.com - http://www.memtest.org */ @@ -13,6 +13,7 @@ #include "config.h" #include <sys/io.h> #include "dmi.h" +#include <inttypes.h> extern int segs, bail; extern volatile ulong *p; @@ -50,19 +51,19 @@ void addr_tst1() /* Now write pattern compliment */ p1 = ~p1; end = v->map[segs-1].end; - for (i=0; i<1000; i++) { + for (i=0; i<100; i++) { mask = 4; do { pt = (ulong *)((ulong)p | mask); - if (pt == p) { + if ((uintptr_t)pt == (uintptr_t)p) { mask = mask << 1; continue; } - if (pt >= end) { + if ((uintptr_t)pt >= (uintptr_t)end) { break; } *pt = p1; - if ((bad = *p) != ~p1) { + if ((uintptr_t)(bad = *p) != (uintptr_t)~p1) { ad_err1((ulong *)p, (ulong *)mask, bad, ~p1); i = 1000; @@ -90,7 +91,7 @@ void addr_tst1() /* Force start address to be a multiple of 256k */ p = (ulong *)roundup((ulong)p, bank - 1); end = v->map[j].end; - while (p < end) { + while ((uintptr_t)p < (uintptr_t)end) { *p = p1; p1 = ~p1; @@ -99,15 +100,15 @@ void addr_tst1() do { pt = (ulong *) ((ulong)p | mask); - if (pt == p) { + if ((uintptr_t)pt == (uintptr_t)p) { mask = mask << 1; continue; } - if (pt >= end) { + if ((uintptr_t)pt >= (uintptr_t)end) { break; } *pt = p1; - if ((bad = *p) != ~p1) { + if ((uintptr_t)(bad = *p) != (uintptr_t)~p1) { ad_err1((ulong *)p, (ulong *)mask, bad,~p1); @@ -116,7 +117,7 @@ void addr_tst1() mask = mask << 1; } while(mask); } - if (p + bank/4 > p) { + if ((uintptr_t)(p + bank/4) > (uintptr_t)p) { p += bank/4; } else { p = end; @@ -150,16 +151,16 @@ void addr_tst2() done = 0; do { /* Check for overflow */ - if (pe + SPINSZ > pe) { + if ((uintptr_t)(pe + SPINSZ) > (uintptr_t)pe) { pe += SPINSZ; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { pe = end; done++; } - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe) { break; } @@ -194,16 +195,16 @@ void addr_tst2() done = 0; do { /* Check for overflow */ - if (pe + SPINSZ > pe) { + if ((uintptr_t)(pe + SPINSZ) > (uintptr_t)pe) { pe += SPINSZ; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { pe = end; done++; } - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe ) { break; } /* Original C code replaced with hand tuned assembly code @@ -260,6 +261,7 @@ void movinvr() volatile ulong *pe; volatile ulong *start,*end; ulong num; + uintptr_t seg_start; /* Initialize memory with initial sequence of random numbers. */ if (v->rdtsc) { @@ -277,19 +279,20 @@ void movinvr() end = v->map[j].end; pe = start; p = start; + seg_start = (uintptr_t)p; done = 0; do { /* Check for overflow */ - if (pe + SPINSZ > pe) { + if ((uintptr_t)(pe + SPINSZ) > (uintptr_t)pe) { pe += SPINSZ; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { pe = end; done++; } - if (p == pe ) { + if (seg_start == (uintptr_t)pe) { break; } /* Original C code replaced with hand tuned assembly code */ @@ -310,7 +313,7 @@ void movinvr() "jb L200\n\t" : "=D" (p) : "D" (p), "b" (pe) - : "eax" + : "eax", "edx" ); do_tick(); @@ -328,19 +331,20 @@ void movinvr() end = v->map[j].end; pe = start; p = start; + seg_start = (uintptr_t)p; done = 0; do { /* Check for overflow */ - if (pe + SPINSZ > pe) { + if ((uintptr_t)(pe + SPINSZ) > (uintptr_t)pe) { pe += SPINSZ; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { pe = end; done++; } - if (p == pe ) { + if (seg_start == (uintptr_t)pe) { break; } /* Original C code replaced with hand tuned assembly code */ @@ -427,17 +431,17 @@ void movinv1(int iter, ulong p1, ulong p2) done = 0; do { /* Check for overflow */ - if (pe + SPINSZ > pe) { + if ((uintptr_t)(pe + SPINSZ) > (uintptr_t)pe) { pe += SPINSZ; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { pe = end; done++; } len = pe - p; - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe) { break; } /* Original C code replaced with hand tuned assembly code @@ -468,16 +472,16 @@ void movinv1(int iter, ulong p1, ulong p2) done = 0; do { /* Check for overflow */ - if (pe + SPINSZ > pe) { + if ((uintptr_t)(pe + SPINSZ) > (uintptr_t)pe) { pe += SPINSZ; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { pe = end; done++; } - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe) { break; } /* Original C code replaced with hand tuned assembly code @@ -534,16 +538,16 @@ void movinv1(int iter, ulong p1, ulong p2) done = 0; do { /* Check for underflow */ - if (pe - SPINSZ < pe) { + if ((uintptr_t)(pe - SPINSZ) < (uintptr_t)pe) { pe -= SPINSZ; } else { pe = start; } - if (pe <= start) { + if ((uintptr_t)pe <= (uintptr_t)start) { pe = start; done++; } - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe) { break; } /* Original C code replaced with hand tuned assembly code @@ -623,16 +627,16 @@ void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off) pat = p1; do { /* Check for overflow */ - if (pe + SPINSZ > pe) { + if ((uintptr_t)(pe + SPINSZ) > (uintptr_t)pe) { pe += SPINSZ; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { pe = end; done++; } - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe) { break; } /* Do a SPINSZ section of memory */ @@ -685,16 +689,16 @@ void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off) pat = p1; do { /* Check for overflow */ - if (pe + SPINSZ > pe) { + if ((uintptr_t)(pe + SPINSZ) > (uintptr_t)pe) { pe += SPINSZ; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { pe = end; done++; } - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe) { break; } /* Original C code replaced with hand tuned assembly code @@ -798,16 +802,16 @@ void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off) done = 0; do { /* Check for underflow */ - if (pe - SPINSZ < pe) { + if ((uintptr_t)(pe - SPINSZ) < (uintptr_t)pe) { pe -= SPINSZ; } else { pe = start; } - if (pe <= start) { + if ((uintptr_t)pe <= (uintptr_t)start) { pe = start; done++; } - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe) { break; } /* Original C code replaced with hand tuned assembly code @@ -906,16 +910,16 @@ void modtst(int offset, int iter, ulong p1, ulong p2) done = 0; do { /* Check for overflow */ - if (pe + SPINSZ > pe) { + if ((uintptr_t)(pe + SPINSZ) > (uintptr_t)pe) { pe += SPINSZ; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { pe = end; done++; } - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe) { break; } /* Original C code replaced with hand tuned assembly code @@ -951,16 +955,16 @@ void modtst(int offset, int iter, ulong p1, ulong p2) k = 0; do { /* Check for overflow */ - if (pe + SPINSZ > pe) { + if ((uintptr_t)(pe + SPINSZ) > (uintptr_t)pe) { pe += SPINSZ; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { pe = end; done++; } - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe) { break; } /* Original C code replaced with hand tuned assembly code @@ -1009,16 +1013,17 @@ void modtst(int offset, int iter, ulong p1, ulong p2) done = 0; do { /* Check for overflow */ - if (pe + SPINSZ > pe) { + if ((uintptr_t)(pe + SPINSZ) > (uintptr_t)pe) { pe += SPINSZ; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { + pe = end; done++; } - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe) { break; } /* Original C code replaced with hand tuned assembly code @@ -1098,16 +1103,18 @@ void block_move(int iter) done = 0; do { /* Check for overflow */ - if (pe + SPINSZ*4 > pe) { + if ((uintptr_t)(pe + SPINSZ*4) > (uintptr_t)pe) { pe += SPINSZ*4; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { + pe = end; done++; } - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe) { + break; } len = ((ulong)pe - (ulong)p) / 64; @@ -1167,16 +1174,16 @@ void block_move(int iter) done = 0; do { /* Check for overflow */ - if (pe + SPINSZ*4 > pe) { + if ((uintptr_t)(pe + SPINSZ*4) > (uintptr_t)pe) { pe += SPINSZ*4; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { pe = end; done++; } - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe) { break; } pp = p + ((pe - p) / 2); @@ -1234,16 +1241,16 @@ void block_move(int iter) done = 0; do { /* Check for overflow */ - if (pe + SPINSZ*4 > pe) { + if ((uintptr_t)(pe + SPINSZ*4) > (uintptr_t)pe) { pe += SPINSZ*4; } else { pe = end; } - if (pe >= end) { + if ((uintptr_t)pe >= (uintptr_t)end) { pe = end; done++; } - if (p == pe ) { + if ((uintptr_t)p == (uintptr_t)pe) { break; } asm __volatile__ ( @@ -8,7 +8,8 @@ * http://www.canardpc.com - http://www.memtest.org */ - +#ifndef _TEST_H_ +#define _TEST_H_ #define E88 0x00 #define E801 0x04 #define E820NR 0x08 /* # entries in E820MAP */ @@ -16,6 +17,7 @@ #define E820MAX 32 /* number of entries in E820MAP */ #define E820ENTRY_SIZE 20 #define MEMINFO_SIZE 0x28c +#define MAX_DMI_MEMDEVS 16 #ifndef __ASSEMBLY__ @@ -39,10 +41,11 @@ struct mem_info_t { }; typedef unsigned long ulong; -#define SPINSZ 0x800000 +#define SPINSZ 0x2000000 #define MOD_SZ 20 #define BAILOUT if (bail) goto skip_test; #define BAILR if (bail) return; +#define NULL 0 #define DMI_SEARCH_START 0x0000F000 #define DMI_SEARCH_LENGTH 0x000F0FFF @@ -86,7 +89,7 @@ typedef unsigned long ulong; #define POP2_H 21 #define POP2_X 3 #define POP2_Y 2 -#define NULL 0 +//#define NULL 0 /* memspeed operations */ #define MS_COPY 1 @@ -152,6 +155,7 @@ void addr_tst2(void); void bit_fade(void); void sleep(int sec, int sms); void beep(unsigned int frequency); +int getnum(ulong val); void block_move(int iter); void find_ticks(void); void print_err(ulong *adr, ulong good, ulong bad, ulong xor); @@ -249,7 +253,6 @@ struct tseq { short cache; short pat; short iter; - short ticks; short errors; char *msg; }; @@ -292,7 +295,7 @@ struct err_info { /* Define common variables accross relocations of memtest86+ */ struct vars { - int test; + volatile int test; int pass; unsigned long *eadr; unsigned long exor; @@ -320,6 +323,7 @@ struct vars { ulong snaph; ulong snapl; ulong extclock; + unsigned long imc_type; int printmode; int numpatn; struct pair patn [BADRAM_MAXPATNS]; @@ -338,4 +342,10 @@ extern unsigned char _size, _pages; extern struct mem_info_t mem_info; +/* CPU mode types */ +#define CPM_SINGLE 1 +#define CPM_RROBIN 2 +#define CPM_SEQ 3 + #endif /* __ASSEMBLY__ */ +#endif /* _TEST_H_ */
\ No newline at end of file |