diff options
author | Simon Rettberg | 2020-06-02 13:57:33 +0200 |
---|---|---|
committer | Simon Rettberg | 2020-06-02 13:57:33 +0200 |
commit | b26b1ad7f9213a89262ae0334b97d60e025a3562 (patch) | |
tree | d52207b8ecb64a9a5f6cdb22cfe65b3385713d48 | |
parent | [import] Import version 5.01 (diff) | |
download | memtest86-b26b1ad7f9213a89262ae0334b97d60e025a3562.tar.gz memtest86-b26b1ad7f9213a89262ae0334b97d60e025a3562.tar.xz memtest86-b26b1ad7f9213a89262ae0334b97d60e025a3562.zip |
[import] Import version 5.31b
https://www.memtest.org/download/5.31b/memtest86+-5.31b.tar.gz
-rw-r--r-- | Makefile | 43 | ||||
-rw-r--r-- | README.background | 4 | ||||
-rw-r--r-- | README.build-process | 6 | ||||
-rw-r--r-- | config.c | 82 | ||||
-rw-r--r-- | controller.c | 6556 | ||||
-rw-r--r-- | cpuid.h | 14 | ||||
-rw-r--r-- | defs.h | 2 | ||||
-rw-r--r-- | dmi.c | 49 | ||||
-rw-r--r-- | error.c | 1014 | ||||
-rw-r--r-- | init.c | 481 | ||||
-rw-r--r-- | io.h | 21 | ||||
-rw-r--r-- | jedec_id.h | 1971 | ||||
-rw-r--r-- | lib.c | 1858 | ||||
-rw-r--r-- | linuxbios.c | 6 | ||||
-rw-r--r-- | main.c | 2212 | ||||
-rwxr-xr-x | makeiso.sh | 6 | ||||
-rw-r--r-- | memsize.c | 75 | ||||
-rw-r--r-- | patn.c | 132 | ||||
-rwxr-xr-x | precomp.bin | bin | 150024 -> 153868 bytes | |||
-rw-r--r-- | reloc.c | 367 | ||||
-rw-r--r-- | self_test.c | 209 | ||||
-rw-r--r-- | serial.h | 1 | ||||
-rw-r--r-- | smp.c | 888 | ||||
-rw-r--r-- | spd.c | 1087 | ||||
-rw-r--r-- | test.c | 2895 | ||||
-rw-r--r-- | test.h | 212 | ||||
-rw-r--r-- | vmem.c | 229 |
27 files changed, 10343 insertions, 10077 deletions
@@ -12,16 +12,21 @@ FDISK=/dev/fd0 AS=as -32 CC=gcc -CFLAGS= -Wall -march=i486 -m32 -O1 -fomit-frame-pointer -fno-builtin \ - -ffreestanding -fPIC $(SMP_FL) -fno-stack-protector - +CFLAGS= -Wall -Werror -march=i486 -m32 -O1 -fomit-frame-pointer -fno-builtin \ + -ffreestanding -fPIC $(SMP_FL) -fno-stack-protector + +SELF_TEST_CFLAGS = -Wall -Werror -march=i486 -m32 -O1 -g + OBJS= head.o reloc.o main.o test.o init.o lib.o patn.o screen_buffer.o \ - config.o cpuid.o linuxbios.o pci.o memsize.o spd.o error.o dmi.o controller.o \ - smp.o vmem.o random.o - + config.o cpuid.o linuxbios.o pci.o spd.o error.o dmi.o controller.o \ + smp.o vmem.o memsize.o random.o + +SELF_TEST_OBJS = test.o self_test.o cpuid.o random.o + +all: clean memtest.bin memtest -all: clean memtest.bin memtest - scp memtest.bin root@192.168.0.12:/srv/tftp/mt86plus +run_self_test : self_test + ./self_test && touch run_self_test # Link it statically once so I know I don't have undefined # symbols and then link it dynamically so I have full @@ -37,6 +42,9 @@ memtest_shared.bin: memtest_shared memtest: memtest_shared.bin memtest.lds $(LD) -s -T memtest.lds -b binary memtest_shared.bin -o $@ +self_test : $(SELF_TEST_OBJS) + $(CC) $(SELF_TEST_CFLAGS) -o $@ $(SELF_TEST_OBJS) + head.s: head.S config.h defs.h test.h $(CC) -E -traditional $< -o $@ @@ -50,22 +58,18 @@ memtest.bin: memtest_shared.bin bootsect.o setup.o memtest.bin.lds $(LD) -T memtest.bin.lds bootsect.o setup.o -b binary \ memtest_shared.bin -o memtest.bin -reloc.o: reloc.c - $(CC) -c $(CFLAGS) -fno-strict-aliasing reloc.c +self_test.o : self_test.c + $(CC) -c $(SELF_TEST_CFLAGS) self_test.c -test.o: test.c - $(CC) -c -Wall -march=i486 -m32 -O0 -fomit-frame-pointer -fno-builtin -ffreestanding test.c +memsize.o: memsize.c + $(CC) -Wall -Werror -march=i486 -m32 -O0 -fomit-frame-pointer -fno-builtin -ffreestanding -fPIC $(SMP_FL) -fno-stack-protector -c -o memsize.o memsize.c random.o: random.c $(CC) -c -Wall -march=i486 -m32 -O3 -fomit-frame-pointer -fno-builtin -ffreestanding random.c - -# rule for build number generation -build_number: - sh make_buildnum.sh clean: rm -f *.o *.s *.iso memtest.bin memtest memtest_shared \ - memtest_shared.bin memtest.iso + memtest_shared.bin memtest.iso run_self_test self_test iso: make all @@ -76,6 +80,9 @@ install: all install-precomp: dd <precomp.bin >$(FDISK) bs=8192 - + dos: all cat mt86+_loader memtest.bin > memtest.exe + +debug2pxe: all + cp memtest.bin /srv/tftp/memtest/memtest diff --git a/README.background b/README.background index 9c35250..4acab8e 100644 --- a/README.background +++ b/README.background @@ -132,9 +132,9 @@ addr memory that is being tested... |0x200000 | |RAM_E e820 map which we have stored in v->pmap[] array, since all memory in the selected window address range may correspond to RAM or can be usable. A list of segments within the window is - created , which contain the usable portions of the window. + created, which contain the usable portions of the window. This is stored in v->mmap[] array. - vi. Once the v->mmap[] array populated, we have the list of + vi. Once the v->mmap[] array is populated, we have the list of non-overlapping segments in the current window which are the final address ranges that can be tested. The BSP executes the test first and lets each AP execute the test one by one. Once diff --git a/README.build-process b/README.build-process index 19edfcf..12158d6 100644 --- a/README.build-process +++ b/README.build-process @@ -5,11 +5,11 @@ affect of position independent code. A 16 bit loader is prepended to memtest86 so it can be loaded from a floppy, or from lilo. In restructuring the build process I had several goals. Maintainability and -comprehsibility of the build process. Simplicity of the toolset. And the +comprehensibility of the build process. Simplicity of the toolset. And the ability to build images bootable by both the legacy x86 bootloader, and images bootable by bootloaders that directly load static ELF images. -With the ability to proecess relocation records, memtest.bin has been +With the ability to process relocation records, memtest.bin has been reduced in size from 84480 bytes to 49308 bytes. And now only requires one copy of memtest86. A reduction in size of 35K. And the build process can now ignore the size of memtest86. @@ -33,7 +33,7 @@ when memtest86 is relocated, and memtest86 can be relocated to any address. The one thing to watch out for is pointers to data inside of memtest86. Except for constant pointers to static data there is not enough information to generate relocation records for pointers so they will not change when memtest86 is -relocated, which might lead to nasty surpises. +relocated, which might lead to nasty surprises. Eric Biederman <ebiederman@lnxi.com> @@ -61,7 +61,7 @@ void get_config() cprint(POP_Y+5, POP_X+6, "(3) Select Test"); cprint(POP_Y+6, POP_X+6, "(4) Enter Test List"); cprint(POP_Y+7, POP_X+6, "(0) Cancel"); - if (v->testsel < 0) { + if (vv->testsel < 0) { cprint(POP_Y+3, POP_X+5, ">"); } else { cprint(POP_Y+5, POP_X+5, ">"); @@ -102,7 +102,7 @@ void get_config() } /* Now set the selection */ tseq[n].sel = 1; - v->pass = -1; + vv->pass = -1; test = n; find_ticks_for_pass(); sflag++; @@ -132,7 +132,7 @@ void get_config() * list */ i = j = m = 0; while (1) { - if (isdigit(cp[i])) { + if (mt86_isdigit(cp[i])) { n = cp[i]-'0'; j = j*10 + n; i++; @@ -157,7 +157,7 @@ void get_config() k++; } } - v->pass = -1; + vv->pass = -1; test = n; find_ticks_for_pass(); sflag++; @@ -189,12 +189,12 @@ void get_config() "Lower Limit: "); cprint(POP_Y+4, POP_X+4, "Current: "); - aprint(POP_Y+4, POP_X+13, v->plim_lower); + aprint(POP_Y+4, POP_X+13, vv->plim_lower); cprint(POP_Y+6, POP_X+4, "New: "); page = getval(POP_Y+6, POP_X+9, 12); - if (page + 1 <= v->plim_upper) { - v->plim_lower = page; + if (page + 1 <= vv->plim_upper) { + vv->plim_lower = page; test--; bail++; } @@ -210,12 +210,12 @@ void get_config() "Upper Limit: "); cprint(POP_Y+4, POP_X+4, "Current: "); - aprint(POP_Y+4, POP_X+13, v->plim_upper); + aprint(POP_Y+4, POP_X+13, vv->plim_upper); cprint(POP_Y+6, POP_X+4, "New: "); page = getval(POP_Y+6, POP_X+9, 12); - if (page - 1 >= v->plim_lower) { - v->plim_upper = page; + if (page - 1 >= vv->plim_lower) { + vv->plim_upper = page; bail++; test--; } @@ -226,9 +226,9 @@ void get_config() break; case 4: /* All of memory */ - v->plim_lower = 0; - v->plim_upper = - v->pmap[v->msegs - 1].end; + vv->plim_lower = 0; + vv->plim_upper = + vv->pmap[vv->msegs - 1].end; test--; bail++; adj_mem(); @@ -255,37 +255,37 @@ void get_config() cprint(POP_Y+6, POP_X+6, "(4) Error Counts Only"); cprint(POP_Y+7, POP_X+6, "(5) Beep on Error"); cprint(POP_Y+8, POP_X+6, "(0) Cancel"); - cprint(POP_Y+3+v->printmode, POP_X+5, ">"); + cprint(POP_Y+3+vv->printmode, POP_X+5, ">"); if (beepmode) { cprint(POP_Y+7, POP_X+5, ">"); } wait_keyup(); while (!sflag) { switch(get_key()) { case 2: /* Error Summary */ - v->printmode=PRINTMODE_SUMMARY; - v->erri.eadr = 0; - v->erri.hdr_flag = 0; + vv->printmode=PRINTMODE_SUMMARY; + vv->erri.eadr = 0; + vv->erri.hdr_flag = 0; sflag++; break; case 3: /* Separate Addresses */ - v->printmode=PRINTMODE_ADDRESSES; - v->erri.eadr = 0; - v->erri.hdr_flag = 0; - v->msg_line = LINE_SCROLL-1; + vv->printmode=PRINTMODE_ADDRESSES; + vv->erri.eadr = 0; + vv->erri.hdr_flag = 0; + vv->msg_line = LINE_SCROLL-1; sflag++; break; case 4: /* BadRAM Patterns */ - v->printmode=PRINTMODE_PATTERNS; - v->erri.hdr_flag = 0; + vv->printmode=PRINTMODE_PATTERNS; + vv->erri.hdr_flag = 0; sflag++; prt++; break; case 5: /* Error Counts Only */ - v->printmode=PRINTMODE_NONE; - v->erri.hdr_flag = 0; + vv->printmode=PRINTMODE_NONE; + vv->erri.hdr_flag = 0; sflag++; break; case 6: @@ -491,41 +491,41 @@ void adj_mem(void) { int i; - v->selected_pages = 0; - for (i=0; i< v->msegs; i++) { + vv->selected_pages = 0; + for (i=0; i< vv->msegs; i++) { /* Segment inside limits ? */ - if (v->pmap[i].start >= v->plim_lower && - v->pmap[i].end <= v->plim_upper) { - v->selected_pages += (v->pmap[i].end - v->pmap[i].start); + if (vv->pmap[i].start >= vv->plim_lower && + vv->pmap[i].end <= vv->plim_upper) { + vv->selected_pages += (vv->pmap[i].end - vv->pmap[i].start); continue; } /* Segment starts below limit? */ - if (v->pmap[i].start < v->plim_lower) { + if (vv->pmap[i].start < vv->plim_lower) { /* Also ends below limit? */ - if (v->pmap[i].end < v->plim_lower) { + if (vv->pmap[i].end < vv->plim_lower) { continue; } /* Ends past upper limit? */ - if (v->pmap[i].end > v->plim_upper) { - v->selected_pages += - v->plim_upper - v->plim_lower; + if (vv->pmap[i].end > vv->plim_upper) { + vv->selected_pages += + vv->plim_upper - vv->plim_lower; } else { /* Straddles lower limit */ - v->selected_pages += - (v->pmap[i].end - v->plim_lower); + vv->selected_pages += + (vv->pmap[i].end - vv->plim_lower); } continue; } /* Segment ends above limit? */ - if (v->pmap[i].end > v->plim_upper) { + if (vv->pmap[i].end > vv->plim_upper) { /* Also starts above limit? */ - if (v->pmap[i].start > v->plim_upper) { + if (vv->pmap[i].start > vv->plim_upper) { continue; } /* Straddles upper limit */ - v->selected_pages += - (v->plim_upper - v->pmap[i].start); + vv->selected_pages += + (vv->plim_upper - vv->pmap[i].start); } } } diff --git a/controller.c b/controller.c index f4f7371..6d3f202 100644 --- a/controller.c +++ b/controller.c @@ -23,15 +23,15 @@ extern ulong extclock; extern unsigned long imc_type; extern struct cpu_ident cpu_id; /* -#define rdmsr(msr,val1,val2) \ - __asm__ __volatile__("rdmsr" \ - : "=a" (val1), "=d" (val2) \ - : "c" (msr) : "edi") - -#define wrmsr(msr,val1,val2) \ - __asm__ __volatile__("wrmsr" \ - : \ - : "c" (msr), "a" (val1), "d" (val2) : "edi") + #define rdmsr(msr,val1,val2) \ + __asm__ __volatile__("rdmsr" \ + : "=a" (val1), "=d" (val2) \ + : "c" (msr) : "edi") + + #define wrmsr(msr,val1,val2) \ + __asm__ __volatile__("wrmsr" \ + : \ + : "c" (msr), "a" (val1), "d" (val2) : "edi") */ /* controller ECC capabilities and mode */ #define __ECC_UNEXPECTED 1 /* Unknown ECC capability present */ @@ -50,1253 +50,1255 @@ extern struct cpu_ident cpu_id; static struct ecc_info { - int index; - int poll; - unsigned bus; - unsigned dev; - unsigned fn; - unsigned cap; - unsigned mode; + int index; + int poll; + unsigned bus; + unsigned dev; + unsigned fn; + unsigned cap; + unsigned mode; } ctrl = -{ - .index = 0, - /* I know of no case where the memory controller is not on the - * host bridge, and the host bridge is not on bus 0 device 0 - * fn 0. But just in case leave these as variables. - */ - .bus = 0, - .dev = 0, - .fn = 0, - /* Properties of the current memory controller */ - .cap = ECC_UNKNOWN, - .mode = ECC_UNKNOWN, -}; + { + .index = 0, + /* I know of no case where the memory controller is not on the + * host bridge, and the host bridge is not on bus 0 device 0 + * fn 0. But just in case leave these as variables. + */ + .bus = 0, + .dev = 0, + .fn = 0, + /* Properties of the current memory controller */ + .cap = ECC_UNKNOWN, + .mode = ECC_UNKNOWN, + }; void coretemp(void) { - unsigned int msrl, msrh; - unsigned int tjunc, tabs, tnow; - unsigned long rtcr; - double amd_raw_temp; - - // Only enable coretemp if IMC is known - if(imc_type == 0) { return; } - - tnow = 0; - - // Intel CPU - if(cpu_id.vend_id.char_array[0] == 'G' && cpu_id.max_cpuid >= 6) - { - if(cpu_id.dts_pmp & 1){ - rdmsr(MSR_IA32_THERM_STATUS, msrl, msrh); - tabs = ((msrl >> 16) & 0x7F); - rdmsr(MSR_IA32_TEMPERATURE_TARGET, msrl, msrh); - tjunc = ((msrl >> 16) & 0x7F); - if(tjunc < 50 || tjunc > 125) { tjunc = 90; } // assume Tjunc = 90°C if boggus value received. - tnow = tjunc - tabs; - dprint(LINE_CPU+1, 30, v->check_temp, 3, 0); - v->check_temp = tnow; - } - return; - } - - // AMD CPU - if(cpu_id.vend_id.char_array[0] == 'A' && cpu_id.vers.bits.extendedFamily > 0) - { - pci_conf_read(0, 24, 3, 0xA4, 4, &rtcr); - amd_raw_temp = ((rtcr >> 21) & 0x7FF); - v->check_temp = (int)(amd_raw_temp / 8); - dprint(LINE_CPU+1, 30, v->check_temp, 3, 0); - } + unsigned int msrl, msrh; + unsigned int tjunc, tabs, tnow; + unsigned long rtcr; + double amd_raw_temp; + + // Only enable coretemp if IMC is known + if(imc_type == 0) { return; } + + tnow = 0; + + // Intel CPU + if(cpu_id.vend_id.char_array[0] == 'G' && cpu_id.max_cpuid >= 6) + { + if(cpu_id.dts_pmp & 1){ + rdmsr(MSR_IA32_THERM_STATUS, msrl, msrh); + tabs = ((msrl >> 16) & 0x7F); + rdmsr(MSR_IA32_TEMPERATURE_TARGET, msrl, msrh); + tjunc = ((msrl >> 16) & 0x7F); + if(tjunc < 50 || tjunc > 125) { tjunc = 90; } // assume Tjunc = 90°C if boggus value received. + tnow = tjunc - tabs; + dprint(LINE_CPU+1, 30, vv->check_temp, 3, 0); + vv->check_temp = tnow; + } + return; + } + + // AMD CPU + if(cpu_id.vend_id.char_array[0] == 'A' && cpu_id.vers.bits.extendedFamily > 0) + { + pci_conf_read(0, 24, 3, 0xA4, 4, &rtcr); + amd_raw_temp = ((rtcr >> 21) & 0x7FF); + vv->check_temp = (int)(amd_raw_temp / 8); + dprint(LINE_CPU+1, 30, vv->check_temp, 3, 0); + } } void print_cpu_line(float dram_freq, float fsb_freq, int ram_type) { - int cur_col = COL_SPEC; - - cprint(LINE_CPU, cur_col, "RAM: "); - cur_col += 5; - dprint(LINE_CPU, cur_col, dram_freq, 4, 1); - cur_col += 4; - cprint(LINE_CPU, cur_col, "MHz ("); - cur_col += 5; - - switch(ram_type) - { - default: - case 1: - cprint(LINE_CPU, cur_col, "DDR-"); - cur_col += 4; - break; - case 2: - cprint(LINE_CPU, cur_col, "DDR2-"); - cur_col += 5; - break; - case 3: - cprint(LINE_CPU, cur_col, "DDR3-"); - cur_col += 5; - break; - } - - if(dram_freq < 500) - { - dprint(LINE_CPU, cur_col, dram_freq*2, 3, 0); - cur_col += 3; - } else { - dprint(LINE_CPU, cur_col, dram_freq*2, 4, 0); - cur_col += 4; - } - cprint(LINE_CPU, cur_col, ")"); - cur_col++; - - if(fsb_freq > 10) - { - cprint(LINE_CPU, cur_col, " - BCLK: "); - cur_col += 9; - - dprint(LINE_CPU, cur_col, fsb_freq, 3, 0); - } + int cur_col = COL_SPEC; + + cprint(LINE_CPU, cur_col, "RAM: "); + cur_col += 5; + dprint(LINE_CPU, cur_col, dram_freq, 4, 1); + cur_col += 4; + cprint(LINE_CPU, cur_col, "MHz ("); + cur_col += 5; + + switch(ram_type) + { + default: + case 1: + cprint(LINE_CPU, cur_col, "DDR-"); + cur_col += 4; + break; + case 2: + cprint(LINE_CPU, cur_col, "DDR2-"); + cur_col += 5; + break; + case 3: + cprint(LINE_CPU, cur_col, "DDR3-"); + cur_col += 5; + break; + } + + if(dram_freq < 500) + { + dprint(LINE_CPU, cur_col, dram_freq*2, 3, 0); + cur_col += 3; + } else { + dprint(LINE_CPU, cur_col, dram_freq*2, 4, 0); + cur_col += 4; + } + cprint(LINE_CPU, cur_col, ")"); + cur_col++; + + if(fsb_freq > 10) + { + cprint(LINE_CPU, cur_col, " - BCLK: "); + cur_col += 9; + + dprint(LINE_CPU, cur_col, fsb_freq, 3, 0); + } } void print_ram_line(float cas, int rcd, int rp, int ras, int chan) { - int cur_col = COL_SPEC; - - cprint(LINE_RAM, cur_col, "Timings: CAS "); - cur_col += 13; - - // CAS Latency (tCAS) - if (cas == 1.5) { - cprint(LINE_RAM, cur_col, "1.5"); cur_col += 3; - } else if (cas == 2.5) { - cprint(LINE_RAM, cur_col, "2.5"); cur_col += 3; - } else if (cas < 10) { - dprint(LINE_RAM, cur_col, cas, 1, 0); cur_col += 1; - } else { - dprint(LINE_RAM, cur_col, cas, 2, 0); cur_col += 2; - } - cprint(LINE_RAM, cur_col, "-"); cur_col += 1; - - // RAS-To-CAS (tRCD) - if (rcd < 10) { - dprint(LINE_RAM, cur_col, rcd, 1, 0); - cur_col += 1; - } else { - dprint(LINE_RAM, cur_col, rcd, 2, 0); - cur_col += 2; - } - cprint(LINE_RAM, cur_col, "-"); cur_col += 1; - - // RAS Precharge (tRP) - if (rp < 10) { - dprint(LINE_RAM, cur_col, rp, 1, 0); - cur_col += 1; - } else { - dprint(LINE_RAM, cur_col, rp, 2, 0); - cur_col += 2; - } - cprint(LINE_RAM, cur_col, "-"); cur_col += 1; - - // RAS Active to precharge (tRAS) - if (ras < 10) { - dprint(LINE_RAM, cur_col, ras, 1, 0); - cur_col += 1; - } else { - dprint(LINE_RAM, cur_col, ras, 2, 0); - cur_col += 2; - } + int cur_col = COL_SPEC; + + cprint(LINE_RAM, cur_col, "Timings: CAS "); + cur_col += 13; + + // CAS Latency (tCAS) + if (cas == 1.5) { + cprint(LINE_RAM, cur_col, "1.5"); cur_col += 3; + } else if (cas == 2.5) { + cprint(LINE_RAM, cur_col, "2.5"); cur_col += 3; + } else if (cas < 10) { + dprint(LINE_RAM, cur_col, cas, 1, 0); cur_col += 1; + } else { + dprint(LINE_RAM, cur_col, cas, 2, 0); cur_col += 2; + } + cprint(LINE_RAM, cur_col, "-"); cur_col += 1; + + // RAS-To-CAS (tRCD) + if (rcd < 10) { + dprint(LINE_RAM, cur_col, rcd, 1, 0); + cur_col += 1; + } else { + dprint(LINE_RAM, cur_col, rcd, 2, 0); + cur_col += 2; + } + cprint(LINE_RAM, cur_col, "-"); cur_col += 1; + + // RAS Precharge (tRP) + if (rp < 10) { + dprint(LINE_RAM, cur_col, rp, 1, 0); + cur_col += 1; + } else { + dprint(LINE_RAM, cur_col, rp, 2, 0); + cur_col += 2; + } + cprint(LINE_RAM, cur_col, "-"); cur_col += 1; + + // RAS Active to precharge (tRAS) + if (ras < 10) { + dprint(LINE_RAM, cur_col, ras, 1, 0); + cur_col += 1; + } else { + dprint(LINE_RAM, cur_col, ras, 2, 0); + cur_col += 2; + } - switch(chan) - { - case 0: - break; - case 1: - cprint(LINE_RAM, cur_col, " @ 64-bit Mode"); - break; - case 2: - cprint(LINE_RAM, cur_col, " @ 128-bit Mode"); - break; - case 3: - cprint(LINE_RAM, cur_col, " @ 192-bit Mode"); - break; - case 4: - cprint(LINE_RAM, cur_col, " @ 256-bit Mode"); - break; - } + switch(chan) + { + case 0: + break; + case 1: + cprint(LINE_RAM, cur_col, " @ 64-bit Mode"); + break; + case 2: + cprint(LINE_RAM, cur_col, " @ 128-bit Mode"); + break; + case 3: + cprint(LINE_RAM, cur_col, " @ 192-bit Mode"); + break; + case 4: + cprint(LINE_RAM, cur_col, " @ 256-bit Mode"); + break; + } } static void poll_fsb_nothing(void) { - char *name; + char *name; - /* Print the controller name */ - name = controllers[ctrl.index].name; - cprint(LINE_CPU, COL_SPEC, "Chipset: "); - cprint(LINE_CPU, COL_SPEC+9, name); - return; + /* Print the controller name */ + name = controllers[ctrl.index].name; + cprint(LINE_CPU, COL_SPEC, "Chipset: "); + cprint(LINE_CPU, COL_SPEC+9, name); + return; } static void poll_timings_nothing(void) { - char *ram_type; + char *ram_type; - /* Print the controller name */ - ram_type = controllers[ctrl.index].ram_type; - cprint(LINE_RAM, COL_SPEC, "RAM Type: "); - cprint(LINE_RAM, COL_SPEC+10, ram_type); - return; + /* Print the controller name */ + ram_type = controllers[ctrl.index].ram_type; + cprint(LINE_RAM, COL_SPEC, "RAM Type: "); + cprint(LINE_RAM, COL_SPEC+10, ram_type); + return; } static void setup_nothing(void) { - ctrl.cap = ECC_NONE; - ctrl.mode = ECC_NONE; + ctrl.cap = ECC_NONE; + ctrl.mode = ECC_NONE; } static void poll_nothing(void) { -/* Code to run when we don't know how, or can't ask the memory - * controller about memory errors. - */ - return; + /* Code to run when we don't know how, or can't ask the memory + * controller about memory errors. + */ + return; } static void setup_wmr(void) { - ulong dev0; + ulong dev0; - // Activate MMR I/O - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - if (!(dev0 & 0x1)) { - pci_conf_write( 0, 0, 0, 0x48, 1, dev0 | 1); - } + // Activate MMR I/O + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + if (!(dev0 & 0x1)) { + pci_conf_write( 0, 0, 0, 0x48, 1, dev0 | 1); + } } static void setup_nhm(void) { - static float possible_nhm_bus[] = {0xFF, 0x7F, 0x3F}; - unsigned long did, vid, mc_control, mc_ssrcontrol; - int i; - - //Nehalem supports Scrubbing */ - ctrl.cap = ECC_SCRUB; - ctrl.mode = ECC_NONE; - - /* First, locate the PCI bus where the MCH is located */ - - for(i = 0; i < sizeof(possible_nhm_bus); i++) { - 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 &= 0xFF00; - if(vid == 0x8086 && did >= 0x2C00) { - nhm_bus = possible_nhm_bus[i]; - } -} - - /* Now, we have the last IMC bus number in nhm_bus */ - /* Check for ECC & Scrub */ - - pci_conf_read(nhm_bus, 3, 0, 0x4C, 2, &mc_control); - if((mc_control >> 4) & 1) { - ctrl.mode = ECC_CORRECT; - pci_conf_read(nhm_bus, 3, 2, 0x48, 2, &mc_ssrcontrol); - if(mc_ssrcontrol & 3) { - ctrl.mode = ECC_SCRUB; - } - } + static float possible_nhm_bus[] = {0xFF, 0x7F, 0x3F}; + unsigned long did, vid, mc_control, mc_ssrcontrol; + int i; + + //Nehalem supports Scrubbing */ + ctrl.cap = ECC_SCRUB; + ctrl.mode = ECC_NONE; + + /* First, locate the PCI bus where the MCH is located */ + + for(i = 0; i < (sizeof(possible_nhm_bus) / + sizeof(possible_nhm_bus[0])); i++) { + 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 &= 0xFF00; + if(vid == 0x8086 && did >= 0x2C00) { + nhm_bus = possible_nhm_bus[i]; + } + } + + /* Now, we have the last IMC bus number in nhm_bus */ + /* Check for ECC & Scrub */ + + pci_conf_read(nhm_bus, 3, 0, 0x4C, 2, &mc_control); + if((mc_control >> 4) & 1) { + ctrl.mode = ECC_CORRECT; + pci_conf_read(nhm_bus, 3, 2, 0x48, 2, &mc_ssrcontrol); + if(mc_ssrcontrol & 3) { + ctrl.mode = ECC_SCRUB; + } + } } static void setup_nhm32(void) { - static float possible_nhm_bus[] = {0xFF, 0x7F, 0x3F}; - unsigned long did, vid, mc_control, mc_ssrcontrol; - int i; - - //Nehalem supports Scrubbing */ - ctrl.cap = ECC_SCRUB; - ctrl.mode = ECC_NONE; - - /* First, locate the PCI bus where the MCH is located */ - for(i = 0; i < sizeof(possible_nhm_bus); i++) { - 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 &= 0xFF00; - if(vid == 0x8086 && did >= 0x2C00) { - nhm_bus = possible_nhm_bus[i]; - } - } - - /* Now, we have the last IMC bus number in nhm_bus */ - /* Check for ECC & Scrub */ - pci_conf_read(nhm_bus, 3, 0, 0x48, 2, &mc_control); - if((mc_control >> 1) & 1) { - ctrl.mode = ECC_CORRECT; - pci_conf_read(nhm_bus, 3, 2, 0x48, 2, &mc_ssrcontrol); - if(mc_ssrcontrol & 1) { - ctrl.mode = ECC_SCRUB; - } - } + static float possible_nhm_bus[] = {0xFF, 0x7F, 0x3F}; + unsigned long did, vid, mc_control, mc_ssrcontrol; + int i; + + //Nehalem supports Scrubbing */ + ctrl.cap = ECC_SCRUB; + ctrl.mode = ECC_NONE; + + /* First, locate the PCI bus where the MCH is located */ + for(i = 0; i < (sizeof(possible_nhm_bus) / + sizeof(possible_nhm_bus[0])); i++) { + 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 &= 0xFF00; + if(vid == 0x8086 && did >= 0x2C00) { + nhm_bus = possible_nhm_bus[i]; + } + } + + /* Now, we have the last IMC bus number in nhm_bus */ + /* Check for ECC & Scrub */ + pci_conf_read(nhm_bus, 3, 0, 0x48, 2, &mc_control); + if((mc_control >> 1) & 1) { + ctrl.mode = ECC_CORRECT; + pci_conf_read(nhm_bus, 3, 2, 0x48, 2, &mc_ssrcontrol); + if(mc_ssrcontrol & 1) { + ctrl.mode = ECC_SCRUB; + } + } } static void setup_amd64(void) { - static const int ddim[] = { ECC_NONE, ECC_CORRECT, ECC_RESERVED, ECC_CHIPKILL }; - unsigned long nbxcfg; - unsigned int mcgsrl; - unsigned int mcgsth; - unsigned long mcanb; - unsigned long dramcl; + static const int ddim[] = { ECC_NONE, ECC_CORRECT, ECC_RESERVED, ECC_CHIPKILL }; + unsigned long nbxcfg; + unsigned int mcgsrl; + unsigned int mcgsth; + unsigned long mcanb; + unsigned long dramcl; - /* All AMD64 support Chipkill */ - ctrl.cap = ECC_CHIPKILL; + /* All AMD64 support Chipkill */ + ctrl.cap = ECC_CHIPKILL; - /* Check First if ECC DRAM Modules are used */ - pci_conf_read(0, 24, 2, 0x90, 4, &dramcl); + /* Check First if ECC DRAM Modules are used */ + pci_conf_read(0, 24, 2, 0x90, 4, &dramcl); - if (cpu_id.vers.bits.extendedModel >= 4) { - /* NEW K8 0Fh Family 90 nm */ + if (cpu_id.vers.bits.extendedModel >= 4) { + /* NEW K8 0Fh Family 90 nm */ - if ((dramcl >> 19)&1){ - /* Fill in the correct memory capabilites */ - pci_conf_read(0, 24, 3, 0x44, 4, &nbxcfg); - ctrl.mode = ddim[(nbxcfg >> 22)&3]; - } else { - ctrl.mode = ECC_NONE; - } - /* Enable NB ECC Logging by MSR Write */ - rdmsr(0x017B, mcgsrl, mcgsth); - wrmsr(0x017B, 0x10, mcgsth); - - /* Clear any previous error */ - pci_conf_read(0, 24, 3, 0x4C, 4, &mcanb); - pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7FFFFFFF ); - - } else { - /* OLD K8 130 nm */ + if ((dramcl >> 19)&1){ + /* Fill in the correct memory capabilites */ + pci_conf_read(0, 24, 3, 0x44, 4, &nbxcfg); + ctrl.mode = ddim[(nbxcfg >> 22)&3]; + } else { + ctrl.mode = ECC_NONE; + } + /* Enable NB ECC Logging by MSR Write */ + rdmsr(0x017B, mcgsrl, mcgsth); + wrmsr(0x017B, 0x10, mcgsth); + + /* Clear any previous error */ + pci_conf_read(0, 24, 3, 0x4C, 4, &mcanb); + pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7FFFFFFF ); + + } else { + /* OLD K8 130 nm */ - if ((dramcl >> 17)&1){ - /* Fill in the correct memory capabilites */ - pci_conf_read(0, 24, 3, 0x44, 4, &nbxcfg); - ctrl.mode = ddim[(nbxcfg >> 22)&3]; - } else { - ctrl.mode = ECC_NONE; - } - /* Enable NB ECC Logging by MSR Write */ - rdmsr(0x017B, mcgsrl, mcgsth); - wrmsr(0x017B, 0x10, mcgsth); - - /* Clear any previous error */ - pci_conf_read(0, 24, 3, 0x4C, 4, &mcanb); - pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7F801EFC ); - } + if ((dramcl >> 17)&1){ + /* Fill in the correct memory capabilites */ + pci_conf_read(0, 24, 3, 0x44, 4, &nbxcfg); + ctrl.mode = ddim[(nbxcfg >> 22)&3]; + } else { + ctrl.mode = ECC_NONE; + } + /* Enable NB ECC Logging by MSR Write */ + rdmsr(0x017B, mcgsrl, mcgsth); + wrmsr(0x017B, 0x10, mcgsth); + + /* Clear any previous error */ + pci_conf_read(0, 24, 3, 0x4C, 4, &mcanb); + pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7F801EFC ); + } } static void setup_k10(void) { - static const int ddim[] = { ECC_NONE, ECC_CORRECT, ECC_CHIPKILL, ECC_CHIPKILL }; - unsigned long nbxcfg; - unsigned int mcgsrl; - unsigned int mcgsth; - unsigned long mcanb; - unsigned long dramcl; - ulong msr_low, msr_high; - - // All AMD64 support Chipkill */ - ctrl.cap = ECC_CHIPKILL; - - // Check First if ECC DRAM Modules are used */ - pci_conf_read(0, 24, 2, 0x90, 4, &dramcl); - - if ((dramcl >> 19)&1){ - // Fill in the correct memory capabilites */ - pci_conf_read(0, 24, 3, 0x44, 4, &nbxcfg); - ctrl.mode = ddim[(nbxcfg >> 22)&3]; - } else { - ctrl.mode = ECC_NONE; - } - // Enable NB ECC Logging by MSR Write */ - rdmsr(0x017B, mcgsrl, mcgsth); - wrmsr(0x017B, 0x10, mcgsth); - - // Clear any previous error */ - pci_conf_read(0, 24, 3, 0x4C, 4, &mcanb); - pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7FFFFFFF ); + static const int ddim[] = { ECC_NONE, ECC_CORRECT, ECC_CHIPKILL, ECC_CHIPKILL }; + unsigned long nbxcfg; + unsigned int mcgsrl; + unsigned int mcgsth; + unsigned long mcanb; + unsigned long dramcl; + ulong msr_low, msr_high; + + // All AMD64 support Chipkill */ + ctrl.cap = ECC_CHIPKILL; + + // Check First if ECC DRAM Modules are used */ + pci_conf_read(0, 24, 2, 0x90, 4, &dramcl); + + if ((dramcl >> 19)&1){ + // Fill in the correct memory capabilites */ + pci_conf_read(0, 24, 3, 0x44, 4, &nbxcfg); + ctrl.mode = ddim[(nbxcfg >> 22)&3]; + } else { + ctrl.mode = ECC_NONE; + } + // Enable NB ECC Logging by MSR Write */ + rdmsr(0x017B, mcgsrl, mcgsth); + wrmsr(0x017B, 0x10, mcgsth); + + // Clear any previous error */ + pci_conf_read(0, 24, 3, 0x4C, 4, &mcanb); + 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); + /* Enable ECS */ + rdmsr(0xC001001F, msr_low, msr_high); + wrmsr(0xC001001F, msr_low, (msr_high | 0x4000)); + rdmsr(0xC001001F, msr_low, msr_high); } static void setup_apu(void) { - ulong msr_low, msr_high; + ulong msr_low, msr_high; - /* Enable ECS */ - rdmsr(0xC001001F, msr_low, msr_high); - wrmsr(0xC001001F, msr_low, (msr_high | 0x4000)); - rdmsr(0xC001001F, msr_low, msr_high); + /* 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) -{ + static void poll_amd64(void) + { - unsigned long mcanb; - unsigned long page, offset; - unsigned long celog_syndrome; - unsigned long mcanb_add; + unsigned long mcanb; + unsigned long page, offset; + unsigned long celog_syndrome; + unsigned long mcanb_add; - pci_conf_read(0, 24, 3, 0x4C, 4, &mcanb); + pci_conf_read(0, 24, 3, 0x4C, 4, &mcanb); - if (((mcanb >> 31)&1) && ((mcanb >> 14)&1)) { - // Find out about the first correctable error - // Syndrome code -> bits use a complex matrix. Will add this later - // Read the error location - pci_conf_read(0, 24, 3, 0x50, 4, &mcanb_add); + if (((mcanb >> 31)&1) && ((mcanb >> 14)&1)) { + // Find out about the first correctable error + // Syndrome code -> bits use a complex matrix. Will add this later + // Read the error location + pci_conf_read(0, 24, 3, 0x50, 4, &mcanb_add); - // Read the syndrome - celog_syndrome = (mcanb >> 15)&0xFF; + // Read the syndrome + celog_syndrome = (mcanb >> 15)&0xFF; - // Parse the error location - page = (mcanb_add >> 12); - offset = (mcanb_add >> 3) & 0xFFF; + // Parse the error location + page = (mcanb_add >> 12); + offset = (mcanb_add >> 3) & 0xFFF; - // Report the error - print_ecc_err(page, offset, 1, celog_syndrome, 0); + // Report the error + print_ecc_err(page, offset, 1, celog_syndrome, 0); - // Clear the error registers - pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7FFFFFFF ); - } - if (((mcanb >> 31)&1) && ((mcanb >> 13)&1)) { - // Found out about the first uncorrectable error - // Read the error location - pci_conf_read(0, 24, 3, 0x50, 4, &mcanb_add); + // Clear the error registers + pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7FFFFFFF ); + } + if (((mcanb >> 31)&1) && ((mcanb >> 13)&1)) { + // Found out about the first uncorrectable error + // Read the error location + pci_conf_read(0, 24, 3, 0x50, 4, &mcanb_add); - // Parse the error location - page = (mcanb_add >> 12); - offset = (mcanb_add >> 3) & 0xFFF; + // Parse the error location + page = (mcanb_add >> 12); + offset = (mcanb_add >> 3) & 0xFFF; - // Report the error - print_ecc_err(page, offset, 0, 0, 0); + // Report the error + print_ecc_err(page, offset, 0, 0, 0); - // Clear the error registers - pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7FFFFFF ); + // Clear the error registers + pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7FFFFFF ); - } + } -} + } */ static void setup_amd751(void) { - unsigned long dram_status; + unsigned long dram_status; - /* Fill in the correct memory capabilites */ - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x5a, 2, &dram_status); - ctrl.cap = ECC_CORRECT; - ctrl.mode = (dram_status & (1 << 2))?ECC_CORRECT: ECC_NONE; + /* Fill in the correct memory capabilites */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x5a, 2, &dram_status); + ctrl.cap = ECC_CORRECT; + ctrl.mode = (dram_status & (1 << 2))?ECC_CORRECT: ECC_NONE; } /* -static void poll_amd751(void) -{ - unsigned long ecc_status; - unsigned long bank_addr; - unsigned long bank_info; - unsigned long page; - int bits; - int i; - - // Read the error status - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x58, 2, &ecc_status); - if (ecc_status & (3 << 8)) { - for(i = 0; i < 6; i++) { - if (!(ecc_status & (1 << i))) { - continue; - } - // Find the bank the error occured on - bank_addr = 0x40 + (i << 1); - - // Now get the information on the erroring bank - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, bank_addr, 2, &bank_info); - - // Parse the error location and error type - page = (bank_info & 0xFF80) << 4; - bits = (((ecc_status >> 8) &3) == 2)?1:2; - - // Report the error - print_ecc_err(page, 0, bits==1?1:0, 0, 0); - - } - - // Clear the error status - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0x58, 2, 0); - } -} - -// Still waiting for the CORRECT intel datasheet -static void setup_i85x(void) -{ - unsigned long drc; - ctrl.cap = ECC_CORRECT; - - pci_conf_read(ctrl.bus, ctrl.dev, 1, 0x70, 4, &drc); - ctrl.mode = ((drc>>20)&1)?ECC_CORRECT:ECC_NONE; - -} + static void poll_amd751(void) + { + unsigned long ecc_status; + unsigned long bank_addr; + unsigned long bank_info; + unsigned long page; + int bits; + int i; + + // Read the error status + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x58, 2, &ecc_status); + if (ecc_status & (3 << 8)) { + for(i = 0; i < 6; i++) { + if (!(ecc_status & (1 << i))) { + continue; + } + // Find the bank the error occured on + bank_addr = 0x40 + (i << 1); + + // Now get the information on the erroring bank + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, bank_addr, 2, &bank_info); + + // Parse the error location and error type + page = (bank_info & 0xFF80) << 4; + bits = (((ecc_status >> 8) &3) == 2)?1:2; + + // Report the error + print_ecc_err(page, 0, bits==1?1:0, 0, 0); + + } + + // Clear the error status + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0x58, 2, 0); + } + } + + // Still waiting for the CORRECT intel datasheet + static void setup_i85x(void) + { + unsigned long drc; + ctrl.cap = ECC_CORRECT; + + pci_conf_read(ctrl.bus, ctrl.dev, 1, 0x70, 4, &drc); + ctrl.mode = ((drc>>20)&1)?ECC_CORRECT:ECC_NONE; + + } */ static void setup_amd76x(void) { - static const int ddim[] = { ECC_NONE, ECC_DETECT, ECC_CORRECT, ECC_CORRECT }; - unsigned long ecc_mode_status; + static const int ddim[] = { ECC_NONE, ECC_DETECT, ECC_CORRECT, ECC_CORRECT }; + unsigned long ecc_mode_status; - /* Fill in the correct memory capabilites */ - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x48, 4, &ecc_mode_status); - ctrl.cap = ECC_CORRECT; - ctrl.mode = ddim[(ecc_mode_status >> 10)&3]; + /* Fill in the correct memory capabilites */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x48, 4, &ecc_mode_status); + ctrl.cap = ECC_CORRECT; + ctrl.mode = ddim[(ecc_mode_status >> 10)&3]; } /* -static void poll_amd76x(void) -{ - unsigned long ecc_mode_status; - unsigned long bank_addr; - unsigned long bank_info; - unsigned long page; - - // Read the error status - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x48, 4, &ecc_mode_status); - // Multibit error - if (ecc_mode_status & (1 << 9)) { - // Find the bank the error occured on - bank_addr = 0xC0 + (((ecc_mode_status >> 4) & 0xf) << 2); - - // Now get the information on the erroring bank - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, bank_addr, 4, &bank_info); - - // Parse the error location and error type - page = (bank_info & 0xFF800000) >> 12; - - // Report the error - print_ecc_err(page, 0, 1, 0, 0); - - } - // Singlebit error - if (ecc_mode_status & (1 << 8)) { - // Find the bank the error occured on - bank_addr = 0xC0 + (((ecc_mode_status >> 0) & 0xf) << 2); - - // Now get the information on the erroring bank - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, bank_addr, 4, &bank_info); - - // Parse the error location and error type - page = (bank_info & 0xFF800000) >> 12; - - // Report the error - print_ecc_err(page, 0, 0, 0, 0); - - } - // Clear the error status - if (ecc_mode_status & (3 << 8)) { - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0x48, 4, ecc_mode_status); - } -} + static void poll_amd76x(void) + { + unsigned long ecc_mode_status; + unsigned long bank_addr; + unsigned long bank_info; + unsigned long page; + + // Read the error status + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x48, 4, &ecc_mode_status); + // Multibit error + if (ecc_mode_status & (1 << 9)) { + // Find the bank the error occured on + bank_addr = 0xC0 + (((ecc_mode_status >> 4) & 0xf) << 2); + + // Now get the information on the erroring bank + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, bank_addr, 4, &bank_info); + + // Parse the error location and error type + page = (bank_info & 0xFF800000) >> 12; + + // Report the error + print_ecc_err(page, 0, 1, 0, 0); + + } + // Singlebit error + if (ecc_mode_status & (1 << 8)) { + // Find the bank the error occured on + bank_addr = 0xC0 + (((ecc_mode_status >> 0) & 0xf) << 2); + + // Now get the information on the erroring bank + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, bank_addr, 4, &bank_info); + + // Parse the error location and error type + page = (bank_info & 0xFF800000) >> 12; + + // Report the error + print_ecc_err(page, 0, 0, 0, 0); + + } + // Clear the error status + if (ecc_mode_status & (3 << 8)) { + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0x48, 4, ecc_mode_status); + } + } */ static void setup_cnb20(void) { - /* Fill in the correct memory capabilites */ - ctrl.cap = ECC_CORRECT; + /* Fill in the correct memory capabilites */ + ctrl.cap = ECC_CORRECT; - /* FIXME add ECC error polling. I don't have the documentation - * do it right now. - */ + /* FIXME add ECC error polling. I don't have the documentation + * do it right now. + */ } static void setup_E5400(void) { - unsigned long mcs; + unsigned long mcs; - /* Read the hardware capabilities */ - pci_conf_read(ctrl.bus, 16, 1, 0x40, 4, &mcs); + /* Read the hardware capabilities */ + pci_conf_read(ctrl.bus, 16, 1, 0x40, 4, &mcs); - /* Fill in the correct memory capabilities */ - ctrl.mode = 0; - ctrl.cap = ECC_SCRUB; + /* Fill in the correct memory capabilities */ + ctrl.mode = 0; + ctrl.cap = ECC_SCRUB; - /* Checking and correcting enabled */ - if (((mcs >> 5) & 1) == 1) { - ctrl.mode |= ECC_CORRECT; - } + /* Checking and correcting enabled */ + if (((mcs >> 5) & 1) == 1) { + ctrl.mode |= ECC_CORRECT; + } - /* scrub enabled */ - if (((mcs >> 7) & 1) == 1) { - ctrl.mode |= __ECC_SCRUB; - } + /* scrub enabled */ + if (((mcs >> 7) & 1) == 1) { + ctrl.mode |= __ECC_SCRUB; + } } static void setup_iE7xxx(void) { - unsigned long mchcfgns; - unsigned long drc; - unsigned long device; - unsigned long dvnp; + unsigned long mchcfgns; + unsigned long drc; + unsigned long device; + unsigned long dvnp; - /* Read the hardare capabilities */ - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x52, 2, &mchcfgns); - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x7C, 4, &drc); + /* Read the hardare capabilities */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x52, 2, &mchcfgns); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x7C, 4, &drc); - /* This is a check for E7205 */ - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x02, 2, &device); + /* This is a check for E7205 */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x02, 2, &device); - /* Fill in the correct memory capabilities */ - ctrl.mode = 0; - ctrl.cap = ECC_CORRECT; + /* Fill in the correct memory capabilities */ + ctrl.mode = 0; + ctrl.cap = ECC_CORRECT; - /* checking and correcting enabled */ - if (((drc >> 20) & 3) == 2) { - ctrl.mode |= ECC_CORRECT; - } + /* checking and correcting enabled */ + if (((drc >> 20) & 3) == 2) { + ctrl.mode |= ECC_CORRECT; + } - /* E7205 doesn't support scrubbing */ - if (device != 0x255d) { - /* scrub enabled */ - /* For E7501, valid SCRUB operations is bit 0 / D0:F0:R70-73 */ - ctrl.cap = ECC_SCRUB; - if (mchcfgns & 1) { - ctrl.mode |= __ECC_SCRUB; - } + /* E7205 doesn't support scrubbing */ + if (device != 0x255d) { + /* scrub enabled */ + /* For E7501, valid SCRUB operations is bit 0 / D0:F0:R70-73 */ + ctrl.cap = ECC_SCRUB; + if (mchcfgns & 1) { + ctrl.mode |= __ECC_SCRUB; + } - /* Now, we can active Dev1/Fun1 */ - /* Thanks to Tyan for providing us the board to solve this */ - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE0, 2, &dvnp); - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn , 0xE0, 2, (dvnp & 0xFE)); + /* Now, we can active Dev1/Fun1 */ + /* Thanks to Tyan for providing us the board to solve this */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE0, 2, &dvnp); + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn , 0xE0, 2, (dvnp & 0xFE)); - /* Clear any routing of ECC errors to interrupts that the BIOS might have set up */ - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x88, 1, 0x0); - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x8A, 1, 0x0); - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x8C, 1, 0x0); + /* Clear any routing of ECC errors to interrupts that the BIOS might have set up */ + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x88, 1, 0x0); + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x8A, 1, 0x0); + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x8C, 1, 0x0); - } + } - /* Clear any prexisting error reports */ - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 1, 3); - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 1, 3); + /* Clear any prexisting error reports */ + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 1, 3); + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 1, 3); } static void setup_iE7520(void) { - unsigned long mchscrb; - unsigned long drc; - unsigned long dvnp1; + unsigned long mchscrb; + unsigned long drc; + unsigned long dvnp1; - /* Read the hardare capabilities */ - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x52, 2, &mchscrb); - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x7C, 4, &drc); + /* Read the hardare capabilities */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x52, 2, &mchscrb); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x7C, 4, &drc); - /* Fill in the correct memory capabilities */ - ctrl.mode = 0; - ctrl.cap = ECC_CORRECT; + /* Fill in the correct memory capabilities */ + ctrl.mode = 0; + ctrl.cap = ECC_CORRECT; - /* Checking and correcting enabled */ - if (((drc >> 20) & 3) != 0) { - ctrl.mode |= ECC_CORRECT; - } + /* Checking and correcting enabled */ + if (((drc >> 20) & 3) != 0) { + ctrl.mode |= ECC_CORRECT; + } - /* scrub enabled */ - ctrl.cap = ECC_SCRUB; - if ((mchscrb & 3) == 2) { - ctrl.mode |= __ECC_SCRUB; - } + /* scrub enabled */ + ctrl.cap = ECC_SCRUB; + if ((mchscrb & 3) == 2) { + ctrl.mode |= __ECC_SCRUB; + } - /* Now, we can activate Fun1 */ - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xF4, 1, &dvnp1); - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn , 0xF4, 1, (dvnp1 | 0x20)); + /* Now, we can activate Fun1 */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xF4, 1, &dvnp1); + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn , 0xF4, 1, (dvnp1 | 0x20)); - /* Clear any prexisting error reports */ - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 2, 0x4747); - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 2, 0x4747); + /* Clear any prexisting error reports */ + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 2, 0x4747); + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 2, 0x4747); } /* -static void poll_iE7xxx(void) -{ - unsigned long ferr; - unsigned long nerr; + static void poll_iE7xxx(void) + { + unsigned long ferr; + unsigned long nerr; - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 1, &ferr); - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 1, &nerr); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 1, &ferr); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 1, &nerr); - if (ferr & 1) { - // Find out about the first correctable error - unsigned long celog_add; - unsigned long celog_syndrome; - unsigned long page; + if (ferr & 1) { + // Find out about the first correctable error + unsigned long celog_add; + unsigned long celog_syndrome; + unsigned long page; - // Read the error location - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xA0, 4, &celog_add); - // Read the syndrome - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xD0, 2, &celog_syndrome); + // Read the error location + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xA0, 4, &celog_add); + // Read the syndrome + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xD0, 2, &celog_syndrome); - // Parse the error location - page = (celog_add & 0x0FFFFFC0) >> 6; + // Parse the error location + page = (celog_add & 0x0FFFFFC0) >> 6; - // Report the error - print_ecc_err(page, 0, 1, celog_syndrome, 0); + // Report the error + print_ecc_err(page, 0, 1, celog_syndrome, 0); - // Clear Bit - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 1, ferr & 3); - } + // Clear Bit + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 1, ferr & 3); + } - if (ferr & 2) { - // Found out about the first uncorrectable error - unsigned long uccelog_add; - unsigned long page; + if (ferr & 2) { + // Found out about the first uncorrectable error + unsigned long uccelog_add; + unsigned long page; - // Read the error location - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xB0, 4, &uccelog_add); + // Read the error location + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xB0, 4, &uccelog_add); - // Parse the error location - page = (uccelog_add & 0x0FFFFFC0) >> 6; + // Parse the error location + page = (uccelog_add & 0x0FFFFFC0) >> 6; - // Report the error - print_ecc_err(page, 0, 0, 0, 0); + // Report the error + print_ecc_err(page, 0, 0, 0, 0); - // Clear Bit - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 1, ferr & 3); - } + // Clear Bit + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 1, ferr & 3); + } - // Check if DRAM_NERR contains data - if (nerr & 3) { - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 1, nerr & 3); - } + // Check if DRAM_NERR contains data + if (nerr & 3) { + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 1, nerr & 3); + } -} + } */ static void setup_i440gx(void) { - static const int ddim[] = { ECC_NONE, ECC_DETECT, ECC_CORRECT, ECC_CORRECT }; - unsigned long nbxcfg; + static const int ddim[] = { ECC_NONE, ECC_DETECT, ECC_CORRECT, ECC_CORRECT }; + unsigned long nbxcfg; - /* Fill in the correct memory capabilites */ - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x50, 4, &nbxcfg); - ctrl.cap = ECC_CORRECT; - ctrl.mode = ddim[(nbxcfg >> 7)&3]; + /* Fill in the correct memory capabilites */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x50, 4, &nbxcfg); + ctrl.cap = ECC_CORRECT; + ctrl.mode = ddim[(nbxcfg >> 7)&3]; } /* -static void poll_i440gx(void) -{ - unsigned long errsts; - unsigned long page; - int bits; - // Read the error status - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x91, 2, &errsts); - if (errsts & 0x11) { - unsigned long eap; - // Read the error location - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x80, 4, &eap); - - // Parse the error location and error type - page = (eap & 0xFFFFF000) >> 12; - bits = 0; - if (eap &3) { - bits = ((eap & 3) == 1)?1:2; - } - - if (bits) { - // Report the error - print_ecc_err(page, 0, bits==1?1:0, 0, 0); - } - - // Clear the error status - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0x91, 2, 0x11); - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0x80, 4, 3); - } - -} + static void poll_i440gx(void) + { + unsigned long errsts; + unsigned long page; + int bits; + // Read the error status + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x91, 2, &errsts); + if (errsts & 0x11) { + unsigned long eap; + // Read the error location + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x80, 4, &eap); + + // Parse the error location and error type + page = (eap & 0xFFFFF000) >> 12; + bits = 0; + if (eap &3) { + bits = ((eap & 3) == 1)?1:2; + } + + if (bits) { + // Report the error + print_ecc_err(page, 0, bits==1?1:0, 0, 0); + } + + // Clear the error status + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0x91, 2, 0x11); + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0x80, 4, 3); + } + + } */ static void setup_i840(void) { - static const int ddim[] = { ECC_NONE, ECC_RESERVED, ECC_CORRECT, ECC_CORRECT }; - unsigned long mchcfg; + static const int ddim[] = { ECC_NONE, ECC_RESERVED, ECC_CORRECT, ECC_CORRECT }; + unsigned long mchcfg; - /* Fill in the correct memory capabilites */ - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x50, 2, &mchcfg); - ctrl.cap = ECC_CORRECT; - ctrl.mode = ddim[(mchcfg >> 7)&3]; + /* Fill in the correct memory capabilites */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x50, 2, &mchcfg); + ctrl.cap = ECC_CORRECT; + ctrl.mode = ddim[(mchcfg >> 7)&3]; } /* -static void poll_i840(void) -{ - unsigned long errsts; - unsigned long page; - unsigned long syndrome; - int channel; - int bits; - // Read the error status - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); - if (errsts & 3) { - unsigned long eap; - unsigned long derrctl_sts; - // Read the error location - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE4, 4, &eap); - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE2, 2, &derrctl_sts); - - // Parse the error location and error type - page = (eap & 0xFFFFF800) >> 11; - channel = eap & 1; - syndrome = derrctl_sts & 0xFF; - bits = ((errsts & 3) == 1)?1:2; - - // Report the error - print_ecc_err(page, 0, bits==1?1:0, syndrome, channel); - - // Clear the error status - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xE2, 2, 3 << 10); - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 3); - } -} + static void poll_i840(void) + { + unsigned long errsts; + unsigned long page; + unsigned long syndrome; + int channel; + int bits; + // Read the error status + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); + if (errsts & 3) { + unsigned long eap; + unsigned long derrctl_sts; + // Read the error location + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE4, 4, &eap); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE2, 2, &derrctl_sts); + + // Parse the error location and error type + page = (eap & 0xFFFFF800) >> 11; + channel = eap & 1; + syndrome = derrctl_sts & 0xFF; + bits = ((errsts & 3) == 1)?1:2; + + // Report the error + print_ecc_err(page, 0, bits==1?1:0, syndrome, channel); + + // Clear the error status + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xE2, 2, 3 << 10); + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 3); + } + } */ static void setup_i875(void) { - long *ptr; - ulong dev0, dev6 ; + long *ptr; + ulong dev0, dev6 ; - /* Fill in the correct memory capabilites */ + /* Fill in the correct memory capabilites */ - ctrl.cap = ECC_CORRECT; - ctrl.mode = ECC_NONE; + ctrl.cap = ECC_CORRECT; + ctrl.mode = ECC_NONE; - /* From my article : http://www.x86-secret.com/articles/tweak/pat/patsecrets-2.htm */ - /* Activate Device 6 */ - pci_conf_read( 0, 0, 0, 0xF4, 1, &dev0); - pci_conf_write( 0, 0, 0, 0xF4, 1, (dev0 | 0x2)); + /* From my article : http://www.x86-secret.com/articles/tweak/pat/patsecrets-2.htm */ + /* Activate Device 6 */ + pci_conf_read( 0, 0, 0, 0xF4, 1, &dev0); + pci_conf_write( 0, 0, 0, 0xF4, 1, (dev0 | 0x2)); - /* Activate Device 6 MMR */ - pci_conf_read( 0, 6, 0, 0x04, 2, &dev6); - pci_conf_write( 0, 6, 0, 0x04, 2, (dev6 | 0x2)); + /* Activate Device 6 MMR */ + pci_conf_read( 0, 6, 0, 0x04, 2, &dev6); + pci_conf_write( 0, 6, 0, 0x04, 2, (dev6 | 0x2)); - /* Read the MMR Base Address & Define the pointer*/ - pci_conf_read( 0, 6, 0, 0x10, 4, &dev6); - ptr=(long*)(dev6+0x68); + /* Read the MMR Base Address & Define the pointer*/ + pci_conf_read( 0, 6, 0, 0x10, 4, &dev6); + ptr=(long*)(dev6+0x68); - if (((*ptr >> 18)&1) == 1) { ctrl.mode = ECC_CORRECT; } + if (((*ptr >> 18)&1) == 1) { ctrl.mode = ECC_CORRECT; } - /* Reseting state */ - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 0x81); + /* Reseting state */ + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 0x81); } static void setup_i925(void) { - // Activate MMR I/O - ulong dev0, drc; - unsigned long tolm; - long *ptr; - - pci_conf_read( 0, 0, 0, 0x54, 4, &dev0); - dev0 = dev0 | 0x10000000; - pci_conf_write( 0, 0, 0, 0x54, 4, dev0); - - // CDH start - pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); - if (!(dev0 & 0xFFFFC000)) { - pci_conf_read( 0, 0, 0, 0x9C, 1, &tolm); - pci_conf_write( 0, 0, 0, 0x47, 1, tolm & 0xF8); - } - // CDH end - - // ECC Checking - ctrl.cap = ECC_CORRECT; - - dev0 &= 0xFFFFC000; - ptr=(long*)(dev0+0x120); - drc = *ptr & 0xFFFFFFFF; - - if (((drc >> 20) & 3) == 2) { - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 3); - ctrl.mode = ECC_CORRECT; - } else { - ctrl.mode = ECC_NONE; - } + // Activate MMR I/O + ulong dev0, drc; + unsigned long tolm; + long *ptr; + + pci_conf_read( 0, 0, 0, 0x54, 4, &dev0); + dev0 = dev0 | 0x10000000; + pci_conf_write( 0, 0, 0, 0x54, 4, dev0); + + // CDH start + pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); + if (!(dev0 & 0xFFFFC000)) { + pci_conf_read( 0, 0, 0, 0x9C, 1, &tolm); + pci_conf_write( 0, 0, 0, 0x47, 1, tolm & 0xF8); + } + // CDH end + + // ECC Checking + ctrl.cap = ECC_CORRECT; + + dev0 &= 0xFFFFC000; + ptr=(long*)(dev0+0x120); + drc = *ptr & 0xFFFFFFFF; + + if (((drc >> 20) & 3) == 2) { + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 3); + ctrl.mode = ECC_CORRECT; + } else { + ctrl.mode = ECC_NONE; + } } static void setup_p35(void) { - // Activate MMR I/O - ulong dev0, capid0; - - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - if (!(dev0 & 0x1)) { - pci_conf_write( 0, 0, 0, 0x48, 1, dev0 | 1); - } - - // ECC Checking (No poll on X38/48 for now) - pci_conf_read( 0, 0, 0, 0xE4, 4, &capid0); - if ((capid0 >> 8) & 1) { - ctrl.cap = ECC_NONE; - } else { - ctrl.cap = ECC_CORRECT; - } - - ctrl.mode = ECC_NONE; - - /* - ulong toto; - pci_conf_write(0, 31, 3, 0x40, 1, 0x1); - pci_conf_read(0, 31, 3, 0x0, 4, &toto); - hprint(11,0,toto); - pci_conf_read(0, 31, 3, 0x10, 4, &toto); - hprint(11,10,toto) ; - pci_conf_read(0, 31, 3, 0x20, 4, &toto); - hprint(11,20,toto) ; - pci_conf_read(0, 28, 0, 0x0, 4, &toto); - hprint(11,30,toto); - pci_conf_read(0, 31, 0, 0x0, 4, &toto); - hprint(11,40,toto) ; - pci_conf_read(0, 31, 1, 0x0, 4, &toto); - hprint(11,50,toto) ; - pci_conf_read(0, 31, 2, 0x0, 4, &toto); - hprint(11,60,toto) ; - */ + // Activate MMR I/O + ulong dev0, capid0; + + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + if (!(dev0 & 0x1)) { + pci_conf_write( 0, 0, 0, 0x48, 1, dev0 | 1); + } + + // ECC Checking (No poll on X38/48 for now) + pci_conf_read( 0, 0, 0, 0xE4, 4, &capid0); + if ((capid0 >> 8) & 1) { + ctrl.cap = ECC_NONE; + } else { + ctrl.cap = ECC_CORRECT; + } + + ctrl.mode = ECC_NONE; + + /* + ulong toto; + pci_conf_write(0, 31, 3, 0x40, 1, 0x1); + pci_conf_read(0, 31, 3, 0x0, 4, &toto); + hprint(11,0,toto); + pci_conf_read(0, 31, 3, 0x10, 4, &toto); + hprint(11,10,toto) ; + pci_conf_read(0, 31, 3, 0x20, 4, &toto); + hprint(11,20,toto) ; + pci_conf_read(0, 28, 0, 0x0, 4, &toto); + hprint(11,30,toto); + pci_conf_read(0, 31, 0, 0x0, 4, &toto); + hprint(11,40,toto) ; + pci_conf_read(0, 31, 1, 0x0, 4, &toto); + hprint(11,50,toto) ; + pci_conf_read(0, 31, 2, 0x0, 4, &toto); + hprint(11,60,toto) ; + */ } /* -static void poll_i875(void) -{ - unsigned long errsts; - unsigned long page; - unsigned long des; - unsigned long syndrome; - int channel; - int bits; - // Read the error status - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); - if (errsts & 0x81) { - unsigned long eap; - unsigned long derrsyn; - // Read the error location, syndrome and channel - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x58, 4, &eap); - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x5C, 1, &derrsyn); - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x5D, 1, &des); - - // Parse the error location and error type - page = (eap & 0xFFFFF000) >> 12; - syndrome = derrsyn; - channel = des & 1; - bits = (errsts & 0x80)?0:1; - - // Report the error - print_ecc_err(page, 0, bits, syndrome, channel); - - // Clear the error status - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 0x81); - } -} + static void poll_i875(void) + { + unsigned long errsts; + unsigned long page; + unsigned long des; + unsigned long syndrome; + int channel; + int bits; + // Read the error status + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); + if (errsts & 0x81) { + unsigned long eap; + unsigned long derrsyn; + // Read the error location, syndrome and channel + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x58, 4, &eap); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x5C, 1, &derrsyn); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x5D, 1, &des); + + // Parse the error location and error type + page = (eap & 0xFFFFF000) >> 12; + syndrome = derrsyn; + channel = des & 1; + bits = (errsts & 0x80)?0:1; + + // Report the error + print_ecc_err(page, 0, bits, syndrome, channel); + + // Clear the error status + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 0x81); + } + } */ static void setup_i845(void) { - static const int ddim[] = { ECC_NONE, ECC_RESERVED, ECC_CORRECT, ECC_RESERVED }; - unsigned long drc; + static const int ddim[] = { ECC_NONE, ECC_RESERVED, ECC_CORRECT, ECC_RESERVED }; + unsigned long drc; - // Fill in the correct memory capabilites - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x7C, 4, &drc); - ctrl.cap = ECC_CORRECT; - ctrl.mode = ddim[(drc >> 20)&3]; + // Fill in the correct memory capabilites + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x7C, 4, &drc); + ctrl.cap = ECC_CORRECT; + ctrl.mode = ddim[(drc >> 20)&3]; } /* -static void poll_i845(void) -{ - unsigned long errsts; - unsigned long page, offset; - unsigned long syndrome; - int bits; - // Read the error status - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); - if (errsts & 3) { - unsigned long eap; - unsigned long derrsyn; - // Read the error location - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x8C, 4, &eap); - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x86, 1, &derrsyn); - - // Parse the error location and error type - offset = (eap & 0xFE) << 4; - page = (eap & 0x3FFFFFFE) >> 8; - syndrome = derrsyn; - bits = ((errsts & 3) == 1)?1:2; - - // Report the error - print_ecc_err(page, offset, bits==1?1:0, syndrome, 0); - - // Clear the error status - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 3); - } -} + static void poll_i845(void) + { + unsigned long errsts; + unsigned long page, offset; + unsigned long syndrome; + int bits; + // Read the error status + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); + if (errsts & 3) { + unsigned long eap; + unsigned long derrsyn; + // Read the error location + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x8C, 4, &eap); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x86, 1, &derrsyn); + + // Parse the error location and error type + offset = (eap & 0xFE) << 4; + page = (eap & 0x3FFFFFFE) >> 8; + syndrome = derrsyn; + bits = ((errsts & 3) == 1)?1:2; + + // Report the error + print_ecc_err(page, offset, bits==1?1:0, syndrome, 0); + + // Clear the error status + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 3); + } + } */ static void setup_i820(void) { - static const int ddim[] = { ECC_NONE, ECC_RESERVED, ECC_CORRECT, ECC_CORRECT }; - unsigned long mchcfg; + static const int ddim[] = { ECC_NONE, ECC_RESERVED, ECC_CORRECT, ECC_CORRECT }; + unsigned long mchcfg; - // Fill in the correct memory capabilites - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xbe, 2, &mchcfg); - ctrl.cap = ECC_CORRECT; - ctrl.mode = ddim[(mchcfg >> 7)&3]; + // Fill in the correct memory capabilites + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xbe, 2, &mchcfg); + ctrl.cap = ECC_CORRECT; + ctrl.mode = ddim[(mchcfg >> 7)&3]; } /* -static void poll_i820(void) -{ - unsigned long errsts; - unsigned long page; - unsigned long syndrome; - int bits; - // Read the error status - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); - if (errsts & 3) { - unsigned long eap; - // Read the error location - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xc4, 4, &eap); - - // Parse the error location and error type - page = (eap & 0xFFFFF000) >> 4; - syndrome = eap & 0xFF; - bits = ((errsts & 3) == 1)?1:2; - - // Report the error - print_ecc_err(page, 0, bits==1?1:0, syndrome, 0); - - // Clear the error status - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 3); - } -} + static void poll_i820(void) + { + unsigned long errsts; + unsigned long page; + unsigned long syndrome; + int bits; + // Read the error status + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); + if (errsts & 3) { + unsigned long eap; + // Read the error location + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xc4, 4, &eap); + + // Parse the error location and error type + page = (eap & 0xFFFFF000) >> 4; + syndrome = eap & 0xFF; + bits = ((errsts & 3) == 1)?1:2; + + // Report the error + print_ecc_err(page, 0, bits==1?1:0, syndrome, 0); + + // Clear the error status + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 3); + } + } */ static void setup_i850(void) { - static const int ddim[] = { ECC_NONE, ECC_RESERVED, ECC_CORRECT, ECC_RESERVED }; - unsigned long mchcfg; + static const int ddim[] = { ECC_NONE, ECC_RESERVED, ECC_CORRECT, ECC_RESERVED }; + unsigned long mchcfg; - // Fill in the correct memory capabilites - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x50, 2, &mchcfg); - ctrl.cap = ECC_CORRECT; - ctrl.mode = ddim[(mchcfg >> 7)&3]; + // Fill in the correct memory capabilites + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x50, 2, &mchcfg); + ctrl.cap = ECC_CORRECT; + ctrl.mode = ddim[(mchcfg >> 7)&3]; } /* -static void poll_i850(void) -{ - unsigned long errsts; - unsigned long page; - unsigned long syndrome; - int channel; - int bits; - // Read the error status - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); - if (errsts & 3) { - unsigned long eap; - unsigned long derrctl_sts; - // Read the error location - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE4, 4, &eap); - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE2, 2, &derrctl_sts); - - // Parse the error location and error type - page = (eap & 0xFFFFF800) >> 11; - channel = eap & 1; - syndrome = derrctl_sts & 0xFF; - bits = ((errsts & 3) == 1)?1:2; - - // Report the error - print_ecc_err(page, 0, bits==1?1:0, syndrome, channel); - - // Clear the error status - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, errsts & 3); - } -} + static void poll_i850(void) + { + unsigned long errsts; + unsigned long page; + unsigned long syndrome; + int channel; + int bits; + // Read the error status + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); + if (errsts & 3) { + unsigned long eap; + unsigned long derrctl_sts; + // Read the error location + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE4, 4, &eap); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE2, 2, &derrctl_sts); + + // Parse the error location and error type + page = (eap & 0xFFFFF800) >> 11; + channel = eap & 1; + syndrome = derrctl_sts & 0xFF; + bits = ((errsts & 3) == 1)?1:2; + + // Report the error + print_ecc_err(page, 0, bits==1?1:0, syndrome, channel); + + // Clear the error status + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, errsts & 3); + } + } */ static void setup_i860(void) { - static const int ddim[] = { ECC_NONE, ECC_RESERVED, ECC_CORRECT, ECC_RESERVED }; - unsigned long mchcfg; - unsigned long errsts; - - // Fill in the correct memory capabilites - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x50, 2, &mchcfg); - ctrl.cap = ECC_CORRECT; - ctrl.mode = ddim[(mchcfg >> 7)&3]; - - // Clear any prexisting error reports - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, errsts & 3); + static const int ddim[] = { ECC_NONE, ECC_RESERVED, ECC_CORRECT, ECC_RESERVED }; + unsigned long mchcfg; + unsigned long errsts; + + // Fill in the correct memory capabilites + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x50, 2, &mchcfg); + ctrl.cap = ECC_CORRECT; + ctrl.mode = ddim[(mchcfg >> 7)&3]; + + // Clear any prexisting error reports + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, errsts & 3); } /* -static void poll_i860(void) -{ - unsigned long errsts; - unsigned long page; - unsigned char syndrome; - int channel; - int bits; - // Read the error status - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); - if (errsts & 3) { - unsigned long eap; - unsigned long derrctl_sts; - // Read the error location - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE4, 4, &eap); - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE2, 2, &derrctl_sts); - - // Parse the error location and error type - page = (eap & 0xFFFFFE00) >> 9; - channel = eap & 1; - syndrome = derrctl_sts & 0xFF; - bits = ((errsts & 3) == 1)?1:2; - - // Report the error - print_ecc_err(page, 0, bits==1?1:0, syndrome, channel); - - // Clear the error status - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, errsts & 3); - } -} - - -static void poll_iE7221(void) -{ - unsigned long errsts; - unsigned long page; - unsigned char syndrome; - int channel; - int bits; - int errocc; - - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); - - errocc = errsts & 3; - - if ((errocc == 1) || (errocc == 2)) { - unsigned long eap, offset; - unsigned long derrctl_sts; + static void poll_i860(void) + { + unsigned long errsts; + unsigned long page; + unsigned char syndrome; + int channel; + int bits; + // Read the error status + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); + if (errsts & 3) { + unsigned long eap; + unsigned long derrctl_sts; + // Read the error location + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE4, 4, &eap); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE2, 2, &derrctl_sts); + + // Parse the error location and error type + page = (eap & 0xFFFFFE00) >> 9; + channel = eap & 1; + syndrome = derrctl_sts & 0xFF; + bits = ((errsts & 3) == 1)?1:2; + + // Report the error + print_ecc_err(page, 0, bits==1?1:0, syndrome, channel); + + // Clear the error status + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, errsts & 3); + } + } + + + static void poll_iE7221(void) + { + unsigned long errsts; + unsigned long page; + unsigned char syndrome; + int channel; + int bits; + int errocc; + + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); + + errocc = errsts & 3; + + if ((errocc == 1) || (errocc == 2)) { + unsigned long eap, offset; + unsigned long derrctl_sts; - // Read the error location - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x58, 4, &eap); - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x5C, 1, &derrctl_sts); + // Read the error location + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x58, 4, &eap); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x5C, 1, &derrctl_sts); - // Parse the error location and error type - channel = eap & 1; - eap = eap & 0xFFFFFF80; - page = eap >> 12; - offset = eap & 0xFFF; - syndrome = derrctl_sts & 0xFF; - bits = errocc & 1; + // Parse the error location and error type + channel = eap & 1; + eap = eap & 0xFFFFFF80; + page = eap >> 12; + offset = eap & 0xFFF; + syndrome = derrctl_sts & 0xFF; + bits = errocc & 1; - // Report the error - print_ecc_err(page, offset, bits, syndrome, channel); + // Report the error + print_ecc_err(page, offset, bits, syndrome, channel); - // Clear the error status - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, errsts & 3); - } + // Clear the error status + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, errsts & 3); + } - else if (errocc == 3) { + else if (errocc == 3) { - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, errsts & 3); + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, errsts & 3); - } -} + } + } -static void poll_iE7520(void) -{ - unsigned long ferr; - unsigned long nerr; + static void poll_iE7520(void) + { + unsigned long ferr; + unsigned long nerr; - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 2, &ferr); - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 2, &nerr); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 2, &ferr); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 2, &nerr); - if (ferr & 0x0101) { - // Find out about the first correctable error - unsigned long celog_add; - unsigned long celog_syndrome; - unsigned long page; + if (ferr & 0x0101) { + // Find out about the first correctable error + unsigned long celog_add; + unsigned long celog_syndrome; + unsigned long page; - // Read the error location - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xA0, 4,&celog_add); - // Read the syndrome - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xC4, 2, &celog_syndrome); + // Read the error location + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xA0, 4,&celog_add); + // Read the syndrome + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xC4, 2, &celog_syndrome); - // Parse the error location - page = (celog_add & 0x7FFFFFFC) >> 2; + // Parse the error location + page = (celog_add & 0x7FFFFFFC) >> 2; - // Report the error - print_ecc_err(page, 0, 1, celog_syndrome, 0); + // Report the error + print_ecc_err(page, 0, 1, celog_syndrome, 0); - // Clear Bit - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 2, ferr& 0x0101); - } + // Clear Bit + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 2, ferr& 0x0101); + } - if (ferr & 0x4646) { - // Found out about the first uncorrectable error - unsigned long uccelog_add; - unsigned long page; + if (ferr & 0x4646) { + // Found out about the first uncorrectable error + unsigned long uccelog_add; + unsigned long page; - // Read the error location - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xA4, 4, &uccelog_add); + // Read the error location + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xA4, 4, &uccelog_add); - // Parse the error location - page = (uccelog_add & 0x7FFFFFFC) >> 2; + // Parse the error location + page = (uccelog_add & 0x7FFFFFFC) >> 2; - // Report the error - print_ecc_err(page, 0, 0, 0, 0); + // Report the error + print_ecc_err(page, 0, 0, 0, 0); - // Clear Bit - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 2, ferr & 0x4646); - } + // Clear Bit + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 2, ferr & 0x4646); + } - // Check if DRAM_NERR contains data - if (nerr & 0x4747) { - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 2, nerr & 0x4747); - } -} + // Check if DRAM_NERR contains data + if (nerr & 0x4747) { + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 2, nerr & 0x4747); + } + } */ @@ -1310,256 +1312,256 @@ static float p4model1ratios[] = {16, 17, 18, 19, 20, 21, 22, 23, 8, 9, 10, 11, 1 static float getP4PMmultiplier(void) { - //unsigned int msr_lo, msr_hi; - int msr_lo, msr_hi; - float coef; - - - /* Find multiplier (by MSR) */ - if (cpu_id.vers.bits.family == 6) - { - if(cpu_id.fid.bits.eist & 1) - { - rdmsr(0x198, msr_lo, msr_hi); - coef = ((msr_lo) >> 8) & 0x1F; - if ((msr_lo >> 14) & 0x1) { coef += 0.5f; } - // Atom Fix - if(coef == 6) - { - coef = ((msr_hi) >> 8) & 0x1F; - if ((msr_hi >> 14) & 0x1) { coef += 0.5f; } - } - } else { - rdmsr(0x2A, msr_lo, msr_hi); - coef = (msr_lo >> 22) & 0x1F; - } - } - else - { - if (cpu_id.vers.bits.model < 2) - { - rdmsr(0x2A, msr_lo, msr_hi); - coef = (msr_lo >> 8) & 0xF; - coef = p4model1ratios[(int)coef]; - } - else - { - rdmsr(0x2C, msr_lo, msr_hi); - coef = (msr_lo >> 24) & 0x1F; - } - } - - return coef; + //unsigned int msr_lo, msr_hi; + int msr_lo, msr_hi; + float coef; + + + /* Find multiplier (by MSR) */ + if (cpu_id.vers.bits.family == 6) + { + if(cpu_id.fid.bits.eist & 1) + { + rdmsr(0x198, msr_lo, msr_hi); + coef = ((msr_lo) >> 8) & 0x1F; + if ((msr_lo >> 14) & 0x1) { coef += 0.5f; } + // Atom Fix + if(coef == 6) + { + coef = ((msr_hi) >> 8) & 0x1F; + if ((msr_hi >> 14) & 0x1) { coef += 0.5f; } + } + } else { + rdmsr(0x2A, msr_lo, msr_hi); + coef = (msr_lo >> 22) & 0x1F; + } + } + else + { + if (cpu_id.vers.bits.model < 2) + { + rdmsr(0x2A, msr_lo, msr_hi); + coef = (msr_lo >> 8) & 0xF; + coef = p4model1ratios[(int)coef]; + } + else + { + rdmsr(0x2C, msr_lo, msr_hi); + coef = (msr_lo >> 24) & 0x1F; + } + } + + return coef; } static float getNHMmultiplier(void) { - unsigned int msr_lo, msr_hi; - float coef; - - /* Find multiplier (by MSR) */ - /* First, check if Flexible Ratio is Enabled */ - rdmsr(0x194, msr_lo, msr_hi); - if((msr_lo >> 16) & 1){ - coef = (msr_lo >> 8) & 0xFF; - } else { - rdmsr(0xCE, msr_lo, msr_hi); - coef = (msr_lo >> 8) & 0xFF; - } - - return coef; + unsigned int msr_lo, msr_hi; + float coef; + + /* Find multiplier (by MSR) */ + /* First, check if Flexible Ratio is Enabled */ + rdmsr(0x194, msr_lo, msr_hi); + if((msr_lo >> 16) & 1){ + coef = (msr_lo >> 8) & 0xFF; + } else { + rdmsr(0xCE, msr_lo, msr_hi); + coef = (msr_lo >> 8) & 0xFF; + } + + return coef; } static float getSNBmultiplier(void) { - unsigned int msr_lo, msr_hi; - float coef; + unsigned int msr_lo, msr_hi; + float coef; - rdmsr(0xCE, msr_lo, msr_hi); - coef = (msr_lo >> 8) & 0xFF; + rdmsr(0xCE, msr_lo, msr_hi); + coef = (msr_lo >> 8) & 0xFF; - return coef; + return coef; } static void poll_fsb_ct(void) { - unsigned long mcr, mdr; - double dramratio, dramclock, fsb; - float coef = getP4PMmultiplier(); - - /* Build the MCR Message*/ - mcr = (0x10 << 24); // 10h = Read - 11h = Write - mcr += (0x01 << 16); // DRAM Registers located on port 01h - mcr += (0x01 << 8); // DRP = 00h, DTR0 = 01h, DTR1 = 02h, DTR2 = 03h - mcr &= 0xFFFFFFF0; // bit 03:00 RSVD - - /* Send Message to GMCH */ - pci_conf_write(0, 0, 0, 0xD0, 4, mcr); - - /* Read Answer from Sideband bus */ - pci_conf_read(0, 0, 0, 0xD4, 4, &mdr); - - /* Get RAM ratio */ - switch (mdr & 0x3) { - default: - case 0: dramratio = 3.0f; break; - case 1: dramratio = 4.0f; break; - case 2: dramratio = 5.0f; break; - case 3: dramratio = 6.0f; break; - } - - // Compute FSB & RAM Frequency - fsb = ((extclock / 1000) / coef); - dramclock = fsb * dramratio; - - // Print'em all. Whoa ! - print_cpu_line(dramclock, fsb, 3); + unsigned long mcr, mdr; + double dramratio, dramclock, fsb; + float coef = getP4PMmultiplier(); + + /* Build the MCR Message*/ + mcr = (0x10 << 24); // 10h = Read - 11h = Write + mcr += (0x01 << 16); // DRAM Registers located on port 01h + mcr += (0x01 << 8); // DRP = 00h, DTR0 = 01h, DTR1 = 02h, DTR2 = 03h + mcr &= 0xFFFFFFF0; // bit 03:00 RSVD + + /* Send Message to GMCH */ + pci_conf_write(0, 0, 0, 0xD0, 4, mcr); + + /* Read Answer from Sideband bus */ + pci_conf_read(0, 0, 0, 0xD4, 4, &mdr); + + /* Get RAM ratio */ + switch (mdr & 0x3) { + default: + case 0: dramratio = 3.0f; break; + case 1: dramratio = 4.0f; break; + case 2: dramratio = 5.0f; break; + case 3: dramratio = 6.0f; break; + } + + // Compute FSB & RAM Frequency + fsb = ((extclock / 1000) / coef); + dramclock = fsb * dramratio; + + // Print'em all. Whoa ! + print_cpu_line(dramclock, fsb, 3); } static void poll_fsb_amd64(void) { - unsigned int mcgsrl; - unsigned int mcgsth; - unsigned long fid, temp2; - unsigned long dramchr; - float clockratio; - double dramclock; - unsigned int dummy[3]; - int ram_type; - - float coef = 10; - - cpuid(0x80000007, &dummy[0], &dummy[1], &dummy[2], &dummy[3]); - - /* First, got the FID by MSR */ - /* First look if Cool 'n Quiet is supported to choose the best msr */ - if (((dummy[3] >> 1) & 1) == 1) { - rdmsr(0xc0010042, mcgsrl, mcgsth); - fid = (mcgsrl & 0x3F); - } else { - rdmsr(0xc0010015, mcgsrl, mcgsth); - fid = ((mcgsrl >> 24)& 0x3F); - } - - /* Extreme simplification. */ - coef = ( fid / 2 ) + 4.0; - - /* Support for .5 coef */ - if (fid & 1) { coef = coef + 0.5; } - - /* Next, we need the clock ratio */ - if (cpu_id.vers.bits.extendedModel >= 4) { + unsigned int mcgsrl; + unsigned int mcgsth; + unsigned long fid, temp2; + unsigned long dramchr; + float clockratio; + double dramclock; + unsigned int dummy[3]; + int ram_type; + + float coef = 10; + + cpuid(0x80000007, &dummy[0], &dummy[1], &dummy[2], &dummy[3]); + + /* First, got the FID by MSR */ + /* First look if Cool 'n Quiet is supported to choose the best msr */ + if (((dummy[3] >> 1) & 1) == 1) { + rdmsr(0xc0010042, mcgsrl, mcgsth); + fid = (mcgsrl & 0x3F); + } else { + rdmsr(0xc0010015, mcgsrl, mcgsth); + fid = ((mcgsrl >> 24)& 0x3F); + } + + /* Extreme simplification. */ + coef = ( fid / 2 ) + 4.0; + + /* Support for .5 coef */ + if (fid & 1) { coef = coef + 0.5; } + + /* Next, we need the clock ratio */ + if (cpu_id.vers.bits.extendedModel >= 4) { /* K8 0FH */ - pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); - temp2 = (dramchr & 0x7); - clockratio = coef; - ram_type = 2; - - switch (temp2) { - case 0x0: - clockratio = (int)(coef); - break; - case 0x1: - clockratio = (int)(coef * 3.0f/4.0f); - break; - case 0x2: - clockratio = (int)(coef * 3.0f/5.0f); - break; - case 0x3: - clockratio = (int)(coef * 3.0f/6.0f); - break; - } - - } else { - /* OLD K8 */ - pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); - temp2 = (dramchr >> 20) & 0x7; - ram_type = 1; - clockratio = coef; - - switch (temp2) { - case 0x0: - clockratio = (int)(coef * 2.0f); - break; - case 0x2: - clockratio = (int)((coef * 3.0f/2.0f) + 0.81f); - break; - case 0x4: - clockratio = (int)((coef * 4.0f/3.0f) + 0.81f); - break; - case 0x5: - clockratio = (int)((coef * 6.0f/5.0f) + 0.81f); - break; - case 0x6: - clockratio = (int)((coef * 10.0f/9.0f) + 0.81f); - break; - case 0x7: - clockratio = (int)(coef + 0.81f); - break; - } - } - - /* Compute the final DRAM Clock */ - dramclock = (extclock / 1000) / clockratio; - - /* ...and print */ - print_cpu_line(dramclock, (extclock / 1000 / coef), ram_type); + pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); + temp2 = (dramchr & 0x7); + clockratio = coef; + ram_type = 2; + + switch (temp2) { + case 0x0: + clockratio = (int)(coef); + break; + case 0x1: + clockratio = (int)(coef * 3.0f/4.0f); + break; + case 0x2: + clockratio = (int)(coef * 3.0f/5.0f); + break; + case 0x3: + clockratio = (int)(coef * 3.0f/6.0f); + break; + } + + } else { + /* OLD K8 */ + pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); + temp2 = (dramchr >> 20) & 0x7; + ram_type = 1; + clockratio = coef; + + switch (temp2) { + case 0x0: + clockratio = (int)(coef * 2.0f); + break; + case 0x2: + clockratio = (int)((coef * 3.0f/2.0f) + 0.81f); + break; + case 0x4: + clockratio = (int)((coef * 4.0f/3.0f) + 0.81f); + break; + case 0x5: + clockratio = (int)((coef * 6.0f/5.0f) + 0.81f); + break; + case 0x6: + clockratio = (int)((coef * 10.0f/9.0f) + 0.81f); + break; + case 0x7: + clockratio = (int)(coef + 0.81f); + break; + } + } + + /* Compute the final DRAM Clock */ + dramclock = (extclock / 1000) / clockratio; + + /* ...and print */ + print_cpu_line(dramclock, (extclock / 1000 / coef), ram_type); } static void poll_fsb_k10(void) { - unsigned int mcgsrl; - unsigned int mcgsth; - unsigned long temp2; - unsigned long dramchr; - unsigned long mainPllId; - double dramclock; - ulong offset = 0; - int ram_type = 2; - - /* First, we need the clock ratio */ - pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); - temp2 = (dramchr & 0x7); - - switch (temp2) { - case 0x7: temp2++; - case 0x6: temp2++; - case 0x5: temp2++; - case 0x4: temp2++; - default: temp2 += 3; - } - - /* Compute the final DRAM Clock */ - if (((cpu_id.vers.bits.extendedModel >> 4) & 0xFF) == 1) { - dramclock = ((temp2 * 200) / 3.0) + 0.25; - } else { - unsigned long target; - unsigned long dx; - unsigned divisor; - - target = temp2 * 400; - - /* Get the FID by MSR */ - rdmsr(0xc0010071, mcgsrl, mcgsth); - - pci_conf_read(0, 24, 3, 0xD4, 4, &mainPllId); - - if ( mainPllId & 0x40 ) - mainPllId &= 0x3F; - else - mainPllId = 8; /* FID for 1600 */ - - mcgsth = (mcgsth >> 17) & 0x3F; - if ( mcgsth ) { - if ( mainPllId > mcgsth ) - mainPllId = mcgsth; - } - - dx = (mainPllId + 8) * 1200; - for ( divisor = 3; divisor < 100; divisor++ ) - if ( (dx / divisor) <= target ) - break; + unsigned int mcgsrl; + unsigned int mcgsth; + unsigned long temp2; + unsigned long dramchr; + unsigned long mainPllId; + double dramclock; + ulong offset = 0; + int ram_type = 2; + + /* First, we need the clock ratio */ + pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); + temp2 = (dramchr & 0x7); + + switch (temp2) { + case 0x7: temp2++; + case 0x6: temp2++; + case 0x5: temp2++; + case 0x4: temp2++; + default: temp2 += 3; + } + + /* Compute the final DRAM Clock */ + if (((cpu_id.vers.bits.extendedModel >> 4) & 0xFF) == 1) { + dramclock = ((temp2 * 200) / 3.0) + 0.25; + } else { + unsigned long target; + unsigned long dx; + unsigned divisor; + + target = temp2 * 400; + + /* Get the FID by MSR */ + rdmsr(0xc0010071, mcgsrl, mcgsth); + + pci_conf_read(0, 24, 3, 0xD4, 4, &mainPllId); + + if ( mainPllId & 0x40 ) + mainPllId &= 0x3F; + else + mainPllId = 8; /* FID for 1600 */ + + mcgsth = (mcgsth >> 17) & 0x3F; + if ( mcgsth ) { + if ( mainPllId > mcgsth ) + mainPllId = mcgsth; + } + + dx = (mainPllId + 8) * 1200; + for ( divisor = 3; divisor < 100; divisor++ ) + if ( (dx / divisor) <= target ) + break; pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); @@ -1567,1254 +1569,1254 @@ static void poll_fsb_k10(void) { // 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); + offset = 0x100; + pci_conf_read(0, 24, 2, 0x94+offset, 4, &dramchr); } //DDR2 or DDR3 if ((dramchr >> 8)&1) { - ram_type = 3; + ram_type = 3; } else { - ram_type = 2;; + ram_type = 2;; } - dramclock = ((dx / divisor) / 6.0) + 0.25; -} + dramclock = ((dx / divisor) / 6.0) + 0.25; + } - /* ...and print */ - print_cpu_line(dramclock, 0, ram_type); + /* ...and print */ + print_cpu_line(dramclock, 0, ram_type); } static void poll_fsb_k12(void) { - unsigned long temp2; - unsigned long dramchr; - double dramratio, dramclock, fsb, did; - unsigned int mcgsrl,mcgsth, fid, did_raw; + unsigned long temp2; + unsigned long dramchr; + double dramratio, dramclock, fsb, did; + unsigned int mcgsrl,mcgsth, fid, did_raw; - // Get current FID & DID - rdmsr(0xc0010071, mcgsrl, mcgsth); - did_raw = mcgsrl & 0xF; - fid = (mcgsrl >> 4) & 0xF; + // Get current FID & DID + rdmsr(0xc0010071, mcgsrl, mcgsth); + did_raw = mcgsrl & 0xF; + fid = (mcgsrl >> 4) & 0xF; - switch(did_raw) - { - default: - case 0x0: - did = 1.0f; - break; - case 0x1: - did = 1.5f; - break; - case 0x2: - did = 2.0f; - break; - case 0x3: - did = 3.0f; - break; - case 0x4: - did = 4.0f; - break; - case 0x5: - did = 6.0f; - break; - case 0x6: - did = 8.0f; - break; - case 0x7: - did = 12.0f; - break; - case 0x8: - did = 16.0f; - break; - } - - fsb = ((extclock / 1000.0f) / ((fid + 16.0f) / did)); + switch(did_raw) + { + default: + case 0x0: + did = 1.0f; + break; + case 0x1: + did = 1.5f; + break; + case 0x2: + did = 2.0f; + break; + case 0x3: + did = 3.0f; + break; + case 0x4: + did = 4.0f; + break; + case 0x5: + did = 6.0f; + break; + case 0x6: + did = 8.0f; + break; + case 0x7: + did = 12.0f; + break; + case 0x8: + did = 16.0f; + break; + } + + fsb = ((extclock / 1000.0f) / ((fid + 16.0f) / did)); - /* Finaly, we need the clock ratio */ - pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); - - if(((dramchr >> 14) & 0x1) == 1) - { - pci_conf_read(0, 24, 2, 0x194, 4, &dramchr); - } - - temp2 = (dramchr & 0x1F); - - switch (temp2) { - default: - case 0x06: - dramratio = 4.0f; - break; - case 0x0A: - dramratio = 16.0f / 3.0f; - break; - case 0x0E: - dramratio = 20.0f / 3.0f; - break; - case 0x12: - dramratio = 8.0f; - break; - case 0x16: - dramratio = 28.0f / 3.0f; - break; - } - - dramclock = fsb * dramratio; - - /* print */ - print_cpu_line(dramclock, fsb, 3); + /* Finaly, we need the clock ratio */ + pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); + + if(((dramchr >> 14) & 0x1) == 1) + { + pci_conf_read(0, 24, 2, 0x194, 4, &dramchr); + } + + temp2 = (dramchr & 0x1F); + + switch (temp2) { + default: + case 0x06: + dramratio = 4.0f; + break; + case 0x0A: + dramratio = 16.0f / 3.0f; + break; + case 0x0E: + dramratio = 20.0f / 3.0f; + break; + case 0x12: + dramratio = 8.0f; + break; + case 0x16: + dramratio = 28.0f / 3.0f; + break; + } + + dramclock = fsb * dramratio; + + /* print */ + print_cpu_line(dramclock, fsb, 3); } static void poll_fsb_k16(void) { - unsigned long dramchr; - double dramratio, dramclock, fsb; + unsigned long dramchr; + double dramratio, dramclock, fsb; - // FIXME: Unable to find a real way to detect multiplier. - fsb = 100.0f; + // FIXME: Unable to find a real way to detect multiplier. + fsb = 100.0f; - /* Clock ratio */ - pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); - - switch (dramchr & 0x1F) { - default: - case 0x04: /* 333 */ - dramratio = 10.0f / 3.0f; - break; - case 0x06: /* 400 */ - dramratio = 4.0f; - break; - case 0x0A: /* 533 */ - dramratio = 16.0f / 3.0f; - break; - case 0x0E: /* 667 */ - dramratio = 20.0f / 3.0f; - break; - case 0x12: /* 800 */ - dramratio = 8.0f; - break; - case 0x16: /* 933 */ - dramratio = 28.0f / 3.0f; - break; - case 0x19: /* 1050 */ - dramratio = 21.0f / 2.0f; - break; - case 0x1A: /* 1066 */ - dramratio = 32.0f / 3.0f; - break; - } - - dramclock = fsb * dramratio; - - /* print */ - print_cpu_line(dramclock, fsb, 3); + /* Clock ratio */ + pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); + + switch (dramchr & 0x1F) { + default: + case 0x04: /* 333 */ + dramratio = 10.0f / 3.0f; + break; + case 0x06: /* 400 */ + dramratio = 4.0f; + break; + case 0x0A: /* 533 */ + dramratio = 16.0f / 3.0f; + break; + case 0x0E: /* 667 */ + dramratio = 20.0f / 3.0f; + break; + case 0x12: /* 800 */ + dramratio = 8.0f; + break; + case 0x16: /* 933 */ + dramratio = 28.0f / 3.0f; + break; + case 0x19: /* 1050 */ + dramratio = 21.0f / 2.0f; + break; + case 0x1A: /* 1066 */ + dramratio = 32.0f / 3.0f; + break; + } + + dramclock = fsb * dramratio; + + /* print */ + print_cpu_line(dramclock, fsb, 3); } static void poll_fsb_k15(void) { - unsigned long temp2; - unsigned long dramchr; - double dramratio, dramclock, fsb; - unsigned int mcgsrl,mcgsth, fid, did; + unsigned long temp2; + unsigned long dramchr; + double dramratio, dramclock, fsb; + unsigned int mcgsrl,mcgsth, fid, did; - // Get current FID & DID - rdmsr(0xc0010071, mcgsrl, mcgsth); - fid = mcgsrl & 0x3F; - did = (mcgsrl >> 6) & 0x7; + // Get current FID & DID + rdmsr(0xc0010071, mcgsrl, mcgsth); + fid = mcgsrl & 0x3F; + did = (mcgsrl >> 6) & 0x7; - fsb = ((extclock / 1000.0f) / ((fid + 16.0f) / (2^did)) / 2); - - /* Finaly, we need the clock ratio */ - pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); - - if(((dramchr >> 14) & 0x1) == 1) - { - pci_conf_read(0, 24, 2, 0x194, 4, &dramchr); - } - - temp2 = (dramchr & 0x1F); - - switch (temp2) { - case 0x04: - dramratio = 10.0f / 3.0f; - break; - default: - case 0x06: - dramratio = 4.0f; - break; - case 0x0A: - dramratio = 16.0f / 3.0f; - break; - case 0x0E: - dramratio = 20.0f / 3.0f; - break; - case 0x12: - dramratio = 8.0f; - break; - case 0x16: - dramratio = 28.0f / 3.0f; - break; - case 0x1A: - dramratio = 32.0f / 3.0f; - break; - case 0x1F: - dramratio = 36.0f / 3.0f; - break; - } - - dramclock = fsb * dramratio; - - /* print */ - print_cpu_line(dramclock, fsb, 3); + fsb = ((extclock / 1000.0f) / ((fid + 16.0f) / (2^did)) / 2); + + /* Finaly, we need the clock ratio */ + pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); + + if(((dramchr >> 14) & 0x1) == 1) + { + pci_conf_read(0, 24, 2, 0x194, 4, &dramchr); + } + + temp2 = (dramchr & 0x1F); + + switch (temp2) { + case 0x04: + dramratio = 10.0f / 3.0f; + break; + default: + case 0x06: + dramratio = 4.0f; + break; + case 0x0A: + dramratio = 16.0f / 3.0f; + break; + case 0x0E: + dramratio = 20.0f / 3.0f; + break; + case 0x12: + dramratio = 8.0f; + break; + case 0x16: + dramratio = 28.0f / 3.0f; + break; + case 0x1A: + dramratio = 32.0f / 3.0f; + break; + case 0x1F: + dramratio = 36.0f / 3.0f; + break; + } + + dramclock = fsb * dramratio; + + /* print */ + print_cpu_line(dramclock, fsb, 3); } static void poll_fsb_k14(void) { - unsigned long dramchr; - double dramratio, dramclock, fsb; + unsigned long dramchr; + double dramratio, dramclock, fsb; - // FIXME: Unable to find a real way to detect multiplier. - fsb = 100.0f; + // FIXME: Unable to find a real way to detect multiplier. + fsb = 100.0f; - /* Clock ratio */ - pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); - - switch (dramchr & 0x1F) { - default: - case 0x06: - dramratio = 4.0f; - break; - case 0x0A: - dramratio = 16.0f / 3.0f; - break; - case 0x0E: - dramratio = 20.0f / 3.0f; - break; - case 0x12: - dramratio = 8.0f; - break; - } - - dramclock = fsb * dramratio; - - /* print */ - print_cpu_line(dramclock, fsb, 3); + /* Clock ratio */ + pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); + + switch (dramchr & 0x1F) { + default: + case 0x06: + dramratio = 4.0f; + break; + case 0x0A: + dramratio = 16.0f / 3.0f; + break; + case 0x0E: + dramratio = 20.0f / 3.0f; + break; + case 0x12: + dramratio = 8.0f; + break; + } + + dramclock = fsb * dramratio; + + /* print */ + print_cpu_line(dramclock, fsb, 3); } static void poll_fsb_i925(void) { - double dramclock, dramratio, fsb; - unsigned long mchcfg, mchcfg2, dev0, drc, idetect; - float coef = getP4PMmultiplier(); - long *ptr; - int ddr_type; - - pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); - - /* Find dramratio */ - pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); - dev0 = dev0 & 0xFFFFC000; - ptr=(long*)(dev0+0xC00); - mchcfg = *ptr & 0xFFFF; - ptr=(long*)(dev0+0x120); - drc = *ptr & 0xFFFF; - dramratio = 1; - - mchcfg2 = (mchcfg >> 4)&3; - - if ((drc&3) != 2) { - // We are in DDR1 Mode - if (mchcfg2 == 1) { dramratio = 0.8; } else { dramratio = 1; } - ddr_type = 1; - } else { - // We are in DDR2 Mode - ddr_type = 2; - if ((mchcfg >> 2)&1) { - // We are in FSB1066 Mode - if (mchcfg2 == 2) { dramratio = 0.75; } else { dramratio = 1; } - } else { - switch (mchcfg2) { - case 1: - dramratio = 0.66667; - break; - case 2: - if (idetect != 0x2590) { dramratio = 1; } else { dramratio = 1.5; } - break; - case 3: - // Checking for FSB533 Mode & Alviso - if ((mchcfg & 1) == 0) { dramratio = 1.33334; } - else if (idetect == 0x2590) { dramratio = 2; } - else { dramratio = 1.5; } - } - } - } - // Compute RAM Frequency - fsb = ((extclock / 1000) / coef); - dramclock = fsb * dramratio; - - - print_cpu_line(dramclock, fsb, ddr_type); + double dramclock, dramratio, fsb; + unsigned long mchcfg, mchcfg2, dev0, drc, idetect; + float coef = getP4PMmultiplier(); + long *ptr; + int ddr_type; + + pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); + + /* Find dramratio */ + pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); + dev0 = dev0 & 0xFFFFC000; + ptr=(long*)(dev0+0xC00); + mchcfg = *ptr & 0xFFFF; + ptr=(long*)(dev0+0x120); + drc = *ptr & 0xFFFF; + dramratio = 1; + + mchcfg2 = (mchcfg >> 4)&3; + + if ((drc&3) != 2) { + // We are in DDR1 Mode + if (mchcfg2 == 1) { dramratio = 0.8; } else { dramratio = 1; } + ddr_type = 1; + } else { + // We are in DDR2 Mode + ddr_type = 2; + if ((mchcfg >> 2)&1) { + // We are in FSB1066 Mode + if (mchcfg2 == 2) { dramratio = 0.75; } else { dramratio = 1; } + } else { + switch (mchcfg2) { + case 1: + dramratio = 0.66667; + break; + case 2: + if (idetect != 0x2590) { dramratio = 1; } else { dramratio = 1.5; } + break; + case 3: + // Checking for FSB533 Mode & Alviso + if ((mchcfg & 1) == 0) { dramratio = 1.33334; } + else if (idetect == 0x2590) { dramratio = 2; } + else { dramratio = 1.5; } + } + } + } + // Compute RAM Frequency + fsb = ((extclock / 1000) / coef); + dramclock = fsb * dramratio; + + + print_cpu_line(dramclock, fsb, ddr_type); } static void poll_fsb_i945(void) { - double dramclock, dramratio, fsb; - unsigned long mchcfg, dev0; - float coef = getP4PMmultiplier(); - long *ptr; - - /* Find dramratio */ - pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); - dev0 &= 0xFFFFC000; - ptr=(long*)(dev0+0xC00); - mchcfg = *ptr & 0xFFFF; - dramratio = 1; - - switch ((mchcfg >> 4)&7) { - case 1: dramratio = 1.0; break; - case 2: dramratio = 1.33334; break; - case 3: dramratio = 1.66667; break; - case 4: dramratio = 2.0; break; - } + double dramclock, dramratio, fsb; + unsigned long mchcfg, dev0; + float coef = getP4PMmultiplier(); + long *ptr; - // Compute RAM Frequency - fsb = ((extclock / 1000) / coef); + /* Find dramratio */ + pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); + dev0 &= 0xFFFFC000; + ptr=(long*)(dev0+0xC00); + mchcfg = *ptr & 0xFFFF; + dramratio = 1; - dramclock = fsb * dramratio; + switch ((mchcfg >> 4)&7) { + case 1: dramratio = 1.0; break; + case 2: dramratio = 1.33334; break; + case 3: dramratio = 1.66667; break; + case 4: dramratio = 2.0; break; + } - // Print - print_cpu_line(dramclock, fsb, 2); + // Compute RAM Frequency + fsb = ((extclock / 1000) / coef); -} + dramclock = fsb * dramratio; -static void poll_fsb_i945gme(void) { + // Print + print_cpu_line(dramclock, fsb, 2); - double dramclock, dramratio, fsb; - unsigned long mchcfg, dev0, fsb_mch; - float coef = getP4PMmultiplier(); - long *ptr; - - /* Find dramratio */ - pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); - dev0 &= 0xFFFFC000; - ptr=(long*)(dev0+0xC00); - mchcfg = *ptr & 0xFFFF; - dramratio = 1; - - switch (mchcfg & 7) { - case 0: fsb_mch = 400; break; - default: - case 1: fsb_mch = 533; break; - case 2: fsb_mch = 667; break; - } +} +static void poll_fsb_i945gme(void) { - switch (fsb_mch) { - case 400: - switch ((mchcfg >> 4)&7) { - case 2: dramratio = 1.0f; break; - case 3: dramratio = 4.0f/3.0f; break; - case 4: dramratio = 5.0f/3.0f; break; - } - break; + double dramclock, dramratio, fsb; + unsigned long mchcfg, dev0, fsb_mch; + float coef = getP4PMmultiplier(); + long *ptr; + + /* Find dramratio */ + pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); + dev0 &= 0xFFFFC000; + ptr=(long*)(dev0+0xC00); + mchcfg = *ptr & 0xFFFF; + dramratio = 1; + + switch (mchcfg & 7) { + case 0: fsb_mch = 400; break; + default: + case 1: fsb_mch = 533; break; + case 2: fsb_mch = 667; break; + } + + + switch (fsb_mch) { + case 400: + switch ((mchcfg >> 4)&7) { + case 2: dramratio = 1.0f; break; + case 3: dramratio = 4.0f/3.0f; break; + case 4: dramratio = 5.0f/3.0f; break; + } + break; - default: - case 533: - switch ((mchcfg >> 4)&7) { - case 2: dramratio = 3.0f/4.0f; break; - case 3: dramratio = 1.0f; break; - case 4: dramratio = 5.0f/4.0f; break; - } - break; - - case 667: - switch ((mchcfg >> 4)&7) { - case 2: dramratio = 3.0f/5.0f; break; - case 3: dramratio = 4.0f/5.0f; break; - case 4: dramratio = 1.0f; break; - } - break; - } - - // Compute RAM Frequency - fsb = ((extclock / 1000) / coef); - dramclock = fsb * dramratio * 2; - - print_cpu_line(dramclock, fsb, 2); + default: + case 533: + switch ((mchcfg >> 4)&7) { + case 2: dramratio = 3.0f/4.0f; break; + case 3: dramratio = 1.0f; break; + case 4: dramratio = 5.0f/4.0f; break; + } + break; + + case 667: + switch ((mchcfg >> 4)&7) { + case 2: dramratio = 3.0f/5.0f; break; + case 3: dramratio = 4.0f/5.0f; break; + case 4: dramratio = 1.0f; break; + } + break; + } + + // Compute RAM Frequency + fsb = ((extclock / 1000) / coef); + dramclock = fsb * dramratio * 2; + + print_cpu_line(dramclock, fsb, 2); } static void poll_fsb_i975(void) { - double dramclock, dramratio, fsb; - unsigned long mchcfg, dev0, fsb_mch; - float coef = getP4PMmultiplier(); - long *ptr; - - /* Find dramratio */ - pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); - dev0 &= 0xFFFFC000; - ptr=(long*)(dev0+0xC00); - mchcfg = *ptr & 0xFFFF; - dramratio = 1; - - switch (mchcfg & 7) { - case 1: fsb_mch = 533; break; - case 2: fsb_mch = 800; break; - case 3: fsb_mch = 667; break; - default: fsb_mch = 1066; break; - } - - - switch (fsb_mch) { - case 533: - switch ((mchcfg >> 4)&7) { - case 0: dramratio = 1.25; break; - case 1: dramratio = 1.5; break; - case 2: dramratio = 2.0; break; - } - break; + double dramclock, dramratio, fsb; + unsigned long mchcfg, dev0, fsb_mch; + float coef = getP4PMmultiplier(); + long *ptr; + + /* Find dramratio */ + pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); + dev0 &= 0xFFFFC000; + ptr=(long*)(dev0+0xC00); + mchcfg = *ptr & 0xFFFF; + dramratio = 1; + + switch (mchcfg & 7) { + case 1: fsb_mch = 533; break; + case 2: fsb_mch = 800; break; + case 3: fsb_mch = 667; break; + default: fsb_mch = 1066; break; + } + + + switch (fsb_mch) { + case 533: + switch ((mchcfg >> 4)&7) { + case 0: dramratio = 1.25; break; + case 1: dramratio = 1.5; break; + case 2: dramratio = 2.0; break; + } + break; - default: - case 800: - switch ((mchcfg >> 4)&7) { - case 1: dramratio = 1.0; break; - case 2: dramratio = 1.33334; break; - case 3: dramratio = 1.66667; break; - case 4: dramratio = 2.0; break; - } - break; - - case 1066: - switch ((mchcfg >> 4)&7) { - case 1: dramratio = 0.75; break; - case 2: dramratio = 1.0; break; - case 3: dramratio = 1.25; break; - case 4: dramratio = 1.5; break; - } - break; - } - - // Compute RAM Frequency - fsb = ((extclock / 1000) / coef); - dramclock = fsb * dramratio; - - print_cpu_line(dramclock, fsb, 2); + default: + case 800: + switch ((mchcfg >> 4)&7) { + case 1: dramratio = 1.0; break; + case 2: dramratio = 1.33334; break; + case 3: dramratio = 1.66667; break; + case 4: dramratio = 2.0; break; + } + break; + + case 1066: + switch ((mchcfg >> 4)&7) { + case 1: dramratio = 0.75; break; + case 2: dramratio = 1.0; break; + case 3: dramratio = 1.25; break; + case 4: dramratio = 1.5; break; + } + break; + } + + // Compute RAM Frequency + fsb = ((extclock / 1000) / coef); + dramclock = fsb * dramratio; + + print_cpu_line(dramclock, fsb, 2); } static void poll_fsb_i965(void) { - double dramclock, dramratio, fsb; - unsigned long mchcfg, dev0, fsb_mch; - float coef = getP4PMmultiplier(); - long *ptr; - - /* Find dramratio */ - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - dev0 &= 0xFFFFC000; - ptr=(long*)(dev0+0xC00); - mchcfg = *ptr & 0xFFFF; - dramratio = 1; - - switch (mchcfg & 7) { - case 0: fsb_mch = 1066; break; - case 1: fsb_mch = 533; break; - default: case 2: fsb_mch = 800; break; - case 3: fsb_mch = 667; break; - case 4: fsb_mch = 1333; break; - case 6: fsb_mch = 1600; break; - } - - - switch (fsb_mch) { - case 533: - switch ((mchcfg >> 4)&7) { - case 1: dramratio = 2.0; break; - case 2: dramratio = 2.5; break; - case 3: dramratio = 3.0; break; - } - break; + double dramclock, dramratio, fsb; + unsigned long mchcfg, dev0, fsb_mch; + float coef = getP4PMmultiplier(); + long *ptr; + + /* Find dramratio */ + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + dev0 &= 0xFFFFC000; + ptr=(long*)(dev0+0xC00); + mchcfg = *ptr & 0xFFFF; + dramratio = 1; + + switch (mchcfg & 7) { + case 0: fsb_mch = 1066; break; + case 1: fsb_mch = 533; break; + default: case 2: fsb_mch = 800; break; + case 3: fsb_mch = 667; break; + case 4: fsb_mch = 1333; break; + case 6: fsb_mch = 1600; break; + } + + + switch (fsb_mch) { + case 533: + switch ((mchcfg >> 4)&7) { + case 1: dramratio = 2.0; break; + case 2: dramratio = 2.5; break; + case 3: dramratio = 3.0; break; + } + break; - default: - case 800: - switch ((mchcfg >> 4)&7) { - case 0: dramratio = 1.0; break; - case 1: dramratio = 5.0f/4.0f; break; - case 2: dramratio = 5.0f/3.0f; break; - case 3: dramratio = 2.0f; break; - case 4: dramratio = 8.0f/3.0f; break; - case 5: dramratio = 10.0f/3.0f; break; - } - break; - - case 1066: - switch ((mchcfg >> 4)&7) { - case 1: dramratio = 1.0f; break; - case 2: dramratio = 5.0f/4.0f; break; - case 3: dramratio = 3.0f/2.0f; break; - case 4: dramratio = 2.0f; break; - case 5: dramratio = 5.0f/2.0f; break; - } - break; - - case 1333: - switch ((mchcfg >> 4)&7) { - case 2: dramratio = 1.0f; break; - case 3: dramratio = 6.0f/5.0f; break; - case 4: dramratio = 8.0f/5.0f; break; - case 5: dramratio = 2.0f; break; - } - break; - - case 1600: - switch ((mchcfg >> 4)&7) { - case 3: dramratio = 1.0f; break; - case 4: dramratio = 4.0f/3.0f; break; - case 5: dramratio = 3.0f/2.0f; break; - case 6: dramratio = 2.0f; break; - } - break; - -} - - // Compute RAM Frequency - fsb = ((extclock / 1000) / coef); - dramclock = fsb * dramratio; - - // Print DRAM Freq - print_cpu_line(dramclock, fsb, 2); + default: + case 800: + switch ((mchcfg >> 4)&7) { + case 0: dramratio = 1.0; break; + case 1: dramratio = 5.0f/4.0f; break; + case 2: dramratio = 5.0f/3.0f; break; + case 3: dramratio = 2.0f; break; + case 4: dramratio = 8.0f/3.0f; break; + case 5: dramratio = 10.0f/3.0f; break; + } + break; + + case 1066: + switch ((mchcfg >> 4)&7) { + case 1: dramratio = 1.0f; break; + case 2: dramratio = 5.0f/4.0f; break; + case 3: dramratio = 3.0f/2.0f; break; + case 4: dramratio = 2.0f; break; + case 5: dramratio = 5.0f/2.0f; break; + } + break; + + case 1333: + switch ((mchcfg >> 4)&7) { + case 2: dramratio = 1.0f; break; + case 3: dramratio = 6.0f/5.0f; break; + case 4: dramratio = 8.0f/5.0f; break; + case 5: dramratio = 2.0f; break; + } + break; + + case 1600: + switch ((mchcfg >> 4)&7) { + case 3: dramratio = 1.0f; break; + case 4: dramratio = 4.0f/3.0f; break; + case 5: dramratio = 3.0f/2.0f; break; + case 6: dramratio = 2.0f; break; + } + break; + + } + + // Compute RAM Frequency + fsb = ((extclock / 1000) / coef); + dramclock = fsb * dramratio; + + // Print DRAM Freq + print_cpu_line(dramclock, fsb, 2); } static void poll_fsb_p35(void) { - double dramclock, dramratio, fsb; - unsigned long mchcfg, dev0, fsb_mch, Device_ID, Memory_Check, c0ckectrl, offset; - float coef = getP4PMmultiplier(); - long *ptr; - int ram_type; + double dramclock, dramratio, fsb; + unsigned long mchcfg, dev0, fsb_mch, Device_ID, Memory_Check, c0ckectrl, offset; + float coef = getP4PMmultiplier(); + long *ptr; + int ram_type; - pci_conf_read( 0, 0, 0, 0x02, 2, &Device_ID); - Device_ID &= 0xFFFF; + pci_conf_read( 0, 0, 0, 0x02, 2, &Device_ID); + Device_ID &= 0xFFFF; - /* Find dramratio */ - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - dev0 &= 0xFFFFC000; + /* Find dramratio */ + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + dev0 &= 0xFFFFC000; - ptr = (long*)(dev0+0x260); - c0ckectrl = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+0x260); + c0ckectrl = *ptr & 0xFFFFFFFF; - // If DIMM 0 not populated, check DIMM 1 - ((c0ckectrl) >> 20 & 0xF)?(offset = 0):(offset = 0x400); + // If DIMM 0 not populated, check DIMM 1 + ((c0ckectrl) >> 20 & 0xF)?(offset = 0):(offset = 0x400); - ptr=(long*)(dev0+0xC00); - mchcfg = *ptr & 0xFFFF; - dramratio = 1; + ptr=(long*)(dev0+0xC00); + mchcfg = *ptr & 0xFFFF; + dramratio = 1; - switch (mchcfg & 7) { - case 0: fsb_mch = 1066; break; - case 1: fsb_mch = 533; break; - default: case 2: fsb_mch = 800; break; - case 3: fsb_mch = 667; break; - case 4: fsb_mch = 1333; break; - case 6: fsb_mch = 1600; break; - } + switch (mchcfg & 7) { + case 0: fsb_mch = 1066; break; + case 1: fsb_mch = 533; break; + default: case 2: fsb_mch = 800; break; + case 3: fsb_mch = 667; break; + case 4: fsb_mch = 1333; break; + case 6: fsb_mch = 1600; break; + } - switch (fsb_mch) { - case 533: - switch ((mchcfg >> 4)&7) { - case 1: dramratio = 2.0; break; - case 2: dramratio = 2.5; break; - case 3: dramratio = 3.0; break; - } - break; + switch (fsb_mch) { + case 533: + switch ((mchcfg >> 4)&7) { + case 1: dramratio = 2.0; break; + case 2: dramratio = 2.5; break; + case 3: dramratio = 3.0; break; + } + break; - default: - case 800: - switch ((mchcfg >> 4)&7) { - case 0: dramratio = 1.0; break; - case 1: dramratio = 5.0f/4.0f; break; - case 2: dramratio = 5.0f/3.0f; break; - case 3: dramratio = 2.0; break; - case 4: dramratio = 8.0f/3.0f; break; - case 5: dramratio = 10.0f/3.0f; break; - } - break; - - case 1066: - switch ((mchcfg >> 4)&7) { - case 1: dramratio = 1.0f; break; - case 2: dramratio = 5.0f/4.0f; break; - case 3: dramratio = 3.0f/2.0f; break; - case 4: dramratio = 2.0f; break; - case 5: dramratio = 5.0f/2.0f; break; - } - break; - - case 1333: - switch ((mchcfg >> 4)&7) { - case 2: dramratio = 1.0f; break; - case 3: dramratio = 6.0f/5.0f; break; - case 4: dramratio = 8.0f/5.0f; break; - case 5: dramratio = 2.0f; break; - } - break; - - case 1600: - switch ((mchcfg >> 4)&7) { - case 3: dramratio = 1.0f; break; - case 4: dramratio = 4.0f/3.0f; break; - case 5: dramratio = 3.0f/2.0f; break; - case 6: dramratio = 2.0f; break; - } - break; - - } - - // On P45, check 1A8 - if(Device_ID > 0x2E00 && imc_type != 8) { - ptr = (long*)(dev0+offset+0x1A8); - Memory_Check = *ptr & 0xFFFFFFFF; - Memory_Check >>= 2; - Memory_Check &= 1; - Memory_Check = !Memory_Check; - } else if (imc_type == 8) { - ptr = (long*)(dev0+offset+0x224); - Memory_Check = *ptr & 0xFFFFFFFF; - Memory_Check &= 1; - Memory_Check = !Memory_Check; - } else { - ptr = (long*)(dev0+offset+0x1E8); - Memory_Check = *ptr & 0xFFFFFFFF; - } - - //Determine DDR-II or DDR-III - if (Memory_Check & 1) { - ram_type = 2; - } else { - ram_type = 3; - } - - // Compute RAM Frequency - fsb = ((extclock / 1000) / coef); - dramclock = fsb * dramratio; - - // Print DRAM Freq - print_cpu_line(dramclock, fsb, ram_type); + default: + case 800: + switch ((mchcfg >> 4)&7) { + case 0: dramratio = 1.0; break; + case 1: dramratio = 5.0f/4.0f; break; + case 2: dramratio = 5.0f/3.0f; break; + case 3: dramratio = 2.0; break; + case 4: dramratio = 8.0f/3.0f; break; + case 5: dramratio = 10.0f/3.0f; break; + } + break; + + case 1066: + switch ((mchcfg >> 4)&7) { + case 1: dramratio = 1.0f; break; + case 2: dramratio = 5.0f/4.0f; break; + case 3: dramratio = 3.0f/2.0f; break; + case 4: dramratio = 2.0f; break; + case 5: dramratio = 5.0f/2.0f; break; + } + break; + + case 1333: + switch ((mchcfg >> 4)&7) { + case 2: dramratio = 1.0f; break; + case 3: dramratio = 6.0f/5.0f; break; + case 4: dramratio = 8.0f/5.0f; break; + case 5: dramratio = 2.0f; break; + } + break; + + case 1600: + switch ((mchcfg >> 4)&7) { + case 3: dramratio = 1.0f; break; + case 4: dramratio = 4.0f/3.0f; break; + case 5: dramratio = 3.0f/2.0f; break; + case 6: dramratio = 2.0f; break; + } + break; + + } + + // On P45, check 1A8 + if(Device_ID > 0x2E00 && imc_type != 8) { + ptr = (long*)(dev0+offset+0x1A8); + Memory_Check = *ptr & 0xFFFFFFFF; + Memory_Check >>= 2; + Memory_Check &= 1; + Memory_Check = !Memory_Check; + } else if (imc_type == 8) { + ptr = (long*)(dev0+offset+0x224); + Memory_Check = *ptr & 0xFFFFFFFF; + Memory_Check &= 1; + Memory_Check = !Memory_Check; + } else { + ptr = (long*)(dev0+offset+0x1E8); + Memory_Check = *ptr & 0xFFFFFFFF; + } + + //Determine DDR-II or DDR-III + if (Memory_Check & 1) { + ram_type = 2; + } else { + ram_type = 3; + } + + // Compute RAM Frequency + fsb = ((extclock / 1000) / coef); + dramclock = fsb * dramratio; + + // Print DRAM Freq + print_cpu_line(dramclock, fsb, ram_type); } static void poll_fsb_im965(void) { - double dramclock, dramratio, fsb; - unsigned long mchcfg, dev0, fsb_mch; - float coef = getP4PMmultiplier(); - long *ptr; - - /* Find dramratio */ - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - dev0 &= 0xFFFFC000; - ptr=(long*)(dev0+0xC00); - mchcfg = *ptr & 0xFFFF; - dramratio = 1; - - switch (mchcfg & 7) { - case 1: fsb_mch = 533; break; - default: case 2: fsb_mch = 800; break; - case 3: fsb_mch = 667; break; - case 6: fsb_mch = 1066; break; - } - - - switch (fsb_mch) { - case 533: - switch ((mchcfg >> 4)&7) { - case 1: dramratio = 5.0f/4.0f; break; - case 2: dramratio = 3.0f/2.0f; break; - case 3: dramratio = 2.0f; break; - } - break; - - case 667: - switch ((mchcfg >> 4)&7) { - case 1: dramratio = 1.0f; break; - case 2: dramratio = 6.0f/5.0f; break; - case 3: dramratio = 8.0f/5.0f; break; - case 4: dramratio = 2.0f; break; - case 5: dramratio = 12.0f/5.0f; break; - } - break; - default: - case 800: - switch ((mchcfg >> 4)&7) { - case 1: dramratio = 5.0f/6.0f; break; - case 2: dramratio = 1.0f; break; - case 3: dramratio = 4.0f/3.0f; break; - case 4: dramratio = 5.0f/3.0f; break; - case 5: dramratio = 2.0f; break; - } - break; - case 1066: - switch ((mchcfg >> 4)&7) { - case 5: dramratio = 3.0f/2.0f; break; - case 6: dramratio = 2.0f; break; - } - break; -} - - // Compute RAM Frequency - fsb = ((extclock / 1000) / coef); - dramclock = fsb * dramratio; - - // Print DRAM Freq - print_cpu_line(dramclock, fsb, 2); + double dramclock, dramratio, fsb; + unsigned long mchcfg, dev0, fsb_mch; + float coef = getP4PMmultiplier(); + long *ptr; + + /* Find dramratio */ + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + dev0 &= 0xFFFFC000; + ptr=(long*)(dev0+0xC00); + mchcfg = *ptr & 0xFFFF; + dramratio = 1; + + switch (mchcfg & 7) { + case 1: fsb_mch = 533; break; + default: case 2: fsb_mch = 800; break; + case 3: fsb_mch = 667; break; + case 6: fsb_mch = 1066; break; + } + + + switch (fsb_mch) { + case 533: + switch ((mchcfg >> 4)&7) { + case 1: dramratio = 5.0f/4.0f; break; + case 2: dramratio = 3.0f/2.0f; break; + case 3: dramratio = 2.0f; break; + } + break; + + case 667: + switch ((mchcfg >> 4)&7) { + case 1: dramratio = 1.0f; break; + case 2: dramratio = 6.0f/5.0f; break; + case 3: dramratio = 8.0f/5.0f; break; + case 4: dramratio = 2.0f; break; + case 5: dramratio = 12.0f/5.0f; break; + } + break; + default: + case 800: + switch ((mchcfg >> 4)&7) { + case 1: dramratio = 5.0f/6.0f; break; + case 2: dramratio = 1.0f; break; + case 3: dramratio = 4.0f/3.0f; break; + case 4: dramratio = 5.0f/3.0f; break; + case 5: dramratio = 2.0f; break; + } + break; + case 1066: + switch ((mchcfg >> 4)&7) { + case 5: dramratio = 3.0f/2.0f; break; + case 6: dramratio = 2.0f; break; + } + break; + } + + // Compute RAM Frequency + fsb = ((extclock / 1000) / coef); + dramclock = fsb * dramratio; + + // Print DRAM Freq + print_cpu_line(dramclock, fsb, 2); } static void poll_fsb_5400(void) { - double dramclock, dramratio, fsb; - unsigned long ambase_low, ambase_high, ddrfrq; - float coef = getP4PMmultiplier(); - - /* Find dramratio */ - pci_conf_read( 0, 16, 0, 0x48, 4, &ambase_low); - ambase_low &= 0xFFFE0000; - pci_conf_read( 0, 16, 0, 0x4C, 4, &ambase_high); - ambase_high &= 0xFF; - pci_conf_read( 0, 16, 1, 0x56, 1, &ddrfrq); - ddrfrq &= 7; - dramratio = 1; - - switch (ddrfrq) { - case 0: - case 1: - case 4: - dramratio = 1.0; - break; - case 2: - dramratio = 5.0f/4.0f; - break; - case 3: - case 7: - dramratio = 4.0f/5.0f; - break; - } - - - // Compute RAM Frequency - fsb = ((extclock / 1000) / coef); - dramclock = fsb * dramratio; - - // Print DRAM Freq - print_cpu_line(dramclock, fsb, 2); + double dramclock, dramratio, fsb; + unsigned long ambase_low, ambase_high, ddrfrq; + float coef = getP4PMmultiplier(); + + /* Find dramratio */ + pci_conf_read( 0, 16, 0, 0x48, 4, &ambase_low); + ambase_low &= 0xFFFE0000; + pci_conf_read( 0, 16, 0, 0x4C, 4, &ambase_high); + ambase_high &= 0xFF; + pci_conf_read( 0, 16, 1, 0x56, 1, &ddrfrq); + ddrfrq &= 7; + dramratio = 1; + + switch (ddrfrq) { + case 0: + case 1: + case 4: + dramratio = 1.0; + break; + case 2: + dramratio = 5.0f/4.0f; + break; + case 3: + case 7: + dramratio = 4.0f/5.0f; + break; + } + + + // Compute RAM Frequency + fsb = ((extclock / 1000) / coef); + dramclock = fsb * dramratio; + + // Print DRAM Freq + print_cpu_line(dramclock, fsb, 2); } static void poll_fsb_nf4ie(void) { - double dramclock, dramratio, fsb; - float mratio, nratio; - unsigned long reg74, reg60; - float coef = getP4PMmultiplier(); + double dramclock, dramratio, fsb; + float mratio, nratio; + unsigned long reg74, reg60; + float coef = getP4PMmultiplier(); - /* Find dramratio */ - pci_conf_read(0, 0, 2, 0x74, 2, ®74); - pci_conf_read(0, 0, 2, 0x60, 4, ®60); - mratio = reg74 & 0xF; - nratio = (reg74 >> 4) & 0xF; + /* Find dramratio */ + pci_conf_read(0, 0, 2, 0x74, 2, ®74); + pci_conf_read(0, 0, 2, 0x60, 4, ®60); + mratio = reg74 & 0xF; + nratio = (reg74 >> 4) & 0xF; - // If M or N = 0, then M or N = 16 - if (mratio == 0) { mratio = 16; } - if (nratio == 0) { nratio = 16; } + // If M or N = 0, then M or N = 16 + if (mratio == 0) { mratio = 16; } + if (nratio == 0) { nratio = 16; } - // Check if synchro or pseudo-synchro mode - if((reg60 >> 22) & 1) { - dramratio = 1; - } else { - dramratio = nratio / mratio; - } + // Check if synchro or pseudo-synchro mode + if((reg60 >> 22) & 1) { + dramratio = 1; + } else { + dramratio = nratio / mratio; + } - /* Compute RAM Frequency */ - fsb = ((extclock /1000) / coef); - dramclock = fsb * dramratio; + /* Compute RAM Frequency */ + fsb = ((extclock /1000) / coef); + dramclock = fsb * dramratio; - // Print DRAM Freq - print_cpu_line(dramclock, fsb, 2); + // Print DRAM Freq + print_cpu_line(dramclock, fsb, 2); } static void poll_fsb_i875(void) { - double dramclock, dramratio, fsb; - unsigned long mchcfg, smfs; - float coef = getP4PMmultiplier(); - - /* Find dramratio */ - pci_conf_read(0, 0, 0, 0xC6, 2, &mchcfg); - smfs = (mchcfg >> 10)&3; - dramratio = 1; - - if ((mchcfg&3) == 3) { dramratio = 1; } - if ((mchcfg&3) == 2) { - if (smfs == 2) { dramratio = 1; } - if (smfs == 1) { dramratio = 1.25; } - if (smfs == 0) { dramratio = 1.5; } - } - if ((mchcfg&3) == 1) { - if (smfs == 2) { dramratio = 0.6666666666; } - if (smfs == 1) { dramratio = 0.8; } - if (smfs == 0) { dramratio = 1; } - } - if ((mchcfg&3) == 0) { dramratio = 0.75; } - - - /* Compute RAM Frequency */ - dramclock = ((extclock /1000) / coef) / dramratio; - fsb = ((extclock /1000) / coef); - - /* Print DRAM Freq */ - print_cpu_line(dramclock, fsb, 2); + double dramclock, dramratio, fsb; + unsigned long mchcfg, smfs; + float coef = getP4PMmultiplier(); + + /* Find dramratio */ + pci_conf_read(0, 0, 0, 0xC6, 2, &mchcfg); + smfs = (mchcfg >> 10)&3; + dramratio = 1; + + if ((mchcfg&3) == 3) { dramratio = 1; } + if ((mchcfg&3) == 2) { + if (smfs == 2) { dramratio = 1; } + if (smfs == 1) { dramratio = 1.25; } + if (smfs == 0) { dramratio = 1.5; } + } + if ((mchcfg&3) == 1) { + if (smfs == 2) { dramratio = 0.6666666666; } + if (smfs == 1) { dramratio = 0.8; } + if (smfs == 0) { dramratio = 1; } + } + if ((mchcfg&3) == 0) { dramratio = 0.75; } + + + /* Compute RAM Frequency */ + dramclock = ((extclock /1000) / coef) / dramratio; + fsb = ((extclock /1000) / coef); + + /* Print DRAM Freq */ + print_cpu_line(dramclock, fsb, 2); } static void poll_fsb_p4(void) { - ulong fsb, idetect; - float coef = getP4PMmultiplier(); - char *name; - int col,temp; - - fsb = ((extclock /1000) / coef); - - /* For synchro only chipsets */ - pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); - if (idetect == 0x2540 || idetect == 0x254C) - { - print_cpu_line(fsb, fsb, 1); - } else { - /* Print the controller name */ - col = COL_SPEC; - cprint(LINE_CPU, col, "Chipset: "); - col += 9; - /* Print the controller name */ - name = controllers[ctrl.index].name; - cprint(LINE_CPU, col, name); - /* Now figure out how much I just printed */ - temp = 20; - while(name[temp - 20] != '\0') { - col++; - temp++; - } + ulong fsb, idetect; + float coef = getP4PMmultiplier(); + char *name; + int col,temp; + + fsb = ((extclock /1000) / coef); + + /* For synchro only chipsets */ + pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); + if (idetect == 0x2540 || idetect == 0x254C) + { + print_cpu_line(fsb, fsb, 1); + } else { + /* Print the controller name */ + col = COL_SPEC; + cprint(LINE_CPU, col, "Chipset: "); + col += 9; + /* Print the controller name */ + name = controllers[ctrl.index].name; + cprint(LINE_CPU, col, name); + /* Now figure out how much I just printed */ + temp = 20; + while(name[temp - 20] != '\0') { + col++; + temp++; + } - if(temp < 36){ - cprint(LINE_CPU, col +1, "- FSB : "); - col += 9; - dprint(LINE_CPU, col, fsb, 3,0); - col += 3; - } - - } + if(temp < 36){ + cprint(LINE_CPU, col +1, "- FSB : "); + col += 9; + dprint(LINE_CPU, col, fsb, 3,0); + col += 3; + } + + } } static void poll_fsb_i855(void) { - double dramclock, dramratio, fsb ; - unsigned int msr_lo, msr_hi; - ulong mchcfg, idetect; - int coef; + double dramclock, dramratio, fsb ; + unsigned int msr_lo, msr_hi; + ulong mchcfg, idetect; + int coef; - pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); + pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); - /* Find multiplier (by MSR) */ + /* Find multiplier (by MSR) */ - /* Is it a Pentium M ? */ - if (cpu_id.vers.bits.family == 6) { - rdmsr(0x2A, msr_lo, msr_hi); - coef = (msr_lo >> 22) & 0x1F; - } else { - rdmsr(0x2C, msr_lo, msr_hi); - coef = (msr_lo >> 24) & 0x1F; - } + /* Is it a Pentium M ? */ + if (cpu_id.vers.bits.family == 6) { + rdmsr(0x2A, msr_lo, msr_hi); + coef = (msr_lo >> 22) & 0x1F; + } else { + rdmsr(0x2C, msr_lo, msr_hi); + coef = (msr_lo >> 24) & 0x1F; + } - fsb = ((extclock /1000) / coef); + fsb = ((extclock /1000) / coef); - /* Compute DRAM Clock */ + /* Compute DRAM Clock */ - dramratio = 1; - if (idetect == 0x3580) { - pci_conf_read( 0, 0, 3, 0xC0, 2, &mchcfg); - mchcfg = mchcfg & 0x7; + dramratio = 1; + if (idetect == 0x3580) { + pci_conf_read( 0, 0, 3, 0xC0, 2, &mchcfg); + mchcfg = mchcfg & 0x7; - if (mchcfg == 1 || mchcfg == 2 || mchcfg == 4 || mchcfg == 5) { dramratio = 1; } - if (mchcfg == 0 || mchcfg == 3) { dramratio = 1.333333333; } - if (mchcfg == 6) { dramratio = 1.25; } - if (mchcfg == 7) { dramratio = 1.666666667; } + if (mchcfg == 1 || mchcfg == 2 || mchcfg == 4 || mchcfg == 5) { dramratio = 1; } + if (mchcfg == 0 || mchcfg == 3) { dramratio = 1.333333333; } + if (mchcfg == 6) { dramratio = 1.25; } + if (mchcfg == 7) { dramratio = 1.666666667; } - } else { - pci_conf_read( 0, 0, 0, 0xC6, 2, &mchcfg); - if (((mchcfg >> 10)&3) == 0) { dramratio = 1; } - else if (((mchcfg >> 10)&3) == 1) { dramratio = 1.666667; } - else { dramratio = 1.333333333; } - } + } else { + pci_conf_read( 0, 0, 0, 0xC6, 2, &mchcfg); + if (((mchcfg >> 10)&3) == 0) { dramratio = 1; } + else if (((mchcfg >> 10)&3) == 1) { dramratio = 1.666667; } + else { dramratio = 1.333333333; } + } - dramclock = fsb * dramratio; + dramclock = fsb * dramratio; - /* ...and print */ - print_cpu_line(dramclock, fsb, 1); + /* ...and print */ + print_cpu_line(dramclock, fsb, 1); } static void poll_fsb_amd32(void) { - unsigned int mcgsrl; - unsigned int mcgsth; - unsigned long temp; - double dramclock; - double coef2; - int col; - char *name; - - /* First, got the FID */ - rdmsr(0x0c0010015, mcgsrl, mcgsth); - temp = (mcgsrl >> 24)&0x0F; - - if ((mcgsrl >> 19)&1) { coef2 = athloncoef2[temp]; } - else { coef2 = athloncoef[temp]; } - - if (coef2 == 0) { coef2 = 1; }; - - /* Compute the final FSB Clock */ - dramclock = (extclock /1000) / coef2; - - /* Print the controller name */ - col = COL_SPEC; - cprint(LINE_CPU, col, "Chipset: "); - col += 9; - /* Print the controller name */ - name = controllers[ctrl.index].name; - cprint(LINE_CPU, col, name); - /* Now figure out how much I just printed */ - temp = 20; - while(name[temp - 20] != '\0') { - col++; - temp++; - } - - if(temp < 36){ - cprint(LINE_CPU, col +1, "- FSB : "); - col += 9; - dprint(LINE_CPU, col, dramclock, 3,0); - col += 3; - } + unsigned int mcgsrl; + unsigned int mcgsth; + unsigned long temp; + double dramclock; + double coef2; + int col; + char *name; + + /* First, got the FID */ + rdmsr(0x0c0010015, mcgsrl, mcgsth); + temp = (mcgsrl >> 24)&0x0F; + + if ((mcgsrl >> 19)&1) { coef2 = athloncoef2[temp]; } + else { coef2 = athloncoef[temp]; } + + if (coef2 == 0) { coef2 = 1; }; + + /* Compute the final FSB Clock */ + dramclock = (extclock /1000) / coef2; + + /* Print the controller name */ + col = COL_SPEC; + cprint(LINE_CPU, col, "Chipset: "); + col += 9; + /* Print the controller name */ + name = controllers[ctrl.index].name; + cprint(LINE_CPU, col, name); + /* Now figure out how much I just printed */ + temp = 20; + while(name[temp - 20] != '\0') { + col++; + temp++; + } + + if(temp < 36){ + cprint(LINE_CPU, col +1, "- FSB : "); + col += 9; + dprint(LINE_CPU, col, dramclock, 3,0); + col += 3; + } } static void poll_fsb_nf2(void) { - unsigned int mcgsrl; - unsigned int mcgsth; - unsigned long temp, mempll; - double dramclock, fsb; - double mem_m, mem_n; - float coef; - coef = 10; - - /* First, got the FID */ - rdmsr(0x0c0010015, mcgsrl, mcgsth); - temp = (mcgsrl >> 24)&0x0F; - - if ((mcgsrl >> 19)&1) { coef = athloncoef2[temp]; } - else { coef = athloncoef[temp]; } - - /* Get the coef (COEF = N/M) - Here is for Crush17 */ - pci_conf_read(0, 0, 3, 0x70, 4, &mempll); - mem_m = (mempll&0x0F); - mem_n = ((mempll >> 4) & 0x0F); - - /* If something goes wrong, the chipset is probably a Crush18 */ - if ( mem_m == 0 || mem_n == 0 ) { - pci_conf_read(0, 0, 3, 0x7C, 4, &mempll); - mem_m = (mempll&0x0F); - mem_n = ((mempll >> 4) & 0x0F); - } + unsigned int mcgsrl; + unsigned int mcgsth; + unsigned long temp, mempll; + double dramclock, fsb; + double mem_m, mem_n; + float coef; + coef = 10; - /* Compute the final FSB Clock */ - dramclock = ((extclock /1000) / coef) * (mem_n/mem_m); - fsb = ((extclock /1000) / coef); + /* First, got the FID */ + rdmsr(0x0c0010015, mcgsrl, mcgsth); + temp = (mcgsrl >> 24)&0x0F; - /* ...and print */ - print_cpu_line(dramclock, fsb, 1); + if ((mcgsrl >> 19)&1) { coef = athloncoef2[temp]; } + else { coef = athloncoef[temp]; } -} + /* Get the coef (COEF = N/M) - Here is for Crush17 */ + pci_conf_read(0, 0, 3, 0x70, 4, &mempll); + mem_m = (mempll&0x0F); + mem_n = ((mempll >> 4) & 0x0F); -static void poll_fsb_us15w(void) { + /* If something goes wrong, the chipset is probably a Crush18 */ + if ( mem_m == 0 || mem_n == 0 ) { + pci_conf_read(0, 0, 3, 0x7C, 4, &mempll); + mem_m = (mempll&0x0F); + mem_n = ((mempll >> 4) & 0x0F); + } - double dramclock, dramratio, fsb; - unsigned long msr; + /* Compute the final FSB Clock */ + dramclock = ((extclock /1000) / coef) * (mem_n/mem_m); + fsb = ((extclock /1000) / coef); - /* Find dramratio */ - /* D0 MsgRd, 05 Zunit, 03 MSR */ - pci_conf_write(0, 0, 0, 0xD0, 4, 0xD0050300 ); - pci_conf_read(0, 0, 0, 0xD4, 4, &msr ); - fsb = ( msr >> 3 ) & 1; + /* ...and print */ + print_cpu_line(dramclock, fsb, 1); - dramratio = 0.5; +} - // Compute RAM Frequency - if (( msr >> 3 ) & 1) { - fsb = 533; - } else { - fsb = 400; - } - -/* - switch (( msr >> 0 ) & 7) { - case 0: - gfx = 100; - break; - case 1: - gfx = 133; - break; - case 2: - gfx = 150; - break; - case 3: - gfx = 178; - break; - case 4: - gfx = 200; - break; - case 5: - gfx = 266; - break; - default: - gfx = 0; - break; - } - */ - - dramclock = fsb * dramratio; - - // Print DRAM Freq - print_cpu_line(dramclock, fsb, 1); +static void poll_fsb_us15w(void) { + + double dramclock, dramratio, fsb; + unsigned long msr; + + /* Find dramratio */ + /* D0 MsgRd, 05 Zunit, 03 MSR */ + pci_conf_write(0, 0, 0, 0xD0, 4, 0xD0050300 ); + pci_conf_read(0, 0, 0, 0xD4, 4, &msr ); + fsb = ( msr >> 3 ) & 1; + + dramratio = 0.5; + + // Compute RAM Frequency + if (( msr >> 3 ) & 1) { + fsb = 533; + } else { + fsb = 400; + } + + /* + switch (( msr >> 0 ) & 7) { + case 0: + gfx = 100; + break; + case 1: + gfx = 133; + break; + case 2: + gfx = 150; + break; + case 3: + gfx = 178; + break; + case 4: + gfx = 200; + break; + case 5: + gfx = 266; + break; + default: + gfx = 0; + break; + } + */ + + dramclock = fsb * dramratio; + + // Print DRAM Freq + print_cpu_line(dramclock, fsb, 1); } static void poll_fsb_nhm(void) { - double dramclock, dramratio, fsb; - unsigned long mc_dimm_clk_ratio; - float coef = getNHMmultiplier(); - //unsigned long qpi_pll_status; - //float qpi_speed; - - - fsb = ((extclock /1000) / coef); - - /* Print QPI Speed (if ECC not supported) */ - /* - if(ctrl.mode == ECC_NONE && cpu_id.vers.bits.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 : "); - col += 9; - dprint(LINE_CPU+5, col, qpi_speed/1000, 1,0); - col += 1; - cprint(LINE_CPU+5, col, "."); - col += 1; - qpi_speed = ((qpi_speed / 1000) - (int)(qpi_speed / 1000)) * 10; - dprint(LINE_CPU+5, col, qpi_speed, 1,0); - col += 1; - cprint(LINE_CPU+5, col +1, "GT/s"); - col += 5; - } - */ - - /* Get the clock ratio */ - - pci_conf_read(nhm_bus, 3, 4, 0x54, 2, &mc_dimm_clk_ratio); - dramratio = (mc_dimm_clk_ratio & 0x1F); - - // Compute RAM Frequency - fsb = ((extclock / 1000) / coef); - dramclock = fsb * dramratio / 2; - - // Print DRAM Freq - print_cpu_line(dramclock, fsb, 3); + double dramclock, dramratio, fsb; + unsigned long mc_dimm_clk_ratio; + float coef = getNHMmultiplier(); + //unsigned long qpi_pll_status; + //float qpi_speed; + + + fsb = ((extclock /1000) / coef); + + /* Print QPI Speed (if ECC not supported) */ + /* + if(ctrl.mode == ECC_NONE && cpu_id.vers.bits.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 : "); + col += 9; + dprint(LINE_CPU+5, col, qpi_speed/1000, 1,0); + col += 1; + cprint(LINE_CPU+5, col, "."); + col += 1; + qpi_speed = ((qpi_speed / 1000) - (int)(qpi_speed / 1000)) * 10; + dprint(LINE_CPU+5, col, qpi_speed, 1,0); + col += 1; + cprint(LINE_CPU+5, col +1, "GT/s"); + col += 5; + } + */ + + /* Get the clock ratio */ + + pci_conf_read(nhm_bus, 3, 4, 0x54, 2, &mc_dimm_clk_ratio); + dramratio = (mc_dimm_clk_ratio & 0x1F); + + // Compute RAM Frequency + fsb = ((extclock / 1000) / coef); + dramclock = fsb * dramratio / 2; + + // Print DRAM Freq + print_cpu_line(dramclock, fsb, 3); } static void poll_fsb_nhm32(void) { - double dramclock, dramratio, fsb; - unsigned long mc_dimm_clk_ratio; - float coef = getNHMmultiplier(); - //unsigned long qpi_pll_status; - //float qpi_speed; - - fsb = ((extclock /1000) / coef); - - /* Print QPI Speed (if ECC not supported) */ - /* - if(ctrl.mode == ECC_NONE && cpu_id.vers.bits.model == 12) { - 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 : "); - col += 9; - dprint(LINE_CPU+5, col, qpi_speed/1000, 1,0); - col += 1; - cprint(LINE_CPU+5, col, "."); - col += 1; - qpi_speed = ((qpi_speed / 1000) - (int)(qpi_speed / 1000)) * 10; - dprint(LINE_CPU+5, col, qpi_speed, 1,0); - col += 1; - cprint(LINE_CPU+5, col +1, "GT/s"); - col += 5; - } - */ - - /* Get the clock ratio */ - - pci_conf_read(nhm_bus, 3, 4, 0x50, 2, &mc_dimm_clk_ratio); - dramratio = (mc_dimm_clk_ratio & 0x1F); - - // Compute RAM Frequency - fsb = ((extclock / 1000) / coef); - dramclock = fsb * dramratio / 2; - - // Print DRAM Freq - print_cpu_line(dramclock, fsb, 3); + double dramclock, dramratio, fsb; + unsigned long mc_dimm_clk_ratio; + float coef = getNHMmultiplier(); + //unsigned long qpi_pll_status; + //float qpi_speed; + + fsb = ((extclock /1000) / coef); + + /* Print QPI Speed (if ECC not supported) */ + /* + if(ctrl.mode == ECC_NONE && cpu_id.vers.bits.model == 12) { + 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 : "); + col += 9; + dprint(LINE_CPU+5, col, qpi_speed/1000, 1,0); + col += 1; + cprint(LINE_CPU+5, col, "."); + col += 1; + qpi_speed = ((qpi_speed / 1000) - (int)(qpi_speed / 1000)) * 10; + dprint(LINE_CPU+5, col, qpi_speed, 1,0); + col += 1; + cprint(LINE_CPU+5, col +1, "GT/s"); + col += 5; + } + */ + + /* Get the clock ratio */ + + pci_conf_read(nhm_bus, 3, 4, 0x50, 2, &mc_dimm_clk_ratio); + dramratio = (mc_dimm_clk_ratio & 0x1F); + + // Compute RAM Frequency + fsb = ((extclock / 1000) / coef); + dramclock = fsb * dramratio / 2; + + // Print DRAM Freq + print_cpu_line(dramclock, fsb, 3); } static void poll_fsb_wmr(void) { - double dramclock, dramratio, fsb; - unsigned long dev0; - float coef = getNHMmultiplier(); - long *ptr; + double dramclock, dramratio, fsb; + unsigned long dev0; + float coef = getNHMmultiplier(); + long *ptr; - fsb = ((extclock / 1000) / coef); + fsb = ((extclock / 1000) / coef); - /* Find dramratio */ - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - dev0 &= 0xFFFFC000; - ptr=(long*)(dev0+0x2C20); - dramratio = 1; + /* Find dramratio */ + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + dev0 &= 0xFFFFC000; + ptr=(long*)(dev0+0x2C20); + dramratio = 1; - /* Get the clock ratio */ - dramratio = 0.25 * (float)(*ptr & 0x1F); + /* Get the clock ratio */ + dramratio = 0.25 * (float)(*ptr & 0x1F); - // Compute RAM Frequency - dramclock = fsb * dramratio; + // Compute RAM Frequency + dramclock = fsb * dramratio; - // Print DRAM Freq - print_cpu_line(dramclock, fsb, 3); + // Print DRAM Freq + print_cpu_line(dramclock, fsb, 3); } static void poll_fsb_snb(void) { - double dramclock, dramratio, fsb; - unsigned long dev0; - float coef = getSNBmultiplier(); - long *ptr; + double dramclock, dramratio, fsb; + unsigned long dev0; + float coef = getSNBmultiplier(); + long *ptr; - fsb = ((extclock / 1000) / coef); + fsb = ((extclock / 1000) / coef); - /* Find dramratio */ - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - dev0 &= 0xFFFFC000; - ptr=(long*)(dev0+0x5E04); - dramratio = 1; + /* Find dramratio */ + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + dev0 &= 0xFFFFC000; + ptr=(long*)(dev0+0x5E04); + dramratio = 1; - /* Get the clock ratio */ - dramratio = (float)(*ptr & 0x1F) * (133.34f / 100.0f); + /* Get the clock ratio */ + dramratio = (float)(*ptr & 0x1F) * (133.34f / 100.0f); - // Compute RAM Frequency - dramclock = fsb * dramratio; + // Compute RAM Frequency + dramclock = fsb * dramratio; - // Print DRAM Freq - print_cpu_line(dramclock, fsb, 3); + // Print DRAM Freq + print_cpu_line(dramclock, fsb, 3); } static void poll_fsb_ivb(void) { - double dramclock, dramratio, fsb; - unsigned long dev0, mchcfg; - float coef = getSNBmultiplier(); - long *ptr; - - fsb = ((extclock / 1000) / coef); - - /* Find dramratio */ - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - dev0 &= 0xFFFFC000; - ptr=(long*)(dev0+0x5E04); - mchcfg = *ptr & 0xFFFF; - dramratio = 1; - - /* Get the clock ratio */ - switch((mchcfg >> 8) & 0x01) - { - case 0x0: - dramratio = (float)(*ptr & 0x1F) * (133.34f / 100.0f); - break; - case 0x1: - dramratio = (float)(*ptr & 0x1F) * (100.0f / 100.0f); - break; - } - - // Compute RAM Frequency - dramclock = fsb * dramratio; - - // Print DRAM Freq - print_cpu_line(dramclock, fsb, 3); + double dramclock, dramratio, fsb; + unsigned long dev0, mchcfg; + float coef = getSNBmultiplier(); + long *ptr; + + fsb = ((extclock / 1000) / coef); + + /* Find dramratio */ + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + dev0 &= 0xFFFFC000; + ptr=(long*)(dev0+0x5E04); + mchcfg = *ptr & 0xFFFF; + dramratio = 1; + + /* Get the clock ratio */ + switch((mchcfg >> 8) & 0x01) + { + case 0x0: + dramratio = (float)(*ptr & 0x1F) * (133.34f / 100.0f); + break; + case 0x1: + dramratio = (float)(*ptr & 0x1F) * (100.0f / 100.0f); + break; + } + + // Compute RAM Frequency + dramclock = fsb * dramratio; + + // Print DRAM Freq + print_cpu_line(dramclock, fsb, 3); } static void poll_fsb_snbe(void) { - double dramclock, dramratio, fsb; - unsigned long dev0; - float coef = getSNBmultiplier(); + double dramclock, dramratio, fsb; + unsigned long dev0; + float coef = getSNBmultiplier(); - fsb = ((extclock / 1000) / coef); + fsb = ((extclock / 1000) / coef); - /* Find dramratio */ - pci_conf_read( 0xFF, 10, 1, 0x98, 4, &dev0); - dev0 &= 0xFFFFFFFF; - dramratio = 1; + /* Find dramratio */ + pci_conf_read( 0xFF, 10, 1, 0x98, 4, &dev0); + dev0 &= 0xFFFFFFFF; + dramratio = 1; - /* Get the clock ratio */ - dramratio = (float)(dev0 & 0x3F) * (66.67f / 100.0f); + /* Get the clock ratio */ + dramratio = (float)(dev0 & 0x3F) * (66.67f / 100.0f); - // Compute RAM Frequency - dramclock = fsb * dramratio; + // Compute RAM Frequency + dramclock = fsb * dramratio; - // Print DRAM Freq - print_cpu_line(dramclock, fsb, 3); + // Print DRAM Freq + print_cpu_line(dramclock, fsb, 3); @@ -2826,1036 +2828,1036 @@ static void poll_fsb_snbe(void) { static void poll_timings_nf4ie(void) { - ulong regd0, reg8c, reg9c, reg80; - int cas, rcd, rp, ras, chan; + ulong regd0, reg8c, reg9c, reg80; + int cas, rcd, rp, ras, chan; - //Now, read Registers - pci_conf_read( 0, 1, 1, 0xD0, 4, ®d0); - pci_conf_read( 0, 1, 1, 0x80, 1, ®80); - pci_conf_read( 0, 1, 0, 0x8C, 4, ®8c); - pci_conf_read( 0, 1, 0, 0x9C, 4, ®9c); + //Now, read Registers + pci_conf_read( 0, 1, 1, 0xD0, 4, ®d0); + pci_conf_read( 0, 1, 1, 0x80, 1, ®80); + pci_conf_read( 0, 1, 0, 0x8C, 4, ®8c); + pci_conf_read( 0, 1, 0, 0x9C, 4, ®9c); - // Then, detect timings - cas = (regd0 >> 4) & 0x7; - rcd = (reg8c >> 24) & 0xF; - rp = (reg9c >> 8) & 0xF; - ras = (reg8c >> 16) & 0x3F; + // Then, detect timings + cas = (regd0 >> 4) & 0x7; + rcd = (reg8c >> 24) & 0xF; + rp = (reg9c >> 8) & 0xF; + ras = (reg8c >> 16) & 0x3F; - if (reg80 & 0x3) { - chan = 2; - } else { - chan = 1; - } - print_ram_line(cas, rcd, rp, ras, chan); + if (reg80 & 0x3) { + chan = 2; + } else { + chan = 1; + } + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_i875(void) { - ulong dev6, dev62; - ulong temp; - float cas; - int rcd, rp, ras, chan; - long *ptr, *ptr2; - - pci_conf_read( 0, 6, 0, 0x40, 4, &dev62); - ptr2=(long*)(dev6+0x68); - - /* Read the MMR Base Address & Define the pointer */ - pci_conf_read( 0, 6, 0, 0x10, 4, &dev6); - - /* Now, we could check some additionnals timings infos) */ - ptr=(long*)(dev6+0x60); - // CAS Latency (tCAS) - temp = ((*ptr >> 5)& 0x3); - if (temp == 0x0) { cas = 2.5; } else if (temp == 0x1) { cas = 2; } else { cas = 3; } - - // RAS-To-CAS (tRCD) - temp = ((*ptr >> 2)& 0x3); - if (temp == 0x0) { rcd = 4; } else if (temp == 0x1) { rcd = 3; } else { rcd = 2; } - - // RAS Precharge (tRP) - temp = (*ptr&0x3); - if (temp == 0x0) { rp = 4; } else if (temp == 0x1) { rp = 3; } else { rp = 2; } - - // RAS Active to precharge (tRAS) - temp = ((*ptr >> 7)& 0x7); - ras = 10 - temp; - - // Print 64 or 128 bits mode - if (((*ptr2 >> 21)&3) > 0) { - chan = 2; - } else { - chan = 1; - } - print_ram_line(cas, rcd, rp, ras, chan); + ulong dev6, dev62; + ulong temp; + float cas; + int rcd, rp, ras, chan; + long *ptr, *ptr2; + + pci_conf_read( 0, 6, 0, 0x40, 4, &dev62); + ptr2=(long*)(dev6+0x68); + + /* Read the MMR Base Address & Define the pointer */ + pci_conf_read( 0, 6, 0, 0x10, 4, &dev6); + + /* Now, we could check some additionnals timings infos) */ + ptr=(long*)(dev6+0x60); + // CAS Latency (tCAS) + temp = ((*ptr >> 5)& 0x3); + if (temp == 0x0) { cas = 2.5; } else if (temp == 0x1) { cas = 2; } else { cas = 3; } + + // RAS-To-CAS (tRCD) + temp = ((*ptr >> 2)& 0x3); + if (temp == 0x0) { rcd = 4; } else if (temp == 0x1) { rcd = 3; } else { rcd = 2; } + + // RAS Precharge (tRP) + temp = (*ptr&0x3); + if (temp == 0x0) { rp = 4; } else if (temp == 0x1) { rp = 3; } else { rp = 2; } + + // RAS Active to precharge (tRAS) + temp = ((*ptr >> 7)& 0x7); + ras = 10 - temp; + + // Print 64 or 128 bits mode + if (((*ptr2 >> 21)&3) > 0) { + chan = 2; + } else { + chan = 1; + } + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_i925(void) { - // Thanks for CDH optis - float cas; - int rcd,rp,ras,chan; - ulong dev0, drt, drc, dcc, idetect, temp; - long *ptr; - - //Now, read MMR Base Address - pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); - pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); - dev0 &= 0xFFFFC000; - - //Set pointer for DRT - ptr=(long*)(dev0+0x114); - drt = *ptr & 0xFFFFFFFF; - - //Set pointer for DRC - ptr=(long*)(dev0+0x120); - drc = *ptr & 0xFFFFFFFF; - - //Set pointer for DCC - ptr=(long*)(dev0+0x200); - dcc = *ptr & 0xFFFFFFFF; - - // CAS Latency (tCAS) - temp = ((drt >> 8)& 0x3); - - if ((drc & 3) == 2){ - // Timings DDR-II - if (temp == 0x0) { cas = 5; } - else if (temp == 0x1) { cas = 4; } - else if (temp == 0x2) { cas = 3; } - else { cas = 6; } - } else { - // Timings DDR-I - if (temp == 0x0) { cas = 3; } - else if (temp == 0x1) { cas = 2.5f;} - else { cas = 2; } - } - - // RAS-To-CAS (tRCD) - rcd = ((drt >> 4)& 0x3)+2; - - // RAS Precharge (tRP) - rp = (drt&0x3)+2; - - // RAS Active to precharge (tRAS) - // If Lakeport, than change tRAS computation (Thanks to CDH, again) - if (idetect > 0x2700) - ras = ((drt >> 19)& 0x1F); - else - ras = ((drt >> 20)& 0x0F); - - - temp = (dcc&0x3); - if (temp == 1) { chan = 2; } - else if (temp == 2) { chan = 2; } - else { chan = 1; } + // Thanks for CDH optis + float cas; + int rcd,rp,ras,chan; + ulong dev0, drt, drc, dcc, idetect, temp; + long *ptr; + + //Now, read MMR Base Address + pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); + pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); + dev0 &= 0xFFFFC000; + + //Set pointer for DRT + ptr=(long*)(dev0+0x114); + drt = *ptr & 0xFFFFFFFF; + + //Set pointer for DRC + ptr=(long*)(dev0+0x120); + drc = *ptr & 0xFFFFFFFF; + + //Set pointer for DCC + ptr=(long*)(dev0+0x200); + dcc = *ptr & 0xFFFFFFFF; + + // CAS Latency (tCAS) + temp = ((drt >> 8)& 0x3); + + if ((drc & 3) == 2){ + // Timings DDR-II + if (temp == 0x0) { cas = 5; } + else if (temp == 0x1) { cas = 4; } + else if (temp == 0x2) { cas = 3; } + else { cas = 6; } + } else { + // Timings DDR-I + if (temp == 0x0) { cas = 3; } + else if (temp == 0x1) { cas = 2.5f;} + else { cas = 2; } + } + + // RAS-To-CAS (tRCD) + rcd = ((drt >> 4)& 0x3)+2; + + // RAS Precharge (tRP) + rp = (drt&0x3)+2; + + // RAS Active to precharge (tRAS) + // If Lakeport, than change tRAS computation (Thanks to CDH, again) + if (idetect > 0x2700) + ras = ((drt >> 19)& 0x1F); + else + ras = ((drt >> 20)& 0x0F); + + + temp = (dcc&0x3); + if (temp == 1) { chan = 2; } + else if (temp == 2) { chan = 2; } + else { chan = 1; } - print_ram_line(cas, rcd, rp, ras, chan); + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_i965(void) { - // Thanks for CDH optis - ulong dev0, c0ckectrl, c1ckectrl, offset; - ulong ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register; - long *ptr; - int rcd,rp,ras,chan; - float cas; + // Thanks for CDH optis + ulong dev0, c0ckectrl, c1ckectrl, offset; + ulong ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register; + long *ptr; + int rcd,rp,ras,chan; + float cas; - //Now, read MMR Base Address - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - dev0 &= 0xFFFFC000; + //Now, read MMR Base Address + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + dev0 &= 0xFFFFC000; - ptr = (long*)(dev0+0x260); - c0ckectrl = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+0x260); + c0ckectrl = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+0x660); - c1ckectrl = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+0x660); + c1ckectrl = *ptr & 0xFFFFFFFF; - // If DIMM 0 not populated, check DIMM 1 - ((c0ckectrl) >> 20 & 0xF)?(offset = 0):(offset = 0x400); + // If DIMM 0 not populated, check DIMM 1 + ((c0ckectrl) >> 20 & 0xF)?(offset = 0):(offset = 0x400); - ptr = (long*)(dev0+offset+0x29C); - ODT_Control_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x29C); + ODT_Control_Register = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+offset+0x250); - Precharge_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x250); + Precharge_Register = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+offset+0x252); - ACT_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x252); + ACT_Register = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+offset+0x258); - Read_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x258); + Read_Register = *ptr & 0xFFFFFFFF; - // CAS Latency (tCAS) - cas = ((ODT_Control_Register >> 17)& 7) + 3.0f; + // CAS Latency (tCAS) + cas = ((ODT_Control_Register >> 17)& 7) + 3.0f; - // RAS-To-CAS (tRCD) - rcd = (Read_Register >> 16) & 0xF; + // RAS-To-CAS (tRCD) + rcd = (Read_Register >> 16) & 0xF; - // RAS Precharge (tRP) - rp = (ACT_Register >> 13) & 0xF; + // RAS Precharge (tRP) + rp = (ACT_Register >> 13) & 0xF; - // RAS Active to precharge (tRAS) - ras = (Precharge_Register >> 11) & 0x1F; + // RAS Active to precharge (tRAS) + ras = (Precharge_Register >> 11) & 0x1F; - if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) { - chan = 2; - } else { - chan = 1; - } + if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) { + chan = 2; + } else { + chan = 1; + } - print_ram_line(cas, rcd, rp, ras, chan); + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_im965(void) { - // Thanks for CDH optis - ulong dev0, c0ckectrl, c1ckectrl, offset; - ulong ODT_Control_Register, Precharge_Register; - long *ptr; - int rcd,rp,ras,chan; - float cas; + // Thanks for CDH optis + ulong dev0, c0ckectrl, c1ckectrl, offset; + ulong ODT_Control_Register, Precharge_Register; + long *ptr; + int rcd,rp,ras,chan; + float cas; - //Now, read MMR Base Address - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - dev0 &= 0xFFFFC000; + //Now, read MMR Base Address + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + dev0 &= 0xFFFFC000; - ptr = (long*)(dev0+0x1200); - c0ckectrl = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+0x1200); + c0ckectrl = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+0x1300); - c1ckectrl = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+0x1300); + c1ckectrl = *ptr & 0xFFFFFFFF; - // If DIMM 0 not populated, check DIMM 1 - ((c0ckectrl) >> 20 & 0xF)?(offset = 0):(offset = 0x100); + // If DIMM 0 not populated, check DIMM 1 + ((c0ckectrl) >> 20 & 0xF)?(offset = 0):(offset = 0x100); - ptr = (long*)(dev0+offset+0x121C); - ODT_Control_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x121C); + ODT_Control_Register = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+offset+0x1214); - Precharge_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x1214); + Precharge_Register = *ptr & 0xFFFFFFFF; - // CAS Latency (tCAS) - cas = ((ODT_Control_Register >> 23)& 7) + 3.0f; + // CAS Latency (tCAS) + cas = ((ODT_Control_Register >> 23)& 7) + 3.0f; - // RAS-To-CAS (tRCD) - rcd = ((Precharge_Register >> 5)& 7) + 2.0f; + // RAS-To-CAS (tRCD) + rcd = ((Precharge_Register >> 5)& 7) + 2.0f; - // RAS Precharge (tRP) - rp = (Precharge_Register & 7) + 2.0f; + // RAS Precharge (tRP) + rp = (Precharge_Register & 7) + 2.0f; - // RAS Active to precharge (tRAS) - ras = (Precharge_Register >> 21) & 0x1F; + // RAS Active to precharge (tRAS) + ras = (Precharge_Register >> 21) & 0x1F; - if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) { - chan = 2; - } else { - chan = 1; - } - print_ram_line(cas, rcd, rp, ras, chan); + if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) { + chan = 2; + } else { + chan = 1; + } + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_p35(void) { - // Thanks for CDH optis - float cas; - int rcd, rp, ras, chan; - ulong dev0, Device_ID, c0ckectrl, c1ckectrl, offset; - ulong ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register; - long *ptr; + // Thanks for CDH optis + float cas; + int rcd, rp, ras, chan; + ulong dev0, Device_ID, c0ckectrl, c1ckectrl, offset; + ulong ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register; + long *ptr; - pci_conf_read( 0, 0, 0, 0x02, 2, &Device_ID); - Device_ID &= 0xFFFF; + pci_conf_read( 0, 0, 0, 0x02, 2, &Device_ID); + Device_ID &= 0xFFFF; - //Now, read MMR Base Address - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - dev0 &= 0xFFFFC000; + //Now, read MMR Base Address + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + dev0 &= 0xFFFFC000; - ptr = (long*)(dev0+0x260); - c0ckectrl = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+0x260); + c0ckectrl = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+0x660); - c1ckectrl = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+0x660); + c1ckectrl = *ptr & 0xFFFFFFFF; - // If DIMM 0 not populated, check DIMM 1 - ((c0ckectrl) >> 20 & 0xF)?(offset = 0):(offset = 0x400); + // If DIMM 0 not populated, check DIMM 1 + ((c0ckectrl) >> 20 & 0xF)?(offset = 0):(offset = 0x400); - ptr = (long*)(dev0+offset+0x265); - ODT_Control_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x265); + ODT_Control_Register = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+offset+0x25D); - Precharge_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x25D); + Precharge_Register = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+offset+0x252); - ACT_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x252); + ACT_Register = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+offset+0x258); - Read_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x258); + Read_Register = *ptr & 0xFFFFFFFF; - // CAS Latency (tCAS) - if(Device_ID > 0x2E00 && imc_type != 8) { - cas = ((ODT_Control_Register >> 8)& 0x3F) - 6.0f; - } else { - cas = ((ODT_Control_Register >> 8)& 0x3F) - 9.0f; - } + // CAS Latency (tCAS) + if(Device_ID > 0x2E00 && imc_type != 8) { + cas = ((ODT_Control_Register >> 8)& 0x3F) - 6.0f; + } else { + cas = ((ODT_Control_Register >> 8)& 0x3F) - 9.0f; + } - // RAS-To-CAS (tRCD) - rcd = (Read_Register >> 17) & 0xF; + // RAS-To-CAS (tRCD) + rcd = (Read_Register >> 17) & 0xF; - // RAS Precharge (tRP) - rp = (ACT_Register >> 13) & 0xF; + // RAS Precharge (tRP) + rp = (ACT_Register >> 13) & 0xF; - // RAS Active to precharge (tRAS) - ras = Precharge_Register & 0x3F; + // RAS Active to precharge (tRAS) + ras = Precharge_Register & 0x3F; - if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) { - chan = 2; - } else { - chan = 1; - } - print_ram_line(cas, rcd, rp, ras, chan); + if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) { + chan = 2; + } else { + chan = 1; + } + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_wmr(void) { - float cas; - int rcd, rp, ras, chan; - ulong dev0, c0ckectrl, c1ckectrl, offset; - ulong ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register, MRC_Register; - long *ptr; + float cas; + int rcd, rp, ras, chan; + ulong dev0, c0ckectrl, c1ckectrl, offset; + ulong ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register, MRC_Register; + long *ptr; - //Now, read MMR Base Address - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - dev0 &= 0xFFFFC000; + //Now, read MMR Base Address + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + dev0 &= 0xFFFFC000; - ptr = (long*)(dev0+0x260); - c0ckectrl = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+0x260); + c0ckectrl = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+0x660); - c1ckectrl = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+0x660); + c1ckectrl = *ptr & 0xFFFFFFFF; - // If DIMM 0 not populated, check DIMM 1 - ((c0ckectrl) >> 20 & 0xF)?(offset = 0):(offset = 0x400); + // If DIMM 0 not populated, check DIMM 1 + ((c0ckectrl) >> 20 & 0xF)?(offset = 0):(offset = 0x400); - ptr = (long*)(dev0+offset+0x265); - ODT_Control_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x265); + ODT_Control_Register = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+offset+0x25D); - Precharge_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x25D); + Precharge_Register = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+offset+0x252); - ACT_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x252); + ACT_Register = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+offset+0x258); - Read_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x258); + Read_Register = *ptr & 0xFFFFFFFF; - ptr = (long*)(dev0+offset+0x240); - MRC_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x240); + MRC_Register = *ptr & 0xFFFFFFFF; - // CAS Latency (tCAS) - if(MRC_Register & 0xF) { - cas = (MRC_Register & 0xF) + 3.0f; - } else { - cas = ((ODT_Control_Register >> 8)& 0x3F) - 5.0f; - } + // CAS Latency (tCAS) + if(MRC_Register & 0xF) { + cas = (MRC_Register & 0xF) + 3.0f; + } else { + cas = ((ODT_Control_Register >> 8)& 0x3F) - 5.0f; + } - // RAS-To-CAS (tRCD) - rcd = (Read_Register >> 17) & 0xF; + // RAS-To-CAS (tRCD) + rcd = (Read_Register >> 17) & 0xF; - // RAS Precharge (tRP) - rp = (ACT_Register >> 13) & 0xF; + // RAS Precharge (tRP) + rp = (ACT_Register >> 13) & 0xF; - // RAS Active to precharge (tRAS) - ras = Precharge_Register & 0x3F; + // RAS Active to precharge (tRAS) + ras = Precharge_Register & 0x3F; - if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) { - chan = 2; - } else { - chan = 1; - } + if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) { + chan = 2; + } else { + chan = 1; + } - print_ram_line(cas, rcd, rp, ras, chan); + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_snb(void) { - float cas; - int rcd, rp, ras, chan; - ulong dev0, offset; - ulong IMC_Register, MCMain0_Register, MCMain1_Register; - long *ptr; + float cas; + int rcd, rp, ras, chan; + ulong dev0, offset; + ulong IMC_Register, MCMain0_Register, MCMain1_Register; + long *ptr; - //Now, read MMR Base Address - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - dev0 &= 0xFFFFC000; + //Now, read MMR Base Address + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + dev0 &= 0xFFFFC000; - offset = 0x0000; + offset = 0x0000; - ptr = (long*)(dev0+offset+0x4000); - IMC_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x4000); + IMC_Register = *ptr & 0xFFFFFFFF; - // CAS Latency (tCAS) - cas = (float)((IMC_Register >> 8) & 0x0F); + // CAS Latency (tCAS) + cas = (float)((IMC_Register >> 8) & 0x0F); - // RAS-To-CAS (tRCD) - rcd = IMC_Register & 0x0F; + // RAS-To-CAS (tRCD) + rcd = IMC_Register & 0x0F; - // RAS Precharge (tRP) - rp = (IMC_Register >> 4) & 0x0F; + // RAS Precharge (tRP) + rp = (IMC_Register >> 4) & 0x0F; - // RAS Active to precharge (tRAS) - ras = (IMC_Register >> 16) & 0xFF; + // RAS Active to precharge (tRAS) + ras = (IMC_Register >> 16) & 0xFF; - // Channels - ptr = (long*)(dev0+offset+0x5004); - MCMain0_Register = *ptr & 0xFFFF; - ptr = (long*)(dev0+offset+0x5008); - MCMain1_Register = *ptr & 0xFFFF; + // Channels + ptr = (long*)(dev0+offset+0x5004); + MCMain0_Register = *ptr & 0xFFFF; + ptr = (long*)(dev0+offset+0x5008); + MCMain1_Register = *ptr & 0xFFFF; - if(MCMain0_Register == 0 || MCMain1_Register == 0) { - chan = 1; - } else { - chan = 2; - } + if(MCMain0_Register == 0 || MCMain1_Register == 0) { + chan = 1; + } else { + chan = 2; + } - print_ram_line(cas, rcd, rp, ras, chan); + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_hsw(void) { - float cas; - int rcd, rp, ras, chan; - ulong dev0, offset = 0; - ulong IMC_Register, MCMain0_Register, MCMain1_Register; - long *ptr; + float cas; + int rcd, rp, ras, chan; + ulong dev0, offset = 0; + ulong IMC_Register, MCMain0_Register, MCMain1_Register; + long *ptr; - //Now, read MMR Base Address - pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); - dev0 &= 0xFFFFC000; + //Now, read MMR Base Address + pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); + dev0 &= 0xFFFFC000; - // Channels - ptr = (long*)(dev0+offset+0x5004); - MCMain0_Register = *ptr & 0xFFFF; + // Channels + ptr = (long*)(dev0+offset+0x5004); + MCMain0_Register = *ptr & 0xFFFF; - ptr = (long*)(dev0+offset+0x5008); - MCMain1_Register = *ptr & 0xFFFF; + ptr = (long*)(dev0+offset+0x5008); + MCMain1_Register = *ptr & 0xFFFF; - if(MCMain0_Register && MCMain1_Register) { - chan = 2; - } else { - chan = 1; - } + if(MCMain0_Register && MCMain1_Register) { + chan = 2; + } else { + chan = 1; + } - if(MCMain0_Register) { offset = 0x0000; } else { offset = 0x0400; } + if(MCMain0_Register) { offset = 0x0000; } else { offset = 0x0400; } - // CAS Latency (tCAS) - ptr = (long*)(dev0+offset+0x4014); - IMC_Register = *ptr & 0xFFFFFFFF; - cas = (float)(IMC_Register & 0x1F); + // CAS Latency (tCAS) + ptr = (long*)(dev0+offset+0x4014); + IMC_Register = *ptr & 0xFFFFFFFF; + cas = (float)(IMC_Register & 0x1F); - ptr = (long*)(dev0+offset+0x4000); - IMC_Register = *ptr & 0xFFFFFFFF; + ptr = (long*)(dev0+offset+0x4000); + IMC_Register = *ptr & 0xFFFFFFFF; - // RAS-To-CAS (tRCD) - rcd = IMC_Register & 0x1F; + // RAS-To-CAS (tRCD) + rcd = IMC_Register & 0x1F; - // RAS Precharge (tRP) - rp = (IMC_Register >> 5) & 0x1F; + // RAS Precharge (tRP) + rp = (IMC_Register >> 5) & 0x1F; - // RAS Active to precharge (tRAS) - ras = (IMC_Register >> 10) & 0x3F; + // RAS Active to precharge (tRAS) + ras = (IMC_Register >> 10) & 0x3F; - print_ram_line(cas, rcd, rp, ras, chan); + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_snbe(void) { - float cas; - int rcd, rp, ras; - int nb_channel = 0, current_channel = 0; - ulong temp, IMC_Register; - long *ptr; + float cas; + int rcd, rp, ras; + int nb_channel = 0, current_channel = 0; + ulong temp, IMC_Register; + long *ptr; - //Read Channel #1 - pci_conf_read(0xFF, 16, 2, 0x80, 4, &temp); - temp &= 0x3F; - if(temp != 0xB) { current_channel = 0; nb_channel++; } + //Read Channel #1 + pci_conf_read(0xFF, 16, 2, 0x80, 4, &temp); + temp &= 0x3F; + if(temp != 0xB) { current_channel = 0; nb_channel++; } - //Read Channel #2 - pci_conf_read(0xFF, 16, 3, 0x80, 4, &temp); - temp &= 0x3F; - if(temp != 0xB) { current_channel = 1; nb_channel++; } + //Read Channel #2 + pci_conf_read(0xFF, 16, 3, 0x80, 4, &temp); + temp &= 0x3F; + if(temp != 0xB) { current_channel = 1; nb_channel++; } - //Read Channel #3 - pci_conf_read(0xFF, 16, 6, 0x80, 4, &temp); - temp &= 0x3F; - if(temp != 0xB) { current_channel = 4; nb_channel++; } + //Read Channel #3 + pci_conf_read(0xFF, 16, 6, 0x80, 4, &temp); + temp &= 0x3F; + if(temp != 0xB) { current_channel = 4; nb_channel++; } - //Read Channel #4 - pci_conf_read(0xFF, 16, 7, 0x80, 4, &temp); - temp &= 0x3F; - if(temp != 0xB) { current_channel = 5; nb_channel++; } + //Read Channel #4 + pci_conf_read(0xFF, 16, 7, 0x80, 4, &temp); + temp &= 0x3F; + if(temp != 0xB) { current_channel = 5; nb_channel++; } - pci_conf_read(0, 5, 0, 0x84, 4, &temp); - ptr = (long*)((temp & 0xFC000000) + (MAKE_PCIE_ADDRESS(0xFF,16,current_channel) | 0x200)); - IMC_Register = *ptr & 0xFFFFFFFF; + pci_conf_read(0, 5, 0, 0x84, 4, &temp); + ptr = (long*)((temp & 0xFC000000) + (MAKE_PCIE_ADDRESS(0xFF,16,current_channel) | 0x200)); + IMC_Register = *ptr & 0xFFFFFFFF; - // CAS Latency (tCAS) - cas = (float)((IMC_Register >> 9) & 0x1F); + // CAS Latency (tCAS) + cas = (float)((IMC_Register >> 9) & 0x1F); - // RAS-To-CAS (tRCD) - rcd = IMC_Register & 0x1F; + // RAS-To-CAS (tRCD) + rcd = IMC_Register & 0x1F; - // RAS Precharge (tRP) - rp = (IMC_Register >> 5) & 0x0F; + // RAS Precharge (tRP) + rp = (IMC_Register >> 5) & 0x0F; - // RAS Active to precharge (tRAS) - ras = (IMC_Register >> 19) & 0x3F; + // RAS Active to precharge (tRAS) + ras = (IMC_Register >> 19) & 0x3F; - print_ram_line(cas, rcd, rp, ras, nb_channel); + print_ram_line(cas, rcd, rp, ras, nb_channel); } static void poll_timings_5400(void) { - // Thanks for CDH optis - ulong ambase, mtr1, mtr2, offset, mca; - long *ptr; - float cas; - int rcd, rp, ras, chan; - - //Hard-coded Ambase value (should not be realocated by software when using Memtest86+ - ambase = 0xFE000000; - offset = mtr1 = mtr2 = 0; - - // Will loop until a valid populated channel is found - // Bug : DIMM 0 must be populated or it will fall in an endless loop - while(((mtr2 & 0xF) < 3) || ((mtr2 & 0xF) > 6)) { - ptr = (long*)(ambase+0x378+offset); - mtr1 = *ptr & 0xFFFFFFFF; - - ptr = (long*)(ambase+0x37C+offset); - mtr2 = *ptr & 0xFFFFFFFF; - offset += 0x8000; - } + // Thanks for CDH optis + ulong ambase, mtr1, mtr2, offset, mca; + long *ptr; + float cas; + int rcd, rp, ras, chan; + + //Hard-coded Ambase value (should not be realocated by software when using Memtest86+ + ambase = 0xFE000000; + offset = mtr1 = mtr2 = 0; - pci_conf_read( 0, 16, 1, 0x58, 4, &mca); + // Will loop until a valid populated channel is found + // Bug : DIMM 0 must be populated or it will fall in an endless loop + while(((mtr2 & 0xF) < 3) || ((mtr2 & 0xF) > 6)) { + ptr = (long*)(ambase+0x378+offset); + mtr1 = *ptr & 0xFFFFFFFF; + + ptr = (long*)(ambase+0x37C+offset); + mtr2 = *ptr & 0xFFFFFFFF; + offset += 0x8000; + } - //This chipset only supports FB-DIMM (Removed => too long) - //cprint(LINE_CPU+5, col +1, "- Type : FBD"); + pci_conf_read( 0, 16, 1, 0x58, 4, &mca); - // Now, detect timings + //This chipset only supports FB-DIMM (Removed => too long) + //cprint(LINE_CPU+5, col +1, "- Type : FBD"); - // CAS Latency (tCAS) - cas = mtr2 & 0xF; + // Now, detect timings - // RAS-To-CAS (tRCD) - rcd = 6 - ((mtr1 >> 10) & 3); + // CAS Latency (tCAS) + cas = mtr2 & 0xF; - // RAS Precharge (tRP) - rp = 6 - ((mtr1 >> 8) & 3); + // RAS-To-CAS (tRCD) + rcd = 6 - ((mtr1 >> 10) & 3); - // RAS Active to precharge (tRAS) - ras = 16 - (3 * ((mtr1 >> 29) & 3)) + ((mtr1 >> 12) & 3); - if(((mtr1 >> 12) & 3) == 3 && ((mtr1 >> 29) & 3) == 2) { ras = 9; } + // RAS Precharge (tRP) + rp = 6 - ((mtr1 >> 8) & 3); + // RAS Active to precharge (tRAS) + ras = 16 - (3 * ((mtr1 >> 29) & 3)) + ((mtr1 >> 12) & 3); + if(((mtr1 >> 12) & 3) == 3 && ((mtr1 >> 29) & 3) == 2) { ras = 9; } - if ((mca >> 14) & 1) { - chan = 1; - } else { - chan = 2; - } - print_ram_line(cas, rcd, rp, ras, chan); + if ((mca >> 14) & 1) { + chan = 1; + } else { + chan = 2; + } + + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_E7520(void) { - ulong drt, ddrcsr; - float cas; - int rcd, rp, ras, chan; + ulong drt, ddrcsr; + float cas; + int rcd, rp, ras, chan; - pci_conf_read( 0, 0, 0, 0x78, 4, &drt); - pci_conf_read( 0, 0, 0, 0x9A, 2, &ddrcsr); + pci_conf_read( 0, 0, 0, 0x78, 4, &drt); + pci_conf_read( 0, 0, 0, 0x9A, 2, &ddrcsr); - cas = ((drt >> 2) & 3) + 2; - rcd = ((drt >> 10) & 1) + 3; - rp = ((drt >> 9) & 1) + 3; - ras = ((drt >> 14) & 3) + 11; + cas = ((drt >> 2) & 3) + 2; + rcd = ((drt >> 10) & 1) + 3; + rp = ((drt >> 9) & 1) + 3; + ras = ((drt >> 14) & 3) + 11; - if ((ddrcsr & 0xF) >= 0xC) { - chan = 2; - } else { - chan = 1; - } + if ((ddrcsr & 0xF) >= 0xC) { + chan = 2; + } else { + chan = 1; + } - print_ram_line(cas, rcd, rp, ras, chan); + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_i855(void) { - ulong drt, temp; - float cas; - int rcd, rp, ras; + ulong drt, temp; + float cas; + int rcd, rp, ras; - pci_conf_read( 0, 0, 0, 0x78, 4, &drt); + pci_conf_read( 0, 0, 0, 0x78, 4, &drt); - /* Now, we could print some additionnals timings infos) */ - cprint(LINE_CPU+6, col2 +1, "/ CAS : "); - col2 += 9; + /* Now, we could print some additionnals timings infos) */ + cprint(LINE_CPU+6, col2 +1, "/ CAS : "); + col2 += 9; - // CAS Latency (tCAS) - temp = ((drt >> 4)&0x1); - if (temp == 0x0) { cas = 2.5; } - else { cas = 2; } + // CAS Latency (tCAS) + temp = ((drt >> 4)&0x1); + if (temp == 0x0) { cas = 2.5; } + else { cas = 2; } - // RAS-To-CAS (tRCD) - temp = ((drt >> 2)& 0x1); - if (temp == 0x0) { rcd = 3; } - else { rcd = 2; } + // RAS-To-CAS (tRCD) + temp = ((drt >> 2)& 0x1); + if (temp == 0x0) { rcd = 3; } + else { rcd = 2; } - // RAS Precharge (tRP) - temp = (drt&0x1); - if (temp == 0x0) { rp = 3 ; } - else { rp = 2; } + // RAS Precharge (tRP) + temp = (drt&0x1); + if (temp == 0x0) { rp = 3 ; } + else { rp = 2; } - // RAS Active to precharge (tRAS) - temp = 7-((drt >> 9)& 0x3); - if (temp == 0x0) { ras = 7; } - if (temp == 0x1) { ras = 6; } - if (temp == 0x2) { ras = 5; } + // RAS Active to precharge (tRAS) + temp = 7-((drt >> 9)& 0x3); + if (temp == 0x0) { ras = 7; } + if (temp == 0x1) { ras = 6; } + if (temp == 0x2) { ras = 5; } - print_ram_line(cas, rcd, rp, ras, 1); + print_ram_line(cas, rcd, rp, ras, 1); } static void poll_timings_E750x(void) { - ulong drt, drc, temp; - float cas; - int rcd, rp, ras, chan; + ulong drt, drc, temp; + float cas; + int rcd, rp, ras, chan; - pci_conf_read( 0, 0, 0, 0x78, 4, &drt); - pci_conf_read( 0, 0, 0, 0x7C, 4, &drc); + pci_conf_read( 0, 0, 0, 0x78, 4, &drt); + pci_conf_read( 0, 0, 0, 0x7C, 4, &drc); - if ((drt >> 4) & 1) { cas = 2; } else { cas = 2.5; }; - if ((drt >> 1) & 1) { rcd = 2; } else { rcd = 3; }; - if (drt & 1) { rp = 2; } else { rp = 3; }; + if ((drt >> 4) & 1) { cas = 2; } else { cas = 2.5; }; + if ((drt >> 1) & 1) { rcd = 2; } else { rcd = 3; }; + if (drt & 1) { rp = 2; } else { rp = 3; }; - temp = ((drt >> 9) & 3); - if (temp == 2) { ras = 5; } else if (temp == 1) { ras = 6; } else { ras = 7; } + temp = ((drt >> 9) & 3); + if (temp == 2) { ras = 5; } else if (temp == 1) { ras = 6; } else { ras = 7; } - if (((drc >> 22)&1) == 1) { - chan = 2; - } else { - chan = 1; - } + if (((drc >> 22)&1) == 1) { + chan = 2; + } else { + chan = 1; + } - print_ram_line(cas, rcd, rp, ras, chan); + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_i852(void) { - ulong drt, temp; - float cas; - int rcd, rp, ras; + ulong drt, temp; + float cas; + int rcd, rp, ras; - pci_conf_read( 0, 0, 1, 0x60, 4, &drt); + pci_conf_read( 0, 0, 1, 0x60, 4, &drt); - /* Now, we could print some additionnals timings infos) */ - cprint(LINE_CPU+6, col2 +1, "/ CAS : "); - col2 += 9; + /* Now, we could print some additionnals timings infos) */ + cprint(LINE_CPU+6, col2 +1, "/ CAS : "); + col2 += 9; - // CAS Latency (tCAS) - temp = ((drt >> 5)&0x1); - if (temp == 0x0) { cas = 2.5; } - else { cas = 2; } + // CAS Latency (tCAS) + temp = ((drt >> 5)&0x1); + if (temp == 0x0) { cas = 2.5; } + else { cas = 2; } - // RAS-To-CAS (tRCD) - temp = ((drt >> 2)& 0x3); - if (temp == 0x0) { rcd = 4; } - if (temp == 0x1) { rcd = 3; } - else { rcd = 2; } + // RAS-To-CAS (tRCD) + temp = ((drt >> 2)& 0x3); + if (temp == 0x0) { rcd = 4; } + if (temp == 0x1) { rcd = 3; } + else { rcd = 2; } - // RAS Precharge (tRP) - temp = (drt&0x3); - if (temp == 0x0) { rp = 4; } - if (temp == 0x1) { rp = 3; } - else { rp = 2; } + // RAS Precharge (tRP) + temp = (drt&0x3); + if (temp == 0x0) { rp = 4; } + if (temp == 0x1) { rp = 3; } + else { rp = 2; } - // RAS Active to precharge (tRAS) - temp = ((drt >> 9)& 0x3); - if (temp == 0x0) { ras = 8; } - if (temp == 0x1) { ras = 7; } - if (temp == 0x2) { ras = 6; } - if (temp == 0x3) { ras = 5; } + // RAS Active to precharge (tRAS) + temp = ((drt >> 9)& 0x3); + if (temp == 0x0) { ras = 8; } + if (temp == 0x1) { ras = 7; } + if (temp == 0x2) { ras = 6; } + if (temp == 0x3) { ras = 5; } - print_ram_line(cas, rcd, rp, ras, 1); + print_ram_line(cas, rcd, rp, ras, 1); } static void poll_timings_amd64(void) { - ulong dramtlr, dramclr; - int temp, chan; - float tcas; - int trcd, trp, tras ; + ulong dramtlr, dramclr; + int temp, chan; + float tcas; + int trcd, trp, tras ; - pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr); - pci_conf_read(0, 24, 2, 0x90, 4, &dramclr); + pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr); + pci_conf_read(0, 24, 2, 0x90, 4, &dramclr); - if (cpu_id.vers.bits.extendedModel >= 4) { - /* NEW K8 0Fh Family 90 nm (DDR2) */ + if (cpu_id.vers.bits.extendedModel >= 4) { + /* NEW K8 0Fh Family 90 nm (DDR2) */ - // CAS Latency (tCAS) - tcas = (dramtlr & 0x7) + 1; + // CAS Latency (tCAS) + tcas = (dramtlr & 0x7) + 1; - // RAS-To-CAS (tRCD) - trcd = ((dramtlr >> 4) & 0x3) + 3; + // RAS-To-CAS (tRCD) + trcd = ((dramtlr >> 4) & 0x3) + 3; - // RAS Precharge (tRP) - trp = ((dramtlr >> 8) & 0x3) + 3; + // RAS Precharge (tRP) + trp = ((dramtlr >> 8) & 0x3) + 3; - // RAS Active to precharge (tRAS) - tras = ((dramtlr >> 12) & 0xF) + 3; + // RAS Active to precharge (tRAS) + tras = ((dramtlr >> 12) & 0xF) + 3; - // Print 64 or 128 bits mode - if ((dramclr >> 11)&1) { - chan = 2; - } else { - chan = 1; - } - - } else { - /* OLD K8 (DDR1) */ - - // CAS Latency (tCAS) - temp = (dramtlr & 0x7); - if (temp == 0x1) { tcas = 2; } - if (temp == 0x2) { tcas = 3; } - if (temp == 0x5) { tcas = 2.5; } + // Print 64 or 128 bits mode + if ((dramclr >> 11)&1) { + chan = 2; + } else { + chan = 1; + } + + } else { + /* OLD K8 (DDR1) */ + + // CAS Latency (tCAS) + temp = (dramtlr & 0x7); + if (temp == 0x1) { tcas = 2; } + if (temp == 0x2) { tcas = 3; } + if (temp == 0x5) { tcas = 2.5; } - // RAS-To-CAS (tRCD) - trcd = ((dramtlr >> 12) & 0x7); + // RAS-To-CAS (tRCD) + trcd = ((dramtlr >> 12) & 0x7); - // RAS Precharge (tRP) - trp = ((dramtlr >> 24) & 0x7); + // RAS Precharge (tRP) + trp = ((dramtlr >> 24) & 0x7); - // RAS Active to precharge (tRAS) - tras = ((dramtlr >> 20) & 0xF); + // RAS Active to precharge (tRAS) + tras = ((dramtlr >> 20) & 0xF); - // Print 64 or 128 bits mode - if (((dramclr >> 16)&1) == 1) { - chan = 2; - } else { - chan = 1; - } - } + // Print 64 or 128 bits mode + if (((dramclr >> 16)&1) == 1) { + chan = 2; + } else { + chan = 1; + } + } - print_ram_line(tcas, trcd, trp, tras, chan); + print_ram_line(tcas, trcd, trp, tras, chan); } static void poll_timings_k10(void) { - ulong dramtlr, dramclr, dramchr, dramchrb; - ulong offset = 0; - int cas, rcd, rp, ras, chan; - - pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); - pci_conf_read(0, 24, 2, 0x194, 4, &dramchrb); - - if(((dramchr>>14) & 0x1) || ((dramchr>>14) & 0x1)) { chan = 1; } else { chan = 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); - } - - 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; - } else { + ulong dramtlr, dramclr, dramchr, dramchrb; + ulong offset = 0; + int cas, rcd, rp, ras, chan; + + pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); + pci_conf_read(0, 24, 2, 0x194, 4, &dramchrb); + + if(((dramchr>>14) & 0x1) || ((dramchr>>14) & 0x1)) { chan = 1; } else { chan = 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); + } + + 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; + } else { // DDR2-800 or less - cas = (dramtlr & 0xF) + 1; - rcd = ((dramtlr >> 4) & 0x3) + 3; - rp = ((dramtlr >> 8) & 0x3) + 3; - ras = ((dramtlr >> 12) & 0xF) + 3; - } + cas = (dramtlr & 0xF) + 1; + rcd = ((dramtlr >> 4) & 0x3) + 3; + rp = ((dramtlr >> 8) & 0x3) + 3; + ras = ((dramtlr >> 12) & 0xF) + 3; + } - print_ram_line(cas, rcd, rp, ras, chan); + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_k12(void) { - ulong dramt0, dramlow, dimma, dimmb; - int cas, rcd, rp, ras, chan = 0; - - pci_conf_read(0, 24, 2, 0x94, 4, &dimma); - pci_conf_read(0, 24, 2, 0x194, 4, &dimmb); - - if(((dimma >> 14) & 0x1) == 0) - { - chan++; - pci_conf_read(0, 24, 2, 0x88, 4, &dramlow); - pci_conf_write(0, 24, 2, 0xF0, 4, 0x00000040); - pci_conf_read(0, 24, 2, 0xF4, 4, &dramt0); - } - - if(((dimmb >> 14) & 0x1) == 0) - { - chan++; - pci_conf_read(0, 24, 2, 0x188, 4, &dramlow); - pci_conf_write(0, 24, 2, 0x1F0, 4, 0x00000040); - pci_conf_read(0, 24, 2, 0x1F4, 4, &dramt0); - } - - cas = (dramlow & 0xF) + 4; - rcd = (dramt0 & 0xF) + 5; - rp = ((dramt0 >> 8) & 0xF) + 5; - ras = ((dramt0 >> 16) & 0x1F) + 15; - - print_ram_line(cas, rcd, rp, ras, chan); + ulong dramt0, dramlow, dimma, dimmb; + int cas, rcd, rp, ras, chan = 0; + + pci_conf_read(0, 24, 2, 0x94, 4, &dimma); + pci_conf_read(0, 24, 2, 0x194, 4, &dimmb); + + if(((dimma >> 14) & 0x1) == 0) + { + chan++; + pci_conf_read(0, 24, 2, 0x88, 4, &dramlow); + pci_conf_write(0, 24, 2, 0xF0, 4, 0x00000040); + pci_conf_read(0, 24, 2, 0xF4, 4, &dramt0); + } + + if(((dimmb >> 14) & 0x1) == 0) + { + chan++; + pci_conf_read(0, 24, 2, 0x188, 4, &dramlow); + pci_conf_write(0, 24, 2, 0x1F0, 4, 0x00000040); + pci_conf_read(0, 24, 2, 0x1F4, 4, &dramt0); + } + + cas = (dramlow & 0xF) + 4; + rcd = (dramt0 & 0xF) + 5; + rp = ((dramt0 >> 8) & 0xF) + 5; + ras = ((dramt0 >> 16) & 0x1F) + 15; + + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_k14(void) { - ulong dramt0, dramlow; - int cas, rcd, rp, ras; + ulong dramt0, dramlow; + int cas, rcd, rp, ras; - pci_conf_read(0, 24, 2, 0x88, 4, &dramlow); - pci_conf_write(0, 24, 2, 0xF0, 4, 0x00000040); - pci_conf_read(0, 24, 2, 0xF4, 4, &dramt0); + pci_conf_read(0, 24, 2, 0x88, 4, &dramlow); + pci_conf_write(0, 24, 2, 0xF0, 4, 0x00000040); + pci_conf_read(0, 24, 2, 0xF4, 4, &dramt0); - cas = (dramlow & 0xF) + 4; - rcd = (dramt0 & 0xF) + 5; - rp = ((dramt0 >> 8) & 0xF) + 5; - ras = ((dramt0 >> 16) & 0x1F) + 15; + cas = (dramlow & 0xF) + 4; + rcd = (dramt0 & 0xF) + 5; + rp = ((dramt0 >> 8) & 0xF) + 5; + ras = ((dramt0 >> 16) & 0x1F) + 15; - print_ram_line(cas, rcd, rp, ras, 1); + print_ram_line(cas, rcd, rp, ras, 1); } static void poll_timings_k15(void) { - ulong dramp1, dramp2, dimma, dimmb; - int cas, rcd, rp, ras, chan = 0; + ulong dramp1, dramp2, dimma, dimmb; + int cas, rcd, rp, ras, chan = 0; - pci_conf_read(0, 24, 2, 0x94, 4, &dimma); - pci_conf_read(0, 24, 2, 0x194, 4, &dimmb); - if(((dimma>>14) & 0x1) || ((dimmb>>14) & 0x1)) { chan = 1; } else { chan = 2; } + pci_conf_read(0, 24, 2, 0x94, 4, &dimma); + pci_conf_read(0, 24, 2, 0x194, 4, &dimmb); + if(((dimma>>14) & 0x1) || ((dimmb>>14) & 0x1)) { chan = 1; } else { chan = 2; } - pci_conf_read(0, 24, 2, 0x200, 4, &dramp1); - pci_conf_read(0, 24, 2, 0x204, 4, &dramp2); + pci_conf_read(0, 24, 2, 0x200, 4, &dramp1); + pci_conf_read(0, 24, 2, 0x204, 4, &dramp2); - cas = dramp1 & 0x1F; - rcd = (dramp1 >> 8) & 0x1F; - rp = (dramp1 >> 16) & 0x1F; - ras = (dramp1 >> 24) & 0x3F; + cas = dramp1 & 0x1F; + rcd = (dramp1 >> 8) & 0x1F; + rp = (dramp1 >> 16) & 0x1F; + ras = (dramp1 >> 24) & 0x3F; - print_ram_line(cas, rcd, rp, ras, chan); + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_k16(void) { - ulong dramt0, dramt1; - int cas, rcd, rp, rc, ras; + ulong dramt0, dramt1; + int cas, rcd, rp, /*rc,*/ ras; - pci_conf_read(0, 24, 2, 0x200, 4, &dramt0); - pci_conf_read(0, 24, 2, 0x204, 4, &dramt1); + pci_conf_read(0, 24, 2, 0x200, 4, &dramt0); + pci_conf_read(0, 24, 2, 0x204, 4, &dramt1); - cas = (dramt0 & 0x1F); - rcd = ((dramt0 >> 8) & 0x1F); - rp = ((dramt0 >> 16) & 0x1F); - ras = ((dramt0 >> 24) & 0x3F); - - rc = (dramt1 & 0x3F); - - print_ram_line(cas, rcd, rp, ras, 1); + cas = (dramt0 & 0x1F); + rcd = ((dramt0 >> 8) & 0x1F); + rp = ((dramt0 >> 16) & 0x1F); + ras = ((dramt0 >> 24) & 0x3F); + + // rc = (dramt1 & 0x3F); + + print_ram_line(cas, rcd, rp, ras, 1); } static void poll_timings_EP80579(void) { - ulong drt1, drt2; - float cas; - int rcd, rp, ras; + ulong drt1, drt2; + float cas; + int rcd, rp, ras; - pci_conf_read( 0, 0, 0, 0x78, 4, &drt1); - pci_conf_read( 0, 0, 0, 0x64, 4, &drt2); + pci_conf_read( 0, 0, 0, 0x78, 4, &drt1); + pci_conf_read( 0, 0, 0, 0x64, 4, &drt2); - cas = ((drt1 >> 3) & 0x7) + 3; - rcd = ((drt1 >> 9) & 0x7) + 3; - rp = ((drt1 >> 6) & 0x7) + 3; - ras = ((drt2 >> 28) & 0xF) + 8; + cas = ((drt1 >> 3) & 0x7) + 3; + rcd = ((drt1 >> 9) & 0x7) + 3; + rp = ((drt1 >> 6) & 0x7) + 3; + ras = ((drt2 >> 28) & 0xF) + 8; - print_ram_line(cas, rcd, rp, ras, 0); + print_ram_line(cas, rcd, rp, ras, 0); } static void poll_timings_nf2(void) { - ulong dramtlr, dramtlr2, dramtlr3, temp; - ulong dimm1p, dimm2p, dimm3p; - float cas; - int rcd, rp, ras, chan; - - pci_conf_read(0, 0, 1, 0x90, 4, &dramtlr); - pci_conf_read(0, 0, 1, 0xA0, 4, &dramtlr2); - pci_conf_read(0, 0, 1, 0x84, 4, &dramtlr3); - pci_conf_read(0, 0, 2, 0x40, 4, &dimm1p); - pci_conf_read(0, 0, 2, 0x44, 4, &dimm2p); - pci_conf_read(0, 0, 2, 0x48, 4, &dimm3p); - - // CAS Latency (tCAS) - temp = ((dramtlr2 >> 4) & 0x7); - if (temp == 0x2) { cas = 2; } - if (temp == 0x3) { cas = 3; } - if (temp == 0x6) { cas = 2.5; } + ulong dramtlr, dramtlr2, dramtlr3, temp; + ulong dimm1p, dimm2p, dimm3p; + float cas; + int rcd, rp, ras, chan; + + pci_conf_read(0, 0, 1, 0x90, 4, &dramtlr); + pci_conf_read(0, 0, 1, 0xA0, 4, &dramtlr2); + pci_conf_read(0, 0, 1, 0x84, 4, &dramtlr3); + pci_conf_read(0, 0, 2, 0x40, 4, &dimm1p); + pci_conf_read(0, 0, 2, 0x44, 4, &dimm2p); + pci_conf_read(0, 0, 2, 0x48, 4, &dimm3p); + + // CAS Latency (tCAS) + temp = ((dramtlr2 >> 4) & 0x7); + if (temp == 0x2) { cas = 2; } + if (temp == 0x3) { cas = 3; } + if (temp == 0x6) { cas = 2.5; } - // RAS-To-CAS (tRCD) - rcd = ((dramtlr >> 20) & 0xF); + // RAS-To-CAS (tRCD) + rcd = ((dramtlr >> 20) & 0xF); - // RAS Precharge (tRP) - rp = ((dramtlr >> 28) & 0xF); + // RAS Precharge (tRP) + rp = ((dramtlr >> 28) & 0xF); - // RAS Active to precharge (tRAS) - ras = ((dramtlr >> 15) & 0xF); + // RAS Active to precharge (tRAS) + ras = ((dramtlr >> 15) & 0xF); - // Print 64 or 128 bits mode - // If DIMM1 & DIMM3 or DIMM1 & DIMM2 populated, than Dual Channel. + // Print 64 or 128 bits mode + // If DIMM1 & DIMM3 or DIMM1 & DIMM2 populated, than Dual Channel. - if ((dimm3p&1) + (dimm2p&1) == 2 || (dimm3p&1) + (dimm1p&1) == 2 ) { - chan = 2; - } else { - chan = 1; - } - print_ram_line(cas, rcd, rp, ras, chan); + if ((dimm3p&1) + (dimm2p&1) == 2 || (dimm3p&1) + (dimm1p&1) == 2 ) { + chan = 2; + } else { + chan = 1; + } + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_us15w(void) { - // Thanks for CDH optis - ulong dtr; - float cas; - int rcd, rp; + // Thanks for CDH optis + ulong dtr; + float cas; + int rcd, rp; - /* Find dramratio */ - /* D0 MsgRd, 01 Dunit, 01 DTR */ - pci_conf_write(0, 0, 0, 0xD0, 4, 0xD0010100 ); - pci_conf_read(0, 0, 0, 0xD4, 4, &dtr ); + /* Find dramratio */ + /* D0 MsgRd, 01 Dunit, 01 DTR */ + pci_conf_write(0, 0, 0, 0xD0, 4, 0xD0010100 ); + pci_conf_read(0, 0, 0, 0xD4, 4, &dtr ); - // CAS Latency (tCAS) - cas = ((dtr >> 4) & 0x3) + 3; + // CAS Latency (tCAS) + cas = ((dtr >> 4) & 0x3) + 3; - // RAS-To-CAS (tRCD) - rcd = ((dtr >> 2) & 0x3) + 3; + // RAS-To-CAS (tRCD) + rcd = ((dtr >> 2) & 0x3) + 3; - // RAS Precharge (tRP) - rp = ((dtr >> 0) & 0x3) + 3; + // RAS Precharge (tRP) + rp = ((dtr >> 0) & 0x3) + 3; - print_ram_line(cas, rcd, rp, 9, 1); + print_ram_line(cas, rcd, rp, 9, 1); } static void poll_timings_nhm(void) { - ulong mc_channel_bank_timing, mc_control, mc_channel_mrs_value; - float cas; - int rcd, rp, ras, chan; - int fvc_bn = 4; - - /* Find which channels are populated */ - pci_conf_read(nhm_bus, 3, 0, 0x48, 2, &mc_control); - mc_control = (mc_control >> 8) & 0x7; - - /* Get the first valid channel */ - if(mc_control & 1) { - fvc_bn = 4; - } else if(mc_control & 2) { - fvc_bn = 5; - } else if(mc_control & 4) { - fvc_bn = 6; - } - - // Now, detect timings - // CAS Latency (tCAS) / RAS-To-CAS (tRCD) / RAS Precharge (tRP) / RAS Active to precharge (tRAS) - pci_conf_read(nhm_bus, fvc_bn, 0, 0x88, 4, &mc_channel_bank_timing); - pci_conf_read(nhm_bus, fvc_bn, 0, 0x70, 4, &mc_channel_mrs_value); - cas = ((mc_channel_mrs_value >> 4) & 0xF ) + 4.0f; - rcd = (mc_channel_bank_timing >> 9) & 0xF; - ras = (mc_channel_bank_timing >> 4) & 0x1F; - rp = mc_channel_bank_timing & 0xF; - - // Print 1, 2 or 3 Channels - if (mc_control == 1 || mc_control == 2 || mc_control == 4 ) { - chan = 1; - } else if (mc_control == 7) { - chan = 3; - } else { - chan = 2; - } - print_ram_line(cas, rcd, rp, ras, chan); + ulong mc_channel_bank_timing, mc_control, mc_channel_mrs_value; + float cas; + int rcd, rp, ras, chan; + int fvc_bn = 4; + + /* Find which channels are populated */ + pci_conf_read(nhm_bus, 3, 0, 0x48, 2, &mc_control); + mc_control = (mc_control >> 8) & 0x7; + + /* Get the first valid channel */ + if(mc_control & 1) { + fvc_bn = 4; + } else if(mc_control & 2) { + fvc_bn = 5; + } else if(mc_control & 4) { + fvc_bn = 6; + } + + // Now, detect timings + // CAS Latency (tCAS) / RAS-To-CAS (tRCD) / RAS Precharge (tRP) / RAS Active to precharge (tRAS) + pci_conf_read(nhm_bus, fvc_bn, 0, 0x88, 4, &mc_channel_bank_timing); + pci_conf_read(nhm_bus, fvc_bn, 0, 0x70, 4, &mc_channel_mrs_value); + cas = ((mc_channel_mrs_value >> 4) & 0xF ) + 4.0f; + rcd = (mc_channel_bank_timing >> 9) & 0xF; + ras = (mc_channel_bank_timing >> 4) & 0x1F; + rp = mc_channel_bank_timing & 0xF; + + // Print 1, 2 or 3 Channels + if (mc_control == 1 || mc_control == 2 || mc_control == 4 ) { + chan = 1; + } else if (mc_control == 7) { + chan = 3; + } else { + chan = 2; + } + print_ram_line(cas, rcd, rp, ras, chan); } static void poll_timings_ct(void) { - unsigned long mcr,mdr; - float cas; - int rcd, rp, ras; + unsigned long mcr,mdr; + float cas; + int rcd, rp, ras; - /* Build the MCR Message*/ - mcr = (0x10 << 24); // 10h = Read - 11h = Write - mcr += (0x01 << 16); // DRAM Registers located on port 01h - mcr += (0x01 << 8); // DRP = 00h, DTR0 = 01h, DTR1 = 02h, DTR2 = 03h - mcr &= 0xFFFFFFF0; // bit 03:00 RSVD + /* Build the MCR Message*/ + mcr = (0x10 << 24); // 10h = Read - 11h = Write + mcr += (0x01 << 16); // DRAM Registers located on port 01h + mcr += (0x01 << 8); // DRP = 00h, DTR0 = 01h, DTR1 = 02h, DTR2 = 03h + mcr &= 0xFFFFFFF0; // bit 03:00 RSVD - /* Send Message to GMCH */ - pci_conf_write(0, 0, 0, 0xD0, 4, mcr); + /* Send Message to GMCH */ + pci_conf_write(0, 0, 0, 0xD0, 4, mcr); - /* Read Answer from Sideband bus */ - pci_conf_read(0, 0, 0, 0xD4, 4, &mdr); + /* Read Answer from Sideband bus */ + pci_conf_read(0, 0, 0, 0xD4, 4, &mdr); - // CAS Latency (tCAS) - cas = ((mdr >> 12)& 0x7) + 5.0f; + // CAS Latency (tCAS) + cas = ((mdr >> 12)& 0x7) + 5.0f; - // RAS-To-CAS (tRCD) - rcd = ((mdr >> 8)& 0x7) + 5; + // RAS-To-CAS (tRCD) + rcd = ((mdr >> 8)& 0x7) + 5; - // RAS Precharge (tRP) - rp = ((mdr >> 4)& 0x7) + 5; + // RAS Precharge (tRP) + rp = ((mdr >> 4)& 0x7) + 5; - // RAS is in DTR1. Read Again. - mcr = 0x10010200; // Quick Mode ! Awesome ! - pci_conf_write(0, 0, 0, 0xD0, 4, mcr); - pci_conf_read(0, 0, 0, 0xD4, 4, &mdr); + // RAS is in DTR1. Read Again. + mcr = 0x10010200; // Quick Mode ! Awesome ! + pci_conf_write(0, 0, 0, 0xD0, 4, mcr); + pci_conf_read(0, 0, 0, 0xD4, 4, &mdr); - // RAS Active to precharge (tRAS) - ras = (mdr >> 20) & 0xF; + // RAS Active to precharge (tRAS) + ras = (mdr >> 20) & 0xF; - // Print - print_ram_line(cas, rcd, rp, ras, 1); + // Print + print_ram_line(cas, rcd, rp, ras, 1); } @@ -3863,291 +3865,291 @@ static void poll_timings_ct(void) /* ---------------------------------------------------- */ struct pci_memory_controller controllers[] = { - /* Default unknown chipset */ - { 0, 0, "","", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - - /* AMD */ - { 0x1022, 0x7006, "AMD 751","SDRAM PC-100", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd751, poll_nothing }, - { 0x1022, 0x700c, "AMD 762","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd76x, poll_nothing }, - { 0x1022, 0x700e, "AMD 761","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd76x, poll_nothing }, - - /* SiS */ - { 0x1039, 0x0600, "SiS 600","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0620, "SiS 620","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x5600, "SiS 5600","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0645, "SiS 645","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0646, "SiS 645DX","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0630, "SiS 630","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0650, "SiS 650","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0651, "SiS 651","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0730, "SiS 730","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0735, "SiS 735","DDR-SDRAM", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0740, "SiS 740","DDR-SDRAM", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0745, "SiS 745","DDR-SDRAM", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0748, "SiS 748","DDR-SDRAM", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0655, "SiS 655","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0656, "SiS 656","DDR/DDR2-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0648, "SiS 648","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0649, "SiS 649","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0661, "SiS 661","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0671, "SiS 671","DDR2-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0672, "SiS 672","DDR2-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - - /* ALi */ - { 0x10b9, 0x1531, "ALi Aladdin 4","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x10b9, 0x1541, "ALi Aladdin 5","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x10b9, 0x1644, "ALi Aladdin M1644","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - - /* ATi */ - { 0x1002, 0x5830, "ATi Radeon 9100 IGP","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1002, 0x5831, "ATi Radeon 9100 IGP","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1002, 0x5832, "ATi Radeon 9100 IGP","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1002, 0x5833, "ATi Radeon 9100 IGP","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1002, 0x5954, "ATi Xpress 200","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1002, 0x5A41, "ATi Xpress 200","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - - /* nVidia */ - { 0x10de, 0x01A4, "nVidia nForce","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x10de, 0x01E0, "nVidia nForce2 SPP","", 0, poll_fsb_nf2, poll_timings_nf2, setup_nothing, poll_nothing }, - { 0x10de, 0x0071, "nForce4 SLI","", 0, poll_fsb_nf4ie, poll_timings_nf4ie, setup_nothing, poll_nothing }, - - /* VIA */ - { 0x1106, 0x0305, "VIA KT133/KT133A","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x0391, "VIA KX133","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x0501, "VIA MVP4","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x0585, "VIA VP/VPX","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x0595, "VIA VP2","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x0597, "VIA VP3","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x0598, "VIA MVP3","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x0691, "VIA Apollo Pro 133(A)","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x0693, "VIA Apollo Pro+","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x0601, "VIA PLE133","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x3099, "VIA KT266(A)/KT333","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x3189, "VIA KT400(A)/600","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x0269, "VIA KT880","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x3205, "VIA KM400","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x3116, "VIA KM266","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x3156, "VIA KN266","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x3123, "VIA CLE266","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x0198, "VIA PT800","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1106, 0x3258, "VIA PT880","DDR2-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - - /* Serverworks */ - { 0x1166, 0x0008, "CNB20HE","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_cnb20, poll_nothing }, - { 0x1166, 0x0009, "CNB20LE","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_cnb20, poll_nothing }, - - /* Intel */ - { 0x8086, 0x1130, "Intel i815","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x122d, "Intel i430FX","EDO DRAM",0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x1235, "Intel i430MX","EDO DRAM",0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x1237, "Intel i440FX","EDO DRAM",0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x1250, "Intel i430HX","EDO DRAM",0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x1A21, "Intel i840","RDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_i840, poll_nothing }, - { 0x8086, 0x1A30, "Intel i845","SDR/DDR", 0, poll_fsb_p4, poll_timings_nothing, setup_i845, poll_nothing }, - { 0x8086, 0x2560, "Intel i845E/G/PE/GE","", 0, poll_fsb_p4, poll_timings_nothing, setup_i845, poll_nothing }, - { 0x8086, 0x2500, "Intel i820","RDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_i820, poll_nothing }, - { 0x8086, 0x2530, "Intel i850","RDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_i850, poll_nothing }, - { 0x8086, 0x2531, "Intel i860","RDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_i860, poll_nothing }, - { 0x8086, 0x7030, "Intel i430VX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x7100, "Intel i430TX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x7120, "Intel i810","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x7122, "Intel i810","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x7124, "Intel i810E","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x7180, "Intel i440[LE]X","SDRAM",0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x7190, "Intel i440BX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x7192, "Intel i440BX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x71A0, "Intel i440GX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_i440gx, poll_nothing }, - { 0x8086, 0x71A2, "Intel i440GX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_i440gx, poll_nothing }, - { 0x8086, 0x84C5, "Intel i450GX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x2540, "Intel E7500","DDR-SDRAM",0, poll_fsb_p4, poll_timings_E750x, setup_iE7xxx, poll_nothing }, - { 0x8086, 0x254C, "Intel E7501","DDR-SDRAM",0, poll_fsb_p4, poll_timings_E750x, setup_iE7xxx, poll_nothing }, - { 0x8086, 0x255d, "Intel E7205","DDR-SDRAM",0, poll_fsb_p4, poll_timings_nothing, setup_iE7xxx, poll_nothing }, - { 0x8086, 0x3592, "Intel E7320","DDR-SDRAM",0, poll_fsb_p4, poll_timings_E7520, setup_iE7520, poll_nothing }, - { 0x8086, 0x2588, "Intel E7221","DDR-SDRAM",0, poll_fsb_i925, poll_timings_i925, setup_i925, poll_nothing }, - { 0x8086, 0x3590, "Intel E7520","DDR-SDRAM",0, poll_fsb_p4, poll_timings_E7520, setup_iE7520, poll_nothing }, - { 0x8086, 0x2600, "Intel E8500","DDR-SDRAM",0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x8086, 0x2570, "Intel i848/i865","", 0, poll_fsb_i875, poll_timings_i875, setup_i875, poll_nothing }, - { 0x8086, 0x2578, "Intel i875P","", 0, poll_fsb_i875, poll_timings_i875, setup_i875, poll_nothing }, - { 0x8086, 0x2550, "Intel E7505","DDR-SDRAM",0, poll_fsb_p4, poll_timings_nothing, setup_iE7xxx, poll_nothing }, - { 0x8086, 0x3580, "Intel i852P/i855G","", 0, poll_fsb_i855, poll_timings_i852, setup_nothing, poll_nothing }, - { 0x8086, 0x3340, "Intel i855PM","", 0, poll_fsb_i855, poll_timings_i855, setup_nothing, poll_nothing }, - { 0x8086, 0x2580, "Intel i915P/G","", 0, poll_fsb_i925, poll_timings_i925, setup_i925, poll_nothing }, - { 0x8086, 0x2590, "Intel i915PM/GM","", 0, poll_fsb_i925, poll_timings_i925, setup_i925, poll_nothing }, - { 0x8086, 0x2584, "Intel i925X/XE","", 0, poll_fsb_i925, poll_timings_i925, setup_i925, poll_nothing }, - { 0x8086, 0x2770, "Intel i945P/G","", 0, poll_fsb_i945, poll_timings_i925, setup_i925, poll_nothing }, - { 0x8086, 0x27A0, "Intel i945GM/PM","", 0, poll_fsb_i945, poll_timings_i925, setup_i925, poll_nothing }, - { 0x8086, 0x27AC, "Intel i945GME","", 0, poll_fsb_i945gme, poll_timings_i925, setup_i925, poll_nothing }, - { 0x8086, 0x2774, "Intel i955X","", 0, poll_fsb_i945, poll_timings_i925, setup_i925, poll_nothing}, - { 0x8086, 0x277C, "Intel i975X","", 0, poll_fsb_i975, poll_timings_i925, setup_i925, poll_nothing}, - { 0x8086, 0x2970, "Intel i946PL/GZ","", 0, poll_fsb_i965, poll_timings_i965, setup_p35, poll_nothing}, - { 0x8086, 0x2990, "Intel Q963/Q965","", 0, poll_fsb_i965, poll_timings_i965, setup_p35, poll_nothing}, - { 0x8086, 0x29A0, "Intel P965/G965","", 0, poll_fsb_i965, poll_timings_i965, setup_p35, poll_nothing}, - { 0x8086, 0x2A00, "Intel GM965/GL960","", 0, poll_fsb_im965, poll_timings_im965, setup_p35, poll_nothing}, - { 0x8086, 0x2A10, "Intel GME965/GLE960","", 0, poll_fsb_im965, poll_timings_im965, setup_p35, poll_nothing}, - { 0x8086, 0x2A40, "Intel PM/GM45/47","", 0, poll_fsb_im965, poll_timings_im965, setup_p35, poll_nothing}, - { 0x8086, 0x29B0, "Intel Q35","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, - { 0x8086, 0x29C0, "Intel P35/G33","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, - { 0x8086, 0x29D0, "Intel Q33","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, - { 0x8086, 0x29E0, "Intel X38/X48","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, - { 0x8086, 0x29F0, "Intel 3200/3210","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, - { 0x8086, 0x2E10, "Intel Q45/Q43","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, - { 0x8086, 0x2E20, "Intel P45/G45","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, - { 0x8086, 0x2E30, "Intel G41","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, - { 0x8086, 0x4001, "Intel 5400A","", 0, poll_fsb_5400, poll_timings_5400, setup_E5400, poll_nothing}, - { 0x8086, 0x4003, "Intel 5400B","", 0, poll_fsb_5400, poll_timings_5400, setup_E5400, poll_nothing}, - { 0x8086, 0x25D8, "Intel 5000P","", 0, poll_fsb_5400, poll_timings_5400, setup_E5400, poll_nothing}, - { 0x8086, 0x25D4, "Intel 5000V","", 0, poll_fsb_5400, poll_timings_5400, setup_E5400, poll_nothing}, - { 0x8086, 0x25C0, "Intel 5000X","", 0, poll_fsb_5400, poll_timings_5400, setup_E5400, poll_nothing}, - { 0x8086, 0x25D0, "Intel 5000Z","", 0, poll_fsb_5400, poll_timings_5400, setup_E5400, poll_nothing}, - { 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}, - - /* INTEL IMC (Integrated Memory Controllers) */ - { 0xFFFF, 0x0001, "Core IMC","", 0, poll_fsb_nhm, poll_timings_nhm, setup_nhm, poll_nothing}, - { 0xFFFF, 0x0002, "Core IMC","", 0, poll_fsb_nhm32, poll_timings_nhm, setup_nhm32, poll_nothing}, - { 0xFFFF, 0x0003, "Core IMC","", 0, poll_fsb_wmr, poll_timings_wmr, setup_wmr, poll_nothing}, - { 0xFFFF, 0x0004, "SNB IMC","", 0, poll_fsb_snb, poll_timings_snb, setup_wmr, poll_nothing}, - { 0xFFFF, 0x0005, "SNB-E IMC","", 0, poll_fsb_snbe, poll_timings_snbe, setup_wmr, poll_nothing}, - { 0xFFFF, 0x0006, "IVB IMC","", 0, poll_fsb_ivb, poll_timings_snb, setup_wmr, poll_nothing}, - { 0xFFFF, 0x0007, "HSW IMC","", 0, poll_fsb_ivb, poll_timings_hsw, setup_wmr, poll_nothing}, - { 0xFFFF, 0x0008, "PineView IMC","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, - { 0xFFFF, 0x0009, "CedarTrail IMC","", 0, poll_fsb_ct, poll_timings_ct, setup_nothing, poll_nothing}, - - /* AMD IMC (Integrated Memory Controllers) */ - { 0xFFFF, 0x0100, "AMD K8 IMC","", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_nothing }, - { 0xFFFF, 0x0101, "AMD K10 IMC","", 0, poll_fsb_k10, poll_timings_k10, setup_k10, poll_nothing }, - { 0xFFFF, 0x0102, "AMD K12 IMC","", 0, poll_fsb_k12, poll_timings_k12, setup_apu, poll_nothing }, - { 0xFFFF, 0x0103, "AMD K14 IMC","", 0, poll_fsb_k14, poll_timings_k14, setup_apu, poll_nothing }, - { 0xFFFF, 0x0104, "AMD K15 IMC","", 0, poll_fsb_k15, poll_timings_k15, setup_apu, poll_nothing }, - { 0xFFFF, 0x0105, "AMD K16 IMC","", 0, poll_fsb_k16, poll_timings_k16, setup_apu, poll_nothing } + /* Default unknown chipset */ + { 0, 0, "","", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + + /* AMD */ + { 0x1022, 0x7006, "AMD 751","SDRAM PC-100", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd751, poll_nothing }, + { 0x1022, 0x700c, "AMD 762","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd76x, poll_nothing }, + { 0x1022, 0x700e, "AMD 761","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd76x, poll_nothing }, + + /* SiS */ + { 0x1039, 0x0600, "SiS 600","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0620, "SiS 620","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x5600, "SiS 5600","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0645, "SiS 645","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0646, "SiS 645DX","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0630, "SiS 630","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0650, "SiS 650","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0651, "SiS 651","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0730, "SiS 730","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0735, "SiS 735","DDR-SDRAM", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0740, "SiS 740","DDR-SDRAM", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0745, "SiS 745","DDR-SDRAM", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0748, "SiS 748","DDR-SDRAM", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0655, "SiS 655","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0656, "SiS 656","DDR/DDR2-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0648, "SiS 648","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0649, "SiS 649","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0661, "SiS 661","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0671, "SiS 671","DDR2-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0672, "SiS 672","DDR2-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + + /* ALi */ + { 0x10b9, 0x1531, "ALi Aladdin 4","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x10b9, 0x1541, "ALi Aladdin 5","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x10b9, 0x1644, "ALi Aladdin M1644","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + + /* ATi */ + { 0x1002, 0x5830, "ATi Radeon 9100 IGP","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1002, 0x5831, "ATi Radeon 9100 IGP","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1002, 0x5832, "ATi Radeon 9100 IGP","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1002, 0x5833, "ATi Radeon 9100 IGP","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1002, 0x5954, "ATi Xpress 200","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1002, 0x5A41, "ATi Xpress 200","DDR-SDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + + /* nVidia */ + { 0x10de, 0x01A4, "nVidia nForce","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x10de, 0x01E0, "nVidia nForce2 SPP","", 0, poll_fsb_nf2, poll_timings_nf2, setup_nothing, poll_nothing }, + { 0x10de, 0x0071, "nForce4 SLI","", 0, poll_fsb_nf4ie, poll_timings_nf4ie, setup_nothing, poll_nothing }, + + /* VIA */ + { 0x1106, 0x0305, "VIA KT133/KT133A","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x0391, "VIA KX133","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x0501, "VIA MVP4","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x0585, "VIA VP/VPX","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x0595, "VIA VP2","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x0597, "VIA VP3","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x0598, "VIA MVP3","EDO/SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x0691, "VIA Apollo Pro 133(A)","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x0693, "VIA Apollo Pro+","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x0601, "VIA PLE133","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x3099, "VIA KT266(A)/KT333","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x3189, "VIA KT400(A)/600","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x0269, "VIA KT880","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x3205, "VIA KM400","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x3116, "VIA KM266","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x3156, "VIA KN266","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x3123, "VIA CLE266","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x0198, "VIA PT800","DDR-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1106, 0x3258, "VIA PT880","DDR2-SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + + /* Serverworks */ + { 0x1166, 0x0008, "CNB20HE","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_cnb20, poll_nothing }, + { 0x1166, 0x0009, "CNB20LE","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_cnb20, poll_nothing }, + + /* Intel */ + { 0x8086, 0x1130, "Intel i815","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x122d, "Intel i430FX","EDO DRAM",0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x1235, "Intel i430MX","EDO DRAM",0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x1237, "Intel i440FX","EDO DRAM",0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x1250, "Intel i430HX","EDO DRAM",0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x1A21, "Intel i840","RDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_i840, poll_nothing }, + { 0x8086, 0x1A30, "Intel i845","SDR/DDR", 0, poll_fsb_p4, poll_timings_nothing, setup_i845, poll_nothing }, + { 0x8086, 0x2560, "Intel i845E/G/PE/GE","", 0, poll_fsb_p4, poll_timings_nothing, setup_i845, poll_nothing }, + { 0x8086, 0x2500, "Intel i820","RDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_i820, poll_nothing }, + { 0x8086, 0x2530, "Intel i850","RDRAM", 0, poll_fsb_p4, poll_timings_nothing, setup_i850, poll_nothing }, + { 0x8086, 0x2531, "Intel i860","RDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_i860, poll_nothing }, + { 0x8086, 0x7030, "Intel i430VX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x7100, "Intel i430TX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x7120, "Intel i810","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x7122, "Intel i810","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x7124, "Intel i810E","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x7180, "Intel i440[LE]X","SDRAM",0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x7190, "Intel i440BX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x7192, "Intel i440BX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x71A0, "Intel i440GX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_i440gx, poll_nothing }, + { 0x8086, 0x71A2, "Intel i440GX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_i440gx, poll_nothing }, + { 0x8086, 0x84C5, "Intel i450GX","SDRAM", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x2540, "Intel E7500","DDR-SDRAM",0, poll_fsb_p4, poll_timings_E750x, setup_iE7xxx, poll_nothing }, + { 0x8086, 0x254C, "Intel E7501","DDR-SDRAM",0, poll_fsb_p4, poll_timings_E750x, setup_iE7xxx, poll_nothing }, + { 0x8086, 0x255d, "Intel E7205","DDR-SDRAM",0, poll_fsb_p4, poll_timings_nothing, setup_iE7xxx, poll_nothing }, + { 0x8086, 0x3592, "Intel E7320","DDR-SDRAM",0, poll_fsb_p4, poll_timings_E7520, setup_iE7520, poll_nothing }, + { 0x8086, 0x2588, "Intel E7221","DDR-SDRAM",0, poll_fsb_i925, poll_timings_i925, setup_i925, poll_nothing }, + { 0x8086, 0x3590, "Intel E7520","DDR-SDRAM",0, poll_fsb_p4, poll_timings_E7520, setup_iE7520, poll_nothing }, + { 0x8086, 0x2600, "Intel E8500","DDR-SDRAM",0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x8086, 0x2570, "Intel i848/i865","", 0, poll_fsb_i875, poll_timings_i875, setup_i875, poll_nothing }, + { 0x8086, 0x2578, "Intel i875P","", 0, poll_fsb_i875, poll_timings_i875, setup_i875, poll_nothing }, + { 0x8086, 0x2550, "Intel E7505","DDR-SDRAM",0, poll_fsb_p4, poll_timings_nothing, setup_iE7xxx, poll_nothing }, + { 0x8086, 0x3580, "Intel i852P/i855G","", 0, poll_fsb_i855, poll_timings_i852, setup_nothing, poll_nothing }, + { 0x8086, 0x3340, "Intel i855PM","", 0, poll_fsb_i855, poll_timings_i855, setup_nothing, poll_nothing }, + { 0x8086, 0x2580, "Intel i915P/G","", 0, poll_fsb_i925, poll_timings_i925, setup_i925, poll_nothing }, + { 0x8086, 0x2590, "Intel i915PM/GM","", 0, poll_fsb_i925, poll_timings_i925, setup_i925, poll_nothing }, + { 0x8086, 0x2584, "Intel i925X/XE","", 0, poll_fsb_i925, poll_timings_i925, setup_i925, poll_nothing }, + { 0x8086, 0x2770, "Intel i945P/G","", 0, poll_fsb_i945, poll_timings_i925, setup_i925, poll_nothing }, + { 0x8086, 0x27A0, "Intel i945GM/PM","", 0, poll_fsb_i945, poll_timings_i925, setup_i925, poll_nothing }, + { 0x8086, 0x27AC, "Intel i945GME","", 0, poll_fsb_i945gme, poll_timings_i925, setup_i925, poll_nothing }, + { 0x8086, 0x2774, "Intel i955X","", 0, poll_fsb_i945, poll_timings_i925, setup_i925, poll_nothing}, + { 0x8086, 0x277C, "Intel i975X","", 0, poll_fsb_i975, poll_timings_i925, setup_i925, poll_nothing}, + { 0x8086, 0x2970, "Intel i946PL/GZ","", 0, poll_fsb_i965, poll_timings_i965, setup_p35, poll_nothing}, + { 0x8086, 0x2990, "Intel Q963/Q965","", 0, poll_fsb_i965, poll_timings_i965, setup_p35, poll_nothing}, + { 0x8086, 0x29A0, "Intel P965/G965","", 0, poll_fsb_i965, poll_timings_i965, setup_p35, poll_nothing}, + { 0x8086, 0x2A00, "Intel GM965/GL960","", 0, poll_fsb_im965, poll_timings_im965, setup_p35, poll_nothing}, + { 0x8086, 0x2A10, "Intel GME965/GLE960","", 0, poll_fsb_im965, poll_timings_im965, setup_p35, poll_nothing}, + { 0x8086, 0x2A40, "Intel PM/GM45/47","", 0, poll_fsb_im965, poll_timings_im965, setup_p35, poll_nothing}, + { 0x8086, 0x29B0, "Intel Q35","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, + { 0x8086, 0x29C0, "Intel P35/G33","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, + { 0x8086, 0x29D0, "Intel Q33","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, + { 0x8086, 0x29E0, "Intel X38/X48","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, + { 0x8086, 0x29F0, "Intel 3200/3210","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, + { 0x8086, 0x2E10, "Intel Q45/Q43","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, + { 0x8086, 0x2E20, "Intel P45/G45","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, + { 0x8086, 0x2E30, "Intel G41","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, + { 0x8086, 0x4001, "Intel 5400A","", 0, poll_fsb_5400, poll_timings_5400, setup_E5400, poll_nothing}, + { 0x8086, 0x4003, "Intel 5400B","", 0, poll_fsb_5400, poll_timings_5400, setup_E5400, poll_nothing}, + { 0x8086, 0x25D8, "Intel 5000P","", 0, poll_fsb_5400, poll_timings_5400, setup_E5400, poll_nothing}, + { 0x8086, 0x25D4, "Intel 5000V","", 0, poll_fsb_5400, poll_timings_5400, setup_E5400, poll_nothing}, + { 0x8086, 0x25C0, "Intel 5000X","", 0, poll_fsb_5400, poll_timings_5400, setup_E5400, poll_nothing}, + { 0x8086, 0x25D0, "Intel 5000Z","", 0, poll_fsb_5400, poll_timings_5400, setup_E5400, poll_nothing}, + { 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}, + + /* INTEL IMC (Integrated Memory Controllers) */ + { 0xFFFF, 0x0001, "Core IMC","", 0, poll_fsb_nhm, poll_timings_nhm, setup_nhm, poll_nothing}, + { 0xFFFF, 0x0002, "Core IMC","", 0, poll_fsb_nhm32, poll_timings_nhm, setup_nhm32, poll_nothing}, + { 0xFFFF, 0x0003, "Core IMC","", 0, poll_fsb_wmr, poll_timings_wmr, setup_wmr, poll_nothing}, + { 0xFFFF, 0x0004, "SNB IMC","", 0, poll_fsb_snb, poll_timings_snb, setup_wmr, poll_nothing}, + { 0xFFFF, 0x0005, "SNB-E IMC","", 0, poll_fsb_snbe, poll_timings_snbe, setup_wmr, poll_nothing}, + { 0xFFFF, 0x0006, "IVB IMC","", 0, poll_fsb_ivb, poll_timings_snb, setup_wmr, poll_nothing}, + { 0xFFFF, 0x0007, "HSW IMC","", 0, poll_fsb_ivb, poll_timings_hsw, setup_wmr, poll_nothing}, + { 0xFFFF, 0x0008, "PineView IMC","", 0, poll_fsb_p35, poll_timings_p35, setup_p35, poll_nothing}, + { 0xFFFF, 0x0009, "CedarTrail IMC","", 0, poll_fsb_ct, poll_timings_ct, setup_nothing, poll_nothing}, + + /* AMD IMC (Integrated Memory Controllers) */ + { 0xFFFF, 0x0100, "AMD K8 IMC","", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_nothing }, + { 0xFFFF, 0x0101, "AMD K10 IMC","", 0, poll_fsb_k10, poll_timings_k10, setup_k10, poll_nothing }, + { 0xFFFF, 0x0102, "AMD K12 IMC","", 0, poll_fsb_k12, poll_timings_k12, setup_apu, poll_nothing }, + { 0xFFFF, 0x0103, "AMD K14 IMC","", 0, poll_fsb_k14, poll_timings_k14, setup_apu, poll_nothing }, + { 0xFFFF, 0x0104, "AMD K15 IMC","", 0, poll_fsb_k15, poll_timings_k15, setup_apu, poll_nothing }, + { 0xFFFF, 0x0105, "AMD K16 IMC","", 0, poll_fsb_k16, poll_timings_k16, setup_apu, poll_nothing } }; static void print_memory_controller(void) { - /* Print memory controller info */ - if (ctrl.index == 0) { - return; - } - - /* Now print the memory controller capabilities */ - /* - cprint(LINE_CPU+5, col, " "); col++; - if (ctrl.cap == ECC_UNKNOWN) { - return; - } - if (ctrl.cap & __ECC_DETECT) { - int on; - on = ctrl.mode & __ECC_DETECT; - cprint(LINE_CPU+5, col, "(ECC : "); - cprint(LINE_CPU+5, col +7, on?"Detect":"Disabled)"); - on?(col += 13):(col += 16); - } - if (ctrl.mode & __ECC_CORRECT) { - int on; - on = ctrl.mode & __ECC_CORRECT; - cprint(LINE_CPU+5, col, " / "); - if (ctrl.cap & __ECC_CHIPKILL) { - cprint(LINE_CPU+5, col +3, on?"Correct -":""); - on?(col += 12):(col +=3); - } else { - cprint(LINE_CPU+5, col +3, on?"Correct)":""); - on?(col += 11):(col +=3); - } - } - if (ctrl.mode & __ECC_DETECT) { - if (ctrl.cap & __ECC_CHIPKILL) { - int on; - on = ctrl.mode & __ECC_CHIPKILL; - cprint(LINE_CPU+5, col, " Chipkill : "); - cprint(LINE_CPU+5, col +12, on?"On)":"Off)"); - on?(col += 15):(col +=16); - }} - if (ctrl.mode & __ECC_SCRUB) { - int on; - on = ctrl.mode & __ECC_SCRUB; - cprint(LINE_CPU+5, col, " Scrub"); - cprint(LINE_CPU+5, col +6, on?"+ ":"- "); - col += 7; - } - if (ctrl.cap & __ECC_UNEXPECTED) { - int on; - on = ctrl.mode & __ECC_UNEXPECTED; - cprint(LINE_CPU+5, col, "Unknown"); - cprint(LINE_CPU+5, col +7, on?"+ ":"- "); - col += 9; - } - */ - - - - /* Print advanced caracteristics */ - col2 = 0; - - controllers[ctrl.index].poll_fsb(); - controllers[ctrl.index].poll_timings(); + /* Print memory controller info */ + if (ctrl.index == 0) { + return; + } + + /* Now print the memory controller capabilities */ + /* + cprint(LINE_CPU+5, col, " "); col++; + if (ctrl.cap == ECC_UNKNOWN) { + return; + } + if (ctrl.cap & __ECC_DETECT) { + int on; + on = ctrl.mode & __ECC_DETECT; + cprint(LINE_CPU+5, col, "(ECC : "); + cprint(LINE_CPU+5, col +7, on?"Detect":"Disabled)"); + on?(col += 13):(col += 16); + } + if (ctrl.mode & __ECC_CORRECT) { + int on; + on = ctrl.mode & __ECC_CORRECT; + cprint(LINE_CPU+5, col, " / "); + if (ctrl.cap & __ECC_CHIPKILL) { + cprint(LINE_CPU+5, col +3, on?"Correct -":""); + on?(col += 12):(col +=3); + } else { + cprint(LINE_CPU+5, col +3, on?"Correct)":""); + on?(col += 11):(col +=3); + } + } + if (ctrl.mode & __ECC_DETECT) { + if (ctrl.cap & __ECC_CHIPKILL) { + int on; + on = ctrl.mode & __ECC_CHIPKILL; + cprint(LINE_CPU+5, col, " Chipkill : "); + cprint(LINE_CPU+5, col +12, on?"On)":"Off)"); + on?(col += 15):(col +=16); + }} + if (ctrl.mode & __ECC_SCRUB) { + int on; + on = ctrl.mode & __ECC_SCRUB; + cprint(LINE_CPU+5, col, " Scrub"); + cprint(LINE_CPU+5, col +6, on?"+ ":"- "); + col += 7; + } + if (ctrl.cap & __ECC_UNEXPECTED) { + int on; + on = ctrl.mode & __ECC_UNEXPECTED; + cprint(LINE_CPU+5, col, "Unknown"); + cprint(LINE_CPU+5, col +7, on?"+ ":"- "); + col += 9; + } + */ + + + + /* Print advanced caracteristics */ + col2 = 0; + + controllers[ctrl.index].poll_fsb(); + controllers[ctrl.index].poll_timings(); } void find_controller(void) { - unsigned long vendor; - unsigned long device; - int i; - 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; } - if(v->fail_safe & 1) { vendor = 0xFFFF; device = 0xFFFF; } + unsigned long vendor; + unsigned long device; + int i; + 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; } + if(vv->fail_safe & 1) { vendor = 0xFFFF; device = 0xFFFF; } - //hprint(11,0,vendor); hprint(11,10,device); + //hprint(11,0,vendor); hprint(11,10,device); - ctrl.index = 0; - if (result == 0 || imc_type) { - for(i = 1; i < sizeof(controllers)/sizeof(controllers[0]); i++) { - if ((controllers[i].vendor == vendor) && (controllers[i].device == device)) { - ctrl.index = i; - break; - } - } - } - - controllers[ctrl.index].setup_ecc(); - /* Don't enable ECC polling by default unless it has - * been well tested. - */ - //set_ecc_polling(-1); - print_memory_controller(); - - if(imc_type) { print_dmi_startup_info(); } + ctrl.index = 0; + if (result == 0 || imc_type) { + for(i = 1; i < sizeof(controllers)/sizeof(controllers[0]); i++) { + if ((controllers[i].vendor == vendor) && (controllers[i].device == device)) { + ctrl.index = i; + break; + } + } + } + + controllers[ctrl.index].setup_ecc(); + /* Don't enable ECC polling by default unless it has + * been well tested. + */ + //set_ecc_polling(-1); + print_memory_controller(); + + if(imc_type) { print_dmi_startup_info(); } } void poll_errors(void) { - if (ctrl.poll) { - controllers[ctrl.index].poll_errors(); - } + if (ctrl.poll) { + controllers[ctrl.index].poll_errors(); + } } /* -void set_ecc_polling(int val) -{ - int tested = controllers[ctrl.index].tested; - if (val == -1) { - val = tested; - } - if (val && (ctrl.mode & __ECC_DETECT)) { - ctrl.poll = 1; - cprint(LINE_INFO, COL_ECC, tested? " on": " ON"); - } else { - ctrl.poll = 0; - cprint(LINE_INFO, COL_ECC, "off"); - } -} + void set_ecc_polling(int val) + { + int tested = controllers[ctrl.index].tested; + if (val == -1) { + val = tested; + } + if (val && (ctrl.mode & __ECC_DETECT)) { + ctrl.poll = 1; + cprint(LINE_INFO, COL_ECC, tested? " on": " ON"); + } else { + ctrl.poll = 0; + cprint(LINE_INFO, COL_ECC, "off"); + } + } */ @@ -1,3 +1,6 @@ +#ifndef CPUID_H_ +#define CPUID_H_ + /* * cpuid.h -- * contains the data structures required for CPUID @@ -12,7 +15,7 @@ extern struct cpu_ident cpu_id; static inline void __cpuid(unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) + unsigned int *ecx, unsigned int *edx) { /* ecx is often an input as well as an output. */ asm volatile("\t" @@ -150,9 +153,9 @@ typedef union { uint32_t mon:1; uint32_t dscpl:1; uint32_t vmx:1; - uint32_t smx:1; - uint32_t eist:1; - uint32_t tm2:1; + uint32_t smx:1; + uint32_t eist:1; + uint32_t tm2:1; uint32_t bits_9_31:23; uint32_t bits0_28:29; /* EDX extended feature flags, bit 0 */ uint32_t lm:1; /* Long Mode */ @@ -194,3 +197,6 @@ struct cpuid4_ecx { uint32_t number_of_sets:32; }; +void get_cpuid(); + +#endif // CPUID_H_ @@ -15,7 +15,7 @@ */ #define LOW_TEST_ADR 0x00010000 /* Final adrs for test code */ -#define BOOTSEG 0x07c0 /* Segment adrs for inital boot */ +#define BOOTSEG 0x07c0 /* Segment adrs for initial boot */ #define INITSEG 0x9000 /* Segment adrs for relocated boot */ #define SETUPSEG (INITSEG+0x20) /* Segment adrs for relocated setup */ #define TSTLOAD 0x1000 /* Segment adrs for load of test */ @@ -10,13 +10,11 @@ #include "test.h" -#include <stdint.h> - +#include "stdint.h" #define round_up(x,y) (((x) + (y) - 1) & ~((y)-1)) #define round_down(x,y) ((x) & ~((y)-1)) - struct dmi_eps { uint8_t anchor[4]; int8_t checksum; @@ -95,6 +93,12 @@ struct mem_dev { uint8_t serialnum; uint8_t asset; uint8_t partnum; + uint8_t attributes; + uint8_t ext_size; + uint8_t conf_ram_speed; + uint8_t min_voltage; + uint8_t max_votage; + uint8_t conf_voltage; } __attribute__((packed)); struct md_map{ @@ -122,7 +126,7 @@ static char *form_factors[] = { "?", "Other", "Unknown", "SIMM", "SIP", "Chip", "DIP", "ZIP", "Proprietary Card", "DIMM", "TSOP", "Row of chips", "RIMM", - "SODIMM", "SRIMM", "FB-DIMM" + "SODIMM", "SRIMM", "FB-DIMM", "Die" }; @@ -131,7 +135,8 @@ static char *memory_types[] = { "Other", "????", "DRAM", "EDRAM", "VRAM", "SRAM", "RAM", "ROM", "FLASH", "EEPROM", "FEPROM", "EPROM", "CDRAM", "3DRAM", "SDRAM", "SGRAM", "RDRAM", "DDR", "DDR2", "DDR2 FB", "RSVD", - "RSVD","RSVD","DDR3","FBD2" + "RSVD","RSVD","DDR3","FBD2", "DDR4", "LPDDR", "LPDDR2", "LPDDR3", + "LPDDR4", "LNVD", "HBM", "HBM2", "DDR5", "LPDDR5" }; @@ -198,7 +203,6 @@ int open_dmi(void){ return -1; } - table_start=(char *)eps->tableaddress; dmi=table_start; //look at all structs @@ -208,8 +212,8 @@ int open_dmi(void){ if (header->type == 17) mem_devs[mem_devs_count++] = (struct mem_dev *)dmi; - // Need fix (SMBIOS/DDR3) - if (header->type == 20 || header->type == 1) + // Mem Dev Map + if (header->type == 20) md_maps[md_maps_count++] = (struct md_map *)dmi; // MB_SPEC @@ -256,11 +260,11 @@ void print_dmi_startup_info(void) if(!dmi_initialized) { init_dmi(); } string1 = get_tstruct_string(&dmi_system_info->header,dmi_system_info->manufacturer); - sl1 = strlen(string1); + sl1 = mt86_strlen(string1); string2 = get_tstruct_string(&dmi_system_info->header,dmi_system_info->productname); - sl2 = strlen(string2); + sl2 = mt86_strlen(string2); string3 = get_tstruct_string(&dmi_cpu_info->header,dmi_cpu_info->cpu_socket); - sl3 = strlen(string3); + sl3 = mt86_strlen(string3); slenght = sl1 + sl2; if(sl3 > 2) { slenght += sl3 + 4; } else { slenght++; } @@ -314,17 +318,22 @@ void print_dmi_info(void){ int size_in_mb; int yof; - yof=POP2_Y+5+2*(i-8*(page-1)); + yof = POP2_Y+5+2*(i-8*(page-1)); cprint(yof, POP2_X+4, get_tstruct_string(&(mem_devs[i]->header), mem_devs[i]->dev_locator)); - + if (mem_devs[i]->size == 0){ cprint(yof, POP2_X+4+18, "Empty"); }else if (mem_devs[i]->size == 0xFFFF){ cprint(yof, POP2_X+4+18, "Unknown"); + }else if (mem_devs[i]->size == 0x7FFF){ + // SMBIOS 2.7+ + size_in_mb = mem_devs[i]->ext_size; + itoa(string, size_in_mb); + cprint(yof, POP2_X+4+18, string); }else{ - size_in_mb = 0xEFFF & mem_devs[i]->size; + size_in_mb = 0xFFFF & mem_devs[i]->size; if (mem_devs[i]->size & 0x8000) - size_in_mb = size_in_mb<<10; + size_in_mb <<= 10; itoa(string, size_in_mb); cprint(yof, POP2_X+4+18, string); } @@ -408,22 +417,22 @@ void print_dmi_err(void){ scroll(); - cprint(v->msg_line, 0,"Bad Memory Devices: "); + cprint(vv->msg_line, 0,"Bad Memory Devices: "); of=20; for ( i=count=0; i < MAX_DMI_MEMDEVS; i++){ if (!dmi_err_cnts[i]) continue; struct mem_dev *md = mem_devs[i]; if(count++){ - cprint(v->msg_line, of, ", "); + cprint(vv->msg_line, of, ", "); of+=2; } string=get_tstruct_string((struct tstruct_header *)md,md->dev_locator); - if (strlen(string) + of > 80){ + if (mt86_strlen(string) + of > 80){ scroll(); of=7; } - cprint(v->msg_line, of, string); - of += strlen(string); + cprint(vv->msg_line, of, string); + of += mt86_strlen(string); } } @@ -28,49 +28,63 @@ static void print_err_counts(void); static void common_err(); static int syn, chan, len=1; +static void paint_line(int msg_line, unsigned vga_color) { + if (msg_line < 24) { + char* pp; + int i; + for(i=0, pp=(char *)((SCREEN_ADR+msg_line*160+1)); + i<76; i++, pp+=2) { + *pp = vga_color; + } + } +} + +/* + * Report an assertion failure. This is typically NOT a memory error. + */ +void assert_fail(const char* file, int line_no) { + spin_lock(&barr->mutex); + + scroll(); + cprint(vv->msg_line, 0, " *** INTERNAL ERROR *** line "); + dprint(vv->msg_line, 31, line_no, 5, 1); + cprint(vv->msg_line, 37, file); + paint_line(vv->msg_line, 0x0E /* yellow on black */); + + spin_unlock(&barr->mutex); + + // Ensure the message remains visible for a while + // before it scrolls away. Assert-fails should be rare + // and may indicate that subsequent result aren't valid. + sleep(60, 0, 0, 0); +} + /* * Display data error message. Don't display duplicate errors. */ -void error(ulong *adr, ulong good, ulong bad) +void mt86_error(ulong *adr, ulong good, ulong bad) { - - ulong xor; + ulong xor; - spin_lock(&barr->mutex); - - xor = good ^ bad; + spin_lock(&barr->mutex); + + xor = good ^ bad; #ifdef USB_WAR - /* Skip any errrors that appear to be due to the BIOS using location - * 0x4e0 for USB keyboard support. This often happens with Intel - * 810, 815 and 820 chipsets. It is possible that we will skip - * a real error but the odds are very low. - */ - if ((ulong)adr == 0x4e0 || (ulong)adr == 0x410) { - return; - } + /* Skip any errors that appear to be due to the BIOS using location + * 0x4e0 for USB keyboard support. This often happens with Intel + * 810, 815 and 820 chipsets. It is possible that we will skip + * a real error but the odds are very low. + */ + if ((ulong)adr == 0x4e0 || (ulong)adr == 0x410) { + return; + } #endif - /* A sporadic bug exists in test #6, with SMP enabled, that - * reports false positives on < 65K-0.5MB range. I was - * not able to solve this. After investigations, it seems - * related to a BIOS issue similiar to the one solved by - * USB_WAR, but for MP Table. - */ - /* Solved - if (test == 6 && (ulong)adr <= 0x07FFFF && num_cpus > 1) - { - cprint(6,78,"-"); // Debug - return; - } - */ - - common_err(adr, good, bad, xor, 0); - spin_unlock(&barr->mutex); + common_err(adr, good, bad, xor, 0); + spin_unlock(&barr->mutex); } - - /* * Display address error message. * Since this is strictly an address test, trying to create BadRAM @@ -78,9 +92,9 @@ void error(ulong *adr, ulong good, ulong bad) */ void ad_err1(ulong *adr1, ulong *mask, ulong bad, ulong good) { - spin_lock(&barr->mutex); - common_err(adr1, good, bad, (ulong)mask, 1); - spin_unlock(&barr->mutex); + spin_lock(&barr->mutex); + common_err(adr1, good, bad, (ulong)mask, 1); + spin_unlock(&barr->mutex); } /* @@ -90,49 +104,41 @@ void ad_err1(ulong *adr1, ulong *mask, ulong bad, ulong good) */ void ad_err2(ulong *adr, ulong bad) { - spin_lock(&barr->mutex); - common_err(adr, (ulong)adr, bad, ((ulong)adr) ^ bad, 0); - spin_unlock(&barr->mutex); + spin_lock(&barr->mutex); + common_err(adr, (ulong)adr, bad, ((ulong)adr) ^ bad, 0); + spin_unlock(&barr->mutex); } static void update_err_counts(void) { - if (beepmode){ - beep(600); - beep(1000); - } + if (beepmode){ + beep(600); + beep(1000); + } - if (v->pass && v->ecount == 0) { - cprint(LINE_MSG, COL_MSG, - " "); - } - ++(v->ecount); - tseq[test].errors++; - + if (vv->pass && vv->ecount == 0) { + cprint(LINE_MSG, COL_MSG, + " "); + } + ++(vv->ecount); + tseq[test].errors++; } static void print_err_counts(void) { - int i; - char *pp; - - if ((v->ecount > 4096) && (v->ecount % 256 != 0)) return; - - dprint(LINE_INFO, 72, v->ecount, 6, 0); -/* - dprint(LINE_INFO, 56, v->ecc_ecount, 6, 0); -*/ - - /* Paint the error messages on the screen red to provide a vivid */ - /* indicator that an error has occured */ - if ((v->printmode == PRINTMODE_ADDRESSES || - v->printmode == PRINTMODE_PATTERNS) && - v->msg_line < 24) { - for(i=0, pp=(char *)((SCREEN_ADR+v->msg_line*160+1)); - i<76; i++, pp+=2) { - *pp = 0x47; - } - } + if ((vv->ecount > 4096) && (vv->ecount % 256 != 0)) return; + + dprint(LINE_INFO, 72, vv->ecount, 6, 0); + /* + dprint(LINE_INFO, 56, vv->ecc_ecount, 6, 0); + */ + + /* Paint the error messages on the screen red to provide a vivid */ + /* indicator that an error has occured */ + if ((vv->printmode == PRINTMODE_ADDRESSES || + vv->printmode == PRINTMODE_PATTERNS)) { + paint_line(vv->msg_line, 0x47 /* gray-on-red */); + } } /* @@ -140,264 +146,264 @@ static void print_err_counts(void) */ void common_err( ulong *adr, ulong good, ulong bad, ulong xor, int type) { - int i, j, n, x, flag=0; - ulong page, offset; - int patnchg; - ulong mb; - - update_err_counts(); - - switch(v->printmode) { - case PRINTMODE_SUMMARY: - /* Don't do anything for a parity error. */ - if (type == 3) { - return; - } - - /* Address error */ - if (type == 1) { - xor = good ^ bad; - } - - /* Ecc correctable errors */ - if (type == 2) { - /* the bad value is the corrected flag */ - if (bad) { - v->erri.cor_err++; - } - page = (ulong)adr; - offset = good; - } else { - page = page_of(adr); - offset = (ulong)adr & 0xFFF; - } - - /* Calc upper and lower error addresses */ - if (v->erri.low_addr.page > page) { - v->erri.low_addr.page = page; - v->erri.low_addr.offset = offset; - flag++; - } else if (v->erri.low_addr.page == page && - v->erri.low_addr.offset > offset) { - v->erri.low_addr.offset = offset; - v->erri.high_addr.offset = offset; - flag++; - } else if (v->erri.high_addr.page < page) { - v->erri.high_addr.page = page; - flag++; - } - if (v->erri.high_addr.page == page && - v->erri.high_addr.offset < offset) { - v->erri.high_addr.offset = offset; - flag++; - } - - /* Calc bits in error */ - for (i=0, n=0; i<32; i++) { - if (xor>>i & 1) { - n++; - } - } - v->erri.tbits += n; - if (n > v->erri.max_bits) { - v->erri.max_bits = n; - flag++; - } - if (n < v->erri.min_bits) { - v->erri.min_bits = n; - flag++; - } - if (v->erri.ebits ^ xor) { - flag++; - } - v->erri.ebits |= xor; - - /* Calc max contig errors */ - len = 1; - if ((ulong)adr == (ulong)v->erri.eadr+4 || - (ulong)adr == (ulong)v->erri.eadr-4 ) { - len++; - } - if (len > v->erri.maxl) { - v->erri.maxl = len; - flag++; - } - v->erri.eadr = (ulong)adr; - - if (v->erri.hdr_flag == 0) { - clear_scroll(); - cprint(LINE_HEADER+0, 1, "Error Confidence Value:"); - cprint(LINE_HEADER+1, 1, " Lowest Error Address:"); - cprint(LINE_HEADER+2, 1, " Highest Error Address:"); - cprint(LINE_HEADER+3, 1, " Bits in Error Mask:"); - cprint(LINE_HEADER+4, 1, " Bits in Error - Total:"); - cprint(LINE_HEADER+4, 29, "Min: Max: Avg:"); - cprint(LINE_HEADER+5, 1, " Max Contiguous Errors:"); - x = 24; - if (dmi_initialized) { - for ( i=0; i < MAX_DMI_MEMDEVS;){ - n = LINE_HEADER+7; - for (j=0; j<4; j++) { - if (dmi_err_cnts[i] >= 0) { - dprint(n, x, i, 2, 0); - cprint(n, x+2, ": 0"); - } - i++; - n++; - } - x += 10; - } - } + int i, j, n, x, flag=0; + ulong page, offset; + int patnchg; + ulong mb; + + update_err_counts(); + + switch(vv->printmode) { + case PRINTMODE_SUMMARY: + /* Don't do anything for a parity error. */ + if (type == 3) { + return; + } + + /* Address error */ + if (type == 1) { + xor = good ^ bad; + } + + /* Ecc correctable errors */ + if (type == 2) { + /* the bad value is the corrected flag */ + if (bad) { + vv->erri.cor_err++; + } + page = (ulong)adr; + offset = good; + } else { + page = page_of(adr); + offset = (ulong)adr & 0xFFF; + } + + /* Calc upper and lower error addresses */ + if (vv->erri.low_addr.page > page) { + vv->erri.low_addr.page = page; + vv->erri.low_addr.offset = offset; + flag++; + } else if (vv->erri.low_addr.page == page && + vv->erri.low_addr.offset > offset) { + vv->erri.low_addr.offset = offset; + vv->erri.high_addr.offset = offset; + flag++; + } else if (vv->erri.high_addr.page < page) { + vv->erri.high_addr.page = page; + flag++; + } + if (vv->erri.high_addr.page == page && + vv->erri.high_addr.offset < offset) { + vv->erri.high_addr.offset = offset; + flag++; + } + + /* Calc bits in error */ + for (i=0, n=0; i<32; i++) { + if (xor>>i & 1) { + n++; + } + } + vv->erri.tbits += n; + if (n > vv->erri.max_bits) { + vv->erri.max_bits = n; + flag++; + } + if (n < vv->erri.min_bits) { + vv->erri.min_bits = n; + flag++; + } + if (vv->erri.ebits ^ xor) { + flag++; + } + vv->erri.ebits |= xor; + + /* Calc max contig errors */ + len = 1; + if ((ulong)adr == (ulong)vv->erri.eadr+4 || + (ulong)adr == (ulong)vv->erri.eadr-4 ) { + len++; + } + if (len > vv->erri.maxl) { + vv->erri.maxl = len; + flag++; + } + vv->erri.eadr = (ulong)adr; + + if (vv->erri.hdr_flag == 0) { + clear_scroll(); + cprint(LINE_HEADER+0, 1, "Error Confidence Value:"); + cprint(LINE_HEADER+1, 1, " Lowest Error Address:"); + cprint(LINE_HEADER+2, 1, " Highest Error Address:"); + cprint(LINE_HEADER+3, 1, " Bits in Error Mask:"); + cprint(LINE_HEADER+4, 1, " Bits in Error - Total:"); + cprint(LINE_HEADER+4, 29, "Min: Max: Avg:"); + cprint(LINE_HEADER+5, 1, " Max Contiguous Errors:"); + x = 24; + if (dmi_initialized) { + for ( i=0; i < MAX_DMI_MEMDEVS;){ + n = LINE_HEADER+7; + for (j=0; j<4; j++) { + if (dmi_err_cnts[i] >= 0) { + dprint(n, x, i, 2, 0); + cprint(n, x+2, ": 0"); + } + i++; + n++; + } + x += 10; + } + } - cprint(LINE_HEADER+0, 64, "Test Errors"); - v->erri.hdr_flag++; - } - if (flag) { - /* Calc bits in error */ - for (i=0, n=0; i<32; i++) { - if (v->erri.ebits>>i & 1) { - n++; - } - } - page = v->erri.low_addr.page; - offset = v->erri.low_addr.offset; - mb = page >> 8; - hprint(LINE_HEADER+1, 25, page); - 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); - page = v->erri.high_addr.page; - offset = v->erri.high_addr.offset; - mb = page >> 8; - hprint(LINE_HEADER+2, 25, page); - 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); - 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); - dprint(LINE_HEADER+4, 42, v->erri.max_bits, 2, 1); - dprint(LINE_HEADER+4, 50, v->erri.tbits/v->ecount, 2, 1); - dprint(LINE_HEADER+5, 25, v->erri.maxl, 7, 1); - x = 28; - for ( i=0; i < MAX_DMI_MEMDEVS;){ - n = LINE_HEADER+7; - for (j=0; j<4; j++) { - if (dmi_err_cnts[i] > 0) { - dprint (n, x, dmi_err_cnts[i], 7, 1); - } - i++; - n++; - } - x += 10; - } + cprint(LINE_HEADER+0, 64, "Test Errors"); + vv->erri.hdr_flag++; + } + if (flag) { + /* Calc bits in error */ + for (i=0, n=0; i<32; i++) { + if (vv->erri.ebits>>i & 1) { + n++; + } + } + page = vv->erri.low_addr.page; + offset = vv->erri.low_addr.offset; + mb = page >> 8; + hprint(LINE_HEADER+1, 25, page); + 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); + page = vv->erri.high_addr.page; + offset = vv->erri.high_addr.offset; + mb = page >> 8; + hprint(LINE_HEADER+2, 25, page); + 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); + hprint(LINE_HEADER+3, 25, vv->erri.ebits); + dprint(LINE_HEADER+4, 25, n, 2, 1); + dprint(LINE_HEADER+4, 34, vv->erri.min_bits, 2, 1); + dprint(LINE_HEADER+4, 42, vv->erri.max_bits, 2, 1); + dprint(LINE_HEADER+4, 50, vv->erri.tbits/vv->ecount, 2, 1); + dprint(LINE_HEADER+5, 25, vv->erri.maxl, 7, 1); + x = 28; + for ( i=0; i < MAX_DMI_MEMDEVS;){ + n = LINE_HEADER+7; + for (j=0; j<4; j++) { + if (dmi_err_cnts[i] > 0) { + dprint (n, x, dmi_err_cnts[i], 7, 1); + } + i++; + n++; + } + x += 10; + } - for (i=0; tseq[i].msg != NULL; i++) { - dprint(LINE_HEADER+1+i, 66, i, 2, 0); - dprint(LINE_HEADER+1+i, 68, tseq[i].errors, 8, 0); - } - } - if (v->erri.cor_err) { - dprint(LINE_HEADER+6, 25, v->erri.cor_err, 8, 1); - } - break; - - case PRINTMODE_ADDRESSES: - /* Don't display duplicate errors */ - if ((ulong)adr == (ulong)v->erri.eadr && - xor == v->erri.exor) { - return; - } - if (v->erri.hdr_flag == 0) { - clear_scroll(); - cprint(LINE_HEADER, 0, -"Tst Pass Failing Address Good Bad Err-Bits Count CPU"); - cprint(LINE_HEADER+1, 0, -"--- ---- ----------------------- -------- -------- -------- ----- ----"); - v->erri.hdr_flag++; - } - /* Check for keyboard input */ - check_input(); - scroll(); + for (i=0; tseq[i].msg != NULL; i++) { + dprint(LINE_HEADER+1+i, 66, i, 2, 0); + dprint(LINE_HEADER+1+i, 68, tseq[i].errors, 8, 0); + } + } + if (vv->erri.cor_err) { + dprint(LINE_HEADER+6, 25, vv->erri.cor_err, 8, 1); + } + break; + + case PRINTMODE_ADDRESSES: + /* Don't display duplicate errors */ + if ((ulong)adr == (ulong)vv->erri.eadr && + xor == vv->erri.exor) { + return; + } + if (vv->erri.hdr_flag == 0) { + clear_scroll(); + cprint(LINE_HEADER, 0, + "Tst Pass Failing Address Good Bad Err-Bits Count CPU"); + cprint(LINE_HEADER+1, 0, + "--- ---- ----------------------- -------- -------- -------- ----- ----"); + vv->erri.hdr_flag++; + } + /* Check for keyboard input */ + check_input(); + scroll(); - if ( type == 2 || type == 3) { - page = (ulong)adr; - offset = good; - } else { - page = page_of(adr); - offset = ((unsigned long)adr) & 0xFFF; - } - mb = page >> 8; - dprint(v->msg_line, 0, test+1, 3, 0); - dprint(v->msg_line, 4, v->pass, 5, 0); - hprint(v->msg_line, 11, page); - 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); - - if (type == 3) { - /* ECC error */ - cprint(v->msg_line, 36, - bad?"corrected ": "uncorrected "); - hprint2(v->msg_line, 60, syn, 4); - cprint(v->msg_line, 68, "ECC"); - dprint(v->msg_line, 74, chan, 2, 0); - } else if (type == 2) { - cprint(v->msg_line, 36, "Parity error detected "); - } else { - hprint(v->msg_line, 36, good); - hprint(v->msg_line, 46, bad); - hprint(v->msg_line, 56, xor); - dprint(v->msg_line, 66, v->ecount, 5, 0); - dprint(v->msg_line, 74, smp_my_cpu_num(), 2,1); - v->erri.exor = xor; - } - v->erri.eadr = (ulong)adr; - print_err_counts(); - break; - - case PRINTMODE_PATTERNS: - if (v->erri.hdr_flag == 0) { - clear_scroll(); - v->erri.hdr_flag++; - } - /* Do not do badram patterns from test 0 or 5 */ - if (test == 0 || test == 5) { - return; - } - /* Only do patterns for data errors */ - if ( type != 0) { - return; - } - /* Process the address in the pattern administration */ - patnchg=insertaddress ((ulong) adr); - if (patnchg) { - printpatn(); - } - break; - - case PRINTMODE_NONE: - if (v->erri.hdr_flag == 0) { - clear_scroll(); - v->erri.hdr_flag++; - } - break; - } + if ( type == 2 || type == 3) { + page = (ulong)adr; + offset = good; + } else { + page = page_of(adr); + offset = ((unsigned long)adr) & 0xFFF; + } + mb = page >> 8; + dprint(vv->msg_line, 0, test+1, 3, 0); + dprint(vv->msg_line, 4, vv->pass, 5, 0); + hprint(vv->msg_line, 11, page); + hprint2(vv->msg_line, 19, offset, 3); + cprint(vv->msg_line, 22, " - . MB"); + dprint(vv->msg_line, 25, mb, 5, 0); + dprint(vv->msg_line, 31, ((page & 0xF)*10)/16, 1, 0); + + if (type == 3) { + /* ECC error */ + cprint(vv->msg_line, 36, + bad?"corrected ": "uncorrected "); + hprint2(vv->msg_line, 60, syn, 4); + cprint(vv->msg_line, 68, "ECC"); + dprint(vv->msg_line, 74, chan, 2, 0); + } else if (type == 2) { + cprint(vv->msg_line, 36, "Parity error detected "); + } else { + hprint(vv->msg_line, 36, good); + hprint(vv->msg_line, 46, bad); + hprint(vv->msg_line, 56, xor); + dprint(vv->msg_line, 66, vv->ecount, 5, 0); + dprint(vv->msg_line, 74, smp_my_cpu_num(), 2,1); + vv->erri.exor = xor; + } + vv->erri.eadr = (ulong)adr; + print_err_counts(); + break; + + case PRINTMODE_PATTERNS: + if (vv->erri.hdr_flag == 0) { + clear_scroll(); + vv->erri.hdr_flag++; + } + /* Do not do badram patterns from test 0 or 5 */ + if (test == 0 || test == 5) { + return; + } + /* Only do patterns for data errors */ + if ( type != 0) { + return; + } + /* Process the address in the pattern administration */ + patnchg=insertaddress ((ulong) adr); + if (patnchg) { + printpatn(); + } + break; + + case PRINTMODE_NONE: + if (vv->erri.hdr_flag == 0) { + clear_scroll(); + vv->erri.hdr_flag++; + } + break; + } } /* * Print an ecc error */ void print_ecc_err(unsigned long page, unsigned long offset, - int corrected, unsigned short syndrome, int channel) + int corrected, unsigned short syndrome, int channel) { - ++(v->ecc_ecount); - syn = syndrome; - chan = channel; - common_err((ulong *)page, offset, corrected, 0, 2); + ++(vv->ecc_ecount); + syn = syndrome; + chan = channel; + common_err((ulong *)page, offset, corrected, 0, 2); } #ifdef PARITY_MEM @@ -406,14 +412,14 @@ void print_ecc_err(unsigned long page, unsigned long offset, */ void parity_err( unsigned long edi, unsigned long esi) { - unsigned long addr; - - if (test == 5) { - addr = esi; - } else { - addr = edi; - } - common_err((ulong *)addr, addr & 0xFFF, 0, 0, 3); + unsigned long addr; + + if (test == 5) { + addr = esi; + } else { + addr = edi; + } + common_err((ulong *)addr, addr & 0xFFF, 0, 0, 3); } #endif @@ -422,34 +428,34 @@ void parity_err( unsigned long edi, unsigned long esi) */ void printpatn (void) { - int idx=0; - int x; - - /* Check for keyboard input */ - check_input(); - - if (v->numpatn == 0) - return; - - scroll(); - - cprint (v->msg_line, 0, "badram="); - x=7; - - for (idx = 0; idx < v->numpatn; idx++) { - - if (x > 80-22) { - scroll(); - x=7; - } - cprint (v->msg_line, x, "0x"); - hprint (v->msg_line, x+2, v->patn[idx].adr ); - cprint (v->msg_line, x+10, ",0x"); - hprint (v->msg_line, x+13, v->patn[idx].mask); - if (idx+1 < v->numpatn) - cprint (v->msg_line, x+21, ","); - x+=22; - } + int idx=0; + int x; + + /* Check for keyboard input */ + check_input(); + + if (vv->numpatn == 0) + return; + + scroll(); + + cprint (vv->msg_line, 0, "badram="); + x=7; + + for (idx = 0; idx < vv->numpatn; idx++) { + + if (x > 80-22) { + scroll(); + x=7; + } + cprint (vv->msg_line, x, "0x"); + hprint (vv->msg_line, x+2, vv->patn[idx].adr ); + cprint (vv->msg_line, x+10, ",0x"); + hprint (vv->msg_line, x+13, vv->patn[idx].mask); + if (idx+1 < vv->numpatn) + cprint (vv->msg_line, x+21, ","); + x+=22; + } } /* @@ -460,168 +466,164 @@ char spin[4] = {'|','/','-','\\'}; void do_tick(int me) { - int i, j, pct; - ulong h, l, n, t; - extern int mstr_cpu; - - if (++spin_idx[me] > 3) { - spin_idx[me] = 0; - } - cplace(8, me+7, spin[spin_idx[me]]); + int i, j, pct; + ulong h, l, n, t; + extern int mstr_cpu; + + if (++spin_idx[me] > 3) { + spin_idx[me] = 0; + } + cplace(8, me+7, spin[spin_idx[me]]); - /* Check for keyboard input */ - if (me == mstr_cpu) { - check_input(); - } - /* A barrier here holds the other CPUs until the configuration - * changes are done */ - s_barrier(); - - /* Only the first selected CPU does the update */ - if (me != mstr_cpu) { - return; - } - - /* FIXME only print serial error messages from the tick handler */ - if (v->ecount) { - print_err_counts(); - } + /* Check for keyboard input */ + if (me == mstr_cpu) { + check_input(); + } + /* A barrier here holds the other CPUs until the configuration + * changes are done */ + s_barrier(); + + /* Only the first selected CPU does the update */ + if (me != mstr_cpu) { + return; + } + + /* FIXME only print serial error messages from the tick handler */ + if (vv->ecount) { + print_err_counts(); + } - nticks++; - v->total_ticks++; - - if (test_ticks) { - pct = 100*nticks/test_ticks; - if (pct > 100) { - pct = 100; - } - } else { - pct = 0; - } - dprint(2, COL_MID+4, pct, 3, 0); - i = (BAR_SIZE * pct) / 100; - while (i > v->tptr) { - if (v->tptr >= BAR_SIZE) { - break; - } - cprint(2, COL_MID+9+v->tptr, "#"); - v->tptr++; - } + nticks++; + vv->total_ticks++; + + if (test_ticks) { + pct = 100*nticks/test_ticks; + if (pct > 100) { + pct = 100; + } + } else { + pct = 0; + } + dprint(2, COL_MID+4, pct, 3, 0); + i = (BAR_SIZE * pct) / 100; + while (i > vv->tptr) { + if (vv->tptr >= BAR_SIZE) { + break; + } + cprint(2, COL_MID+9+vv->tptr, "#"); + vv->tptr++; + } - if (v->pass_ticks) { - pct = 100*v->total_ticks/v->pass_ticks; - if (pct > 100) { - pct = 100; - } - } else { - pct = 0; + if (vv->pass_ticks) { + pct = 100*vv->total_ticks/vv->pass_ticks; + if (pct > 100) { + pct = 100; + } + } else { + pct = 0; + } + dprint(1, COL_MID+4, pct, 3, 0); + i = (BAR_SIZE * pct) / 100; + while (i > vv->pptr) { + if (vv->pptr >= BAR_SIZE) { + break; } - dprint(1, COL_MID+4, pct, 3, 0); - i = (BAR_SIZE * pct) / 100; - while (i > v->pptr) { - if (v->pptr >= BAR_SIZE) { - break; - } - cprint(1, COL_MID+9+v->pptr, "#"); - v->pptr++; - } - - if (v->ecount && v->printmode == PRINTMODE_SUMMARY) { - /* Compute confidence score */ - pct = 0; - - /* If there are no errors within 1mb of start - end addresses */ - h = v->pmap[v->msegs - 1].end - 0x100; - if (v->erri.low_addr.page > 0x100 && - v->erri.high_addr.page < h) { - pct += 8; - } - - /* Errors for only some tests */ - if (v->pass) { - for (i=0, n=0; tseq[i].msg != NULL; i++) { - if (tseq[i].errors == 0) { - n++; - } - } - pct += n*3; - } else { - for (i=0, n=0; i<test; i++) { - if (tseq[i].errors == 0) { - n++; - } - } - pct += n*2; + cprint(1, COL_MID+9+vv->pptr, "#"); + vv->pptr++; + } + + if (vv->ecount && vv->printmode == PRINTMODE_SUMMARY) { + /* Compute confidence score */ + pct = 0; + + /* If there are no errors within 1mb of start - end addresses */ + h = vv->pmap[vv->msegs - 1].end - 0x100; + if (vv->erri.low_addr.page > 0x100 && + vv->erri.high_addr.page < h) { + pct += 8; + } + + /* Errors for only some tests */ + if (vv->pass) { + for (i=0, n=0; tseq[i].msg != NULL; i++) { + if (tseq[i].errors == 0) { + n++; + } + } + pct += n*3; + } else { + for (i=0, n=0; i<test; i++) { + if (tseq[i].errors == 0) { + n++; + } + } + pct += n*2; - } - - /* Only some bits in error */ - n = 0; - if (v->erri.ebits & 0xf) n++; - if (v->erri.ebits & 0xf0) n++; - if (v->erri.ebits & 0xf00) n++; - if (v->erri.ebits & 0xf000) n++; - if (v->erri.ebits & 0xf0000) n++; - if (v->erri.ebits & 0xf00000) n++; - if (v->erri.ebits & 0xf000000) n++; - if (v->erri.ebits & 0xf0000000) n++; - pct += (8-n)*2; - - /* Adjust the score */ - pct = pct*100/22; -/* - if (pct > 100) { - pct = 100; - } -*/ - dprint(LINE_HEADER+0, 25, pct, 3, 1); - } + } + + /* Only some bits in error */ + n = 0; + if (vv->erri.ebits & 0xf) n++; + if (vv->erri.ebits & 0xf0) n++; + if (vv->erri.ebits & 0xf00) n++; + if (vv->erri.ebits & 0xf000) n++; + if (vv->erri.ebits & 0xf0000) n++; + if (vv->erri.ebits & 0xf00000) n++; + if (vv->erri.ebits & 0xf000000) n++; + if (vv->erri.ebits & 0xf0000000) n++; + pct += (8-n)*2; + + /* Adjust the score */ + pct = pct*100/22; + /* + if (pct > 100) { + pct = 100; + } + */ + dprint(LINE_HEADER+0, 25, pct, 3, 1); + } - /* We can't do the elapsed time unless the rdtsc instruction - * is supported - */ - if (cpu_id.fid.bits.rdtsc) { - asm __volatile__( - "rdtsc":"=a" (l),"=d" (h)); - asm __volatile__ ( - "subl %2,%0\n\t" - "sbbl %3,%1" - :"=a" (l), "=d" (h) - :"g" (v->startl), "g" (v->starth), - "0" (l), "1" (h)); - t = h * ((unsigned)0xffffffff / v->clks_msec) / 1000; - t += (l / v->clks_msec) / 1000; - i = t % 60; - j = i % 10; + /* We can't do the elapsed time unless the rdtsc instruction + * is supported + */ + if (cpu_id.fid.bits.rdtsc) { + asm __volatile__( + "rdtsc":"=a" (l),"=d" (h)); + asm __volatile__ ( + "subl %2,%0\n\t" + "sbbl %3,%1" + :"=a" (l), "=d" (h) + :"g" (vv->startl), "g" (vv->starth), + "0" (l), "1" (h)); + t = h * ((unsigned)0xffffffff / vv->clks_msec) / 1000; + t += (l / vv->clks_msec) / 1000; + i = t % 60; + j = i % 10; - if(j != v->each_sec) - { + if(j != vv->each_sec) + { - dprint(LINE_TIME, COL_TIME+9, i % 10, 1, 0); - dprint(LINE_TIME, COL_TIME+8, i / 10, 1, 0); - t /= 60; - i = t % 60; - dprint(LINE_TIME, COL_TIME+6, i % 10, 1, 0); - dprint(LINE_TIME, COL_TIME+5, i / 10, 1, 0); - t /= 60; - dprint(LINE_TIME, COL_TIME, t, 4, 0); + dprint(LINE_TIME, COL_TIME+9, i % 10, 1, 0); + dprint(LINE_TIME, COL_TIME+8, i / 10, 1, 0); + t /= 60; + i = t % 60; + dprint(LINE_TIME, COL_TIME+6, i % 10, 1, 0); + dprint(LINE_TIME, COL_TIME+5, i / 10, 1, 0); + t /= 60; + dprint(LINE_TIME, COL_TIME, t, 4, 0); - if(v->check_temp > 0 && !(v->fail_safe & 4)) - { - coretemp(); - } - v->each_sec = j; - } - - } - - - - /* Poll for ECC errors */ -/* - poll_errors(); -*/ + if(vv->check_temp > 0 && !(vv->fail_safe & 4)) + { + coretemp(); + } + vv->each_sec = j; + } + } + + /* Poll for ECC errors */ + /* + poll_errors(); + */ } - @@ -55,129 +55,125 @@ extern int dmi_err_cnts[MAX_DMI_MEMDEVS]; /* 3: MP SMP - 4-7: RSVD */ void failsafe(int msec, int scs) { - int i; - ulong sh, sl, l, h, t; - unsigned char c; - volatile char *pp; - - for(i=0, pp=(char *)(SCREEN_ADR+(18*160)+(18*2)+1); i<40; i++, pp+=2) { - *pp = 0x1E; - } - for(i=0, pp=(char *)(SCREEN_ADR+(18*160)+(18*2)+1); i<3; i++, pp+=2) { - *pp = 0x9E; - } - for(i=0, pp=(char *)(SCREEN_ADR+(18*160)+(55*2)+1); i<3; i++, pp+=2) { - *pp = 0x9E; - } + int i; + ulong sh, sl, l, h, t; + unsigned char c; + volatile char *pp; - cprint(18, 18, "==> Press F1 to enter Fail-Safe Mode <=="); + for(i=0, pp=(char *)(SCREEN_ADR+(18*160)+(18*2)+1); i<40; i++, pp+=2) { + *pp = 0x1E; + } + for(i=0, pp=(char *)(SCREEN_ADR+(18*160)+(18*2)+1); i<3; i++, pp+=2) { + *pp = 0x9E; + } + for(i=0, pp=(char *)(SCREEN_ADR+(18*160)+(55*2)+1); i<3; i++, pp+=2) { + *pp = 0x9E; + } + + cprint(18, 18, "==> Press F1 to enter Fail-Safe Mode <=="); - if(v->fail_safe & 2) - { - cprint(19, 15, "==> Press F2 to force Multi-Threading (SMP) <=="); - } - - /* save the starting time */ - asm __volatile__( - "rdtsc":"=a" (sl),"=d" (sh)); - - /* loop for n seconds */ - while (1) { - asm __volatile__( - "rdtsc":"=a" (l),"=d" (h)); - asm __volatile__ ( - "subl %2,%0\n\t" - "sbbl %3,%1" - :"=a" (l), "=d" (h) - :"g" (sl), "g" (sh), - "0" (l), "1" (h)); - - t = h * ((unsigned)0xffffffff / v->clks_msec); - t += (l / v->clks_msec); - - /* Is the time up? */ - if (t >= msec) { break; } + if(vv->fail_safe & 2) + { + cprint(19, 15, "==> Press F2 to force Multi-Threading (SMP) <=="); + } + + /* save the starting time */ + asm __volatile__ + ("rdtsc":"=a" (sl),"=d" (sh)); + + /* loop for n seconds */ + while (1) { + asm __volatile__( + "rdtsc":"=a" (l),"=d" (h)); + asm __volatile__ ( + "subl %2,%0\n\t" + "sbbl %3,%1" + :"=a" (l), "=d" (h) + :"g" (sl), "g" (sh), + "0" (l), "1" (h)); + + t = h * ((unsigned)0xffffffff / vv->clks_msec); + t += (l / vv->clks_msec); + + /* Is the time up? */ + if (t >= msec) { break; } - /* Is expected Scan code pressed? */ - c = get_key(); - c &= 0x7f; + /* Is expected Scan code pressed? */ + c = get_key(); + c &= 0x7f; - /* F1 */ - if(c == scs) { v->fail_safe |= 1; break; } + /* F1 */ + if(c == scs) { vv->fail_safe |= 1; break; } - /* F2 */ - if(c == scs+1) - { - v->fail_safe ^= 2; - break; - - } + /* F2 */ + if(c == scs+1) + { + vv->fail_safe ^= 2; + break; + + } - /* F3 */ - if(c == scs+2) - { - if(v->fail_safe & 2) { v->fail_safe ^= 2; } - v->fail_safe |= 8; - break; - } - - } - - cprint(18, 18, " "); - cprint(19, 15, " "); - - for(i=0, pp=(char *)(SCREEN_ADR+(18*160)+(18*2)+1); i<40; i++, pp+=2) { - *pp = 0x17; - } - + /* F3 */ + if(c == scs+2) + { + if(vv->fail_safe & 2) { vv->fail_safe ^= 2; } + vv->fail_safe |= 8; + break; + } + } + + cprint(18, 18, " "); + cprint(19, 15, " "); + + for(i=0, pp=(char *)(SCREEN_ADR+(18*160)+(18*2)+1); i<40; i++, pp+=2) { + *pp = 0x17; + } } - - static void display_init(void) { - int i; - volatile char *pp; + int i; + volatile char *pp; - /* Set HW cursor out of screen boundaries */ - __outb(0x0F, 0x03D4); - __outb(0xFF, 0x03D5); - - __outb(0x0E, 0x03D4); - __outb(0xFF, 0x03D5); - - - serial_echo_init(); - serial_echo_print("[LINE_SCROLL;24r"); /* Set scroll area row 7-23 */ - serial_echo_print("[H[2J"); /* Clear Screen */ - serial_echo_print("[37m[44m"); - serial_echo_print("[0m"); - serial_echo_print("[37m[44m"); - - /* Clear screen & set background to blue */ - for(i=0, pp=(char *)(SCREEN_ADR); i<80*24; i++) { - *pp++ = ' '; - *pp++ = 0x17; - } - - /* Make the name background green */ - for(i=0, pp=(char *)(SCREEN_ADR+1); i<TITLE_WIDTH; i++, pp+=2) { - *pp = 0x20; - } - cprint(0, 0, " Memtest86 5.01 "); - - /* Set Blinking "+" */ - for(i=0, pp=(char *)(SCREEN_ADR+1); i<2; i++, pp+=30) { - *pp = 0xA4; - } - cprint(0, 15, "+"); - - /* Do reverse video for the bottom display line */ - for(i=0, pp=(char *)(SCREEN_ADR+1+(24 * 160)); i<80; i++, pp+=2) { - *pp = 0x71; - } - - serial_echo_print("[0m"); + /* Set HW cursor out of screen boundaries */ + __outb(0x0F, 0x03D4); + __outb(0xFF, 0x03D5); + + __outb(0x0E, 0x03D4); + __outb(0xFF, 0x03D5); + + + serial_echo_init(); + serial_echo_print("[LINE_SCROLL;24r"); /* Set scroll area row 7-23 */ + serial_echo_print("[H[2J"); /* Clear Screen */ + serial_echo_print("[37m[44m"); + serial_echo_print("[0m"); + serial_echo_print("[37m[44m"); + + /* Clear screen & set background to blue */ + for(i=0, pp=(char *)(SCREEN_ADR); i<80*24; i++) { + *pp++ = ' '; + *pp++ = 0x17; + } + + /* Make the name background green */ + for(i=0, pp=(char *)(SCREEN_ADR+1); i<TITLE_WIDTH; i++, pp+=2) { + *pp = 0x20; + } + cprint(0, 0, " Memtest86 5.31b "); + + /* Set Blinking "+" */ + for(i=0, pp=(char *)(SCREEN_ADR+1); i<2; i++, pp+=30) { + *pp = 0xA4; + } + cprint(0, 15, "+"); + + /* Do reverse video for the bottom display line */ + for(i=0, pp=(char *)(SCREEN_ADR+1+(24 * 160)); i<80; i++, pp+=2) { + *pp = 0x71; + } + + serial_echo_print("[0m"); } /* @@ -185,149 +181,148 @@ static void display_init(void) */ void init(void) { - int i; + int i; - outb(0x8, 0x3f2); /* Kill Floppy Motor */ + outb(0x8, 0x3f2); /* Kill Floppy Motor */ - /* Turn on cache */ - set_cache(1); + /* Turn on cache */ + set_cache(1); - /* Setup the display */ - display_init(); + /* Setup the display */ + display_init(); - cprint(5, 60, "| Time: 0:00:00"); - cprint(1, COL_MID,"Pass %"); - cprint(2, COL_MID,"Test %"); - cprint(3, COL_MID,"Test #"); - cprint(4, COL_MID,"Testing: "); - cprint(5, COL_MID,"Pattern: "); - cprint(1, 0, "CLK: (32b Mode)"); - cprint(2, 0, "L1 Cache: Unknown "); - cprint(3, 0, "L2 Cache: Unknown "); - cprint(4, 0, "L3 Cache: None "); - cprint(5, 0, "Memory : "); - cprint(6, 0, "------------------------------------------------------------------------------"); - cprint(7, 0, "Core#:"); - cprint(8, 0, "State:"); - cprint(9, 0, "Cores: Active / Total (Run: All) | Pass: 0 Errors: 0 "); - cprint(10, 0, "------------------------------------------------------------------------------"); - - /* + cprint(5, 60, "| Time: 0:00:00"); + cprint(1, COL_MID,"Pass %"); + cprint(2, COL_MID,"Test %"); + cprint(3, COL_MID,"Test #"); + cprint(4, COL_MID,"Testing: "); + cprint(5, COL_MID,"Pattern: "); + cprint(1, 0, "CLK: (32b Mode)"); + cprint(2, 0, "L1 Cache: Unknown "); + cprint(3, 0, "L2 Cache: Unknown "); + cprint(4, 0, "L3 Cache: None "); + cprint(5, 0, "Memory : "); + cprint(6, 0, "------------------------------------------------------------------------------"); + cprint(7, 0, "Core#:"); + cprint(8, 0, "State:"); + cprint(9, 0, "Cores: Active / Total (Run: All) | Pass: 0 Errors: 0 "); + cprint(10, 0, "------------------------------------------------------------------------------"); + + /* for(i=0, pp=(char *)(SCREEN_ADR+(5*160)+(53*2)+1); i<20; i++, pp+=2) { - *pp = 0x92; + *pp = 0x92; } - + for(i=0, pp=(char *)(SCREEN_ADR+0*160+1); i<80; i++, pp+=2) { - *pp = 0x47; + *pp = 0x47; } - */ - - cprint(7, 39, "| Chipset : Unknown"); - cprint(8, 39, "| Memory Type : Unknown"); + */ + cprint(7, 39, "| Chipset : Unknown"); + cprint(8, 39, "| Memory Type : Unknown"); - for(i=0; i < 6; i++) { - cprint(i, COL_MID-2, "| "); - } - - footer(); - - aprint(5, 10, v->test_pages); - - v->pass = 0; - v->msg_line = 0; - v->ecount = 0; - v->ecc_ecount = 0; - v->testsel = -1; - v->msg_line = LINE_SCROLL-1; - v->scroll_start = v->msg_line * 160; - v->erri.low_addr.page = 0x7fffffff; - v->erri.low_addr.offset = 0xfff; - v->erri.high_addr.page = 0; - v->erri.high_addr.offset = 0; - v->erri.min_bits = 32; - v->erri.max_bits = 0; - v->erri.min_bits = 32; - v->erri.max_bits = 0; - v->erri.maxl = 0; - v->erri.cor_err = 0; - v->erri.ebits = 0; - v->erri.hdr_flag = 0; - v->erri.tbits = 0; - for (i=0; tseq[i].msg != NULL; i++) { - tseq[i].errors = 0; - } - if (dmi_initialized) { - for (i=0; i < MAX_DMI_MEMDEVS; i++){ - if (dmi_err_cnts[i] > 0) { - dmi_err_cnts[i] = 0; - } - } - } + for(i=0; i < 6; i++) { + cprint(i, COL_MID-2, "| "); + } - /* setup beep mode */ - beepmode = BEEP_MODE; + footer(); + + aprint(5, 10, vv->test_pages); + + vv->pass = 0; + vv->msg_line = 0; + vv->ecount = 0; + vv->ecc_ecount = 0; + vv->testsel = -1; + vv->msg_line = LINE_SCROLL-1; + vv->scroll_start = vv->msg_line * 160; + vv->erri.low_addr.page = 0x7fffffff; + vv->erri.low_addr.offset = 0xfff; + vv->erri.high_addr.page = 0; + vv->erri.high_addr.offset = 0; + vv->erri.min_bits = 32; + vv->erri.max_bits = 0; + vv->erri.min_bits = 32; + vv->erri.max_bits = 0; + vv->erri.maxl = 0; + vv->erri.cor_err = 0; + vv->erri.ebits = 0; + vv->erri.hdr_flag = 0; + vv->erri.tbits = 0; + for (i=0; tseq[i].msg != NULL; i++) { + tseq[i].errors = 0; + } + if (dmi_initialized) { + for (i=0; i < MAX_DMI_MEMDEVS; i++){ + if (dmi_err_cnts[i] > 0) { + dmi_err_cnts[i] = 0; + } + } + } - /* Get the cpu and cache information */ - get_cpuid(); + /* setup beep mode */ + beepmode = BEEP_MODE; - /* setup pci */ - pci_init(); + /* Get the cpu and cache information */ + get_cpuid(); - get_cache_size(); + /* setup pci */ + pci_init(); - cpu_type(); + get_cache_size(); - cpu_cache_speed(); + cpu_type(); - /* Check fail safe */ - failsafe(5000, 0x3B); + cpu_cache_speed(); - /* Initalize SMP */ - initialise_cpus(); - - for (i = 0; i <num_cpus; i++) { - dprint(7, i+7, i%10, 1, 0); - cprint(8, i+7, "S"); - } + /* Check fail safe */ + failsafe(5000, 0x3B); - dprint(9, 19, num_cpus, 2, 0); + /* Initalize SMP */ + initialise_cpus(); - if((v->fail_safe & 3) == 2) - { - cprint(LINE_CPU,9, "(SMP: Disabled)"); - cprint(LINE_RAM,9, "Running..."); - } - // dprint(10, 5, found_cpus, 2, 0); + for (i = 0; i <num_cpus; i++) { + dprint(7, i+7, i%10, 1, 0); + cprint(8, i+7, "S"); + } - /* Find Memory Specs */ - if(v->fail_safe & 1) - { - cprint(LINE_CPU, COL_SPEC, " **** FAIL SAFE **** FAIL SAFE **** "); - cprint(LINE_RAM, COL_SPEC, " No detection, same reliability "); - } else { - find_controller(); - get_spd_spec(); - if(num_cpus <= 16 && !(v->fail_safe & 4)) { coretemp(); } - } + dprint(9, 19, num_cpus, 2, 0); - if(v->check_temp > 0 && !(v->fail_safe & 4)) - { - cprint(LINE_CPU, 26, "| CPU Temp"); - cprint(LINE_CPU+1, 26, "| øC"); - } + if((vv->fail_safe & 3) == 2) + { + cprint(LINE_CPU,9, "(SMP: Disabled)"); + cprint(LINE_RAM,9, "Running..."); + } + // dprint(10, 5, found_cpus, 2, 0); + + /* Find Memory Specs */ + if(vv->fail_safe & 1) + { + cprint(LINE_CPU, COL_SPEC, " **** FAIL SAFE **** FAIL SAFE **** "); + cprint(LINE_RAM, COL_SPEC, " No detection, same reliability "); + } else { + find_controller(); + get_spd_spec(); + if(num_cpus <= 16 && !(vv->fail_safe & 4)) { coretemp(); } + } + + if(vv->check_temp > 0 && !(vv->fail_safe & 4)) + { + cprint(LINE_CPU, 26, "| CPU Temp"); + cprint(LINE_CPU+1, 26, "| øC"); + } - beep(600); - beep(1000); + beep(600); + beep(1000); - /* Record the start time */ - asm __volatile__ ("rdtsc":"=a" (v->startl),"=d" (v->starth)); - v->snapl = v->startl; - v->snaph = v->starth; - if (l1_cache == 0) { l1_cache = 64; } - if (l2_cache == 0) { l1_cache = 512; } - v->printmode=PRINTMODE_ADDRESSES; - v->numpatn=0; + /* Record the start time */ + asm __volatile__ ("rdtsc":"=a" (vv->startl),"=d" (vv->starth)); + vv->snapl = vv->startl; + vv->snaph = vv->starth; + if (l1_cache == 0) { l1_cache = 64; } + if (l2_cache == 0) { l1_cache = 512; } + vv->printmode=PRINTMODE_ADDRESSES; + vv->numpatn=0; } /* Get cache sizes for most AMD and Intel CPUs, exceptions for old CPUs are @@ -577,13 +572,13 @@ void detect_imc(void) { case 0x5: if(cpu_id.vers.bits.extendedModel == 2) { imc_type = 0x0003; } // Core i3/i5 1st Gen 45 nm (NHM) - if(cpu_id.vers.bits.extendedModel == 3) { v->fail_safe |= 4; } // Atom Clover Trail + if(cpu_id.vers.bits.extendedModel == 3) { vv->fail_safe |= 4; } // Atom Clover Trail if(cpu_id.vers.bits.extendedModel == 4) { imc_type = 0x0007; } // HSW-ULT break; case 0x6: if(cpu_id.vers.bits.extendedModel == 3) { imc_type = 0x0009; // Atom Cedar Trail - v->fail_safe |= 4; // Disable Core temp + vv->fail_safe |= 4; // Disable Core temp } break; case 0xA: @@ -605,7 +600,7 @@ void detect_imc(void) { case 0x1: if(cpu_id.vers.bits.stepping > 9) { imc_type = 0x0008; } // Atom PineView - v->fail_safe |= 4; // Disable Core temp + vv->fail_safe |= 4; // Disable Core temp break; case 0x2: imc_type = 0x0002; // Core i7 1st Gen 32 nm (WMR) @@ -632,16 +627,16 @@ void smp_default_mode(void) { int i, result; char *cpupsn = cpu_id.brand_id.char_array; - char *disabledcpu[] = { "Opteron", "Xeon", "Genuine Intel" }; + char *disabledcpu[] = { "Opteron", "Xeon", "EPYC", "Genuine Intel" }; for(i = 0; i < 3; i++) { - result = strstr(cpupsn , disabledcpu[i]); - if(result != -1) { v->fail_safe |= 0b10; } + result = mt86_strstr(cpupsn , disabledcpu[i]); + if(result != -1) { vv->fail_safe |= 0b10; } } // For 5.01 release, SMP disabled by defualt by config.h toggle - if(CONSERVATIVE_SMP) { v->fail_safe |= 0b10; } + if(CONSERVATIVE_SMP) { vv->fail_safe |= 0b10; } } @@ -1095,8 +1090,8 @@ void get_mem_speed(int me, int ncpus) /* Make sure that we have enough memory to do the test */ /* If not use all we have */ - if ((1 + (i * 2)) > (v->plim_upper << 2)) { - i = ((v->plim_upper <<2) - 1) / 2; + if ((1 + (i * 2)) > (vv->plim_upper << 2)) { + i = ((vv->plim_upper <<2) - 1) / 2; } speed = memspeed(STEST_ADDR, i * 1024, 100); @@ -1144,11 +1139,11 @@ static int cpuspeed(void) if (loops < 4 || end_low < 50000) { return(-1); } - v->clks_msec = end_low/50; + vv->clks_msec = end_low/50; if (tsc_invariable) end_low = correct_tsc(end_low); - return(v->clks_msec); + return(vv->clks_msec); } /* Measure cache speed by copying a block of memory. */ @@ -1258,7 +1253,7 @@ ulong memspeed(ulong src, ulong len, int iter) if (tsc_invariable) end_low = correct_tsc(end_low); - return((v->clks_msec)/end_low); + return((vv->clks_msec)/end_low); } #define rdmsr(msr,val1,val2) \ @@ -31,7 +31,7 @@ */ #define __OUT1(s,x) \ -extern inline void __out##s(unsigned x value, unsigned short port) { +static inline void __out##s(unsigned x value, unsigned short port) { #define __OUT2(s,s1,s2) \ __asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" @@ -43,7 +43,7 @@ __OUT1(s##_p,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); SLOW_DOWN_IO; } \ __OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); SLOW_DOWN_IO; } #define __IN1(s) \ -extern inline RETURN_TYPE __in##s(unsigned short port) { RETURN_TYPE _v; +static inline RETURN_TYPE __in##s(unsigned short port) { RETURN_TYPE _v; #define __IN2(s,s1,s2) \ __asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" @@ -55,7 +55,7 @@ __IN1(s##_p) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; retu __IN1(s##c_p) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; } #define __OUTS(s) \ -extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \ +static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \ { __asm__ __volatile__ ("cld ; rep ; outs" #s \ : "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); } @@ -116,3 +116,18 @@ __OUTS(l) __inlc(port) : \ __inl(port)) #endif + +static __inline void +outb_p (unsigned char __value, unsigned short int __port ) +{ + __asm__ __volatile__ ("outb %b0,%w1\noutb %%al,$0x80": :"a" (__value), + "Nd" (__port)); +} + +static __inline unsigned char +inb_p (unsigned short int __port) +{ + unsigned char _v; + __asm__ __volatile__ ("inb %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (__port)); + return _v; +}
\ No newline at end of file @@ -1,986 +1,985 @@ -/* MemTest86+ V5 Specific code (GPL V2.0)
- * By Samuel DEMEULEMEESTER, sdemeule@memtest.org
- * http://www.canardpc.com - http://www.memtest.org
- * ------------------------------------------------
- * Based on JEDEC JEP106-AG - January 2012
- * All mo
- */
-
-struct spd_jedec_manufacturer {
- unsigned cont_code;
- unsigned hex_byte;
- char *name;
-};
-
-static 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"},
- { 0, 0x8f, "National"},
- { 0, 0x10, "NEC"},
- { 0, 0x91, "RCA"},
- { 0, 0x92, "Raytheon"},
- { 0, 0x13, "Conexant"},
-// { 0, 0x94, "Seeq"},
- { 0, 0x15, "NXP"},
- { 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"},
- { 0, 0xad, "Hynix"},
- { 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, "Oracle"},
-// { 0, 0xbf, "Silicon Storage Technology"},
- { 0, 0x40, "ProMos/Mosel"},
- { 0, 0xc1, "Infineon"},
-// { 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, "Integrated 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"},
-// { 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"},
-// { 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"},
-// { 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"},
- { 1, 0xd0, "Memory Card"},
-// { 1, 0x51, "CKD"},
-// { 1, 0x52, "Capital Instruments"},
-// { 1, 0xd3, "Aica Kogyo"},
-// { 1, 0x54, "Linvex Technology"},
- { 1, 0xd5, "MSC"},
-// { 1, 0xd6, "AKM Company"},
-// { 1, 0x57, "Dynamem"},
-// { 1, 0x58, "NERA ASA"},
-// { 1, 0xd9, "GSI Technology"},
- { 1, 0xda, "Dane-Elec"},
-// { 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"},
-// { 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"},
-// { 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"},
-// { 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, "Princeton"},
- { 3, 0x0b, "Nanya"},
-// { 3, 0x8c, "Elite Flash Storage"},
-// { 3, 0x0d, "Mysticom"},
-// { 3, 0x0e, "LightSand Communications"},
- { 3, 0x8f, "ATI"},
-// { 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"},
- { 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"},
-// { 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"},
-// { 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"},
-// { 3, 0x57, "Pijnenburg Securealink"},
- { 3, 0x58, "takeMS"},
-// { 3, 0xd9, "Cambridge Silicon Radio"},
- { 3, 0xda, "Swissbit"},
-// { 3, 0x5b, "Nazomi Communications"},
-// { 3, 0xdc, "eWave System"},
-// { 3, 0x5d, "Rockwell Collins"},
-// { 3, 0x5e, "Picocel (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"},
-// { 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"},
-// { 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"},
-// { 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"},
-// { 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"},
-// { 4, 0x4c, "VirtualDigm"},
- { 4, 0xcd, "G.Skill"},
-// { 4, 0xce, "Quanta Computer"},
-// { 4, 0x4f, "Yield Microelectronics"},
-// { 4, 0xd0, "Afa Technologies"},
- { 4, 0x51, "Kingbox"},
-// { 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 KG"},
-// { 4, 0x7c, "Eudar Technology"},
-// { 4, 0xfd, "Focus Enhancements"},
-// { 4, 0xfe, "Xyratex"},
-// { 5, 0x01, "Specular Networks"},
- { 5, 0x02, "Patriot Memory"},
-// { 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"},
-// { 5, 0x15, "c2 Microsystems"},
-// { 5, 0x16, "Level5 Networks"},
- { 5, 0x97, "COS Memory"},
-// { 5, 0x98, "Innovasic Semiconductor"},
-// { 5, 0x19, "02IC"},
-// { 5, 0x1a, "Tabula"},
- { 5, 0x9b, "Crucial"},
-// { 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"},
-// { 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"},
-// { 5, 0xbc, "Kian Tech LLC"},
-// { 5, 0x3d, "Artimi"},
- { 5, 0x3e, "PQI"},
-// { 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, "MSI"},
-// { 5, 0xc7, "Rapport"},
-// { 5, 0xc8, "Makway International"},
-// { 5, 0x49, "Broad Reach Engineering"},
-// { 5, 0x4a, "Semiconductor Mfg Intl Corp"},
-// { 5, 0xcb, "SiConnect"},
-// { 5, 0x4c, "FCI USA"},
-// { 5, 0xcd, "Validity Sensors"},
-// { 5, 0xce, "Coney Technology"},
-// { 5, 0x4f, "Spans Logic"},
-// { 5, 0xd0, "Neterion"},
- { 5, 0x51, "Qimonda"},
-// { 5, 0x52, "New Japan Radio"},
-// { 5, 0xd3, "Velogix"},
-// { 5, 0x54, "Montalvo Systems"},
-// { 5, 0xd5, "iVivity"},
- { 5, 0xd6, "Walton Chaintech"},
- { 5, 0x57, "AENEON"},
-// { 5, 0x58, "Lorom Industrial"},
-// { 5, 0xd9, "Radiospire Networks"},
-// { 5, 0xda, "Sensio Technologies"},
-// { 5, 0x5b, "Nethra Imaging"},
- { 5, 0xdc, "Hexon"},
-// { 5, 0x5d, "CompuStocx (CSX)"},
-// { 5, 0x5e, "Methode Electronics"},
-// { 5, 0xdf, "Connect One"},
-// { 5, 0xe0, "Opulan Technologies"},
-// { 5, 0x61, "Septentrio NV"},
- { 5, 0x62, "Goldenmars"},
- { 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"},
-// { 5, 0xef, "MetaRAM"},
-// { 5, 0x70, "Axel Electronics"},
-// { 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"},
-// { 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"},
-// { 6, 0xa7, "Kingxcon"},
- { 6, 0xa8, "SiS"},
-// { 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"},
- { 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"},
-// { 6, 0x3d, "Space Micro"},
-// { 6, 0x3e, "Wilocity"},
-// { 6, 0xbf, "Novafora, Ic."},
-// { 6, 0x40, "iKoa"},
- { 6, 0xc1, "ASint"},
- { 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"},
- { 6, 0x4f, "TOPRAM"},
-// { 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"},
-// { 6, 0x75, "CopperGate Communications"},
-// { 6, 0x76, "Holtek Semiconductor"},
-// { 6, 0xf7, "Myson Century"},
-// { 6, 0xf8, "FIDELIX"},
-// { 6, 0x79, "Red Digital Cinema"},
-// { 6, 0x7a, "Densbits Technology"},
-// { 6, 0xfb, "Zempro"},
-// { 6, 0x7c, "MoSys"},
-// { 6, 0xfd, "Provigent"},
-// { 6, 0xfe, "Triad Semiconductor"},
-// { 8, 0x01, "Siklu Communication"},
-// { 8, 0x02, "A Force Manufacturing"},
- { 8, 0x83, "Strontium"},
-// { 8, 0x04, "Abilis Systems"},
-// { 8, 0x85, "Siglead"},
-// { 8, 0x86, "Ubicom"},
-// { 8, 0x07, "Unifosa"},
-// { 8, 0x08, "Stretch"},
-// { 8, 0x89, "Lantiq Deutschland"},
-// { 8, 0x8a, "Visipro."},
- { 8, 0x0b, "EKMemory"},
-// { 8, 0x8c, "Microelectronics Institute ZTE"},
-// { 8, 0x0d, "Cognovo"},
-// { 8, 0x0e, "Carry Technology"},
- { 8, 0x8f, "Nokia"},
- { 8, 0x10, "King Tiger"},
-// { 8, 0x91, "Sierra Wireless"},
- { 8, 0x92, "HT Micron"},
- { 8, 0x13, "Albatron"},
-// { 8, 0x94, "Leica Geosystems AG"},
-// { 8, 0x15, "BroadLight"},
-// { 8, 0x16, "AEXEA"},
-// { 8, 0x97, "ClariPhy Communications"},
-// { 8, 0x98, "Green Plug"},
-// { 8, 0x19, "Design Art Networks"},
-// { 8, 0x1a, "Mach Xtreme Technology"},
-// { 8, 0x9b, "ATO Solutions"},
-// { 8, 0x1c, "Ramsta"},
-// { 8, 0x9d, "Greenliant Systems"},
-// { 8, 0x9e, "Teikon"},
-// { 8, 0x1f, "Antec Hadron"},
-// { 8, 0x20, "NavCom Technology"},
-// { 8, 0xa1, "Shanghai Fudan Microelectronics"},
-// { 8, 0xa2, "Calxeda"},
-// { 8, 0x23, "JSC EDC Electronics"},
-// { 8, 0xa4, "Kandit Technology"},
-// { 8, 0x25, "Ramos Technology"},
-// { 8, 0x26, "Goldenmars Technology"},
-// { 8, 0xa7, "XeL Technology"},
-// { 8, 0xa8, "Newzone"},
- { 8, 0x29, "MercyPower"},
-// { 8, 0x2a, "Nanjing Yihuo Technology."},
-// { 8, 0xab, "Nethra Imaging"},
-// { 8, 0x2c, "SiTel Semiconductor BV"},
-// { 8, 0xad, "SolidGear"},
- { 8, 0xae, "Topower"},
-// { 8, 0x2f, "Wilocity"},
-// { 8, 0xb0, "Profichip"},
-// { 8, 0x31, "Gerad Technologies"},
- { 8, 0x32, "Ritek"},
-// { 8, 0xb3, "Gomos Technology Limited"},
- { 8, 0x34, "Memoright"},
-// { 8, 0xb5, "D-Broad"},
-// { 8, 0xb6, "HiSilicon Technologies"},
-// { 8, 0x37, "Syndiant ."},
-// { 8, 0x38, "Enverv"},
-// { 8, 0xb9, "Cognex"},
-// { 8, 0xba, "Xinnova Technology"},
- { 8, 0x3b, "Ultron"},
-// { 8, 0xbc, "Concord Idea"},
-// { 8, 0x3d, "AIM"},
-// { 8, 0x3e, "Lifetime Memory Products"},
-// { 8, 0xbf, "Ramsway"},
-// { 8, 0x40, "Recore Systems B.V."},
-// { 8, 0xc1, "Haotian Jinshibo Science Tech"},
-// { 8, 0xc2, "Being Advanced Memory"},
-// { 8, 0x43, "Adesto Technologies"},
-// { 8, 0xc4, "Giantec Semiconductor"},
-// { 8, 0x45, "HMD Electronics AG"},
-// { 8, 0x46, "Gloway International (HK)"},
-// { 8, 0xc7, "Kingcore"},
-// { 8, 0xc8, "Anucell Technology Holding"},
-// { 8, 0x49, "Accord Software & Systems Pvt."},
-// { 8, 0x4a, "Active-Semi"},
-// { 8, 0xcb, "Denso"},
-// { 8, 0x4c, "TLSI"},
-// { 8, 0xcd, "Shenzhen Daling Electronic"},
-// { 8, 0xce, "Mustang"},
-// { 8, 0x4f, "Orca Systems"},
-// { 8, 0xd0, "Passif Semiconductor"},
-// { 8, 0x51, "GigaDevice Semiconductor (Beijing)"},
-// { 8, 0x52, "Memphis Electronic"},
-// { 8, 0xd3, "Beckhoff Automation"},
-// { 8, 0x54, "Harmony Semiconductor Corp"},
-// { 8, 0xd5, "Air Computers SRL"},
- { 8, 0xd6, "TMT Memory"},
- { 9, 0xff, ""}
-};
-
+/* MemTest86+ V5 Specific code (GPL V2.0) + * By Samuel DEMEULEMEESTER, sdemeule@memtest.org + * http://www.canardpc.com - http://www.memtest.org + * ------------------------------------------------ + * Based on JEDEC JEP106-AG - January 2012 + */ + +struct spd_jedec_manufacturer { + unsigned cont_code; + unsigned hex_byte; + char *name; +}; + +static 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"}, + { 0, 0x8f, "National"}, + { 0, 0x10, "NEC"}, + { 0, 0x91, "RCA"}, + { 0, 0x92, "Raytheon"}, + { 0, 0x13, "Conexant"}, + // { 0, 0x94, "Seeq"}, + { 0, 0x15, "NXP"}, + { 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"}, + { 0, 0xad, "Hynix"}, + { 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, "Oracle"}, + // { 0, 0xbf, "Silicon Storage Technology"}, + { 0, 0x40, "ProMos/Mosel"}, + { 0, 0xc1, "Infineon"}, + // { 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, "Integrated 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"}, + // { 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"}, + // { 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"}, + // { 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"}, + { 1, 0xd0, "Memory Card"}, + // { 1, 0x51, "CKD"}, + // { 1, 0x52, "Capital Instruments"}, + // { 1, 0xd3, "Aica Kogyo"}, + // { 1, 0x54, "Linvex Technology"}, + { 1, 0xd5, "MSC"}, + // { 1, 0xd6, "AKM Company"}, + // { 1, 0x57, "Dynamem"}, + // { 1, 0x58, "NERA ASA"}, + // { 1, 0xd9, "GSI Technology"}, + { 1, 0xda, "Dane-Elec"}, + // { 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"}, + // { 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"}, + // { 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"}, + // { 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, "Princeton"}, + { 3, 0x0b, "Nanya"}, + // { 3, 0x8c, "Elite Flash Storage"}, + // { 3, 0x0d, "Mysticom"}, + // { 3, 0x0e, "LightSand Communications"}, + { 3, 0x8f, "ATI"}, + // { 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"}, + { 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"}, + // { 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"}, + // { 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"}, + // { 3, 0x57, "Pijnenburg Securealink"}, + { 3, 0x58, "takeMS"}, + // { 3, 0xd9, "Cambridge Silicon Radio"}, + { 3, 0xda, "Swissbit"}, + // { 3, 0x5b, "Nazomi Communications"}, + // { 3, 0xdc, "eWave System"}, + // { 3, 0x5d, "Rockwell Collins"}, + // { 3, 0x5e, "Picocel (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"}, + // { 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"}, + // { 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"}, + // { 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"}, + // { 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"}, + // { 4, 0x4c, "VirtualDigm"}, + { 4, 0xcd, "G.Skill"}, + // { 4, 0xce, "Quanta Computer"}, + // { 4, 0x4f, "Yield Microelectronics"}, + // { 4, 0xd0, "Afa Technologies"}, + { 4, 0x51, "Kingbox"}, + // { 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 KG"}, + // { 4, 0x7c, "Eudar Technology"}, + // { 4, 0xfd, "Focus Enhancements"}, + // { 4, 0xfe, "Xyratex"}, + // { 5, 0x01, "Specular Networks"}, + { 5, 0x02, "Patriot Memory"}, + // { 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"}, + // { 5, 0x15, "c2 Microsystems"}, + // { 5, 0x16, "Level5 Networks"}, + { 5, 0x97, "COS Memory"}, + // { 5, 0x98, "Innovasic Semiconductor"}, + // { 5, 0x19, "02IC"}, + // { 5, 0x1a, "Tabula"}, + { 5, 0x9b, "Crucial"}, + // { 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"}, + // { 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"}, + // { 5, 0xbc, "Kian Tech LLC"}, + // { 5, 0x3d, "Artimi"}, + { 5, 0x3e, "PQI"}, + // { 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, "MSI"}, + // { 5, 0xc7, "Rapport"}, + // { 5, 0xc8, "Makway International"}, + // { 5, 0x49, "Broad Reach Engineering"}, + // { 5, 0x4a, "Semiconductor Mfg Intl Corp"}, + // { 5, 0xcb, "SiConnect"}, + // { 5, 0x4c, "FCI USA"}, + // { 5, 0xcd, "Validity Sensors"}, + // { 5, 0xce, "Coney Technology"}, + // { 5, 0x4f, "Spans Logic"}, + // { 5, 0xd0, "Neterion"}, + { 5, 0x51, "Qimonda"}, + // { 5, 0x52, "New Japan Radio"}, + // { 5, 0xd3, "Velogix"}, + // { 5, 0x54, "Montalvo Systems"}, + // { 5, 0xd5, "iVivity"}, + { 5, 0xd6, "Walton Chaintech"}, + { 5, 0x57, "AENEON"}, + // { 5, 0x58, "Lorom Industrial"}, + // { 5, 0xd9, "Radiospire Networks"}, + // { 5, 0xda, "Sensio Technologies"}, + // { 5, 0x5b, "Nethra Imaging"}, + { 5, 0xdc, "Hexon"}, + // { 5, 0x5d, "CompuStocx (CSX)"}, + // { 5, 0x5e, "Methode Electronics"}, + // { 5, 0xdf, "Connect One"}, + // { 5, 0xe0, "Opulan Technologies"}, + // { 5, 0x61, "Septentrio NV"}, + { 5, 0x62, "Goldenmars"}, + { 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"}, + // { 5, 0xef, "MetaRAM"}, + // { 5, 0x70, "Axel Electronics"}, + // { 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"}, + // { 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"}, + // { 6, 0xa7, "Kingxcon"}, + { 6, 0xa8, "SiS"}, + // { 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"}, + { 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"}, + // { 6, 0x3d, "Space Micro"}, + // { 6, 0x3e, "Wilocity"}, + // { 6, 0xbf, "Novafora, Ic."}, + // { 6, 0x40, "iKoa"}, + { 6, 0xc1, "ASint"}, + { 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"}, + { 6, 0x4f, "TOPRAM"}, + // { 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"}, + // { 6, 0x75, "CopperGate Communications"}, + // { 6, 0x76, "Holtek Semiconductor"}, + // { 6, 0xf7, "Myson Century"}, + // { 6, 0xf8, "FIDELIX"}, + // { 6, 0x79, "Red Digital Cinema"}, + // { 6, 0x7a, "Densbits Technology"}, + // { 6, 0xfb, "Zempro"}, + // { 6, 0x7c, "MoSys"}, + // { 6, 0xfd, "Provigent"}, + // { 6, 0xfe, "Triad Semiconductor"}, + // { 8, 0x01, "Siklu Communication"}, + // { 8, 0x02, "A Force Manufacturing"}, + { 8, 0x83, "Strontium"}, + // { 8, 0x04, "Abilis Systems"}, + // { 8, 0x85, "Siglead"}, + // { 8, 0x86, "Ubicom"}, + // { 8, 0x07, "Unifosa"}, + // { 8, 0x08, "Stretch"}, + // { 8, 0x89, "Lantiq Deutschland"}, + // { 8, 0x8a, "Visipro."}, + { 8, 0x0b, "EKMemory"}, + // { 8, 0x8c, "Microelectronics Institute ZTE"}, + // { 8, 0x0d, "Cognovo"}, + // { 8, 0x0e, "Carry Technology"}, + { 8, 0x8f, "Nokia"}, + { 8, 0x10, "King Tiger"}, + // { 8, 0x91, "Sierra Wireless"}, + { 8, 0x92, "HT Micron"}, + { 8, 0x13, "Albatron"}, + // { 8, 0x94, "Leica Geosystems AG"}, + // { 8, 0x15, "BroadLight"}, + // { 8, 0x16, "AEXEA"}, + // { 8, 0x97, "ClariPhy Communications"}, + // { 8, 0x98, "Green Plug"}, + // { 8, 0x19, "Design Art Networks"}, + // { 8, 0x1a, "Mach Xtreme Technology"}, + // { 8, 0x9b, "ATO Solutions"}, + // { 8, 0x1c, "Ramsta"}, + // { 8, 0x9d, "Greenliant Systems"}, + // { 8, 0x9e, "Teikon"}, + // { 8, 0x1f, "Antec Hadron"}, + // { 8, 0x20, "NavCom Technology"}, + // { 8, 0xa1, "Shanghai Fudan Microelectronics"}, + // { 8, 0xa2, "Calxeda"}, + // { 8, 0x23, "JSC EDC Electronics"}, + // { 8, 0xa4, "Kandit Technology"}, + // { 8, 0x25, "Ramos Technology"}, + // { 8, 0x26, "Goldenmars Technology"}, + // { 8, 0xa7, "XeL Technology"}, + // { 8, 0xa8, "Newzone"}, + { 8, 0x29, "MercyPower"}, + // { 8, 0x2a, "Nanjing Yihuo Technology."}, + // { 8, 0xab, "Nethra Imaging"}, + // { 8, 0x2c, "SiTel Semiconductor BV"}, + // { 8, 0xad, "SolidGear"}, + { 8, 0xae, "Topower"}, + // { 8, 0x2f, "Wilocity"}, + // { 8, 0xb0, "Profichip"}, + // { 8, 0x31, "Gerad Technologies"}, + { 8, 0x32, "Ritek"}, + // { 8, 0xb3, "Gomos Technology Limited"}, + { 8, 0x34, "Memoright"}, + // { 8, 0xb5, "D-Broad"}, + // { 8, 0xb6, "HiSilicon Technologies"}, + // { 8, 0x37, "Syndiant ."}, + // { 8, 0x38, "Enverv"}, + // { 8, 0xb9, "Cognex"}, + // { 8, 0xba, "Xinnova Technology"}, + { 8, 0x3b, "Ultron"}, + // { 8, 0xbc, "Concord Idea"}, + // { 8, 0x3d, "AIM"}, + // { 8, 0x3e, "Lifetime Memory Products"}, + // { 8, 0xbf, "Ramsway"}, + // { 8, 0x40, "Recore Systems B.V."}, + // { 8, 0xc1, "Haotian Jinshibo Science Tech"}, + // { 8, 0xc2, "Being Advanced Memory"}, + // { 8, 0x43, "Adesto Technologies"}, + // { 8, 0xc4, "Giantec Semiconductor"}, + // { 8, 0x45, "HMD Electronics AG"}, + // { 8, 0x46, "Gloway International (HK)"}, + // { 8, 0xc7, "Kingcore"}, + // { 8, 0xc8, "Anucell Technology Holding"}, + // { 8, 0x49, "Accord Software & Systems Pvt."}, + // { 8, 0x4a, "Active-Semi"}, + // { 8, 0xcb, "Denso"}, + // { 8, 0x4c, "TLSI"}, + // { 8, 0xcd, "Shenzhen Daling Electronic"}, + // { 8, 0xce, "Mustang"}, + // { 8, 0x4f, "Orca Systems"}, + // { 8, 0xd0, "Passif Semiconductor"}, + // { 8, 0x51, "GigaDevice Semiconductor (Beijing)"}, + // { 8, 0x52, "Memphis Electronic"}, + // { 8, 0xd3, "Beckhoff Automation"}, + // { 8, 0x54, "Harmony Semiconductor Corp"}, + // { 8, 0xd5, "Air Computers SRL"}, + { 8, 0xd6, "TMT Memory"}, + { 9, 0xff, ""} + }; @@ -29,142 +29,142 @@ unsigned char serial_parity = 0; unsigned char serial_bits = 8; struct ascii_map_str { - int ascii; - int keycode; + int ascii; + int keycode; }; -inline void reboot(void) +void reboot(void) { - /* tell the BIOS to do a cold start */ - *((unsigned short *)0x472) = 0x0; + /* tell the BIOS to do a cold start */ + *((unsigned short *)0x472) = 0x0; - while(1) - { - outb(0xFE, 0x64); - outb(0x02, 0xcf9); /* reset that doesn't rely on the keyboard controller */ - outb(0x04, 0xcf9); - outb(0x0E, 0xcf9); - } + while(1) + { + outb(0xFE, 0x64); + outb(0x02, 0xcf9); /* reset that doesn't rely on the keyboard controller */ + outb(0x04, 0xcf9); + outb(0x0E, 0xcf9); + } } -int strlen(char * string){ - int i=0; - while(*string++){i++;}; - return i; +int mt86_strlen(char * string){ + int i=0; + while(*string++){i++;}; + return i; } -int strstr(char *haystack, char * needle) +int mt86_strstr(char *haystack, char * needle) { - int i=0,j=0; - int here=0; - while(1){ - if(needle[i]==haystack[j]) - { - if(here==0) - here=j; - i++;j++; - if(i>=strlen(needle)) - { - return here; - } - if(j>=strlen(haystack)) - { - return -1; - } - } else { - j++;i=0;here=0; - } - } + int i=0,j=0; + int here=0; + while(1){ + if(needle[i]==haystack[j]) + { + if(here==0) + here=j; + i++;j++; + if(i>=mt86_strlen(needle)) + { + return here; + } + if(j>=mt86_strlen(haystack)) + { + return -1; + } + } else { + j++;i=0;here=0; + } + } } -int memcmp(const void *s1, const void *s2, ulong count) +int mt86_memcmp(const void *s1, const void *s2, ulong count) { - const unsigned char *src1 = s1, *src2 = s2; - int i; - for(i = 0; i < count; i++) { - if (src1[i] != src2[i]) { - return (int)src1[i] - (int)src2[i]; - } - } - return 0; + const unsigned char *src1 = s1, *src2 = s2; + int i; + for(i = 0; i < count; i++) { + if (src1[i] != src2[i]) { + return (int)src1[i] - (int)src2[i]; + } + } + return 0; } -int strncmp(const char *s1, const char *s2, ulong n) { - signed char res = 0; - while (n) { - res = *s1 - *s2; - if (res != 0) - return res; - if (*s1 == '\0') - return 0; - ++s1, ++s2; - --n; - } - return res; +int mt86_strncmp(const char *s1, const char *s2, ulong n) { + signed char res = 0; + while (n) { + res = *s1 - *s2; + if (res != 0) + return res; + if (*s1 == '\0') + return 0; + ++s1, ++s2; + --n; + } + return res; } -void *memmove(void *dest, const void *src, ulong n) +void *mt86_memmove(void *dest, const void *src, ulong n) { - long i; - char *d = (char *)dest, *s = (char *)src; - - /* If src == dest do nothing */ - if (dest < src) { - for(i = 0; i < n; i++) { - d[i] = s[i]; - } - } - else if (dest > src) { - for(i = n -1; i >= 0; i--) { - d[i] = s[i]; - } - } - return dest; + long i; + char *d = (char *)dest, *s = (char *)src; + + /* If src == dest do nothing */ + if (dest < src) { + for(i = 0; i < n; i++) { + d[i] = s[i]; + } + } + else if (dest > src) { + for(i = n -1; i >= 0; i--) { + d[i] = s[i]; + } + } + return dest; } char toupper(char c) { - if (c >= 'a' && c <= 'z') - return c + 'A' -'a'; - else - return c; + if (c >= 'a' && c <= 'z') + return c + 'A' -'a'; + else + return c; } -int isdigit(char c) +int mt86_isdigit(char c) { - return c >= '0' && c <= '9'; + return c >= '0' && c <= '9'; } int isxdigit(char c) { - return isdigit(c) || (toupper(c) >= 'A' && toupper(c) <= 'F'); } + return mt86_isdigit(c) || (toupper(c) >= 'A' && toupper(c) <= 'F'); } unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) { - unsigned long result = 0, value; - - if (!base) { - base = 10; - if (*cp == '0') { - base = 8; - cp++; - if (toupper(*cp) == 'X' && isxdigit(cp[1])) { - cp++; - base = 16; - } - } - } else if (base == 16) { - if (cp[0] == '0' && toupper(cp[1]) == 'X') - cp += 2; - } - while (isxdigit(*cp) && - (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { - result = result*base + value; - cp++; - } - if (endp) - *endp = (char *)cp; - return result; + unsigned long result = 0, value; + + if (!base) { + base = 10; + if (*cp == '0') { + base = 8; + cp++; + if (toupper(*cp) == 'X' && isxdigit(cp[1])) { + cp++; + base = 16; + } + } + } else if (base == 16) { + if (cp[0] == '0' && toupper(cp[1]) == 'X') + cp += 2; + } + while (isxdigit(*cp) && + (value = mt86_isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { + result = result*base + value; + cp++; + } + if (endp) + *endp = (char *)cp; + return result; } /* @@ -173,34 +173,34 @@ unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) { */ void scroll(void) { - int i, j; - char *s, tmp; - - /* Only scroll if at the bottom of the screen */ - if (v->msg_line < 23) { - v->msg_line++; - } else { - /* If scroll lock is on, loop till it is cleared */ - while (slock) { - check_input(); - } - for (i=LINE_SCROLL; i<23; i++) { - s = (char *)(SCREEN_ADR + ((i+1) * 160)); - for (j=0; j<160; j+=2, s+=2) { - *(s-160) = *s; - tmp = get_scrn_buf(i+1, j/2); - set_scrn_buf(i, j/2, tmp); - } - } - /* Clear the newly opened line */ - s = (char *)(SCREEN_ADR + (23 * 160)); - for (j=0; j<80; j++) { - *s = ' '; - set_scrn_buf(23, j, ' '); - s += 2; - } - tty_print_region(LINE_SCROLL, 0, 23, 79); + int i, j; + char *s, tmp; + + /* Only scroll if at the bottom of the screen */ + if (vv->msg_line < 23) { + vv->msg_line++; + } else { + /* If scroll lock is on, loop till it is cleared */ + while (slock) { + check_input(); + } + for (i=LINE_SCROLL; i<23; i++) { + s = (char *)(SCREEN_ADR + ((i+1) * 160)); + for (j=0; j<160; j+=2, s+=2) { + *(s-160) = *s; + tmp = get_scrn_buf(i+1, j/2); + set_scrn_buf(i, j/2, tmp); + } } + /* Clear the newly opened line */ + s = (char *)(SCREEN_ADR + (23 * 160)); + for (j=0; j<80; j++) { + *s = ' '; + set_scrn_buf(23, j, ' '); + s += 2; + } + tty_print_region(LINE_SCROLL, 0, 23, 79); + } } /* @@ -208,14 +208,14 @@ void scroll(void) */ void clear_scroll(void) { - int i; - char *s; - - s = (char*)(SCREEN_ADR+LINE_HEADER*160); - for(i=0; i<80*(24-LINE_HEADER); i++) { - *s++ = ' '; - *s++ = 0x17; - } + int i; + char *s; + + s = (char*)(SCREEN_ADR+LINE_HEADER*160); + for(i=0; i<80*(24-LINE_HEADER); i++) { + *s++ = ' '; + *s++ = 0x17; + } } /* @@ -223,10 +223,10 @@ void clear_scroll(void) */ void cplace(int y, int x, const char c) { - char *dptr; + char *dptr; - dptr = (char *)(SCREEN_ADR + (160*y) + (2*x)); - *dptr = c; + dptr = (char *)(SCREEN_ADR + (160*y) + (2*x)); + *dptr = c; } /* @@ -234,57 +234,57 @@ void cplace(int y, int x, const char c) */ void cprint(int y, int x, const char *text) { - register int i; - char *dptr; - - dptr = (char *)(SCREEN_ADR + (160*y) + (2*x)); - for (i=0; text[i]; i++) { - *dptr = text[i]; - dptr += 2; - } - tty_print_line(y, x, text); + register int i; + char *dptr; + + dptr = (char *)(SCREEN_ADR + (160*y) + (2*x)); + for (i=0; text[i]; i++) { + *dptr = text[i]; + dptr += 2; + } + tty_print_line(y, x, text); } void itoa(char s[], int n) { - int i, sign; - - if((sign = n) < 0) - n = -n; - i=0; - do { - s[i++] = n % 10 + '0'; - } while ((n /= 10) > 0); - if(sign < 0) - s[i++] = '-'; - s[i] = '\0'; - reverse(s); + int i, sign; + + if((sign = n) < 0) + n = -n; + i=0; + do { + s[i++] = n % 10 + '0'; + } while ((n /= 10) > 0); + if(sign < 0) + s[i++] = '-'; + s[i] = '\0'; + reverse(s); } void reverse(char s[]) { - int c, i, j; - for(j = 0; s[j] != 0; j++) - ; - - for(i=0, j = j - 1; i < j; i++, j--) { - c = s[i]; - s[i] = s[j]; - s[j] = c; - } + int c, i, j; + for(j = 0; s[j] != 0; j++) + ; + + for(i=0, j = j - 1; i < j; i++, j--) { + c = s[i]; + s[i] = s[j]; + s[j] = c; + } } 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++; - } + char *s = (char*)src; + char *d = (char*)dst; + int i; + + if (len <= 0) { + return; + } + for (i = 0 ; i < len; i++) { + *d++ = *s++; + } } /* @@ -292,23 +292,23 @@ void memcpy (void *dst, void *src, int len) */ void aprint(int y, int x, ulong page) { - /* page is in multiples of 4K */ - if ((page << 2) < 9999) { - dprint(y, x, page << 2, 4, 0); - cprint(y, x+4, "K"); - } - else if ((page >>8) < 9999) { - dprint(y, x, (page + (1 << 7)) >> 8, 4, 0); - cprint(y, x+4, "M"); - } - else if ((page >>18) < 9999) { - dprint(y, x, (page + (1 << 17)) >> 18, 4, 0); - cprint(y, x+4, "G"); - } - else { - dprint(y, x, (page + (1 << 27)) >> 28, 4, 0); - cprint(y, x+4, "T"); - } + /* page is in multiples of 4K */ + if ((page << 2) < 9999) { + dprint(y, x, page << 2, 4, 0); + cprint(y, x+4, "K"); + } + else if ((page >>8) < 9999) { + dprint(y, x, (page + (1 << 7)) >> 8, 4, 0); + cprint(y, x+4, "M"); + } + else if ((page >>18) < 9999) { + dprint(y, x, (page + (1 << 17)) >> 18, 4, 0); + cprint(y, x+4, "G"); + } + else { + dprint(y, x, (page + (1 << 27)) >> 28, 4, 0); + cprint(y, x+4, "T"); + } } /* @@ -316,57 +316,57 @@ void aprint(int y, int x, ulong page) */ void dprint(int y, int x, ulong val, int len, int right) { - ulong j, k; - int i, flag=0; - char buf[18]; - - if (val > 999999999 || len > 9) { - return; - } - for(i=0, j=1; i<len-1; i++) { - j *= 10; - } - if (!right) { - for (i=0; j>0; j/=10) { - k = val/j; - if (k > 9) { - j *= 100; - continue; - } - if (flag || k || j == 1) { - buf[i++] = k + '0'; - flag++; - } else { - buf[i++] = ' '; - } - val -= k * j; - } - } else { - for(i=0; i<len; j/=10) { - if (j) { - k = val/j; - if (k > 9) { - j *= 100; - len++; - continue; - } - if (k == 0 && flag == 0) { - continue; - } - buf[i++] = k + '0'; - val -= k * j; - } else { - if (flag == 0 && i < len-1) { - buf[i++] = '0'; - } else { - buf[i++] = ' '; - } - } - flag++; - } - } - buf[i] = 0; - cprint(y,x,buf); + ulong j, k; + int i, flag=0; + char buf[18]; + + if (val > 999999999 || len > 9) { + return; + } + for(i=0, j=1; i<len-1; i++) { + j *= 10; + } + if (!right) { + for (i=0; j>0; j/=10) { + k = val/j; + if (k > 9) { + j *= 100; + continue; + } + if (flag || k || j == 1) { + buf[i++] = k + '0'; + flag++; + } else { + buf[i++] = ' '; + } + val -= k * j; + } + } else { + for(i=0; i<len; j/=10) { + if (j) { + k = val/j; + if (k > 9) { + j *= 100; + len++; + continue; + } + if (k == 0 && flag == 0) { + continue; + } + buf[i++] = k + '0'; + val -= k * j; + } else { + if (flag == 0 && i < len-1) { + buf[i++] = '0'; + } else { + buf[i++] = ' '; + } + } + flag++; + } + } + buf[i] = 0; + cprint(y,x,buf); } /* @@ -374,33 +374,33 @@ void dprint(int y, int x, ulong val, int len, int right) */ void hprint2(int y,int x, unsigned long val, int digits) { - unsigned long j; - int i, idx, flag = 0; - char buf[18]; - - for (i=0, idx=0; i<8; i++) { - j = val >> (28 - (4 * i)); - j &= 0xf; - if (j < 10) { - if (flag || j || i == 7) { - buf[idx++] = j + '0'; - flag++; - } else { - buf[idx++] = '0'; - } - } else { - buf[idx++] = j + 'a' - 10; - flag++; - } + unsigned long j; + int i, idx, flag = 0; + char buf[18]; + + for (i=0, idx=0; i<8; i++) { + j = val >> (28 - (4 * i)); + j &= 0xf; + if (j < 10) { + if (flag || j || i == 7) { + buf[idx++] = j + '0'; + flag++; + } else { + buf[idx++] = '0'; + } + } else { + buf[idx++] = j + 'a' - 10; + flag++; } - if (digits > 8) { - digits = 8; - } - if (flag > digits) { - digits = flag; - } - buf[idx] = 0; - cprint(y,x,buf + (idx - digits)); + } + if (digits > 8) { + digits = 8; + } + if (flag > digits) { + digits = flag; + } + buf[idx] = 0; + cprint(y,x,buf + (idx - digits)); } /* @@ -408,28 +408,28 @@ void hprint2(int y,int x, unsigned long val, int digits) */ void hprint3(int y,int x, unsigned long val, int digits) { - unsigned long j; - int i, idx, flag = 0; - char buf[18]; - - for (i=0, idx=0; i<digits; i++) { - j = 0xf & val; - val /= 16; - - if (j < 10) { - if (flag || j || i == 7) { - buf[digits - ++idx] = j + '0'; - flag++; - } else { - buf[digits - ++idx] = '0'; - } - } else { - buf[digits - ++idx] = j + 'a' - 10; - flag++; - } - } - buf[idx] = 0; - cprint(y,x,buf); + unsigned long j; + int i, idx, flag = 0; + char buf[18]; + + for (i=0, idx=0; i<digits; i++) { + j = 0xf & val; + val /= 16; + + if (j < 10) { + if (flag || j || i == 7) { + buf[digits - ++idx] = j + '0'; + flag++; + } else { + buf[digits - ++idx] = '0'; + } + } else { + buf[digits - ++idx] = j + 'a' - 10; + flag++; + } + } + buf[idx] = 0; + cprint(y,x,buf); } /* @@ -437,7 +437,7 @@ void hprint3(int y,int x, unsigned long val, int digits) */ void hprint(int y, int x, unsigned long val) { - return hprint2(y, x, val, 8); + return hprint2(y, x, val, 8); } /* @@ -445,393 +445,393 @@ void hprint(int y, int x, unsigned long val) */ void xprint(int y,int x, ulong val) { - ulong j; - - j = (val & 0xffc00000) >> 20; - dprint(y, x, j, 4, 0); - cprint(y, x+4, "m"); - j = (val & 0xffc00) >> 10; - dprint(y, x+5, j, 4, 0); - cprint(y, x+9, "k"); - j = val & 0x3ff; - dprint(y, x+10, j, 4, 0); + ulong j; + + j = (val & 0xffc00000) >> 20; + dprint(y, x, j, 4, 0); + cprint(y, x+4, "m"); + j = (val & 0xffc00) >> 10; + dprint(y, x+5, j, 4, 0); + cprint(y, x+9, "k"); + j = val & 0x3ff; + dprint(y, x+10, j, 4, 0); } char *codes[] = { - " Divide", - " Debug", - " NMI", - " Brkpnt", - "Overflow", - " Bound", - " Inv_Op", - " No_Math", - "Double_Fault", - "Seg_Over", - " Inv_TSS", - " Seg_NP", - "Stack_Fault", - "Gen_Prot", - "Page_Fault", - " Resvd", - " FPE", - "Alignment", - " Mch_Chk", - "SIMD FPE" + " Divide", + " Debug", + " NMI", + " Brkpnt", + "Overflow", + " Bound", + " Inv_Op", + " No_Math", + "Double_Fault", + "Seg_Over", + " Inv_TSS", + " Seg_NP", + "Stack_Fault", + "Gen_Prot", + "Page_Fault", + " Resvd", + " FPE", + "Alignment", + " Mch_Chk", + "SIMD FPE" }; struct eregs { - ulong ss; - ulong ds; - ulong esp; - ulong ebp; - ulong esi; - ulong edi; - ulong edx; - ulong ecx; - ulong ebx; - ulong eax; - ulong vect; - ulong code; - ulong eip; - ulong cs; - ulong eflag; + ulong ss; + ulong ds; + ulong esp; + ulong ebp; + ulong esi; + ulong edi; + ulong edx; + ulong ecx; + ulong ebx; + ulong eax; + ulong vect; + ulong code; + ulong eip; + ulong cs; + ulong eflag; }; /* Handle an interrupt */ void inter(struct eregs *trap_regs) { - int i, line; - unsigned char *pp; - ulong address = 0; - int my_cpu_num = smp_my_cpu_num(); - - /* Get the page fault address */ - if (trap_regs->vect == 14) { - __asm__("movl %%cr2,%0":"=r" (address)); - } + int i, line; + unsigned char *pp; + ulong address = 0; + int my_cpu_num = smp_my_cpu_num(); + + /* Get the page fault address */ + if (trap_regs->vect == 14) { + __asm__("movl %%cr2,%0":"=r" (address)); + } #ifdef PARITY_MEM - /* Check for a parity error */ - if (trap_regs->vect == 2) { - parity_err(trap_regs->edi, trap_regs->esi); - return; - } + /* Check for a parity error */ + if (trap_regs->vect == 2) { + parity_err(trap_regs->edi, trap_regs->esi); + return; + } #endif - /* clear scrolling region */ - pp=(unsigned char *)(SCREEN_ADR+(2*80*(LINE_SCROLL-2))); - for(i=0; i<2*80*(24-LINE_SCROLL-2); i++, pp+=2) { - *pp = ' '; - } - line = LINE_SCROLL-2; - - cprint(line, 0, "Unexpected Interrupt - Halting CPU"); - dprint(line, COL_MID + 4, my_cpu_num, 2, 1); - cprint(line+2, 0, " Type: "); - if (trap_regs->vect <= 19) { - cprint(line+2, 7, codes[trap_regs->vect]); - } else { - hprint(line+2, 7, trap_regs->vect); - } - cprint(line+3, 0, " PC: "); - hprint(line+3, 7, trap_regs->eip); - cprint(line+4, 0, " CS: "); - hprint(line+4, 7, trap_regs->cs); - cprint(line+5, 0, "Eflag: "); - hprint(line+5, 7, trap_regs->eflag); - cprint(line+6, 0, " Code: "); - hprint(line+6, 7, trap_regs->code); - cprint(line+7, 0, " DS: "); - hprint(line+7, 7, trap_regs->ds); - cprint(line+8, 0, " SS: "); - hprint(line+8, 7, trap_regs->ss); - if (trap_regs->vect == 14) { - /* Page fault address */ - cprint(line+7, 0, " Addr: "); - hprint(line+7, 7, address); - } - - cprint(line+2, 20, "eax: "); - hprint(line+2, 25, trap_regs->eax); - cprint(line+3, 20, "ebx: "); - hprint(line+3, 25, trap_regs->ebx); - cprint(line+4, 20, "ecx: "); - hprint(line+4, 25, trap_regs->ecx); - cprint(line+5, 20, "edx: "); - hprint(line+5, 25, trap_regs->edx); - cprint(line+6, 20, "edi: "); - hprint(line+6, 25, trap_regs->edi); - cprint(line+7, 20, "esi: "); - hprint(line+7, 25, trap_regs->esi); - cprint(line+8, 20, "ebp: "); - hprint(line+8, 25, trap_regs->ebp); - cprint(line+9, 20, "esp: "); - hprint(line+9, 25, trap_regs->esp); - - cprint(line+1, 38, "Stack:"); - for (i=0; i<10; i++) { - hprint(line+2+i, 38, trap_regs->esp+(4*i)); - hprint(line+2+i, 47, *(ulong*)(trap_regs->esp+(4*i))); - hprint(line+2+i, 57, trap_regs->esp+(4*(i+10))); - hprint(line+2+i, 66, *(ulong*)(trap_regs->esp+(4*(i+10)))); - } - - cprint(line+11, 0, "CS:EIP: "); - pp = (unsigned char *)trap_regs->eip; - for(i = 0; i < 9; i++) { - hprint2(line+11, 8+(3*i), pp[i], 2); - } - - while(1) { - check_input(); - } + /* clear scrolling region */ + pp=(unsigned char *)(SCREEN_ADR+(2*80*(LINE_SCROLL-2))); + for(i=0; i<2*80*(24-LINE_SCROLL-2); i++, pp+=2) { + *pp = ' '; + } + line = LINE_SCROLL-2; + + cprint(line, 0, "Unexpected Interrupt - Halting CPU"); + dprint(line, COL_MID + 4, my_cpu_num, 2, 1); + cprint(line+2, 0, " Type: "); + if (trap_regs->vect <= 19) { + cprint(line+2, 7, codes[trap_regs->vect]); + } else { + hprint(line+2, 7, trap_regs->vect); + } + cprint(line+3, 0, " PC: "); + hprint(line+3, 7, trap_regs->eip); + cprint(line+4, 0, " CS: "); + hprint(line+4, 7, trap_regs->cs); + cprint(line+5, 0, "Eflag: "); + hprint(line+5, 7, trap_regs->eflag); + cprint(line+6, 0, " Code: "); + hprint(line+6, 7, trap_regs->code); + cprint(line+7, 0, " DS: "); + hprint(line+7, 7, trap_regs->ds); + cprint(line+8, 0, " SS: "); + hprint(line+8, 7, trap_regs->ss); + if (trap_regs->vect == 14) { + /* Page fault address */ + cprint(line+7, 0, " Addr: "); + hprint(line+7, 7, address); + } + + cprint(line+2, 20, "eax: "); + hprint(line+2, 25, trap_regs->eax); + cprint(line+3, 20, "ebx: "); + hprint(line+3, 25, trap_regs->ebx); + cprint(line+4, 20, "ecx: "); + hprint(line+4, 25, trap_regs->ecx); + cprint(line+5, 20, "edx: "); + hprint(line+5, 25, trap_regs->edx); + cprint(line+6, 20, "edi: "); + hprint(line+6, 25, trap_regs->edi); + cprint(line+7, 20, "esi: "); + hprint(line+7, 25, trap_regs->esi); + cprint(line+8, 20, "ebp: "); + hprint(line+8, 25, trap_regs->ebp); + cprint(line+9, 20, "esp: "); + hprint(line+9, 25, trap_regs->esp); + + cprint(line+1, 38, "Stack:"); + for (i=0; i<10; i++) { + hprint(line+2+i, 38, trap_regs->esp+(4*i)); + hprint(line+2+i, 47, *(ulong*)(trap_regs->esp+(4*i))); + hprint(line+2+i, 57, trap_regs->esp+(4*(i+10))); + hprint(line+2+i, 66, *(ulong*)(trap_regs->esp+(4*(i+10)))); + } + + cprint(line+11, 0, "CS:EIP: "); + pp = (unsigned char *)trap_regs->eip; + for(i = 0; i < 9; i++) { + hprint2(line+11, 8+(3*i), pp[i], 2); + } + + while(1) { + check_input(); + } } void set_cache(int val) { - switch(val) { - case 0: - cache_off(); - break; - case 1: - cache_on(); - break; - } + switch(val) { + case 0: + cache_off(); + break; + case 1: + cache_on(); + break; + } } int get_key() { - int c; - - c = inb(0x64); - if ((c & 1) == 0) { - if (serial_cons) { - int comstat; - comstat = serial_echo_inb(UART_LSR); - if (comstat & UART_LSR_DR) { - c = serial_echo_inb(UART_RX); - /* Pressing '.' has same effect as 'c' - on a keyboard. - Oct 056 Dec 46 Hex 2E Ascii . - */ - return (ascii_to_keycode(c)); - } - } - return(0); - } - c = inb(0x60); - return((c)); + int c; + + c = inb(0x64); + if ((c & 1) == 0) { + if (serial_cons) { + int comstat; + comstat = serial_echo_inb(UART_LSR); + if (comstat & UART_LSR_DR) { + c = serial_echo_inb(UART_RX); + /* Pressing '.' has same effect as 'c' + on a keyboard. + Oct 056 Dec 46 Hex 2E Ascii . + */ + return (ascii_to_keycode(c)); + } + } + return(0); + } + c = inb(0x60); + return((c)); } void check_input(void) { - unsigned char c; - - if ((c = get_key())) { - switch(c & 0x7f) { - case 1: - /* "ESC" key was pressed, bail out. */ - cprint(LINE_RANGE, COL_MID+23, "Halting... "); - reboot(); - break; - case 46: - /* c - Configure */ - get_config(); - break; - case 28: - /* CR - clear scroll lock */ - slock = 0; - footer(); - break; - case 57: - /* SP - set scroll lock */ - slock = 1; - footer(); - break; - case 0x26: - /* ^L/L - redraw the display */ - tty_print_screen(); - break; - } - } + unsigned char c; + + if ((c = get_key())) { + switch(c & 0x7f) { + case 1: + /* "ESC" key was pressed, bail out. */ + cprint(LINE_RANGE, COL_MID+23, "Halting... "); + reboot(); + break; + case 46: + /* c - Configure */ + get_config(); + break; + case 28: + /* CR - clear scroll lock */ + slock = 0; + footer(); + break; + case 57: + /* SP - set scroll lock */ + slock = 1; + footer(); + break; + case 0x26: + /* ^L/L - redraw the display */ + tty_print_screen(); + break; + } + } } void footer() { - cprint(24, 0, "(ESC)exit (c)configuration (SP)scroll_lock (CR)scroll_unlock"); - if (slock) { - cprint(24, 74, "Locked"); - } else { - cprint(24, 74, " "); - } + cprint(24, 0, "(ESC)exit (c)configuration (SP)scroll_lock (CR)scroll_unlock"); + if (slock) { + cprint(24, 74, "Locked"); + } else { + cprint(24, 74, " "); + } } ulong getval(int x, int y, int result_shift) { - unsigned long val; - int done; - int c; - int i, n; - int base; - int shift; - char buf[16]; - - for(i = 0; i < sizeof(buf)/sizeof(buf[0]); i++ ) { - buf[i] = ' '; - } - buf[sizeof(buf)/sizeof(buf[0]) -1] = '\0'; + unsigned long val; + int done; + int c; + int i, n; + int base; + int shift; + char buf[16]; + + for(i = 0; i < sizeof(buf)/sizeof(buf[0]); i++ ) { + buf[i] = ' '; + } + buf[sizeof(buf)/sizeof(buf[0]) -1] = '\0'; - wait_keyup(); - done = 0; - n = 0; - base = 10; - while(!done) { - /* Read a new character and process it */ - c = get_key(); - switch(c) { - case 0x26: /* ^L/L - redraw the display */ - tty_print_screen(); - break; - case 0x1c: /* CR */ - /* If something has been entered we are done */ - if(n) done = 1; - break; - case 0x19: /* p */ buf[n] = 'p'; break; - case 0x22: /* g */ buf[n] = 'g'; break; - case 0x32: /* m */ buf[n] = 'm'; break; - case 0x25: /* k */ buf[n] = 'k'; break; - case 0x2d: /* x */ - /* Only allow 'x' after an initial 0 */ - if (n == 1 && (buf[0] == '0')) { - buf[n] = 'x'; - } - break; - case 0x0e: /* BS */ - if (n > 0) { - n -= 1; - buf[n] = ' '; - } - break; - /* Don't allow entering a number not in our current base */ - case 0x0B: if (base >= 1) buf[n] = '0'; break; - case 0x02: if (base >= 2) buf[n] = '1'; break; - case 0x03: if (base >= 3) buf[n] = '2'; break; - case 0x04: if (base >= 4) buf[n] = '3'; break; - case 0x05: if (base >= 5) buf[n] = '4'; break; - case 0x06: if (base >= 6) buf[n] = '5'; break; - case 0x07: if (base >= 7) buf[n] = '6'; break; - case 0x08: if (base >= 8) buf[n] = '7'; break; - case 0x09: if (base >= 9) buf[n] = '8'; break; - case 0x0A: if (base >= 10) buf[n] = '9'; break; - case 0x1e: if (base >= 11) buf[n] = 'a'; break; - case 0x30: if (base >= 12) buf[n] = 'b'; break; - case 0x2e: if (base >= 13) buf[n] = 'c'; break; - case 0x20: if (base >= 14) buf[n] = 'd'; break; - case 0x12: if (base >= 15) buf[n] = 'e'; break; - case 0x21: if (base >= 16) buf[n] = 'f'; break; - default: - break; - } - /* Don't allow anything to be entered after a suffix */ - if (n > 0 && ( - (buf[n-1] == 'p') || (buf[n-1] == 'g') || - (buf[n-1] == 'm') || (buf[n-1] == 'k'))) { - buf[n] = ' '; - } - /* If we have entered a character increment n */ - if (buf[n] != ' ') { - n++; - } - buf[n] = ' '; - /* Print the current number */ - cprint(x, y, buf); - - /* Find the base we are entering numbers in */ - base = 10; - if ((buf[0] == '0') && (buf[1] == 'x')) { - base = 16; - } - else if (buf[0] == '0') { - base = 8; - } - } - /* Compute our current shift */ - shift = 0; - switch(buf[n-1]) { - case 'g': /* gig */ shift = 30; break; - case 'm': /* meg */ shift = 20; break; - case 'p': /* page */ shift = 12; break; - case 'k': /* kilo */ shift = 10; break; - } - shift -= result_shift; - - /* Compute our current value */ - val = simple_strtoul(buf, 0, base); - if (shift > 0) { - if (shift >= 32) { - val = 0xffffffff; - } else { - val <<= shift; - } - } else { - if (-shift >= 32) { - val = 0; - } - else { - val >>= -shift; - } - } - return val; + wait_keyup(); + done = 0; + n = 0; + base = 10; + while(!done) { + /* Read a new character and process it */ + c = get_key(); + switch(c) { + case 0x26: /* ^L/L - redraw the display */ + tty_print_screen(); + break; + case 0x1c: /* CR */ + /* If something has been entered we are done */ + if(n) done = 1; + break; + case 0x19: /* p */ buf[n] = 'p'; break; + case 0x22: /* g */ buf[n] = 'g'; break; + case 0x32: /* m */ buf[n] = 'm'; break; + case 0x25: /* k */ buf[n] = 'k'; break; + case 0x2d: /* x */ + /* Only allow 'x' after an initial 0 */ + if (n == 1 && (buf[0] == '0')) { + buf[n] = 'x'; + } + break; + case 0x0e: /* BS */ + if (n > 0) { + n -= 1; + buf[n] = ' '; + } + break; + /* Don't allow entering a number not in our current base */ + case 0x0B: if (base >= 1) buf[n] = '0'; break; + case 0x02: if (base >= 2) buf[n] = '1'; break; + case 0x03: if (base >= 3) buf[n] = '2'; break; + case 0x04: if (base >= 4) buf[n] = '3'; break; + case 0x05: if (base >= 5) buf[n] = '4'; break; + case 0x06: if (base >= 6) buf[n] = '5'; break; + case 0x07: if (base >= 7) buf[n] = '6'; break; + case 0x08: if (base >= 8) buf[n] = '7'; break; + case 0x09: if (base >= 9) buf[n] = '8'; break; + case 0x0A: if (base >= 10) buf[n] = '9'; break; + case 0x1e: if (base >= 11) buf[n] = 'a'; break; + case 0x30: if (base >= 12) buf[n] = 'b'; break; + case 0x2e: if (base >= 13) buf[n] = 'c'; break; + case 0x20: if (base >= 14) buf[n] = 'd'; break; + case 0x12: if (base >= 15) buf[n] = 'e'; break; + case 0x21: if (base >= 16) buf[n] = 'f'; break; + default: + break; + } + /* Don't allow anything to be entered after a suffix */ + if (n > 0 && ( + (buf[n-1] == 'p') || (buf[n-1] == 'g') || + (buf[n-1] == 'm') || (buf[n-1] == 'k'))) { + buf[n] = ' '; + } + /* If we have entered a character increment n */ + if (buf[n] != ' ') { + n++; + } + buf[n] = ' '; + /* Print the current number */ + cprint(x, y, buf); + + /* Find the base we are entering numbers in */ + base = 10; + if ((buf[0] == '0') && (buf[1] == 'x')) { + base = 16; + } + else if (buf[0] == '0') { + base = 8; + } + } + /* Compute our current shift */ + shift = 0; + switch(buf[n-1]) { + case 'g': /* gig */ shift = 30; break; + case 'm': /* meg */ shift = 20; break; + case 'p': /* page */ shift = 12; break; + case 'k': /* kilo */ shift = 10; break; + } + shift -= result_shift; + + /* Compute our current value */ + val = simple_strtoul(buf, 0, base); + if (shift > 0) { + if (shift >= 32) { + val = 0xffffffff; + } else { + val <<= shift; + } + } else { + if (-shift >= 32) { + val = 0; + } + else { + val >>= -shift; + } + } + return val; } void ttyprint(int y, int x, const char *p) { - static char sx[3]; - static char sy[3]; - - sx[0]='\0'; - sy[0]='\0'; - x++; y++; - itoa(sx, x); - itoa(sy, y); - serial_echo_print("["); - serial_echo_print(sy); - serial_echo_print(";"); - serial_echo_print(sx); - serial_echo_print("H"); - serial_echo_print(p); + static char sx[3]; + static char sy[3]; + + sx[0]='\0'; + sy[0]='\0'; + x++; y++; + itoa(sx, x); + itoa(sy, y); + serial_echo_print("["); + serial_echo_print(sy); + serial_echo_print(";"); + serial_echo_print(sx); + serial_echo_print("H"); + serial_echo_print(p); } void serial_echo_init(void) { - int comstat, hi, lo, serial_div; - unsigned char lcr; - - /* read the Divisor Latch */ - comstat = serial_echo_inb(UART_LCR); - serial_echo_outb(comstat | UART_LCR_DLAB, UART_LCR); - hi = serial_echo_inb(UART_DLM); - lo = serial_echo_inb(UART_DLL); - serial_echo_outb(comstat, UART_LCR); - - /* now do hardwired init */ - lcr = serial_parity | (serial_bits - 5); - serial_echo_outb(lcr, UART_LCR); /* No parity, 8 data bits, 1 stop */ - serial_div = 115200 / serial_baud_rate; - serial_echo_outb(0x80|lcr, UART_LCR); /* Access divisor latch */ - serial_echo_outb(serial_div & 0xff, UART_DLL); /* baud rate divisor */ - serial_echo_outb((serial_div >> 8) & 0xff, UART_DLM); - serial_echo_outb(lcr, UART_LCR); /* Done with divisor */ - - /* Prior to disabling interrupts, read the LSR and RBR - * registers */ - comstat = serial_echo_inb(UART_LSR); /* COM? LSR */ - comstat = serial_echo_inb(UART_RX); /* COM? RBR */ - serial_echo_outb(0x00, UART_IER); /* Disable all interrupts */ - - clear_screen_buf(); - - return; + int comstat, serial_div; + unsigned char lcr; + + /* read the Divisor Latch */ + comstat = serial_echo_inb(UART_LCR); + serial_echo_outb(comstat | UART_LCR_DLAB, UART_LCR); + /*hi =*/ serial_echo_inb(UART_DLM); + /*lo =*/ serial_echo_inb(UART_DLL); + serial_echo_outb(comstat, UART_LCR); + + /* now do hardwired init */ + lcr = serial_parity | (serial_bits - 5); + serial_echo_outb(lcr, UART_LCR); /* No parity, 8 data bits, 1 stop */ + serial_div = 115200 / serial_baud_rate; + serial_echo_outb(0x80|lcr, UART_LCR); /* Access divisor latch */ + serial_echo_outb(serial_div & 0xff, UART_DLL); /* baud rate divisor */ + serial_echo_outb((serial_div >> 8) & 0xff, UART_DLM); + serial_echo_outb(lcr, UART_LCR); /* Done with divisor */ + + /* Prior to disabling interrupts, read the LSR and RBR + * registers */ + comstat = serial_echo_inb(UART_LSR); /* COM? LSR */ + comstat = serial_echo_inb(UART_RX); /* COM? RBR */ + serial_echo_outb(0x00, UART_IER); /* Disable all interrupts */ + + clear_screen_buf(); + + return; } /* @@ -839,37 +839,37 @@ void serial_echo_init(void) */ int getnum(ulong val) { - int len = 0; - int i = 1; + int len = 0; + int i = 1; - while(i <= val) - { - len++; - i *= 10; - } + while(i <= val) + { + len++; + i *= 10; + } - return len; + return len; } void serial_echo_print(const char *p) { - if (!serial_cons) { - return; - } - /* Now, do each character */ - while (*p) { - WAIT_FOR_XMITR; - - /* Send the character out. */ - serial_echo_outb(*p, UART_TX); - if(*p==10) { - WAIT_FOR_XMITR; - serial_echo_outb(13, UART_TX); - } - p++; - } + if (!serial_cons) { + return; + } + /* Now, do each character */ + while (*p) { + WAIT_FOR_XMITR; + + /* Send the character out. */ + serial_echo_outb(*p, UART_TX); + if(*p==10) { + WAIT_FOR_XMITR; + serial_echo_outb(13, UART_TX); + } + p++; + } } /* Except for multi-character key sequences this mapping @@ -880,149 +880,149 @@ void serial_echo_print(const char *p) * else we should switch on the character... */ struct ascii_map_str ser_map[] = -/*ascii keycode ascii keycode*/ -{ - /* Special cases come first so I can leave - * their ``normal'' mapping in the table, - * without it being activated. - */ - { 27, 0x01}, /* ^[/ESC -> ESC */ - { 127, 0x0e}, /* DEL -> BS */ - { 8, 0x0e}, /* ^H/BS -> BS */ - { 10, 0x1c}, /* ^L/NL -> CR */ - { 13, 0x1c}, /* ^M/CR -> CR */ - { 9, 0x0f}, /* ^I/TAB -> TAB */ - { 19, 0x39}, /* ^S -> SP */ - { 17, 28}, /* ^Q -> CR */ - - { ' ', 0x39}, /* SP -> SP */ - { 'a', 0x1e}, - { 'A', 0x1e}, - { 1, 0x1e}, /* ^A -> A */ - { 'b', 0x30}, - { 'B', 0x30}, - { 2, 0x30}, /* ^B -> B */ - { 'c', 0x2e}, - { 'C', 0x2e}, - { 3, 0x2e}, /* ^C -> C */ - { 'd', 0x20}, - { 'D', 0x20}, - { 4, 0x20}, /* ^D -> D */ - { 'e', 0x12}, - { 'E', 0x12}, - { 5, 0x12}, /* ^E -> E */ - { 'f', 0x21}, - { 'F', 0x21}, - { 6, 0x21}, /* ^F -> F */ - { 'g', 0x22}, - { 'G', 0x22}, - { 7, 0x22}, /* ^G -> G */ - { 'h', 0x23}, - { 'H', 0x23}, - { 8, 0x23}, /* ^H -> H */ - { 'i', 0x17}, - { 'I', 0x17}, - { 9, 0x17}, /* ^I -> I */ - { 'j', 0x24}, - { 'J', 0x24}, - { 10, 0x24}, /* ^J -> J */ - { 'k', 0x25}, - { 'K', 0x25}, - { 11, 0x25}, /* ^K -> K */ - { 'l', 0x26}, - { 'L', 0x26}, - { 12, 0x26}, /* ^L -> L */ - { 'm', 0x32}, - { 'M', 0x32}, - { 13, 0x32}, /* ^M -> M */ - { 'n', 0x31}, - { 'N', 0x31}, - { 14, 0x31}, /* ^N -> N */ - { 'o', 0x18}, - { 'O', 0x18}, - { 15, 0x18}, /* ^O -> O */ - { 'p', 0x19}, - { 'P', 0x19}, - { 16, 0x19}, /* ^P -> P */ - { 'q', 0x10}, - { 'Q', 0x10}, - { 17, 0x10}, /* ^Q -> Q */ - { 'r', 0x13}, - { 'R', 0x13}, - { 18, 0x13}, /* ^R -> R */ - { 's', 0x1f}, - { 'S', 0x1f}, - { 19, 0x1f}, /* ^S -> S */ - { 't', 0x14}, - { 'T', 0x14}, - { 20, 0x14}, /* ^T -> T */ - { 'u', 0x16}, - { 'U', 0x16}, - { 21, 0x16}, /* ^U -> U */ - { 'v', 0x2f}, - { 'V', 0x2f}, - { 22, 0x2f}, /* ^V -> V */ - { 'w', 0x11}, - { 'W', 0x11}, - { 23, 0x11}, /* ^W -> W */ - { 'x', 0x2d}, - { 'X', 0x2d}, - { 24, 0x2d}, /* ^X -> X */ - { 'y', 0x15}, - { 'Y', 0x15}, - { 25, 0x15}, /* ^Y -> Y */ - { 'z', 0x2c}, - { 'Z', 0x2c}, - { 26, 0x2c}, /* ^Z -> Z */ - { '-', 0x0c}, - { '_', 0x0c}, - { 31, 0x0c}, /* ^_ -> _ */ - { '=', 0x0c}, - { '+', 0x0c}, - { '[', 0x1a}, - { '{', 0x1a}, - { 27, 0x1a}, /* ^[ -> [ */ - { ']', 0x1b}, - { '}', 0x1b}, - { 29, 0x1b}, /* ^] -> ] */ - { ';', 0x27}, - { ':', 0x27}, - { '\'', 0x28}, - { '"', 0x28}, - { '`', 0x29}, - { '~', 0x29}, - { '\\', 0x2b}, - { '|', 0x2b}, - { 28, 0x2b}, /* ^\ -> \ */ - { ',', 0x33}, - { '<', 0x33}, - { '.', 0x34}, - { '>', 0x34}, - { '/', 0x35}, - { '?', 0x35}, - { '1', 0x02}, - { '!', 0x02}, - { '2', 0x03}, - { '@', 0x03}, - { '3', 0x04}, - { '#', 0x04}, - { '4', 0x05}, - { '$', 0x05}, - { '5', 0x06}, - { '%', 0x06}, - { '6', 0x07}, - { '^', 0x07}, - { 30, 0x07}, /* ^^ -> 6 */ - { '7', 0x08}, - { '&', 0x08}, - { '8', 0x09}, - { '*', 0x09}, - { '9', 0x0a}, - { '(', 0x0a}, - { '0', 0x0b}, - { ')', 0x0b}, - { 0, 0} -}; + /*ascii keycode ascii keycode*/ + { + /* Special cases come first so I can leave + * their ``normal'' mapping in the table, + * without it being activated. + */ + { 27, 0x01}, /* ^[/ESC -> ESC */ + { 127, 0x0e}, /* DEL -> BS */ + { 8, 0x0e}, /* ^H/BS -> BS */ + { 10, 0x1c}, /* ^L/NL -> CR */ + { 13, 0x1c}, /* ^M/CR -> CR */ + { 9, 0x0f}, /* ^I/TAB -> TAB */ + { 19, 0x39}, /* ^S -> SP */ + { 17, 28}, /* ^Q -> CR */ + + { ' ', 0x39}, /* SP -> SP */ + { 'a', 0x1e}, + { 'A', 0x1e}, + { 1, 0x1e}, /* ^A -> A */ + { 'b', 0x30}, + { 'B', 0x30}, + { 2, 0x30}, /* ^B -> B */ + { 'c', 0x2e}, + { 'C', 0x2e}, + { 3, 0x2e}, /* ^C -> C */ + { 'd', 0x20}, + { 'D', 0x20}, + { 4, 0x20}, /* ^D -> D */ + { 'e', 0x12}, + { 'E', 0x12}, + { 5, 0x12}, /* ^E -> E */ + { 'f', 0x21}, + { 'F', 0x21}, + { 6, 0x21}, /* ^F -> F */ + { 'g', 0x22}, + { 'G', 0x22}, + { 7, 0x22}, /* ^G -> G */ + { 'h', 0x23}, + { 'H', 0x23}, + { 8, 0x23}, /* ^H -> H */ + { 'i', 0x17}, + { 'I', 0x17}, + { 9, 0x17}, /* ^I -> I */ + { 'j', 0x24}, + { 'J', 0x24}, + { 10, 0x24}, /* ^J -> J */ + { 'k', 0x25}, + { 'K', 0x25}, + { 11, 0x25}, /* ^K -> K */ + { 'l', 0x26}, + { 'L', 0x26}, + { 12, 0x26}, /* ^L -> L */ + { 'm', 0x32}, + { 'M', 0x32}, + { 13, 0x32}, /* ^M -> M */ + { 'n', 0x31}, + { 'N', 0x31}, + { 14, 0x31}, /* ^N -> N */ + { 'o', 0x18}, + { 'O', 0x18}, + { 15, 0x18}, /* ^O -> O */ + { 'p', 0x19}, + { 'P', 0x19}, + { 16, 0x19}, /* ^P -> P */ + { 'q', 0x10}, + { 'Q', 0x10}, + { 17, 0x10}, /* ^Q -> Q */ + { 'r', 0x13}, + { 'R', 0x13}, + { 18, 0x13}, /* ^R -> R */ + { 's', 0x1f}, + { 'S', 0x1f}, + { 19, 0x1f}, /* ^S -> S */ + { 't', 0x14}, + { 'T', 0x14}, + { 20, 0x14}, /* ^T -> T */ + { 'u', 0x16}, + { 'U', 0x16}, + { 21, 0x16}, /* ^U -> U */ + { 'v', 0x2f}, + { 'V', 0x2f}, + { 22, 0x2f}, /* ^V -> V */ + { 'w', 0x11}, + { 'W', 0x11}, + { 23, 0x11}, /* ^W -> W */ + { 'x', 0x2d}, + { 'X', 0x2d}, + { 24, 0x2d}, /* ^X -> X */ + { 'y', 0x15}, + { 'Y', 0x15}, + { 25, 0x15}, /* ^Y -> Y */ + { 'z', 0x2c}, + { 'Z', 0x2c}, + { 26, 0x2c}, /* ^Z -> Z */ + { '-', 0x0c}, + { '_', 0x0c}, + { 31, 0x0c}, /* ^_ -> _ */ + { '=', 0x0c}, + { '+', 0x0c}, + { '[', 0x1a}, + { '{', 0x1a}, + { 27, 0x1a}, /* ^[ -> [ */ + { ']', 0x1b}, + { '}', 0x1b}, + { 29, 0x1b}, /* ^] -> ] */ + { ';', 0x27}, + { ':', 0x27}, + { '\'', 0x28}, + { '"', 0x28}, + { '`', 0x29}, + { '~', 0x29}, + { '\\', 0x2b}, + { '|', 0x2b}, + { 28, 0x2b}, /* ^\ -> \ */ + { ',', 0x33}, + { '<', 0x33}, + { '.', 0x34}, + { '>', 0x34}, + { '/', 0x35}, + { '?', 0x35}, + { '1', 0x02}, + { '!', 0x02}, + { '2', 0x03}, + { '@', 0x03}, + { '3', 0x04}, + { '#', 0x04}, + { '4', 0x05}, + { '$', 0x05}, + { '5', 0x06}, + { '%', 0x06}, + { '6', 0x07}, + { '^', 0x07}, + { 30, 0x07}, /* ^^ -> 6 */ + { '7', 0x08}, + { '&', 0x08}, + { '8', 0x09}, + { '*', 0x09}, + { '9', 0x0a}, + { '(', 0x0a}, + { '0', 0x0b}, + { ')', 0x0b}, + { 0, 0} + }; /* * Given an ascii character, return the keycode @@ -1034,12 +1034,12 @@ struct ascii_map_str ser_map[] = */ int ascii_to_keycode (int in) { - struct ascii_map_str *p; - for (p = ser_map; p->ascii; p++) { - if (in ==p->ascii) - return p->keycode; - } - return 0; + struct ascii_map_str *p; + for (p = ser_map; p->ascii; p++) { + if (in ==p->ascii) + return p->keycode; + } + return 0; } /* @@ -1048,22 +1048,22 @@ int ascii_to_keycode (int in) * serial console. */ void wait_keyup( void ) { - /* Check to see if someone lifted the keyboard key */ - while (1) { - if ((get_key() & 0x80) != 0) { - return; - } - /* Trying to simulate waiting for a key release with - * the serial port is to nasty to let live. - * In particular some menus don't even display until - * you release the key that caused to to get there. - * With the serial port this results in double pressing - * or something worse for just about every key. - */ - if (serial_cons) { - return; - } - } + /* Check to see if someone lifted the keyboard key */ + while (1) { + if ((get_key() & 0x80) != 0) { + return; + } + /* Trying to simulate waiting for a key release with + * the serial port is to nasty to let live. + * In particular some menus don't even display until + * you release the key that caused to to get there. + * With the serial port this results in double pressing + * or something worse for just about every key. + */ + if (serial_cons) { + return; + } + } } /* @@ -1077,123 +1077,123 @@ void wait_keyup( void ) { */ void serial_console_setup(char *param) { - char *option, *end; - unsigned long tty; - unsigned long baud_rate; - unsigned char parity, bits; + char *option, *end; + unsigned long tty; + unsigned long baud_rate; + unsigned char parity, bits; - if (strncmp(param, "ttyS", 4)) - return; /* not a serial port */ + if (mt86_strncmp(param, "ttyS", 4)) + return; /* not a serial port */ - param += 4; + param += 4; - tty = simple_strtoul(param, &option, 10); + tty = simple_strtoul(param, &option, 10); - if (option == param) - return; /* there were no digits */ + if (option == param) + return; /* there were no digits */ - if (tty > 1) - return; /* only ttyS0 and ttyS1 supported */ + if (tty > 1) + return; /* only ttyS0 and ttyS1 supported */ - if (*option == '\0' || *option == ' ') - goto save_tty; /* no options given, just ttyS? */ + if (*option == '\0' || *option == ' ') + goto save_tty; /* no options given, just ttyS? */ - if (*option != ',') - return; /* missing the comma separator */ + if (*option != ',') + return; /* missing the comma separator */ - /* baud rate must follow */ - option++; - baud_rate = simple_strtoul(option, &end, 10); + /* baud rate must follow */ + option++; + baud_rate = simple_strtoul(option, &end, 10); - if (end == option) - return; /* no baudrate after comma */ + if (end == option) + return; /* no baudrate after comma */ - if (baud_rate == 0 || (115200 % baud_rate) != 0) - return; /* wrong baud rate */ + if (baud_rate == 0 || (115200 % baud_rate) != 0) + return; /* wrong baud rate */ - if (*end == '\0' || *end == ' ') - goto save_baud_rate; /* no more options given */ + if (*end == '\0' || *end == ' ') + goto save_baud_rate; /* no more options given */ - switch (toupper(*end)) { - case 'N': - parity = 0; - break; - case 'O': - parity = UART_LCR_PARITY; - break; - case 'E': - parity = UART_LCR_PARITY | UART_LCR_EPAR; - break; - default: - /* Unknown parity */ - return; - } + switch (toupper(*end)) { + case 'N': + parity = 0; + break; + case 'O': + parity = UART_LCR_PARITY; + break; + case 'E': + parity = UART_LCR_PARITY | UART_LCR_EPAR; + break; + default: + /* Unknown parity */ + return; + } - end++; - if (*end == '\0' || *end == ' ') - goto save_parity; + end++; + if (*end == '\0' || *end == ' ') + goto save_parity; - /* word length (bits) */ - if (*end < '7' || *end > '8') - return; /* invalid number of bits */ + /* word length (bits) */ + if (*end < '7' || *end > '8') + return; /* invalid number of bits */ - bits = *end - '0'; + bits = *end - '0'; - end++; + end++; - if (*end != '\0' || *end != ' ') - return; /* garbage at the end */ + if (*end != '\0' || *end != ' ') + return; /* garbage at the end */ - serial_bits = bits; - save_parity: - serial_parity = parity; - save_baud_rate: - serial_baud_rate = (int) baud_rate; - save_tty: - serial_tty = (short) tty; - serial_cons = 1; + serial_bits = bits; + save_parity: + serial_parity = parity; + save_baud_rate: + serial_baud_rate = (int) baud_rate; + save_tty: + serial_tty = (short) tty; + serial_cons = 1; } /* Get a comma seperated list of numbers */ void get_list(int x, int y, int len, char *buf) { - int c, n = 0; - - len--; - wait_keyup(); - while(1) { - /* Read a new character and process it */ - c = get_key(); - switch(c) { - case 0x1c: /* CR */ - /* If something has been entered we are done */ - if(n) { - buf[n] = 0; - return; - } - break; - case 0x0e: /* BS */ - if (n > 0) { - n -= 1; - buf[n] = ' '; - } - break; - case 0x0B: buf[n++] = '0'; break; - case 0x02: buf[n++] = '1'; break; - case 0x03: buf[n++] = '2'; break; - case 0x04: buf[n++] = '3'; break; - case 0x05: buf[n++] = '4'; break; - case 0x06: buf[n++] = '5'; break; - case 0x07: buf[n++] = '6'; break; - case 0x08: buf[n++] = '7'; break; - case 0x09: buf[n++] = '8'; break; - case 0x0a: buf[n++] = '9'; break; - case 0x33: buf[n++] = ','; break; - } - cprint(x, y, buf); - if (n >= len) { - buf[n] = 0; - return; - } - } -}
\ No newline at end of file + int c, n = 0; + + len--; + wait_keyup(); + while(1) { + /* Read a new character and process it */ + c = get_key(); + switch(c) { + case 0x1c: /* CR */ + /* If something has been entered we are done */ + if(n) { + buf[n] = 0; + return; + } + break; + case 0x0e: /* BS */ + if (n > 0) { + n -= 1; + buf[n] = ' '; + } + break; + case 0x0B: buf[n++] = '0'; break; + case 0x02: buf[n++] = '1'; break; + case 0x03: buf[n++] = '2'; break; + case 0x04: buf[n++] = '3'; break; + case 0x05: buf[n++] = '4'; break; + case 0x06: buf[n++] = '5'; break; + case 0x07: buf[n++] = '6'; break; + case 0x08: buf[n++] = '7'; break; + case 0x09: buf[n++] = '8'; break; + case 0x0a: buf[n++] = '9'; break; + case 0x33: buf[n++] = ','; break; + } + cprint(x, y, buf); + if (n >= len) { + buf[n] = 0; + return; + } + } +} diff --git a/linuxbios.c b/linuxbios.c index 75d9181..4804b31 100644 --- a/linuxbios.c +++ b/linuxbios.c @@ -19,7 +19,7 @@ static unsigned long ip_compute_csum(void *addr, unsigned long length) */ buffer = 0; ptr = addr; - memmove(&buffer, ptr, 1); + mt86_memmove(&buffer, ptr, 1); sum += buffer; if (sum > 0xFFFF) sum -= 0xFFFF; @@ -44,7 +44,7 @@ static unsigned long ip_compute_csum(void *addr, unsigned long length) */ buffer = 0; ptr = addr; - memmove(&buffer, ptr, 1); + mt86_memmove(&buffer, ptr, 1); sum += buffer; if (sum > 0xFFFF) sum -= 0xFFFF; @@ -79,7 +79,7 @@ static struct lb_header * __find_lb_table(unsigned long start, unsigned long end for(addr = start; addr < end; addr += 16) { struct lb_header *head = (struct lb_header *)addr; struct lb_record *recs = (struct lb_record *)(addr + sizeof(*head)); - if (memcmp(head->signature, "LBIO", 4) != 0) + if (mt86_memcmp(head->signature, "LBIO", 4) != 0) continue; if (head->header_bytes != sizeof(*head)) continue; @@ -22,7 +22,7 @@ /* The main stack is allocated during boot time. The stack size should * preferably be a multiple of page size(4Kbytes) -*/ + */ extern struct cpu_ident cpu_id; extern char toupper(char c); @@ -47,19 +47,20 @@ int find_chunks(int test); static void test_setup(void); static int compute_segments(struct pmap map, int cpu); int do_test(int ord); -struct tseq tseq[] = { - {1, -1, 0, 6, 0, "[Address test, walking ones, no cache] "}, - {1, -1, 1, 6, 0, "[Address test, own address Sequential] "}, - {1, 32, 2, 6, 0, "[Address test, own address Parallel] "}, - {1, 32, 3, 6, 0, "[Moving inversions, 1s & 0s Parallel] "}, - {1, 32, 5, 3, 0, "[Moving inversions, 8 bit pattern] "}, - {1, 32, 6, 30, 0, "[Moving inversions, random pattern] "}, - {1, 32, 7, 81, 0, "[Block move] "}, - {1, 1, 8, 3, 0, "[Moving inversions, 32 bit pattern] "}, - {1, 32, 9, 48, 0, "[Random number sequence] "}, - {1, 32, 10, 6, 0, "[Modulo 20, Random pattern] "}, - {1, 1, 11, 240, 0, "[Bit fade test, 2 patterns] "}, - {1, 0, 0, 0, 0, NULL} +struct tseq tseq[] = + { + {1, -1, 0, 6, 0, "[Address test, walking ones, no cache] "}, + {1, -1, 1, 6, 0, "[Address test, own address Sequential] "}, + {1, 32, 2, 6, 0, "[Address test, own address Parallel] "}, + {1, 32, 3, 6, 0, "[Moving inversions, 1s & 0s Parallel] "}, + {1, 32, 5, 3, 0, "[Moving inversions, 8 bit pattern] "}, + {1, 32, 6, 30, 0, "[Moving inversions, random pattern] "}, + {1, 32, 7, 81, 0, "[Block move] "}, + {1, 1, 8, 3, 0, "[Moving inversions, 32 bit pattern] "}, + {1, 32, 9, 48, 0, "[Random number sequence] "}, + {1, 32, 10, 6, 0, "[Modulo 20, Random pattern] "}, + {1, 1, 11, 240, 0, "[Bit fade test, 2 patterns] "}, + {1, 0, 0, 0, 0, NULL} }; volatile int mstr_cpu; @@ -74,16 +75,16 @@ short onepass; volatile short btflag = 0; volatile int test; short restart_flag; -bool reloc_pending = FALSE; -uint8_t volatile stacks[MAX_CPUS][STACKSIZE]; +uint8_t volatile stacks[MAX_CPUS][STACKSIZE_BYTES]; int bitf_seq = 0; char cmdline_parsed = 0; struct vars variables = {}; -struct vars * const v = &variables; +struct vars * const vv = &variables; volatile int bail; int nticks; int test_ticks; -volatile int segs; +volatile int segs; /* number of entries in vv->map[] + (Why not be a member of vars then?) */ static int ltest; static int pass_flag = 0; volatile short start_seq = 0; @@ -98,126 +99,127 @@ volatile static struct pmap winx; /* Window struct for mapping windows */ /* Find the next selected test to run */ void next_test() { - test++; - while (tseq[test].sel == 0 && tseq[test].cpu_sel != 0) { - test++; - } - - if (tseq[test].cpu_sel == 0) { - /* We hit the end of the list so we completed a pass */ - pass_flag++; - /* Find the next test to run, start searching from 0 */ - test = 0; - while (tseq[test].sel == 0 && tseq[test].cpu_sel != 0) { - test++; - } - } + test++; + while (tseq[test].sel == 0 && tseq[test].cpu_sel != 0) { + test++; + } + + if (tseq[test].cpu_sel == 0) { + /* We hit the end of the list so we completed a pass */ + pass_flag++; + /* Find the next test to run, start searching from 0 */ + test = 0; + while (tseq[test].sel == 0 && tseq[test].cpu_sel != 0) { + test++; + } + } } /* Set default values for all parameters */ void set_defaults() { - int i; - - if (start_seq == 2) { - /* This is a restart so we reset everything */ - onepass = 0; - i = 0; - while (tseq[i].cpu_sel) { - tseq[i].sel = 1; - i++; - } - test = 0; - if (tseq[0].sel == 0) { - next_test(); - } - } - ltest = -1; - win_next = 0; - window = 0; - bail = 0; - cpu_mode = CPM_ALL; - cpu_sel = 0; - v->printmode=PRINTMODE_ADDRESSES; - v->numpatn=0; - v->plim_lower = 0; - v->plim_upper = v->pmap[v->msegs-1].end; - v->pass = 0; - v->msg_line = 0; - v->ecount = 0; - v->ecc_ecount = 0; - v->msg_line = LINE_SCROLL-1; - v->scroll_start = v->msg_line * 160; - v->erri.low_addr.page = 0x7fffffff; - v->erri.low_addr.offset = 0xfff; - v->erri.high_addr.page = 0; - v->erri.high_addr.offset = 0; - v->erri.min_bits = 32; - v->erri.max_bits = 0; - v->erri.min_bits = 32; - v->erri.max_bits = 0; - v->erri.maxl = 0; - v->erri.cor_err = 0; - v->erri.ebits = 0; - v->erri.hdr_flag = 0; - v->erri.tbits = 0; - for (i=0; tseq[i].msg != NULL; i++) { - tseq[i].errors = 0; - } - restart_flag = 0; - tseq[10].sel = 0; + int i; + + if (start_seq == 2) { + /* This is a restart so we reset everything */ + onepass = 0; + i = 0; + while (tseq[i].cpu_sel) { + tseq[i].sel = 1; + i++; + } + test = 0; + if (tseq[0].sel == 0) { + next_test(); + } + } + ltest = -1; + win_next = 0; + window = 0; + bail = 0; + cpu_mode = CPM_ALL; + cpu_sel = 0; + vv->printmode=PRINTMODE_ADDRESSES; + vv->numpatn=0; + vv->plim_lower = 0; + vv->plim_upper = vv->pmap[vv->msegs-1].end; + vv->pass = 0; + vv->msg_line = 0; + vv->ecount = 0; + vv->ecc_ecount = 0; + vv->msg_line = LINE_SCROLL-1; + vv->scroll_start = vv->msg_line * 160; + vv->debugging = 0; + vv->erri.low_addr.page = 0x7fffffff; + vv->erri.low_addr.offset = 0xfff; + vv->erri.high_addr.page = 0; + vv->erri.high_addr.offset = 0; + vv->erri.min_bits = 32; + vv->erri.max_bits = 0; + vv->erri.min_bits = 32; + vv->erri.max_bits = 0; + vv->erri.maxl = 0; + vv->erri.cor_err = 0; + vv->erri.ebits = 0; + vv->erri.hdr_flag = 0; + vv->erri.tbits = 0; + for (i=0; tseq[i].msg != NULL; i++) { + tseq[i].errors = 0; + } + restart_flag = 0; + tseq[10].sel = 0; } /* Boot trace function */ short tidx = 25; void btrace(int me, int line, char *msg, int wait, long v1, long v2) { - int y, x; - - /* Is tracing turned on? */ - if (btflag == 0) return; - - spin_lock(&barr->mutex); - y = tidx%13; - x = tidx/13*40; - cplace(y+11, x+1, ' '); - if (++tidx > 25) { - tidx = 0; - } - y = tidx%13; - x = tidx/13*40; - - cplace(y+11, x+1, '>'); - dprint(y+11, x+2, me, 2, 0); - dprint(y+11, x+5, line, 4, 0); - cprint(y+11, x+10, msg); - hprint(y+11, x+22, v1); - hprint(y+11, x+31, v2); - if (wait) { - wait_keyup(); - } - spin_unlock(&barr->mutex); + int y, x; + + /* Is tracing turned on? */ + if (btflag == 0) return; + + spin_lock(&barr->mutex); + y = tidx%13; + x = tidx/13*40; + cplace(y+11, x+1, ' '); + if (++tidx > 25) { + tidx = 0; + } + y = tidx%13; + x = tidx/13*40; + + cplace(y+11, x+1, '>'); + dprint(y+11, x+2, me, 2, 0); + dprint(y+11, x+5, line, 4, 0); + cprint(y+11, x+10, msg); + hprint(y+11, x+22, v1); + hprint(y+11, x+31, v2); + if (wait) { + wait_keyup(); + } + spin_unlock(&barr->mutex); } /* Relocate the test to a new address. Be careful to not overlap! */ static void run_at(unsigned long addr, int cpu) { - ulong *ja = (ulong *)(addr + startup_32 - _start); + ulong *ja = (ulong *)(addr + startup_32 - _start); - /* CPU 0, Copy memtest86+ code */ - if (cpu == 0) { - memmove((void *)addr, &_start, _end - _start); - } + /* CPU 0, Copy memtest86+ code */ + if (cpu == 0) { + mt86_memmove((void *)addr, &_start, _end - _start); + } - /* Wait for the copy */ - barrier(); + /* Wait for the copy */ + barrier(); - /* We use a lock to insure that only one CPU at a time jumps to - * the new code. Some of the startup stuff is not thread safe! */ - spin_lock(&barr->mutex); + /* We use a lock to insure that only one CPU at a time jumps to + * the new code. Some of the startup stuff is not thread safe! */ + spin_lock(&barr->mutex); - /* Jump to the start address */ - goto *ja; + /* Jump to the start address */ + goto *ja; } /* Switch from the boot stack to the main stack. First the main stack @@ -227,43 +229,29 @@ static void run_at(unsigned long addr, int cpu) static void switch_to_main_stack(unsigned cpu_num) { - extern uintptr_t boot_stack; - extern uintptr_t boot_stack_top; - uintptr_t *src, *dst; - int offs; - uint8_t * stackAddr, *stackTop; + extern uintptr_t boot_stack; + extern uintptr_t boot_stack_top; + uintptr_t *src, *dst; + int offs; + uint8_t * stackAddr, *stackTop; - stackAddr = (uint8_t *) &stacks[cpu_num][0]; + stackAddr = (uint8_t *) &stacks[cpu_num][0]; - stackTop = stackAddr + STACKSIZE; + stackTop = stackAddr + STACKSIZE_BYTES; - src = (uintptr_t*)&boot_stack_top; - dst = (uintptr_t*)stackTop; - do { - src--; dst--; - *dst = *src; - } while ((uintptr_t *)src > (uintptr_t *)&boot_stack); - - offs = (uint8_t *)&boot_stack_top - stackTop; - __asm__ __volatile__ ( - "subl %%eax, %%esp" - : /*no output*/ - : "a" (offs) : "memory" - ); -} - -void reloc_internal(int cpu) -{ - /* clear variables */ - reloc_pending = FALSE; - - run_at(LOW_TEST_ADR, cpu); -} - -void reloc(void) -{ - bail++; - reloc_pending = TRUE; + src = (uintptr_t*)&boot_stack_top; + dst = (uintptr_t*)stackTop; + do { + src--; dst--; + *dst = *src; + } while ((uintptr_t *)src > (uintptr_t *)&boot_stack); + + offs = (uint8_t *)&boot_stack_top - stackTop; + __asm__ __volatile__ ( + "subl %%eax, %%esp" + : /*no output*/ + : "a" (offs) : "memory" + ); } /* command line passing using the 'old' boot protocol */ @@ -274,547 +262,549 @@ void reloc(void) static void parse_command_line(void) { - long simple_strtoul(char *cmd, char *ptr, int base); - char *cp, dummy; - int i, j, k; - - if (cmdline_parsed) - return; - - /* Fill in the cpu mask array with the default */ - for (i=0; i<MAX_CPUS; i++) { - cpu_mask[i] = 1; - } - - if (*OLD_CL_MAGIC_ADDR != OLD_CL_MAGIC) - return; - - unsigned short offset = *OLD_CL_OFFSET_ADDR; - cp = MK_PTR(INITSEG, offset); - - /* skip leading spaces */ - while (*cp == ' ') - cp++; - - while (*cp) { - if (!strncmp(cp, "console=", 8)) { - cp += 8; - serial_console_setup(cp); - } - /* Enable boot trace? */ - if (!strncmp(cp, "btrace", 6)) { - cp += 6; - btflag++; - } - /* Limit number of CPUs */ - if (!strncmp(cp, "maxcpus=", 8)) { - cp += 8; - maxcpus=(int)simple_strtoul(cp, &dummy, 10); - } - /* Run one pass and exit if there are no errors */ - if (!strncmp(cp, "onepass", 7)) { - cp += 7; - onepass++; - } - /* Setup a list of tests to run */ - if (!strncmp(cp, "tstlist=", 8)) { - cp += 8; - /* Clear all of the tests first */ - k = 0; - while (tseq[k].cpu_sel) { - tseq[k].sel = 0; - k++; - } - - /* Now enable all of the tests in the list */ - j = 0; - while(*cp && isdigit(*cp)) { - i = *cp-'0'; - j = j*10 + i; - cp++; - if (*cp == ',' || !isdigit(*cp)) { - if (j < k) { - tseq[j].sel = 1; - } - if (*cp != ',') break; - j = 0; - cp++; - } - } - } - /* Set a CPU mask to select CPU's to use for testing */ - if (!strncmp(cp, "cpumask=", 8)) { - cp += 8; - if (cp[0] == '0' && toupper(cp[1]) == 'X') cp += 2; - while (*cp && *cp != ' ' && isxdigit(*cp)) { - i = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10; - bin_mask = bin_mask * 16 + i; - cp++; - } - /* Force CPU zero to always be selected */ - bin_mask |= 1; - for (i=0; i<32; i++) { - if (((bin_mask>>i) & 1) == 0) { - cpu_mask[i] = 0; - } - } - } - /* go to the next parameter */ - while (*cp && *cp != ' ') cp++; - while (*cp == ' ') cp++; - } - - cmdline_parsed = 1; + long simple_strtoul(char *cmd, char *ptr, int base); + char *cp, dummy; + int i, j, k; + + if (cmdline_parsed) + return; + + /* Fill in the cpu mask array with the default */ + for (i=0; i<MAX_CPUS; i++) { + cpu_mask[i] = 1; + } + + if (*OLD_CL_MAGIC_ADDR != OLD_CL_MAGIC) + return; + + unsigned short offset = *OLD_CL_OFFSET_ADDR; + cp = MK_PTR(INITSEG, offset); + + /* skip leading spaces */ + while (*cp == ' ') + cp++; + + while (*cp) { + if (!mt86_strncmp(cp, "console=", 8)) { + cp += 8; + serial_console_setup(cp); + } + /* Enable boot trace? */ + if (!mt86_strncmp(cp, "btrace", 6)) { + cp += 6; + btflag++; + } + /* Limit number of CPUs */ + if (!mt86_strncmp(cp, "maxcpus=", 8)) { + cp += 8; + maxcpus=(int)simple_strtoul(cp, &dummy, 10); + } + /* Run one pass and exit if there are no errors */ + if (!mt86_strncmp(cp, "onepass", 7)) { + cp += 7; + onepass++; + } + /* Setup a list of tests to run */ + if (!mt86_strncmp(cp, "tstlist=", 8)) { + cp += 8; + /* Clear all of the tests first */ + k = 0; + while (tseq[k].cpu_sel) { + tseq[k].sel = 0; + k++; + } + + /* Now enable all of the tests in the list */ + j = 0; + while(*cp && mt86_isdigit(*cp)) { + i = *cp-'0'; + j = j*10 + i; + cp++; + if (*cp == ',' || !mt86_isdigit(*cp)) { + if (j < k) { + tseq[j].sel = 1; + } + if (*cp != ',') break; + j = 0; + cp++; + } + } + } + /* Set a CPU mask to select CPU's to use for testing */ + if (!mt86_strncmp(cp, "cpumask=", 8)) { + cp += 8; + if (cp[0] == '0' && toupper(cp[1]) == 'X') cp += 2; + while (*cp && *cp != ' ' && isxdigit(*cp)) { + i = mt86_isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10; + bin_mask = bin_mask * 16 + i; + cp++; + } + /* Force CPU zero to always be selected */ + bin_mask |= 1; + for (i=0; i<32; i++) { + if (((bin_mask>>i) & 1) == 0) { + cpu_mask[i] = 0; + } + } + } + /* go to the next parameter */ + while (*cp && *cp != ' ') cp++; + while (*cp == ' ') cp++; + } + + cmdline_parsed = 1; } void clear_screen() { - int i; - char *pp; - - /* Clear screen & set background to blue */ - for(i=0, pp=(char *)(SCREEN_ADR); i<80*25; i++) { - *pp++ = ' '; - *pp++ = 0x17; - } - if (btflag) { - cprint(1, 0, "Boot Trace Enabled"); - cprint(1, 0, "Press any key to advance to next trace point"); - cprint(9, 1,"CPU Line Message Param #1 Param #2 CPU Line Message Param #1 Param #2"); - cprint(10,1,"--- ---- ----------- -------- -------- --- ---- ----------- -------- --------"); - } + int i; + char *pp; + + /* Clear screen & set background to blue */ + for(i=0, pp=(char *)(SCREEN_ADR); i<80*25; i++) { + *pp++ = ' '; + *pp++ = 0x17; + } + if (btflag) { + cprint(1, 0, "Boot Trace Enabled"); + cprint(1, 0, "Press any key to advance to next trace point"); + cprint(9, 1,"CPU Line Message Param #1 Param #2 CPU Line Message Param #1 Param #2"); + cprint(10,1,"--- ---- ----------- -------- -------- --- ---- ----------- -------- --------"); + } } -/* This is the test entry point. We get here on statup and also whenever + +/* Test entry point. We get here on startup and also whenever * we relocate. */ void test_start(void) { - int my_cpu_num, my_cpu_ord, run; - - /* If this is the first time here we are CPU 0 */ - if (start_seq == 0) { - my_cpu_num = 0; - } else { - my_cpu_num = smp_my_cpu_num(); - } - /* First thing, switch to main stack */ - switch_to_main_stack(my_cpu_num); - - /* First time (for this CPU) initialization */ - if (start_seq < 2) { - - /* These steps are only done by the boot cpu */ - if (my_cpu_num == 0) { - my_cpu_ord = cpu_ord++; - smp_set_ordinal(my_cpu_num, my_cpu_ord); - parse_command_line(); - clear_screen(); - /* Initialize the barrier so the lock in btrace will work. - * Will get redone later when we know how many CPUs we have */ - barrier_init(1); - btrace(my_cpu_num, __LINE__, "Begin ", 1, 0, 0); - /* Find memory size */ - mem_size(); /* must be called before initialise_cpus(); */ - /* Fill in the CPUID table */ - get_cpuid(); - /* Startup the other CPUs */ - start_seq = 1; - //initialise_cpus(); - btrace(my_cpu_num, __LINE__, "BeforeInit", 1, 0, 0); - /* Draw the screen and get system information */ - init(); - - /* Set defaults and initialize variables */ - set_defaults(); - - /* Setup base address for testing, 1 MB */ - win0_start = 0x100; - - /* Set relocation address to 32Mb if there is enough - * memory. Otherwise set it to 3Mb */ - /* Large reloc addr allows for more testing overlap */ - if ((ulong)v->pmap[v->msegs-1].end > 0x2f00) { - high_test_adr = 0x2000000; - } else { - high_test_adr = 0x300000; - } - win1_end = (high_test_adr >> 12); - - /* Adjust the map to not test the page at 939k, - * reserved for locks */ - v->pmap[0].end--; - - find_ticks_for_pass(); - } else { - /* APs only, Register the APs */ - btrace(my_cpu_num, __LINE__, "AP_Start ", 0, my_cpu_num, - cpu_ord); - smp_ap_booted(my_cpu_num); - /* Asign a sequential CPU ordinal to each active cpu */ - spin_lock(&barr->mutex); - my_cpu_ord = cpu_ord++; - smp_set_ordinal(my_cpu_num, my_cpu_ord); - spin_unlock(&barr->mutex); - btrace(my_cpu_num, __LINE__, "AP_Done ", 0, my_cpu_num, - my_cpu_ord); - } - - } else { - /* Unlock after a relocation */ - spin_unlock(&barr->mutex); - /* Get the CPU ordinal since it is lost during relocation */ - my_cpu_ord = smp_my_ord_num(my_cpu_num); - btrace(my_cpu_num, __LINE__, "Reloc_Done",0,my_cpu_num,my_cpu_ord); - } - - /* A barrier to insure that all of the CPUs are done with startup */ - barrier(); - btrace(my_cpu_num, __LINE__, "1st Barr ", 1, my_cpu_num, my_cpu_ord); + int my_cpu_num, my_cpu_ord, run; + + /* If this is the first time here we are CPU 0 */ + if (start_seq == 0) { + my_cpu_num = 0; + } else { + my_cpu_num = smp_my_cpu_num(); + } + /* First thing, switch to main stack */ + switch_to_main_stack(my_cpu_num); + + /* First time (for this CPU) initialization */ + if (start_seq < 2) { + + /* These steps are only done by the boot cpu */ + if (my_cpu_num == 0) { + my_cpu_ord = cpu_ord++; + smp_set_ordinal(my_cpu_num, my_cpu_ord); + parse_command_line(); + clear_screen(); + /* Initialize the barrier so the lock in btrace will work. + * Will get redone later when we know how many CPUs we have */ + barrier_init(1); + btrace(my_cpu_num, __LINE__, "Begin ", 1, 0, 0); + /* Find memory size */ + mem_size(); /* must be called before initialise_cpus(); */ + /* Fill in the CPUID table */ + get_cpuid(); + /* Startup the other CPUs */ + start_seq = 1; + //initialise_cpus(); + btrace(my_cpu_num, __LINE__, "BeforeInit", 1, 0, 0); + /* Draw the screen and get system information */ + init(); + + /* Set defaults and initialize variables */ + set_defaults(); + + /* Setup base address for testing, 1 MB */ + win0_start = 0x100; + + /* Set relocation address to 32Mb if there is enough + * memory. Otherwise set it to 3Mb */ + /* Large reloc addr allows for more testing overlap */ + if ((ulong)vv->pmap[vv->msegs-1].end > 0x2f00) { + high_test_adr = 0x2000000; + } else { + high_test_adr = 0x300000; + } + win1_end = (high_test_adr >> 12); + + /* Adjust the map to not test the page at 939k, + * reserved for locks */ + vv->pmap[0].end--; + + find_ticks_for_pass(); + } else { + /* APs only, Register the APs */ + btrace(my_cpu_num, __LINE__, "AP_Start ", 0, my_cpu_num, + cpu_ord); + smp_ap_booted(my_cpu_num); + /* Asign a sequential CPU ordinal to each active cpu */ + spin_lock(&barr->mutex); + my_cpu_ord = cpu_ord++; + smp_set_ordinal(my_cpu_num, my_cpu_ord); + spin_unlock(&barr->mutex); + btrace(my_cpu_num, __LINE__, "AP_Done ", 0, my_cpu_num, + my_cpu_ord); + } + + } else { + /* Unlock after a relocation */ + spin_unlock(&barr->mutex); + /* Get the CPU ordinal since it is lost during relocation */ + my_cpu_ord = smp_my_ord_num(my_cpu_num); + btrace(my_cpu_num, __LINE__, "Reloc_Done",0,my_cpu_num,my_cpu_ord); + } + + /* A barrier to insure that all of the CPUs are done with startup */ + barrier(); + btrace(my_cpu_num, __LINE__, "1st Barr ", 1, my_cpu_num, my_cpu_ord); - /* Setup Memory Management and measure memory speed, we do it here - * because we need all of the available CPUs */ - if (start_seq < 2) { - - /* Enable floating point processing */ - if (cpu_id.fid.bits.fpu) - __asm__ __volatile__ ( - "movl %%cr0, %%eax\n\t" - "andl $0x7, %%eax\n\t" - "movl %%eax, %%cr0\n\t" - : : - : "ax" - ); - if (cpu_id.fid.bits.sse) - __asm__ __volatile__ ( - "movl %%cr4, %%eax\n\t" - "orl $0x00000200, %%eax\n\t" - "movl %%eax, %%cr4\n\t" - : : - : "ax" - ); - - btrace(my_cpu_num, __LINE__, "Mem Mgmnt ", 1, cpu_id.fid.bits.pae, cpu_id.fid.bits.lm); - /* Setup memory management modes */ - /* If we have PAE, turn it on */ - if (cpu_id.fid.bits.pae == 1) { - __asm__ __volatile__( - "movl %%cr4, %%eax\n\t" - "orl $0x00000020, %%eax\n\t" - "movl %%eax, %%cr4\n\t" - : : - : "ax" - ); - cprint(LINE_TITLE+1, COL_MODE, "(PAE Mode)"); - } - /* If this is a 64 CPU enable long mode */ - if (cpu_id.fid.bits.lm == 1) { - __asm__ __volatile__( - "movl $0xc0000080, %%ecx\n\t" - "rdmsr\n\t" - "orl $0x00000100, %%eax\n\t" - "wrmsr\n\t" - : : - : "ax", "cx" - ); - cprint(LINE_TITLE+1, COL_MODE, "(X64 Mode)"); + /* Setup Memory Management and measure memory speed, we do it here + * because we need all of the available CPUs */ + if (start_seq < 2) { + + /* Enable floating point processing */ + if (cpu_id.fid.bits.fpu) + __asm__ __volatile__ + ( + "movl %%cr0, %%eax\n\t" + "andl $0x7, %%eax\n\t" + "movl %%eax, %%cr0\n\t" + : : + : "ax" + ); + if (cpu_id.fid.bits.sse) + __asm__ __volatile__ + ( + "movl %%cr4, %%eax\n\t" + "orl $0x00000200, %%eax\n\t" + "movl %%eax, %%cr4\n\t" + : : + : "ax" + ); + + btrace(my_cpu_num, __LINE__, "Mem Mgmnt ", + 1, cpu_id.fid.bits.pae, cpu_id.fid.bits.lm); + /* Setup memory management modes */ + /* If we have PAE, turn it on */ + if (cpu_id.fid.bits.pae == 1) { + __asm__ __volatile__ + ( + "movl %%cr4, %%eax\n\t" + "orl $0x00000020, %%eax\n\t" + "movl %%eax, %%cr4\n\t" + : : + : "ax" + ); + cprint(LINE_TITLE+1, COL_MODE, "(PAE Mode)"); + } + /* If this is a 64 CPU enable long mode */ + if (cpu_id.fid.bits.lm == 1) { + __asm__ __volatile__ + ( + "movl $0xc0000080, %%ecx\n\t" + "rdmsr\n\t" + "orl $0x00000100, %%eax\n\t" + "wrmsr\n\t" + : : + : "ax", "cx" + ); + cprint(LINE_TITLE+1, COL_MODE, "(X64 Mode)"); + } + /* Get the memory Speed with all CPUs */ + get_mem_speed(my_cpu_num, num_cpus); + } + + /* Set the initialized flag only after all of the CPU's have + * Reached the barrier. This insures that relocation has + * been completed for each CPU. */ + btrace(my_cpu_num, __LINE__, "Start Done", 1, 0, 0); + start_seq = 2; + + /* Loop through all tests */ + while (1) { + /* If the restart flag is set all initial params */ + if (restart_flag) { + set_defaults(); + continue; + } + /* Skip single CPU tests if we are using only one CPU */ + if (tseq[test].cpu_sel == -1 && + (num_cpus == 1 || cpu_mode != CPM_ALL)) { + test++; + continue; + } + + test_setup(); + + /* Loop through all possible windows */ + while (win_next <= ((ulong)vv->pmap[vv->msegs-1].end + WIN_SZ_PAGES)) { + + /* Main scheduling barrier */ + cprint(8, my_cpu_num+7, "W"); + btrace(my_cpu_num, __LINE__, "Sched_Barr", 1,window,win_next); + barrier(); + + /* Don't go over the 8TB PAE limit */ + if (win_next > MAX_MEM_PAGES) { + break; + } + + /* For the bit fade test, #11, we cannot relocate so bump the + * window to 1 */ + if (tseq[test].pat == 11 && window == 0) { + window = 1; + } + + /* Relocate if required */ + if (window != 0 && (ulong)&_start != LOW_TEST_ADR) { + btrace(my_cpu_num, __LINE__, "Sched_RelL", 1,0,0); + run_at(LOW_TEST_ADR, my_cpu_num); } - /* Get the memory Speed with all CPUs */ - get_mem_speed(my_cpu_num, num_cpus); - } - - /* Set the initialized flag only after all of the CPU's have - * Reached the barrier. This insures that relocation has - * been completed for each CPU. */ - btrace(my_cpu_num, __LINE__, "Start Done", 1, 0, 0); - start_seq = 2; - - /* Loop through all tests */ - while (1) { - /* If the restart flag is set all initial params */ - if (restart_flag) { - set_defaults(); - continue; - } - /* Skip single CPU tests if we are using only one CPU */ - if (tseq[test].cpu_sel == -1 && - (num_cpus == 1 || cpu_mode != CPM_ALL)) { - test++; + if (window == 0 && vv->plim_lower >= win0_start) { + window++; + } + if (window == 0 && (ulong)&_start == LOW_TEST_ADR) { + btrace(my_cpu_num, __LINE__, "Sched_RelH", 1,0,0); + run_at(high_test_adr, my_cpu_num); + } + + /* Decide which CPU(s) to use */ + btrace(my_cpu_num, __LINE__, "Sched_CPU0",1,cpu_sel, + tseq[test].cpu_sel); + run = 1; + switch(cpu_mode) { + case CPM_RROBIN: + case CPM_SEQ: + /* Select a single CPU */ + if (my_cpu_ord == cpu_sel) { + mstr_cpu = cpu_sel; + run_cpus = 1; + } else { + run = 0; + } + break; + case CPM_ALL: + /* Use all CPUs */ + if (tseq[test].cpu_sel == -1) { + /* Round robin through all of the CPUs */ + if (my_cpu_ord == cpu_sel) { + mstr_cpu = cpu_sel; + run_cpus = 1; + } else { + run = 0; + } + } else { + /* Use the number of CPUs specified by the test, + * Starting with zero */ + if (my_cpu_ord >= tseq[test].cpu_sel) { + run = 0; + } + /* Set the master CPU to the highest CPU number + * that has been selected */ + if (act_cpus < tseq[test].cpu_sel) { + mstr_cpu = act_cpus-1; + run_cpus = act_cpus; + } else { + mstr_cpu = tseq[test].cpu_sel-1; + run_cpus = tseq[test].cpu_sel; + } + } + } + btrace(my_cpu_num, __LINE__, "Sched_CPU1",1,run_cpus,run); + barrier(); + dprint(9, 7, run_cpus, 2, 0); + + /* Setup a sub barrier for only the selected CPUs */ + if (my_cpu_ord == mstr_cpu) { + s_barrier_init(run_cpus); + } + + /* Make sure the the sub barrier is ready before proceeding */ + barrier(); + + /* Not selected CPUs go back to the scheduling barrier */ + if (run == 0 ) { continue; } + cprint(8, my_cpu_num+7, "-"); + btrace(my_cpu_num, __LINE__, "Sched_Win0",1,window,win_next); - test_setup(); - - /* Loop through all possible windows */ - while (win_next <= ((ulong)v->pmap[v->msegs-1].end + WIN_SZ)) { - - /* Main scheduling barrier */ - cprint(8, my_cpu_num+7, "W"); - btrace(my_cpu_num, __LINE__, "Sched_Barr", 1,window,win_next); - barrier(); - - /* Don't go over the 8TB PAE limit */ - if (win_next > MAX_MEM) { - break; - } - - /* For the bit fade test, #11, we cannot relocate so bump the - * window to 1 */ - if (tseq[test].pat == 11 && window == 0) { - window = 1; - } - - /* Relocate if required */ - if (window != 0 && (ulong)&_start != LOW_TEST_ADR) { - btrace(my_cpu_num, __LINE__, "Sched_RelL", 1,0,0); - run_at(LOW_TEST_ADR, my_cpu_num); - } - if (window == 0 && v->plim_lower >= win0_start) { - window++; - } - if (window == 0 && (ulong)&_start == LOW_TEST_ADR) { - btrace(my_cpu_num, __LINE__, "Sched_RelH", 1,0,0); - run_at(high_test_adr, my_cpu_num); - } - - /* Decide which CPU(s) to use */ - btrace(my_cpu_num, __LINE__, "Sched_CPU0",1,cpu_sel, - tseq[test].cpu_sel); - run = 1; - switch(cpu_mode) { - case CPM_RROBIN: - case CPM_SEQ: - /* Select a single CPU */ - if (my_cpu_ord == cpu_sel) { - mstr_cpu = cpu_sel; - run_cpus = 1; - } else { - run = 0; - } - break; - case CPM_ALL: - /* Use all CPUs */ - if (tseq[test].cpu_sel == -1) { - /* Round robin through all of the CPUs */ - if (my_cpu_ord == cpu_sel) { - mstr_cpu = cpu_sel; - run_cpus = 1; - } else { - run = 0; - } - } else { - /* Use the number of CPUs specified by the test, - * Starting with zero */ - if (my_cpu_ord >= tseq[test].cpu_sel) { - run = 0; - } - /* Set the master CPU to the highest CPU number - * that has been selected */ - if (act_cpus < tseq[test].cpu_sel) { - mstr_cpu = act_cpus-1; - run_cpus = act_cpus; - } else { - mstr_cpu = tseq[test].cpu_sel-1; - run_cpus = tseq[test].cpu_sel; - } - } - } - btrace(my_cpu_num, __LINE__, "Sched_CPU1",1,run_cpus,run); - barrier(); - dprint(9, 7, run_cpus, 2, 0); - - /* Setup a sub barrier for only the selected CPUs */ - if (my_cpu_ord == mstr_cpu) { - s_barrier_init(run_cpus); - } - - /* Make sure the the sub barrier is ready before proceeding */ - barrier(); - - /* Not selected CPUs go back to the scheduling barrier */ - if (run == 0 ) { - continue; - } - cprint(8, my_cpu_num+7, "-"); - btrace(my_cpu_num, __LINE__, "Sched_Win0",1,window,win_next); - - /* Do we need to exit */ - if(reloc_pending) { - reloc_internal(my_cpu_num); - } - - if (my_cpu_ord == mstr_cpu) { - switch (window) { + if (my_cpu_ord == mstr_cpu) { + switch (window) { /* Special case for relocation */ - case 0: - winx.start = 0; - winx.end = win1_end; - window++; - break; + case 0: + winx.start = 0; + winx.end = win1_end; + window++; + break; /* Special case for first segment */ - case 1: - winx.start = win0_start; - winx.end = WIN_SZ; - win_next += WIN_SZ; - window++; - break; + case 1: + winx.start = win0_start; + winx.end = WIN_SZ_PAGES; + win_next += WIN_SZ_PAGES; + window++; + break; /* For all other windows */ - default: - winx.start = win_next; - win_next += WIN_SZ; - winx.end = win_next; - } - btrace(my_cpu_num,__LINE__,"Sched_Win1",1,winx.start, - winx.end); - - /* Find the memory areas to test */ - segs = compute_segments(winx, my_cpu_num); - } - s_barrier(); - btrace(my_cpu_num,__LINE__,"Sched_Win2",1,segs, - v->map[0].pbase_addr); - - if (segs == 0) { + default: + winx.start = win_next; + win_next += WIN_SZ_PAGES; + winx.end = win_next; + } + btrace(my_cpu_num,__LINE__,"Sched_Win1",1,winx.start, + winx.end); + + /* Find the memory areas to test */ + segs = compute_segments(winx, my_cpu_num); + } + s_barrier(); + btrace(my_cpu_num,__LINE__,"Sched_Win2",1,segs, + vv->map[0].pbase_addr); + + if (segs == 0) { /* No memory in this window so skip it */ - continue; - } - - /* map in the window... */ - if (map_page(v->map[0].pbase_addr) < 0) { - /* Either there is no PAE or we are at the PAE limit */ - break; - } - - btrace(my_cpu_num, __LINE__, "Strt_Test ",1,my_cpu_num, - my_cpu_ord); - do_test(my_cpu_ord); - btrace(my_cpu_num, __LINE__, "End_Test ",1,my_cpu_num, - my_cpu_ord); - - paging_off(); - - } /* End of window loop */ - - s_barrier(); - btrace(my_cpu_num, __LINE__, "End_Win ",1,test, window); - - /* Setup for the next set of windows */ - win_next = 0; - window = 0; - bail = 0; - - /* Only the master CPU does the end of test housekeeping */ - if (my_cpu_ord != mstr_cpu) { - continue; - } - - /* Special handling for the bit fade test #11 */ - if (tseq[test].pat == 11 && bitf_seq != 6) { - /* Keep going until the sequence is complete. */ - bitf_seq++; - continue; - } else { - bitf_seq = 0; - } - - /* Select advancement of CPUs and next test */ - switch(cpu_mode) { - case CPM_RROBIN: - if (++cpu_sel >= act_cpus) { - cpu_sel = 0; - } - next_test(); - break; - case CPM_SEQ: - if (++cpu_sel >= act_cpus) { - cpu_sel = 0; - next_test(); - } - break; - case CPM_ALL: - if (tseq[test].cpu_sel == -1) - { - /* Do the same test for each CPU */ - if (++cpu_sel >= act_cpus) - { + continue; + } + + /* map in the window... */ + if (map_page(vv->map[0].pbase_addr) < 0) { + /* Either there is no PAE or we are at the PAE limit */ + break; + } + + btrace(my_cpu_num, __LINE__, "Strt_Test ",1,my_cpu_num, + my_cpu_ord); + do_test(my_cpu_ord); + btrace(my_cpu_num, __LINE__, "End_Test ",1,my_cpu_num, + my_cpu_ord); + + paging_off(); + + } /* End of window loop */ + + s_barrier(); + btrace(my_cpu_num, __LINE__, "End_Win ",1,test, window); + + /* Setup for the next set of windows */ + win_next = 0; + window = 0; + bail = 0; + + /* Only the master CPU does the end of test housekeeping */ + if (my_cpu_ord != mstr_cpu) { + continue; + } + + /* Special handling for the bit fade test #11 */ + if (tseq[test].pat == 11 && bitf_seq != 6) { + /* Keep going until the sequence is complete. */ + bitf_seq++; + continue; + } else { + bitf_seq = 0; + } + + /* Select advancement of CPUs and next test */ + switch(cpu_mode) { + case CPM_RROBIN: + if (++cpu_sel >= act_cpus) { + cpu_sel = 0; + } + next_test(); + break; + case CPM_SEQ: + if (++cpu_sel >= act_cpus) { + cpu_sel = 0; + next_test(); + } + break; + case CPM_ALL: + if (tseq[test].cpu_sel == -1) + { + /* Do the same test for each CPU */ + if (++cpu_sel >= act_cpus) + { cpu_sel = 0; - next_test(); - } else { - continue; - } - } else { - next_test(); - } - } //???? - btrace(my_cpu_num, __LINE__, "Next_CPU ",1,cpu_sel,test); - - /* If this was the last test then we finished a pass */ - if (pass_flag) - { - pass_flag = 0; + next_test(); + } else { + continue; + } + } else { + next_test(); + } + } //???? + btrace(my_cpu_num, __LINE__, "Next_CPU ",1,cpu_sel,test); + + /* If this was the last test then we finished a pass */ + if (pass_flag) + { + pass_flag = 0; - v->pass++; + vv->pass++; - dprint(LINE_INFO, 49, v->pass, 5, 0); - find_ticks_for_pass(); - ltest = -1; + dprint(LINE_INFO, 49, vv->pass, 5, 0); + find_ticks_for_pass(); + ltest = -1; - if (v->ecount == 0) - { - /* If onepass is enabled and we did not get any errors - * reboot to exit the test */ - if (onepass) { reboot(); } - if (!btflag) cprint(LINE_MSG, COL_MSG-8, "** Pass complete, no errors, press Esc to exit **"); - if(BEEP_END_NO_ERROR) - { - beep(1000); - beep(2000); - beep(1000); - beep(2000); - } - } - } - - bail=0; - } /* End test loop */ -} + if (vv->ecount == 0) + { + /* If onepass is enabled and we did not get any errors + * reboot to exit the test */ + if (onepass) { reboot(); } + if (!btflag) + cprint(LINE_MSG, COL_MSG-8, + "** Pass complete, no errors, press Esc to exit **"); + if(BEEP_END_NO_ERROR) + { + beep(1000); + beep(2000); + beep(1000); + beep(2000); + } + } + } + bail=0; + } /* End test loop */ +} void test_setup() { - static int ltest = -1; - - /* See if a specific test has been selected */ - if (v->testsel >= 0) { - test = v->testsel; - } - - /* Only do the setup if this is a new test */ - if (test == ltest) { - return; - } - ltest = test; - - /* Now setup the test parameters based on the current test number */ - if (v->pass == 0) { - /* Reduce iterations for first pass */ - c_iter = tseq[test].iter/FIRST_DIVISER; - } else { - c_iter = tseq[test].iter; - } - - /* Set the number of iterations. We only do half of the iterations */ - /* on the first pass */ - //dprint(LINE_INFO, 28, c_iter, 3, 0); - test_ticks = find_ticks_for_test(test); - nticks = 0; - v->tptr = 0; - - cprint(LINE_PAT, COL_PAT, " "); - cprint(LINE_PAT, COL_PAT-3, " "); - dprint(LINE_TST, COL_MID+6, tseq[test].pat, 2, 1); - cprint(LINE_TST, COL_MID+9, tseq[test].msg); - cprint(2, COL_MID+8, " "); + static int ltest = -1; + + /* See if a specific test has been selected */ + if (vv->testsel >= 0) { + test = vv->testsel; + } + + /* Only do the setup if this is a new test */ + if (test == ltest) { + return; + } + ltest = test; + + /* Now setup the test parameters based on the current test number */ + if (vv->pass == 0) { + /* Reduce iterations for first pass */ + c_iter = tseq[test].iter/FIRST_DIVISER; + } else { + c_iter = tseq[test].iter; + } + + /* Set the number of iterations. We only do half of the iterations */ + /* on the first pass */ + //dprint(LINE_INFO, 28, c_iter, 3, 0); + test_ticks = find_ticks_for_test(test); + nticks = 0; + vv->tptr = 0; + + cprint(LINE_PAT, COL_PAT, " "); + cprint(LINE_PAT, COL_PAT-3, " "); + dprint(LINE_TST, COL_MID+6, tseq[test].pat, 2, 1); + cprint(LINE_TST, COL_MID+9, tseq[test].msg); + cprint(2, COL_MID+8, " "); } /* A couple static variables for when all cpus share the same pattern */ @@ -822,464 +812,488 @@ static ulong sp1, sp2; int do_test(int my_ord) { - int i=0, j=0; - static int bitf_sleep; - unsigned long p0=0, p1=0, p2=0; - - if (my_ord == mstr_cpu) { - if ((ulong)&_start > LOW_TEST_ADR) { - /* Relocated so we need to test all selected lower memory */ - v->map[0].start = mapping(v->plim_lower); - - /* Good 'ol Legacy USB_WAR */ - if (v->map[0].start < (ulong*)0x500) - { - v->map[0].start = (ulong*)0x500; - } - - cprint(LINE_PAT, COL_MID+25, " R"); - } else { - cprint(LINE_PAT, COL_MID+25, " "); - } - - /* Update display of memory segments being tested */ - p0 = page_of(v->map[0].start); - p1 = page_of(v->map[segs-1].end); - aprint(LINE_RANGE, COL_MID+9, p0); - cprint(LINE_RANGE, COL_MID+14, " - "); - aprint(LINE_RANGE, COL_MID+17, p1); - aprint(LINE_RANGE, COL_MID+25, p1-p0); - cprint(LINE_RANGE, COL_MID+30, " of "); - aprint(LINE_RANGE, COL_MID+34, v->selected_pages); - } - - switch(tseq[test].pat) { - - /* Do the testing according to the selected pattern */ - - case 0: /* Address test, walking ones (test #0) */ - /* Run with cache turned off */ - set_cache(0); - addr_tst1(my_ord); - set_cache(1); - BAILOUT; - break; - - case 1: - case 2: /* Address test, own address (test #1, 2) */ - addr_tst2(my_ord); - BAILOUT; - break; - - case 3: - case 4: /* Moving inversions, all ones and zeros (tests #3, 4) */ - p1 = 0; - p2 = ~p1; - s_barrier(); - movinv1(c_iter,p1,p2,my_ord); - BAILOUT; - - /* Switch patterns */ - s_barrier(); - movinv1(c_iter,p2,p1,my_ord); - BAILOUT; - break; - - case 5: /* Moving inversions, 8 bit walking ones and zeros (test #5) */ - p0 = 0x80; - for (i=0; i<8; i++, p0=p0>>1) { - p1 = p0 | (p0<<8) | (p0<<16) | (p0<<24); - p2 = ~p1; - s_barrier(); - movinv1(c_iter,p1,p2, my_ord); - BAILOUT; + int i=0, j=0; + static int bitf_sleep; + unsigned long p0=0, p1=0, p2=0; + + if (my_ord == mstr_cpu) { + if ((ulong)&_start > LOW_TEST_ADR) { + /* Relocated so we need to test all selected lower memory */ + vv->map[0].start = mapping(vv->plim_lower); + + /* Good 'ol Legacy USB_WAR */ + if (vv->map[0].start < (ulong*)0x500) + { + vv->map[0].start = (ulong*)0x500; + } + + cprint(LINE_PAT, COL_MID+25, " R"); + } else { + cprint(LINE_PAT, COL_MID+25, " "); + } + + /* Update display of memory segments being tested */ + p0 = page_of(vv->map[0].start); + p1 = page_of(vv->map[segs-1].end); + aprint(LINE_RANGE, COL_MID+9, p0); + cprint(LINE_RANGE, COL_MID+14, " - "); + aprint(LINE_RANGE, COL_MID+17, p1); + aprint(LINE_RANGE, COL_MID+25, p1-p0); + cprint(LINE_RANGE, COL_MID+30, " of "); + aprint(LINE_RANGE, COL_MID+34, vv->selected_pages); + } + + switch(tseq[test].pat) { + + /* do the testing according to the selected pattern */ + + case 0: /* Address test, walking ones (test #0) */ + /* Run with cache turned off */ + set_cache(0); + addr_tst1(my_ord); + set_cache(1); + BAILOUT; + break; + + case 1: + case 2: /* Address test, own address (test #1, 2) */ + addr_tst2(my_ord); + BAILOUT; + break; + + case 3: + case 4: /* Moving inversions, all ones and zeros (tests #3, 4) */ + p1 = 0; + p2 = ~p1; + s_barrier(); + movinv1(c_iter,p1,p2,my_ord); + BAILOUT; + + /* Switch patterns */ + s_barrier(); + movinv1(c_iter,p2,p1,my_ord); + BAILOUT; + break; + + case 5: /* Moving inversions, 8 bit walking ones and zeros (test #5) */ + p0 = 0x80; + for (i=0; i<8; i++, p0=p0>>1) { + p1 = p0 | (p0<<8) | (p0<<16) | (p0<<24); + p2 = ~p1; + s_barrier(); + movinv1(c_iter,p1,p2, my_ord); + BAILOUT; - /* Switch patterns */ - s_barrier(); - movinv1(c_iter,p2,p1, my_ord); - BAILOUT - } - break; + /* Switch patterns */ + s_barrier(); + movinv1(c_iter,p2,p1, my_ord); + BAILOUT; + } + break; - case 6: /* Random Data (test #6) */ - /* Seed the random number generator */ - if (my_ord == mstr_cpu) { - if (cpu_id.fid.bits.rdtsc) { - asm __volatile__ ("rdtsc":"=a" (sp1),"=d" (sp2)); - } else { - sp1 = 521288629 + v->pass; - sp2 = 362436069 - v->pass; - } - rand_seed(sp1, sp2, 0); - } - - s_barrier(); - for (i=0; i < c_iter; i++) { - if (my_ord == mstr_cpu) { - sp1 = rand(0); - sp2 = ~p1; - } - s_barrier(); - movinv1(2,sp1,sp2, my_ord); - BAILOUT; - } - break; - - - case 7: /* Block move (test #7) */ - block_move(c_iter, my_ord); - BAILOUT; - break; - - case 8: /* Moving inversions, 32 bit shifting pattern (test #8) */ - for (i=0, p1=1; p1; p1=p1<<1, i++) { - s_barrier(); - movinv32(c_iter,p1, 1, 0x80000000, 0, i, my_ord); - BAILOUT - s_barrier(); - movinv32(c_iter,~p1, 0xfffffffe, - 0x7fffffff, 1, i, my_ord); - BAILOUT - } - break; - - case 9: /* Random Data Sequence (test #9) */ - for (i=0; i < c_iter; i++) { - s_barrier(); - movinvr(my_ord); - BAILOUT; - } - break; - - case 10: /* Modulo 20 check, Random pattern (test #10) */ - for (j=0; j<c_iter; j++) { - p1 = rand(0); - for (i=0; i<MOD_SZ; i++) { - p2 = ~p1; - s_barrier(); - modtst(i, 2, p1, p2, my_ord); - BAILOUT - - /* Switch patterns */ - s_barrier(); - modtst(i, 2, p2, p1, my_ord); - BAILOUT - } - } - break; - - case 11: /* Bit fade test, fill (test #11) */ - /* Use a sequence to process all windows for each stage */ - switch(bitf_seq) { - case 0: /* Fill all of memory 0's */ - bit_fade_fill(0, my_ord); - bitf_sleep = 1; - break; - case 1: /* Sleep for the specified time */ - /* Only sleep once */ - if (bitf_sleep) { - sleep(c_iter, 1, my_ord, 0); - bitf_sleep = 0; - } - break; - case 2: /* Now check all of memory for changes */ - bit_fade_chk(0, my_ord); - break; - case 3: /* Fill all of memory 1's */ - bit_fade_fill(-1, my_ord); - bitf_sleep = 1; - break; - case 4: /* Sleep for the specified time */ - /* Only sleep once */ - if (bitf_sleep) { - sleep(c_iter, 1, my_ord, 0); - bitf_sleep = 0; - } - break; - case 5: /* Now check all of memory for changes */ - bit_fade_chk(-1, my_ord); - break; - } - BAILOUT; - break; - - case 90: /* 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, my_ord); - BAILOUT - - /* Switch patterns */ - p2 = p1; - p1 = ~p2; - modtst(i, c_iter, p1,p2, my_ord); - BAILOUT - } - break; - - case 91: /* 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, c_iter, p1, p2, my_ord); - BAILOUT - - /* Switch patterns */ - p2 = p1; - p1 = ~p2; - modtst(i, c_iter, p1, p2, my_ord); - BAILOUT - } - } - break; - } - return(0); + case 6: /* Random Data (test #6) */ + /* Seed the random number generator */ + if (my_ord == mstr_cpu) { + if (cpu_id.fid.bits.rdtsc) { + asm __volatile__ ("rdtsc":"=a" (sp1),"=d" (sp2)); + } else { + sp1 = 521288629 + vv->pass; + sp2 = 362436069 - vv->pass; + } + rand_seed(sp1, sp2, 0); + } + + s_barrier(); + for (i=0; i < c_iter; i++) { + if (my_ord == mstr_cpu) { + sp1 = rand(0); + sp2 = ~p1; + } + s_barrier(); + movinv1(2,sp1,sp2, my_ord); + BAILOUT; + } + break; + + + case 7: /* Block move (test #7) */ + block_move(c_iter, my_ord); + BAILOUT; + break; + + case 8: /* Moving inversions, 32 bit shifting pattern (test #8) */ + for (i=0, p1=1; p1; p1=p1<<1, i++) { + s_barrier(); + movinv32(c_iter,p1, 1, 0x80000000, 0, i, my_ord); + { BAILOUT } + s_barrier(); + movinv32(c_iter,~p1, 0xfffffffe, + 0x7fffffff, 1, i, my_ord); + { BAILOUT } + } + break; + + case 9: /* Random Data Sequence (test #9) */ + for (i=0; i < c_iter; i++) { + s_barrier(); + movinvr(my_ord); + BAILOUT; + } + break; + + case 10: /* Modulo 20 check, Random pattern (test #10) */ + for (j=0; j<c_iter; j++) { + p1 = rand(0); + for (i=0; i<MOD_SZ; i++) { + p2 = ~p1; + s_barrier(); + modtst(i, 2, p1, p2, my_ord); + BAILOUT; + + /* Switch patterns */ + s_barrier(); + modtst(i, 2, p2, p1, my_ord); + BAILOUT; + } + } + break; + + case 11: /* Bit fade test, fill (test #11) */ + /* Use a sequence to process all windows for each stage */ + switch(bitf_seq) { + case 0: /* Fill all of memory 0's */ + bit_fade_fill(0, my_ord); + bitf_sleep = 1; + break; + case 1: /* Sleep for the specified time */ + /* Only sleep once */ + if (bitf_sleep) { + sleep(c_iter, 1, my_ord, 0); + bitf_sleep = 0; + } + break; + case 2: /* Now check all of memory for changes */ + bit_fade_chk(0, my_ord); + break; + case 3: /* Fill all of memory 1's */ + bit_fade_fill(-1, my_ord); + bitf_sleep = 1; + break; + case 4: /* Sleep for the specified time */ + /* Only sleep once */ + if (bitf_sleep) { + sleep(c_iter, 1, my_ord, 0); + bitf_sleep = 0; + } + break; + case 5: /* Now check all of memory for changes */ + bit_fade_chk(-1, my_ord); + break; + } + BAILOUT; + break; + + case 90: /* 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, my_ord); + BAILOUT; + + /* Switch patterns */ + p2 = p1; + p1 = ~p2; + modtst(i, c_iter, p1,p2, my_ord); + BAILOUT; + } + break; + + case 91: /* 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, c_iter, p1, p2, my_ord); + BAILOUT; + + /* Switch patterns */ + p2 = p1; + p1 = ~p2; + modtst(i, c_iter, p1, p2, my_ord); + BAILOUT; + } + } + break; + } + return(0); } -/* Compute number of SPINSZ chunks being tested */ +/* Compute number of SPINSZ_DWORDS chunks being tested */ int find_chunks(int tst) { - int i, j, sg, wmax, ch; - struct pmap twin={0,0}; - unsigned long wnxt = WIN_SZ; - unsigned long len; - - wmax = MAX_MEM/WIN_SZ+2; /* The number of 2 GB segments +2 */ - /* Compute the number of SPINSZ memory segments */ - ch = 0; - for(j = 0; j < wmax; j++) { - /* special case for relocation */ - if (j == 0) { - twin.start = 0; - twin.end = win1_end; - } - - /* special case for first 2 GB */ - if (j == 1) { - twin.start = win0_start; - twin.end = WIN_SZ; - } - - /* For all other windows */ - if (j > 1) { - twin.start = wnxt; - wnxt += WIN_SZ; - twin.end = wnxt; - } - - /* Find the memory areas I am going to test */ - sg = compute_segments(twin, -1); - for(i = 0; i < sg; i++) { - len = v->map[i].end - v->map[i].start; - - if (cpu_mode == CPM_ALL && num_cpus > 1) { - switch(tseq[tst].pat) { - case 2: - case 4: - case 5: - case 6: - case 9: - case 10: - len /= act_cpus; - break; - case 7: - case 8: - len /= act_cpus; - break; - } - } - ch += (len + SPINSZ -1)/SPINSZ; - } - } - return(ch); + int i, j, sg, wmax, ch; + struct pmap twin={0,0}; + unsigned long wnxt = WIN_SZ_PAGES; + unsigned long len; + + wmax = MAX_MEM_PAGES/WIN_SZ_PAGES+2; /* The number of 2 GB segments +2 */ + /* Compute the number of SPINSZ_DWORDS memory segments */ + ch = 0; + for(j = 0; j < wmax; j++) { + /* special case for relocation */ + if (j == 0) { + twin.start = 0; + twin.end = win1_end; + } + + /* special case for first 2 GB */ + if (j == 1) { + twin.start = win0_start; + twin.end = WIN_SZ_PAGES; + } + + /* For all other windows */ + if (j > 1) { + twin.start = wnxt; + wnxt += WIN_SZ_PAGES; + twin.end = wnxt; + } + + /* Find the memory areas I am going to test */ + sg = compute_segments(twin, -1); + for(i = 0; i < sg; i++) { + len = vv->map[i].end - vv->map[i].start; + + if (cpu_mode == CPM_ALL && num_cpus > 1) { + switch(tseq[tst].pat) { + case 2: + case 4: + case 5: + case 6: + case 9: + case 10: + len /= act_cpus; + break; + case 7: + case 8: + len /= act_cpus; + break; + } + } + ch += (len + SPINSZ_DWORDS -1)/SPINSZ_DWORDS; + } + } + return(ch); } /* Compute the total number of ticks per pass */ void find_ticks_for_pass(void) { - int i; - - v->pptr = 0; - v->pass_ticks = 0; - v->total_ticks = 0; - cprint(1, COL_MID+8, " "); - i = 0; - while (tseq[i].cpu_sel != 0) { - /* Skip tests 2 and 4 if we are using 1 cpu */ - if (act_cpus == 1 && (i == 2 || i == 4)) { - i++; - continue; - } - v->pass_ticks += find_ticks_for_test(i); - i++; - } + int i; + + vv->pptr = 0; + vv->pass_ticks = 0; + vv->total_ticks = 0; + cprint(1, COL_MID+8, " "); + i = 0; + while (tseq[i].cpu_sel != 0) { + /* Skip tests 2 and 4 if we are using 1 cpu */ + if (act_cpus == 1 && (i == 2 || i == 4)) { + i++; + continue; + } + vv->pass_ticks += find_ticks_for_test(i); + i++; + } } static int find_ticks_for_test(int tst) { - int ticks=0, c, ch; - - if (tseq[tst].sel == 0) { - return(0); - } - - /* Determine the number of chunks for this test */ - ch = find_chunks(tst); - - /* Set the number of iterations. We only do 1/2 of the iterations */ - /* on the first pass */ - if (v->pass == 0) { - c = tseq[tst].iter/FIRST_DIVISER; - } else { - c = tseq[tst].iter; - } - - switch(tseq[tst].pat) { - case 0: /* Address test, walking ones */ - ticks = 2; - break; - case 1: /* Address test, own address */ - case 2: - ticks = 2; - break; - case 3: /* Moving inversions, all ones and zeros */ - case 4: - ticks = 2 + 4 * c; - break; - case 5: /* Moving inversions, 8 bit walking ones and zeros */ - ticks = 24 + 24 * c; - break; - case 6: /* Random Data */ - ticks = c + 4 * c; - break; - case 7: /* Block move */ - ticks = (ch + ch/act_cpus + c*ch); - break; - case 8: /* Moving inversions, 32 bit shifting pattern */ - ticks = (1 + c * 2) * 64; - break; - case 9: /* Random Data Sequence */ - ticks = 3 * c; - break; - case 10: /* Modulo 20 check, Random pattern */ - ticks = 4 * 40 * c; - break; - case 11: /* Bit fade test */ - ticks = c * 2 + 4 * ch; - break; - case 90: /* Modulo 20 check, all ones and zeros (unused) */ - ticks = (2 + c) * 40; - break; - case 91: /* Modulo 20 check, 8 bit pattern (unused) */ - ticks = (2 + c) * 40 * 8; - break; - } - if (cpu_mode == CPM_SEQ || tseq[tst].cpu_sel == -1) { - ticks *= act_cpus; - } - if (tseq[tst].pat == 7 || tseq[tst].pat == 11) { - return ticks; - } - return ticks*ch; + int ticks=0, iter, ch; + + if (tseq[tst].sel == 0) { + return(0); + } + + /* Determine the number of SPINSZ chunks for this test */ + ch = find_chunks(tst); + + /* Set the number of iterations. We only do 1/2 of the iterations */ + /* on the first pass */ + if (vv->pass == 0) { + iter = tseq[tst].iter/FIRST_DIVISER; + } else { + iter = tseq[tst].iter; + } + + switch(tseq[tst].pat) { + case 0: /* Address test, walking ones */ + ticks = ch; + break; + case 1: /* Address test, own address */ + case 2: + ticks = ch * 2; + break; + case 3: /* Moving inversions, all ones and zeros */ + case 4: { + const int each_movinv1 = ch * (1 + 2 * iter); // each movinv1() + ticks = 2 * each_movinv1; // which we call twice + break; + } + case 5: { /* Moving inversions, 8 bit walking ones and zeros */ + const int each_movinv1 = ch * (1 + 2 * iter); // same as above + ticks = 16 * each_movinv1; // but here we call it 16x + break; + } + case 6: { /* Random Data */ + const int each_movinv1 = ch * 5; // movinv1() does only 5 ticks here + ticks = iter * each_movinv1; // and we call it 'iter' times. + break; + } + case 7: /* Block move */ + ticks = ch * (2 + iter); + break; + case 8: { /* Moving inversions, 32 bit shifting pattern */ + const int each_movinv32 = ch * (1 + 2 * iter); // Each movinv32() + ticks = each_movinv32 * 64; // We call it 64x + break; + } + case 9: { /* Random Data Sequence */ + const int each_movinvr = 3 * ch; // Each movinvr() ticks 3*ch times + ticks = each_movinvr * iter; // We call it iter times + break; + } + case 10: { /* Modulo 20 check, Random pattern */ + const int each_modtst = ch * 4; + ticks = iter * MOD_SZ * each_modtst; + break; + } + case 11: { /* Bit fade test */ + // Each call to bit_fade_fill() and bit_fade_chk() ticks ch times. + const int each_bit_fade_fill = ch; + const int each_bit_fade_chk = ch; + // We call each twice: fill 0s, check, fill 1s, check. + const int loop_ticks = 2 * each_bit_fade_chk + 2 * each_bit_fade_fill; + // We also sleep for '2*iter' seconds and tick once per second + const int sleep_ticks = iter * 2; + ticks = loop_ticks + sleep_ticks; + break; + } + case 90: { /* Modulo 20 check, all ones and zeros (unused) */ + const int each_modtst = ch * (2 + iter); + ticks = each_modtst * 2 * MOD_SZ; + break; + } + case 91: { /* Modulo 20 check, 8 bit pattern (unused) */ + const int each_modtst = ch * (2 + iter); + ticks = each_modtst * 2 * MOD_SZ * 8; + break; + } + default: + ASSERT(0); + break; + } + if (cpu_mode == CPM_SEQ || tseq[tst].cpu_sel == -1) { + ticks *= act_cpus; + } + return ticks; } static int compute_segments(struct pmap win, int me) { - unsigned long wstart, wend; - int i, sg; - - /* Compute the window I am testing memory in */ - wstart = win.start; - wend = win.end; - sg = 0; - - /* Now reduce my window to the area of memory I want to test */ - if (wstart < v->plim_lower) { - wstart = v->plim_lower; - } - if (wend > v->plim_upper) { - wend = v->plim_upper; - } - if (wstart >= wend) { - return(0); - } - /* List the segments being tested */ - for (i=0; i< v->msegs; i++) { - unsigned long start, end; - start = v->pmap[i].start; - end = v->pmap[i].end; - if (start <= wstart) { - start = wstart; - } - if (end >= wend) { - end = wend; - } + unsigned long wstart, wend; + int i, sg; + + /* Compute the window I am testing memory in */ + wstart = win.start; + wend = win.end; + sg = 0; + + /* Now reduce my window to the area of memory I want to test */ + if (wstart < vv->plim_lower) { + wstart = vv->plim_lower; + } + if (wend > vv->plim_upper) { + wend = vv->plim_upper; + } + if (wstart >= wend) { + return(0); + } + /* List the segments being tested */ + for (i=0; i< vv->msegs; i++) { + unsigned long start, end; + start = vv->pmap[i].start; + end = vv->pmap[i].end; + if (start <= wstart) { + start = wstart; + } + if (end >= wend) { + end = wend; + } #if 0 - cprint(LINE_SCROLL+(2*i), 0, " ("); - hprint(LINE_SCROLL+(2*i), 2, start); - cprint(LINE_SCROLL+(2*i), 10, ", "); - hprint(LINE_SCROLL+(2*i), 12, end); - cprint(LINE_SCROLL+(2*i), 20, ") "); - - cprint(LINE_SCROLL+(2*i), 22, "r("); - hprint(LINE_SCROLL+(2*i), 24, wstart); - cprint(LINE_SCROLL+(2*i), 32, ", "); - hprint(LINE_SCROLL+(2*i), 34, wend); - cprint(LINE_SCROLL+(2*i), 42, ") "); - - cprint(LINE_SCROLL+(2*i), 44, "p("); - hprint(LINE_SCROLL+(2*i), 46, v->plim_lower); - cprint(LINE_SCROLL+(2*i), 54, ", "); - hprint(LINE_SCROLL+(2*i), 56, v->plim_upper); - cprint(LINE_SCROLL+(2*i), 64, ") "); - - cprint(LINE_SCROLL+(2*i+1), 0, "w("); - hprint(LINE_SCROLL+(2*i+1), 2, win.start); - cprint(LINE_SCROLL+(2*i+1), 10, ", "); - hprint(LINE_SCROLL+(2*i+1), 12, win.end); - cprint(LINE_SCROLL+(2*i+1), 20, ") "); - - cprint(LINE_SCROLL+(2*i+1), 22, "m("); - hprint(LINE_SCROLL+(2*i+1), 24, v->pmap[i].start); - cprint(LINE_SCROLL+(2*i+1), 32, ", "); - hprint(LINE_SCROLL+(2*i+1), 34, v->pmap[i].end); - cprint(LINE_SCROLL+(2*i+1), 42, ") "); - - cprint(LINE_SCROLL+(2*i+1), 44, "i="); - hprint(LINE_SCROLL+(2*i+1), 46, i); + cprint(LINE_SCROLL+(2*i), 0, " ("); + hprint(LINE_SCROLL+(2*i), 2, start); + cprint(LINE_SCROLL+(2*i), 10, ", "); + hprint(LINE_SCROLL+(2*i), 12, end); + cprint(LINE_SCROLL+(2*i), 20, ") "); + + cprint(LINE_SCROLL+(2*i), 22, "r("); + hprint(LINE_SCROLL+(2*i), 24, wstart); + cprint(LINE_SCROLL+(2*i), 32, ", "); + hprint(LINE_SCROLL+(2*i), 34, wend); + cprint(LINE_SCROLL+(2*i), 42, ") "); + + cprint(LINE_SCROLL+(2*i), 44, "p("); + hprint(LINE_SCROLL+(2*i), 46, vv->plim_lower); + cprint(LINE_SCROLL+(2*i), 54, ", "); + hprint(LINE_SCROLL+(2*i), 56, vv->plim_upper); + cprint(LINE_SCROLL+(2*i), 64, ") "); + + cprint(LINE_SCROLL+(2*i+1), 0, "w("); + hprint(LINE_SCROLL+(2*i+1), 2, win.start); + cprint(LINE_SCROLL+(2*i+1), 10, ", "); + hprint(LINE_SCROLL+(2*i+1), 12, win.end); + cprint(LINE_SCROLL+(2*i+1), 20, ") "); + + cprint(LINE_SCROLL+(2*i+1), 22, "m("); + hprint(LINE_SCROLL+(2*i+1), 24, vv->pmap[i].start); + cprint(LINE_SCROLL+(2*i+1), 32, ", "); + hprint(LINE_SCROLL+(2*i+1), 34, vv->pmap[i].end); + cprint(LINE_SCROLL+(2*i+1), 42, ") "); + + 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+3), 0, - " " - " "); + cprint(LINE_SCROLL+(2*i+2), 0, + " " + " "); + cprint(LINE_SCROLL+(2*i+3), 0, + " " + " "); #endif - if ((start < end) && (start < wend) && (end > wstart)) { - v->map[sg].pbase_addr = start; - v->map[sg].start = mapping(start); - v->map[sg].end = emapping(end); + if ((start < end) && (start < wend) && (end > wstart)) { + vv->map[sg].pbase_addr = start; + vv->map[sg].start = mapping(start); + vv->map[sg].end = emapping(end); #if 0 - hprint(LINE_SCROLL+(sg+1), 0, sg); - hprint(LINE_SCROLL+(sg+1), 12, v->map[sg].pbase_addr); - hprint(LINE_SCROLL+(sg+1), 22, start); - hprint(LINE_SCROLL+(sg+1), 32, end); - hprint(LINE_SCROLL+(sg+1), 42, mapping(start)); - hprint(LINE_SCROLL+(sg+1), 52, emapping(end)); - cprint(LINE_SCROLL+(sg+2), 0, - " " - " "); + hprint(LINE_SCROLL+(sg+1), 0, sg); + hprint(LINE_SCROLL+(sg+1), 12, vv->map[sg].pbase_addr); + hprint(LINE_SCROLL+(sg+1), 22, start); + hprint(LINE_SCROLL+(sg+1), 32, end); + hprint(LINE_SCROLL+(sg+1), 42, mapping(start)); + hprint(LINE_SCROLL+(sg+1), 52, emapping(end)); + cprint(LINE_SCROLL+(sg+2), 0, + " " + " "); #endif #if 0 - cprint(LINE_SCROLL+(2*i+1), 54, ", sg="); - hprint(LINE_SCROLL+(2*i+1), 59, sg); + cprint(LINE_SCROLL+(2*i+1), 54, ", sg="); + hprint(LINE_SCROLL+(2*i+1), 59, sg); #endif - sg++; - } - } - return (sg); + sg++; + } + } + return (sg); } @@ -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 -genisoimage -A "MKISOFS 1.1.2" -p "Memtest86+ 5.01" -publisher "Samuel D. <sdemeule@memtest.org>" -b boot/memtest.img -c boot/boot.catalog -V "MT501" -o memtest.iso . -mv memtest.iso ../mt501.iso +genisoimage -A "MKISOFS 1.1.2" -p "Memtest86+ 5.31b" -publisher "Samuel D. <memtest@memtest.org>" -b boot/memtest.img -c boot/boot.catalog -V "MT531" -o memtest.iso . +mv memtest.iso ../mt531b.iso cd .. rm -rf cd -echo "Done! Memtest86+ 5.01 ISO is mt501.iso" +echo "Done! Memtest86+ 5.31b ISO is mt501.iso" @@ -8,40 +8,38 @@ #include "defs.h" #include "config.h" -short e820_nr; +short e820_nr = 0; short memsz_mode = SZ_MODE_BIOS; -static ulong alt_mem_k; -static ulong ext_mem_k; +static ulong alt_mem_k = 0; +static ulong ext_mem_k = 0; static struct e820entry e820[E820MAX]; -ulong p1, p2; -ulong *p; - static void sort_pmap(void); -//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); +static int sanitize_e820_map(struct e820entry *orig_map, struct e820entry *new_bios, short old_nr); static void memsize_linuxbios(); /* * Find out how much memory there is. */ +#pragma GCC push_options +#pragma GCC optimize ("O0") void mem_size(void) { - int i, flag=0; - v->test_pages = 0; + int i = 0, flag = 0; + vv->test_pages = 0; /* Get the memory size from the BIOS */ /* Determine the memory map */ + if (query_linuxbios()) { flag = 1; } else if (query_pcbios()) { flag = 2; } - + /* On the first time thru only */ /* Make a copy of the memory info table so that we can re-evaluate */ /* The memory map later */ @@ -63,11 +61,12 @@ void mem_size(void) /* Guarantee that pmap entries are in ascending order */ sort_pmap(); - v->plim_lower = 0; - v->plim_upper = v->pmap[v->msegs-1].end; + vv->plim_lower = 0; + vv->plim_upper = vv->pmap[vv->msegs-1].end; adj_mem(); } +#pragma GCC pop_options static void sort_pmap(void) { @@ -75,10 +74,10 @@ static void sort_pmap(void) /* Do an insertion sort on the pmap, on an already sorted * list this should be a O(1) algorithm. */ - for(i = 0; i < v->msegs; i++) { + for(i = 0; i < vv->msegs; i++) { /* Find where to insert the current element */ for(j = i -1; j >= 0; j--) { - if (v->pmap[i].start > v->pmap[j].start) { + if (vv->pmap[i].start > vv->pmap[j].start) { j++; break; } @@ -86,10 +85,10 @@ static void sort_pmap(void) /* Insert the current element */ if (i != j) { struct pmap temp; - temp = v->pmap[i]; - memmove(&v->pmap[j], &v->pmap[j+1], - (i -j)* sizeof(temp)); - v->pmap[j] = temp; + temp = vv->pmap[i]; + mt86_memmove(&vv->pmap[j], &vv->pmap[j+1], + (i -j)* sizeof(temp)); + vv->pmap[j] = temp; } } } @@ -106,12 +105,12 @@ static void memsize_linuxbios(void) } end = e820[i].addr; end += e820[i].size; - v->pmap[n].start = (e820[i].addr + 4095) >> 12; - v->pmap[n].end = end >> 12; - v->test_pages += v->pmap[n].end - v->pmap[n].start; + vv->pmap[n].start = (e820[i].addr + 4095) >> 12; + vv->pmap[n].end = end >> 12; + vv->test_pages += vv->pmap[n].end - vv->pmap[n].start; n++; } - v->msegs = n; + vv->msegs = n; } static void memsize_820() { @@ -146,22 +145,22 @@ static void memsize_820() if (end > RES_START && end < RES_END) { end = RES_START; } - v->pmap[n].start = (start + 4095) >> 12; - v->pmap[n].end = end >> 12; - v->test_pages += v->pmap[n].end - v->pmap[n].start; + vv->pmap[n].start = (start + 4095) >> 12; + vv->pmap[n].end = end >> 12; + vv->test_pages += vv->pmap[n].end - vv->pmap[n].start; n++; #if 0 int epmap = 0; int lpmap = 0; if(n > 12) { epmap = 34; lpmap = -12; } - hprint (11+n+lpmap,0+epmap,v->pmap[n-1].start); - hprint (11+n+lpmap,10+epmap,v->pmap[n-1].end); - hprint (11+n+lpmap,20+epmap,v->pmap[n-1].end - v->pmap[n-1].start); + hprint (11+n+lpmap,0+epmap,vv->pmap[n-1].start); + hprint (11+n+lpmap,10+epmap,vv->pmap[n-1].end); + hprint (11+n+lpmap,20+epmap,vv->pmap[n-1].end - vv->pmap[n-1].start); dprint (11+n+lpmap,30+epmap,nm[i].type,0,0); #endif } } - v->msegs = n; + vv->msegs = n; } static void memsize_801(void) @@ -177,15 +176,15 @@ static void memsize_801(void) mem_size = alt_mem_k; } /* First we map in the first 640k */ - v->pmap[0].start = 0; - v->pmap[0].end = RES_START >> 12; - v->test_pages = RES_START >> 12; + vv->pmap[0].start = 0; + vv->pmap[0].end = RES_START >> 12; + vv->test_pages = RES_START >> 12; /* Now the extended memory */ - v->pmap[1].start = (RES_END + 4095) >> 12; - v->pmap[1].end = (mem_size + 1024) >> 2; - v->test_pages += mem_size >> 2; - v->msegs = 2; + vv->pmap[1].start = (RES_END + 4095) >> 12; + vv->pmap[1].end = (mem_size + 1024) >> 2; + vv->test_pages += mem_size >> 2; + vv->msegs = 2; } /* @@ -37,65 +37,65 @@ /* Combine two adr/mask pairs to one adr/mask pair. */ void combine (ulong adr1, ulong mask1, ulong adr2, ulong mask2, - ulong *adr, ulong *mask) { + ulong *adr, ulong *mask) { - *mask = COMBINE_MASK (adr1, mask1, adr2, mask2); + *mask = COMBINE_MASK (adr1, mask1, adr2, mask2); - *adr = adr1 | adr2; - *adr &= *mask; // Normalise, no fundamental need for this + *adr = adr1 | adr2; + *adr &= *mask; // Normalise, no fundamental need for this } /* Count the number of addresses covered with a mask. */ ulong addresses (ulong mask) { - ulong ctr=1; - int i=32; - while (i-- > 0) { - if (! (mask & 1)) { - ctr += ctr; - } - mask >>= 1; - } - return ctr; + ulong ctr=1; + int i=32; + while (i-- > 0) { + if (! (mask & 1)) { + ctr += ctr; + } + mask >>= 1; + } + return ctr; } /* Count how much more addresses would be covered by adr1/mask1 when combined * with adr2/mask2. */ ulong combicost (ulong adr1, ulong mask1, ulong adr2, ulong mask2) { - ulong cost1=addresses (mask1); - ulong tmp, mask; - combine (adr1, mask1, adr2, mask2, &tmp, &mask); - return addresses (mask) - cost1; + ulong cost1=addresses (mask1); + ulong tmp, mask; + combine (adr1, mask1, adr2, mask2, &tmp, &mask); + return addresses (mask) - cost1; } /* Find the cheapest array index to extend with the given adr/mask pair. * Return -1 if nothing below the given minimum cost can be found. */ int cheapindex (ulong adr1, ulong mask1, ulong mincost) { - int i=v->numpatn; - int idx=-1; - while (i-- > 0) { - ulong tmpcost=combicost(v->patn[i].adr, v->patn[i].mask, adr1, mask1); - if (tmpcost < mincost) { - mincost=tmpcost; - idx=i; - } - } - return idx; + int i=vv->numpatn; + int idx=-1; + while (i-- > 0) { + ulong tmpcost=combicost(vv->patn[i].adr, vv->patn[i].mask, adr1, mask1); + if (tmpcost < mincost) { + mincost=tmpcost; + idx=i; + } + } + return idx; } /* Try to find a relocation index for idx if it costs nothing. * Return -1 if no such index exists. */ int relocateidx (int idx) { - ulong adr =v->patn[idx].adr; - ulong mask=v->patn[idx].mask; - int new; - v->patn[idx].adr ^= ~0L; // Never select idx - new=cheapindex (adr, mask, 1+addresses (mask)); - v->patn[idx].adr = adr; - return new; + ulong adr =vv->patn[idx].adr; + ulong mask=vv->patn[idx].mask; + int new; + vv->patn[idx].adr ^= ~0L; // Never select idx + new=cheapindex (adr, mask, 1+addresses (mask)); + vv->patn[idx].adr = adr; + return new; } /* Relocate the given index idx only if free of charge. @@ -103,42 +103,42 @@ int relocateidx (int idx) { * Inspired on the Buddy memalloc principle in the Linux kernel. */ void relocateiffree (int idx) { - int newidx=relocateidx (idx); - if (newidx>=0) { - ulong cadr, cmask; - combine (v->patn [newidx].adr, v->patn[newidx].mask, - v->patn [ idx].adr, v->patn[ idx].mask, - &cadr, &cmask); - v->patn[newidx].adr =cadr; - v->patn[newidx].mask=cmask; - if (idx < --v->numpatn) { - v->patn[idx].adr =v->patn[v->numpatn].adr; - v->patn[idx].mask=v->patn[v->numpatn].mask; - } - relocateiffree (newidx); - } + int newidx=relocateidx (idx); + if (newidx>=0) { + ulong cadr, cmask; + combine (vv->patn [newidx].adr, vv->patn[newidx].mask, + vv->patn [ idx].adr, vv->patn[ idx].mask, + &cadr, &cmask); + vv->patn[newidx].adr =cadr; + vv->patn[newidx].mask=cmask; + if (idx < --vv->numpatn) { + vv->patn[idx].adr =vv->patn[vv->numpatn].adr; + vv->patn[idx].mask=vv->patn[vv->numpatn].mask; + } + relocateiffree (newidx); + } } /* Insert a single faulty address in the pattern array. * Return 1 only if the array was changed. */ int insertaddress (ulong adr) { - if (cheapindex (adr, DEFAULT_MASK, 1L) != -1) - return 0; - - if (v->numpatn < BADRAM_MAXPATNS) { - v->patn[v->numpatn].adr =adr; - v->patn[v->numpatn].mask=DEFAULT_MASK; - v->numpatn++; - relocateiffree (v->numpatn-1); - } else { - int idx=cheapindex (adr, DEFAULT_MASK, ~0L); - ulong cadr, cmask; - combine (v->patn [idx].adr, v->patn[idx].mask, - adr, DEFAULT_MASK, &cadr, &cmask); - v->patn[idx].adr =cadr; - v->patn[idx].mask=cmask; - relocateiffree (idx); - } - return 1; + if (cheapindex (adr, DEFAULT_MASK, 1L) != -1) + return 0; + + if (vv->numpatn < BADRAM_MAXPATNS) { + vv->patn[vv->numpatn].adr =adr; + vv->patn[vv->numpatn].mask=DEFAULT_MASK; + vv->numpatn++; + relocateiffree (vv->numpatn-1); + } else { + int idx=cheapindex (adr, DEFAULT_MASK, ~0L); + ulong cadr, cmask; + combine (vv->patn [idx].adr, vv->patn[idx].mask, + adr, DEFAULT_MASK, &cadr, &cmask); + vv->patn[idx].adr =cadr; + vv->patn[idx].mask=cmask; + relocateiffree (idx); + } + return 1; } diff --git a/precomp.bin b/precomp.bin Binary files differindex affaaab..5738e08 100755 --- a/precomp.bin +++ b/precomp.bin @@ -13,255 +13,256 @@ /* We use this macro to refer to ELF types independent of the native wordsize. `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */ - #define ElfW(type) _ElfW (Elf, __ELF_NATIVE_CLASS, type) #define _ElfW(e,w,t) _ElfW_1 (e, w, _##t) #define _ElfW_1(e,w,t) e##w##t -/* We use this macro to refer to ELF types independent of the native wordsize. - `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */ #define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type) -#define assert(expr) ((void) 0) +static inline void __attribute__ ((unused)) +fail_assert(unsigned line_num, unsigned code) { + // Put line num in low bits of %edx and a sentinel in the high bits. + line_num |= 0xEEEC0000; // eek! + asm __volatile__ ("movl %%edx, %%edx" + : "=d"(line_num), "=c" (code) + : "d" (line_num), "c" (code)); + + // Now observe %edx in a virtual machine's debugger. + // Have a nice day. + while(1) {} +} + +// TODO(jcoiner): It would be nice to try to print a message here, +// even though we don't have function calls yet, maybe we can write +// to the screen before going into our infinite loop. +#define assert(expr, code) do { \ + if (!(expr)) { fail_assert(__LINE__, code); } \ + } while(0) - /* This #define produces dynamic linking inline functions for - bootstrap relocation instead of general-purpose relocation. */ +/* This #define produces dynamic linking inline functions for + bootstrap relocation instead of general-purpose relocation. */ #define RTLD_BOOTSTRAP -struct link_map -{ - ElfW(Addr) l_addr; /* Current load address */ - ElfW(Addr) ll_addr; /* Last load address */ - ElfW(Dyn) *l_ld; +struct link_map { + ElfW(Addr) l_addr; /* Current load address */ + ElfW(Addr) ll_addr; /* Last load address */ + ElfW(Dyn) *l_ld; /* Indexed pointers to dynamic section. [0,DT_NUM) are indexed by the processor-independent tags. [DT_NUM,DT_NUM+DT_PROCNUM) are indexed by the tag minus DT_LOPROC. - [DT_NUM+DT_PROCNUM,DT_NUM+DT_PROCNUM+DT_EXTRANUM) are indexed - by DT_EXTRATAGIDX(tagvalue) and [DT_NUM+DT_PROCNUM, DT_NUM+DT_PROCNUM+DT_EXTRANUM) are indexed by DT_EXTRATAGIDX(tagvalue) (see <elf.h>). */ - - ElfW(Dyn) *l_info[DT_NUM + DT_PROCNUM + DT_EXTRANUM]; + ElfW(Dyn) *l_info[DT_NUM + DT_PROCNUM + DT_EXTRANUM]; }; - /* Return the link-time address of _DYNAMIC. Conveniently, this is the first element of the GOT. This must be inlined in a function which uses global data. */ static inline Elf32_Addr __attribute__ ((unused)) -elf_machine_dynamic (void) -{ - register Elf32_Addr *got asm ("%ebx"); - return *got; +elf_machine_dynamic(void) { + register Elf32_Addr *got asm ("%ebx"); + return *got; } /* Return the run-time load address of the shared object. */ static inline Elf32_Addr __attribute__ ((unused)) -elf_machine_load_address (void) -{ - Elf32_Addr addr; - asm volatile ("leal _start@GOTOFF(%%ebx), %0\n" - : "=r" (addr) : : "cc"); - return addr; +elf_machine_load_address(void) { + Elf32_Addr addr; + asm volatile ("leal _start@GOTOFF(%%ebx), %0\n" + : "=r" (addr) : : "cc"); + return addr; } /* Perform the relocation specified by RELOC and SYM (which is fully resolved). MAP is the object containing the reloc. */ static inline void -elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, - const Elf32_Sym *sym, Elf32_Addr *const reloc_addr) -{ - Elf32_Addr ls_addr, s_addr; - Elf32_Addr value; - if (ELF32_R_TYPE (reloc->r_info) == R_386_RELATIVE) - { - *reloc_addr += map->l_addr - map->ll_addr; - return; - } - if (ELF32_R_TYPE(reloc->r_info) == R_386_NONE) { - return; - } - value = sym->st_value; - /* Every section except the undefined section has a base of map->l_addr */ - ls_addr = sym->st_shndx == SHN_UNDEF ? 0 : map->ll_addr; - s_addr = sym->st_shndx == SHN_UNDEF ? 0 : map->l_addr; +elf_machine_rel(struct link_map *map, const Elf32_Rel *reloc, + const Elf32_Sym *sym, Elf32_Addr *const reloc_addr) { + Elf32_Addr ls_addr, s_addr; + Elf32_Addr value; + if (ELF32_R_TYPE (reloc->r_info) == R_386_RELATIVE) + { + *reloc_addr += map->l_addr - map->ll_addr; + return; + } + if (ELF32_R_TYPE(reloc->r_info) == R_386_NONE) { + return; + } + value = sym->st_value; + /* Every section except the undefined section has a base of map->l_addr */ + ls_addr = sym->st_shndx == SHN_UNDEF ? 0 : map->ll_addr; + s_addr = sym->st_shndx == SHN_UNDEF ? 0 : map->l_addr; - switch (ELF32_R_TYPE (reloc->r_info)) - { - case R_386_COPY: - { - /* Roll memcpy by hand as we don't have function calls yet. */ - unsigned char *dest, *src; - long i; - dest = (unsigned char *)reloc_addr; - src = (unsigned char *)(value + s_addr); - for(i = 0; i < sym->st_size; i++) { - dest[i] = src[i]; - } - } + switch (ELF32_R_TYPE (reloc->r_info)) + { + case R_386_COPY: { + /* Roll memcpy by hand as we don't have function calls yet. */ + unsigned char *dest, *src; + long i; + dest = (unsigned char *)reloc_addr; + src = (unsigned char *)(value + s_addr); + for(i = 0; i < sym->st_size; i++) { + dest[i] = src[i]; + } break; - case R_386_GLOB_DAT: - *reloc_addr = s_addr + value; - break; - case R_386_JMP_SLOT: - *reloc_addr = s_addr + value; - break; - case R_386_32: - if (map->ll_addr == 0) { - *reloc_addr += value; - } - *reloc_addr += s_addr - ls_addr; - break; - case R_386_PC32: - if (map->ll_addr == 0) { - *reloc_addr += value - reloc->r_offset; - } - *reloc_addr += (s_addr - map->l_addr) - (ls_addr - map->ll_addr); - break; - default: - assert (! "unexpected dynamic reloc type"); - break; - } + } + case R_386_GLOB_DAT: + *reloc_addr = s_addr + value; + break; + case R_386_JMP_SLOT: + *reloc_addr = s_addr + value; + break; + case R_386_32: + if (map->ll_addr == 0) { + *reloc_addr += value; + } + *reloc_addr += s_addr - ls_addr; + break; + case R_386_PC32: + if (map->ll_addr == 0) { + *reloc_addr += value - reloc->r_offset; + } + *reloc_addr += (s_addr - map->l_addr) - (ls_addr - map->ll_addr); + break; + default: + assert (! "unexpected dynamic reloc type", 0); + break; + } } /* Read the dynamic section at DYN and fill in INFO with indices DT_*. */ static inline void __attribute__ ((unused)) elf_get_dynamic_info(ElfW(Dyn) *dyn, ElfW(Addr) l_addr, - ElfW(Dyn) *info[DT_NUM + DT_PROCNUM + DT_EXTRANUM]) -{ - if (! dyn) - return; - - while (dyn->d_tag != DT_NULL) - { - if (dyn->d_tag < DT_NUM) - info[dyn->d_tag] = dyn; - else if (dyn->d_tag >= DT_LOPROC && - dyn->d_tag < DT_LOPROC + DT_PROCNUM) - info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn; - else if ((Elf32_Word) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM) - info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_PROCNUM - ] = dyn; - else - assert (! "bad dynamic tag"); - ++dyn; - } - - if (info[DT_PLTGOT] != NULL) - info[DT_PLTGOT]->d_un.d_ptr += l_addr; - if (info[DT_STRTAB] != NULL) - info[DT_STRTAB]->d_un.d_ptr += l_addr; - if (info[DT_SYMTAB] != NULL) - info[DT_SYMTAB]->d_un.d_ptr += l_addr; + ElfW(Dyn) *info[DT_NUM + DT_PROCNUM + DT_EXTRANUM]) { + if (! dyn) + return; + + while (dyn->d_tag != DT_NULL) { + if (dyn->d_tag < DT_NUM) + info[dyn->d_tag] = dyn; + else if (dyn->d_tag >= DT_LOPROC && + dyn->d_tag < DT_LOPROC + DT_PROCNUM) + info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn; + else if ((Elf32_Word) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM) + info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_PROCNUM] = dyn; +#if 0 + else { + // JPC this is failing, BOZO! + // Not surprising, there are a bunch of sections we don't + // handle and which modern ELF relocation code in glibc + // will handle and relocate. Bah. + assert (! "bad dynamic tag", dyn->d_tag); + } +#endif + ++dyn; + } + + if (info[DT_PLTGOT] != NULL) + info[DT_PLTGOT]->d_un.d_ptr += l_addr; + if (info[DT_STRTAB] != NULL) + info[DT_STRTAB]->d_un.d_ptr += l_addr; + if (info[DT_SYMTAB] != NULL) + info[DT_SYMTAB]->d_un.d_ptr += l_addr; #if ! ELF_MACHINE_NO_RELA - if (info[DT_RELA] != NULL) - { - assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela))); - info[DT_RELA]->d_un.d_ptr += l_addr; - } + if (info[DT_RELA] != NULL) { + assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela)), 0); + info[DT_RELA]->d_un.d_ptr += l_addr; + } #endif #if ! ELF_MACHINE_NO_REL - if (info[DT_REL] != NULL) - { - assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel))); - info[DT_REL]->d_un.d_ptr += l_addr; - } + if (info[DT_REL] != NULL) { + assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)), 0); + info[DT_REL]->d_un.d_ptr += l_addr; + } #endif - if (info[DT_PLTREL] != NULL) - { + if (info[DT_PLTREL] != NULL) { #if ELF_MACHINE_NO_RELA - assert (info[DT_PLTREL]->d_un.d_val == DT_REL); + assert (info[DT_PLTREL]->d_un.d_val == DT_REL, 0); #elif ELF_MACHINE_NO_REL - assert (info[DT_PLTREL]->d_un.d_val == DT_RELA); + assert (info[DT_PLTREL]->d_un.d_val == DT_RELA, 0); #else - assert (info[DT_PLTREL]->d_un.d_val == DT_REL - || info[DT_PLTREL]->d_un.d_val == DT_RELA); + assert (info[DT_PLTREL]->d_un.d_val == DT_REL + || info[DT_PLTREL]->d_un.d_val == DT_RELA, 0); #endif - } - if (info[DT_JMPREL] != NULL) - info[DT_JMPREL]->d_un.d_ptr += l_addr; + } + if (info[DT_JMPREL] != NULL) + info[DT_JMPREL]->d_un.d_ptr += l_addr; } - - /* Perform the relocations in MAP on the running program image as specified by RELTAG, SZTAG. If LAZY is nonzero, this is the first pass on PLT relocations; they should be set up to call _dl_runtime_resolve, rather than fully resolved now. */ static inline void -elf_dynamic_do_rel (struct link_map *map, - ElfW(Addr) reladdr, ElfW(Addr) relsize) -{ - const ElfW(Rel) *r = (const void *) reladdr; - const ElfW(Rel) *end = (const void *) (reladdr + relsize); +elf_dynamic_do_rel(struct link_map *map, + ElfW(Addr) reladdr, ElfW(Addr) relsize) { + const ElfW(Rel) *r = (const void *) reladdr; + const ElfW(Rel) *end = (const void *) (reladdr + relsize); - const ElfW(Sym) *const symtab = - (const void *) map->l_info[DT_SYMTAB]->d_un.d_ptr; - - for (; r < end; ++r) { - elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], - (void *) (map->l_addr + r->r_offset)); - } -} + const ElfW(Sym) *const symtab = + (const void *) map->l_info[DT_SYMTAB]->d_un.d_ptr; + for (; r < end; ++r) { + elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], + (void *) (map->l_addr + r->r_offset)); + } +} -void _dl_start(void) -{ - static Elf32_Addr last_load_address = 0; - struct link_map map; - size_t cnt; - +void _dl_start(void) { + static Elf32_Addr last_load_address = 0; + struct link_map map; + size_t cnt; - /* Partly clean the `map' structure up. Don't use `memset' - since it might nor be built in or inlined and we cannot make function - calls at this point. */ - for (cnt = 0; cnt < sizeof(map.l_info) / sizeof(map.l_info[0]); ++cnt) { - map.l_info[cnt] = 0; - } + /* Partly clean the `map' structure up. Don't use `memset' + since it might nor be built in or inlined and we cannot make function + calls at this point. */ + for (cnt = 0; cnt < sizeof(map.l_info) / sizeof(map.l_info[0]); ++cnt) { + map.l_info[cnt] = 0; + } - /* Get the last load address */ - map.ll_addr = last_load_address; + /* Get the last load address */ + map.ll_addr = last_load_address; - /* Figure out the run-time load address of the dynamic linker itself. */ - last_load_address = map.l_addr = elf_machine_load_address(); + /* Figure out the run-time load address of the dynamic linker itself. */ + last_load_address = map.l_addr = elf_machine_load_address(); - /* Read our own dynamic section and fill in the info array. */ - map.l_ld = (void *)map.l_addr + elf_machine_dynamic(); + /* Read our own dynamic section and fill in the info array. */ + map.l_ld = (void *)map.l_addr + elf_machine_dynamic(); - elf_get_dynamic_info (map.l_ld, map.l_addr - map.ll_addr, map.l_info); + elf_get_dynamic_info (map.l_ld, map.l_addr - map.ll_addr, map.l_info); - /* Relocate ourselves so we can do normal function calls and - * data access using the global offset table. - */ + /* Relocate ourselves so we can do normal function calls and + * data access using the global offset table. + */ #if !ELF_MACHINE_NO_REL - elf_dynamic_do_rel(&map, - map.l_info[DT_REL]->d_un.d_ptr, - map.l_info[DT_RELSZ]->d_un.d_val); - if (map.l_info[DT_PLTREL]->d_un.d_val == DT_REL) { - elf_dynamic_do_rel(&map, - map.l_info[DT_JMPREL]->d_un.d_ptr, - map.l_info[DT_PLTRELSZ]->d_un.d_val); - } + elf_dynamic_do_rel(&map, + map.l_info[DT_REL]->d_un.d_ptr, + map.l_info[DT_RELSZ]->d_un.d_val); + if (map.l_info[DT_PLTREL]->d_un.d_val == DT_REL) { + elf_dynamic_do_rel(&map, + map.l_info[DT_JMPREL]->d_un.d_ptr, + map.l_info[DT_PLTRELSZ]->d_un.d_val); + } #endif #if !ELF_MACHINE_NO_RELA - elf_dynamic_do_rela(&map, - map.l_info[DT_RELA]->d_un.d_ptr, - map.l_info[DT_RELASZ]->d_un.d_val); - if (map.l_info[DT_PLTREL]->d_un.d_val == DT_RELA) { - elf_dynamic_do_rela(&map, - map.l_info[DT_JMPREL]->d_un.d_ptr, - map.l_info[DT_PLTRELSZ]->d_un.d_val); - } + elf_dynamic_do_rela(&map, + map.l_info[DT_RELA]->d_un.d_ptr, + map.l_info[DT_RELASZ]->d_un.d_val); + if (map.l_info[DT_PLTREL]->d_un.d_val == DT_RELA) { + elf_dynamic_do_rela(&map, + map.l_info[DT_JMPREL]->d_un.d_ptr, + map.l_info[DT_PLTRELSZ]->d_un.d_val); + } #endif - /* Now life is sane; we can call functions and access global data. - Set up to use the operating system facilities, and find out from - the operating system's program loader where to find the program - header table in core. Put the rest of _dl_start into a separate - function, that way the compiler cannot put accesses to the GOT - before ELF_DYNAMIC_RELOCATE. */ - return; + /* Now life is sane; we can call functions and access global data. + Set up to use the operating system facilities, and find out from + the operating system's program loader where to find the program + header table in core. Put the rest of _dl_start into a separate + function, that way the compiler cannot put accesses to the GOT + before ELF_DYNAMIC_RELOCATE. */ + return; } diff --git a/self_test.c b/self_test.c new file mode 100644 index 0000000..975ec40 --- /dev/null +++ b/self_test.c @@ -0,0 +1,209 @@ +/* Usermode self-test. + * + * This is a unit test for memtest86+ itself, + * not a standalone usermode memory tester. Sorry. + * + * It covers the main test routines in test.c, allows running them + * in a debugger or adding printfs as needed. + * + * It does not cover: + * - SMP functionality. There's no fundamental obstacle + * to this, it's just not here yet. + * - Every .c file. Some of them do things that will be + * difficult to test in user mode (eg set page tables) + * without some refactoring. + */ + +#ifdef NDEBUG + #error "Someone disabled asserts, but we want asserts for the self test." +#endif +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "stdint.h" +#include "cpuid.h" +#include "test.h" + +/* Provide alternate versions of the globals */ +volatile int run_cpus = 1; +volatile int bail = 0; +volatile int segs = 0; +struct vars variables; +struct vars* const vv = &variables; +// Self-test only supports single CPU (ordinal 0) for now: +volatile int mstr_cpu = 0; + +void assert_fail(const char* file, int line_no) { + printf("Failing assert at %s:%d\n", file, line_no); + assert(0); +} + +void do_tick(int me) {} +void hprint(int y, int x, ulong val) {} +void cprint(int y,int x, const char *s) {} +void dprint(int y,int x,ulong val,int len, int right) {} +void s_barrier() {} // No SMP support in selftest yet + +// Selftest doesn't have error injection yet, and thus, we +// never expect to detect any error. Fail an assert in these +// error-reporting routines: +void ad_err1(ulong *adr1, ulong *adr2, ulong good, ulong bad) { + assert(0); +} +void ad_err2(ulong *adr, ulong bad) { + assert(0); +} +void mt86_error(ulong* adr, ulong good, ulong bad) { + assert(0); +} + +typedef struct { + ulong* va; + ulong len_dw; +} foreach_chunk; + +#define MAX_CHUNK 16 + +typedef struct { + foreach_chunk chunks[MAX_CHUNK]; + int index; +} foreach_ctx; + +void record_chunks(ulong* va, ulong len_dw, const void* vctx) { + foreach_ctx* ctx = (foreach_ctx*)vctx; + + ctx->chunks[ctx->index].va = va; + ctx->chunks[ctx->index].len_dw = len_dw; + ctx->index++; +} + +void foreach_tests() { + foreach_ctx ctx; + const int me = 0; + + // mapped segment is 3G to 4G exact + memset(&ctx, 0, sizeof(ctx)); + foreach_segment((ulong*)0xc0000000, + (ulong*)0xfffffffc, me, &ctx, record_chunks); + + assert(ctx.index == 4); + assert(ctx.chunks[0].va == (ulong*)0xc0000000); + assert(ctx.chunks[0].len_dw == SPINSZ_DWORDS); + assert(ctx.chunks[1].va == (ulong*)0xd0000000); + assert(ctx.chunks[1].len_dw == SPINSZ_DWORDS); + assert(ctx.chunks[2].va == (ulong*)0xe0000000); + assert(ctx.chunks[2].len_dw == SPINSZ_DWORDS); + assert(ctx.chunks[3].va == (ulong*)0xf0000000); + assert(ctx.chunks[3].len_dw == SPINSZ_DWORDS); + + // mapped segment is 256 bytes, 128 byte aligned + memset(&ctx, 0, sizeof(ctx)); + foreach_segment((ulong*)0xc0000080, + (ulong*)0xc000017c, me, &ctx, record_chunks); + assert(ctx.index == 1); + assert(ctx.chunks[0].va == (ulong*)0xc0000080); + assert(ctx.chunks[0].len_dw == 64); + + // mapped segment starts a bit below 3.75G + // and goes up to the 4G boundary + memset(&ctx, 0, sizeof(ctx)); + foreach_segment((ulong*)0xeffff800, + (ulong*)0xfffffffc, me, &ctx, record_chunks); + assert(ctx.index == 2); + assert(ctx.chunks[0].va == (ulong*)0xeffff800); + assert(ctx.chunks[0].len_dw == SPINSZ_DWORDS); + assert(ctx.chunks[1].va == (ulong*)0xfffff800); + assert(ctx.chunks[1].len_dw == 0x200); + + // mapped segment is 0 to 32M + memset(&ctx, 0, sizeof(ctx)); + foreach_segment((ulong*)0x0, + (ulong*)0x1fffffc, me, &ctx, record_chunks); + assert(ctx.index == 1); + assert(ctx.chunks[0].va == (ulong*)0x0); + assert(ctx.chunks[0].len_dw == 0x800000); +} + +int main() { + memset(&variables, 0, sizeof(variables)); + vv->debugging = 1; + + get_cpuid(); + + // add a non-power-of-2 pad to the size, so things don't line + // up too nicely. Chose 508 because it's not 512. + const int kTestSizeDwords = SPINSZ_DWORDS * 2 + 508; + + // Allocate an extra cache line on each end, where we'll + // write a sentinel pattern to detect overflow or underflow: + const int kRawBufSizeDwords = kTestSizeDwords + 32; + + segs = 1; + ulong raw_start = (ulong)malloc(kRawBufSizeDwords * sizeof(ulong)); + ulong raw_end = raw_start + kRawBufSizeDwords * sizeof(ulong); + + // align to a cache line: + if (raw_start & 0x3f) { + raw_start &= ~0x3f; + raw_start += 0x40; + } + // align to a cache line: + if (raw_end & 0x3f) { + raw_end &= ~0x3f; + } + + const int kSentinelBytes = 48; + ulong start = raw_start + kSentinelBytes; // exclude low sentinel + ulong end = raw_end - kSentinelBytes; // exclude high sentinel + + // setup sentinels + memset((ulong*)raw_start, 'z', kSentinelBytes); + memset((ulong*)end, 'z', kSentinelBytes); + + vv->map[0].start = (ulong*)start; + vv->map[0].end = ((ulong*)end) - 1; // map.end points to xxxxxfc + + const int iter = 2; + const int me = 0; // cpu ordinal + + foreach_tests(); + + // TEST 0 + addr_tst1(me); + + // TEST 1, 2 + addr_tst2(me); + + // TEST 3, 4, 5, 6 + const ulong pat = 0x112211ee; + movinv1(iter, pat, ~pat, 0); + + // TEST 7 + block_move(iter, me); + + // TEST 8 + movinv32(iter, 0x2, 0x1, 0x80000000, 0, 1, me); + + // TEST 9 + movinvr(me); + + // TEST 10 + modtst(2, 1, 0x5555aaaa, 0xaaaa5555, me); + + // TEST 11 + bit_fade_fill(0xdeadbeef, me); + bit_fade_chk(0xdeadbeef, me); + + + // Check sentinels, they should not have been overwritten. Do this last. + for (int j=0; j<kSentinelBytes; j++) { + assert(((char*)raw_start)[j] == 'z'); + assert(((char*)end)[j] == 'z'); + } + + printf("All self-tests PASS.\n"); + + return 0; +} @@ -135,7 +135,6 @@ * the low four bits control software flow control */ -#include "io.h" #define serial_echo_outb(v,a) outb((v),(a)+serial_base_ports[serial_tty]) #define serial_echo_inb(a) inb((a)+serial_base_ports[serial_tty]) #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) @@ -33,75 +33,75 @@ void smp_find_cpus(); void barrier_init(int max) { - /* Set the adddress of the barrier structure */ - barr = (struct barrier_s *)0x9ff00; - barr->lck.slock = 1; - barr->mutex.slock = 1; - barr->maxproc = max; - barr->count = max; - barr->st1.slock = 1; - barr->st2.slock = 0; + /* Set the adddress of the barrier structure */ + barr = (struct barrier_s *)0x9ff00; + barr->lck.slock = 1; + barr->mutex.slock = 1; + barr->maxproc = max; + barr->count = max; + barr->st1.slock = 1; + barr->st2.slock = 0; } void s_barrier_init(int max) { - barr->s_lck.slock = 1; - barr->s_maxproc = max; - barr->s_count = max; - barr->s_st1.slock = 1; - barr->s_st2.slock = 0; + barr->s_lck.slock = 1; + barr->s_maxproc = max; + barr->s_count = max; + barr->s_st1.slock = 1; + barr->s_st2.slock = 0; } void barrier() { - if (num_cpus == 1 || v->fail_safe & 3) { - return; - } - spin_wait(&barr->st1); /* Wait if the barrier is active */ - spin_lock(&barr->lck); /* Get lock for barr struct */ - if (--barr->count == 0) { /* Last process? */ - barr->st1.slock = 0; /* Hold up any processes re-entering */ - barr->st2.slock = 1; /* Release the other processes */ - barr->count++; - spin_unlock(&barr->lck); - } else { - spin_unlock(&barr->lck); - spin_wait(&barr->st2); /* wait for peers to arrive */ - spin_lock(&barr->lck); - if (++barr->count == barr->maxproc) { - barr->st1.slock = 1; - barr->st2.slock = 0; - } - spin_unlock(&barr->lck); + if (num_cpus == 1 || vv->fail_safe & 3) { + return; + } + spin_wait(&barr->st1); /* Wait if the barrier is active */ + spin_lock(&barr->lck); /* Get lock for barr struct */ + if (--barr->count == 0) { /* Last process? */ + barr->st1.slock = 0; /* Hold up any processes re-entering */ + barr->st2.slock = 1; /* Release the other processes */ + barr->count++; + spin_unlock(&barr->lck); + } else { + spin_unlock(&barr->lck); + spin_wait(&barr->st2); /* wait for peers to arrive */ + spin_lock(&barr->lck); + if (++barr->count == barr->maxproc) { + barr->st1.slock = 1; + barr->st2.slock = 0; } + spin_unlock(&barr->lck); + } } void s_barrier() { - if (run_cpus == 1 || v->fail_safe & 3) { - return; - } - spin_wait(&barr->s_st1); /* Wait if the barrier is active */ - spin_lock(&barr->s_lck); /* Get lock for barr struct */ - if (--barr->s_count == 0) { /* Last process? */ - barr->s_st1.slock = 0; /* Hold up any processes re-entering */ - barr->s_st2.slock = 1; /* Release the other processes */ - barr->s_count++; - spin_unlock(&barr->s_lck); - } else { - spin_unlock(&barr->s_lck); - spin_wait(&barr->s_st2); /* wait for peers to arrive */ - spin_lock(&barr->s_lck); - if (++barr->s_count == barr->s_maxproc) { - barr->s_st1.slock = 1; - barr->s_st2.slock = 0; - } - spin_unlock(&barr->s_lck); + if (run_cpus == 1 || vv->fail_safe & 3) { + return; + } + spin_wait(&barr->s_st1); /* Wait if the barrier is active */ + spin_lock(&barr->s_lck); /* Get lock for barr struct */ + if (--barr->s_count == 0) { /* Last process? */ + barr->s_st1.slock = 0; /* Hold up any processes re-entering */ + barr->s_st2.slock = 1; /* Release the other processes */ + barr->s_count++; + spin_unlock(&barr->s_lck); + } else { + spin_unlock(&barr->s_lck); + spin_wait(&barr->s_st2); /* wait for peers to arrive */ + spin_lock(&barr->s_lck); + if (++barr->s_count == barr->s_maxproc) { + barr->s_st1.slock = 1; + barr->s_st2.slock = 0; } + spin_unlock(&barr->s_lck); + } } typedef struct { - bool started; + bool started; } ap_info_t; volatile apic_register_t *APIC = NULL; @@ -111,149 +111,149 @@ volatile ap_info_t AP[MAX_CPUS]; void PUT_MEM16(uintptr_t addr, uint16_t val) { - *((volatile uint16_t *)addr) = val; + *((volatile uint16_t *)addr) = val; } void PUT_MEM32(uintptr_t addr, uint32_t val) { - *((volatile uint32_t *)addr) = val; + *((volatile uint32_t *)addr) = val; } static void inline APIC_WRITE(unsigned reg, uint32_t val) { - APIC[reg][0] = val; + APIC[reg][0] = val; } static inline uint32_t APIC_READ(unsigned reg) { - return APIC[reg][0]; + return APIC[reg][0]; } static void SEND_IPI(unsigned apic_id, unsigned trigger, unsigned level, unsigned mode, - uint8_t vector) + 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); + 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); + 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, +memset (volatile void *dst, char value, int len) { - int i; - for (i = 0 ; i < len ; i++ ) { - *((char *) dst + i) = value; - } + int i; + for (i = 0 ; i < len ; i++ ) { + *((char *) dst + i) = value; + } } void initialise_cpus(void) { - int i; - - act_cpus = 0; - - if (maxcpus > 1) { - smp_find_cpus(); - /* The total number of CPUs may be limited */ - if (num_cpus > maxcpus) { - num_cpus = maxcpus; - } - /* Determine how many cpus have been selected */ - for(i = 0; i < num_cpus; i++) { - if (cpu_mask[i]) { - act_cpus++; - } - } - } else { - act_cpus = found_cpus = num_cpus = 1; - } - - /* Initialize the barrier before starting AP's */ - barrier_init(act_cpus); - - /* let the BSP initialise the APs. */ - for(i = 1; i < num_cpus; i++) { - /* Only start this CPU if it is selected by the mask */ - if (cpu_mask[i]) { - smp_boot_ap(i); - } - } + int i; + + act_cpus = 0; + + if (maxcpus > 1) { + smp_find_cpus(); + /* The total number of CPUs may be limited */ + if (num_cpus > maxcpus) { + num_cpus = maxcpus; + } + /* Determine how many cpus have been selected */ + for(i = 0; i < num_cpus; i++) { + if (cpu_mask[i]) { + act_cpus++; + } + } + } else { + act_cpus = found_cpus = num_cpus = 1; + } + + /* Initialize the barrier before starting AP's */ + barrier_init(act_cpus); + + /* let the BSP initialise the APs. */ + for(i = 1; i < num_cpus; i++) { + /* Only start this CPU if it is selected by the mask */ + if (cpu_mask[i]) { + smp_boot_ap(i); + } + } } void kick_cpu(unsigned cpu_num) { - unsigned num_sipi, apic_id; - apic_id = cpu_num_to_apic_id[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); + // 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); + // 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); + // 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; + for (num_sipi = 0; num_sipi < 2; num_sipi++) { + unsigned timeout; + bool send_pending; + unsigned err; - APIC_WRITE(APICR_ESR, 0); + APIC_WRITE(APICR_ESR, 0); - SEND_IPI(apic_id, 0, 0, APIC_DELMODE_STARTUP, (unsigned)startup_32 >> 12); + SEND_IPI(apic_id, 0, 0, APIC_DELMODE_STARTUP, (unsigned)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); + 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+3, 0, "SMP: STARTUP IPI was never sent"); - } + if (send_pending) { + cprint(LINE_STATUS+3, 0, "SMP: STARTUP IPI was never sent"); + } - delay(100000 / DELAY_FACTOR); - - err = APIC_READ(APICR_ESR) & 0xef; - if (err) { - cprint(LINE_STATUS+3, 0, "SMP: After STARTUP IPI: err = 0x"); - hprint(LINE_STATUS+3, COL_MID, err); - } - } + delay(100000 / DELAY_FACTOR); + + err = APIC_READ(APICR_ESR) & 0xef; + if (err) { + cprint(LINE_STATUS+3, 0, "SMP: After STARTUP IPI: err = 0x"); + hprint(LINE_STATUS+3, COL_MID, err); + } + } } // These memory locations are used for the trampoline code and data. @@ -264,215 +264,215 @@ void kick_cpu(unsigned cpu_num) 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]; + 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); + memcpy((uint8_t*)BOOTCODESTART, &_ap_trampoline_start, len); - // Fixup the LGDT instruction to point to GDT pointer. - PUT_MEM16(BOOTCODESTART + 3, GDTPOINTERADDR); + // 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 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); + // 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); + // 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); + // 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); + // 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; + for (num_sipi = 0; num_sipi < 2; num_sipi++) { + unsigned timeout; + bool send_pending; + unsigned err; - APIC_WRITE(APICR_ESR, 0); + APIC_WRITE(APICR_ESR, 0); - SEND_IPI(apic_id, 0, 0, APIC_DELMODE_STARTUP, BOOTCODESTART >> 12); + 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); + 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+3, 0, "SMP: STARTUP IPI was never sent"); - } + if (send_pending) { + cprint(LINE_STATUS+3, 0, "SMP: STARTUP IPI was never sent"); + } - delay(100000 / DELAY_FACTOR); - - err = APIC_READ(APICR_ESR) & 0xef; - if (err) { - cprint(LINE_STATUS+3, 0, "SMP: After STARTUP IPI: err = 0x"); - hprint(LINE_STATUS+3, COL_MID, err); - } - } + delay(100000 / DELAY_FACTOR); + + err = APIC_READ(APICR_ESR) & 0xef; + if (err) { + cprint(LINE_STATUS+3, 0, "SMP: After STARTUP IPI: err = 0x"); + hprint(LINE_STATUS+3, COL_MID, err); + } + } } static int checksum(unsigned char *mp, int len) { - int sum = 0; + int sum = 0; - while (len--) { - sum += *mp++; - } - return (sum & 0xFF); + while (len--) { + sum += *mp++; + } + return (sum & 0xFF); } /* Parse an MP config table for CPU information */ 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; - - if (mpc->signature != MPCSignature) { - return FALSE; - } - if (checksum((unsigned char*)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; + mp_config_table_header_t *mpc = (mp_config_table_header_t*)addr; + uint8_t *tab_entry_ptr; + uint8_t *mpc_table_end; + + if (mpc->signature != MPCSignature) { + return FALSE; + } + if (checksum((unsigned char*)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; + 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 (num_cpus < MAX_CPUS) { - cpu_num_to_apic_id[num_cpus] = pe->apic_id; - num_cpus++; - } - found_cpus++; + if (pe->cpu_flag & CPU_BOOTPROCESSOR) { + // BSP is CPU 0 + cpu_num_to_apic_id[0] = pe->apic_id; + } else if (num_cpus < MAX_CPUS) { + cpu_num_to_apic_id[num_cpus] = pe->apic_id; + num_cpus++; + } + found_cpus++; - // we cannot handle non-local 82489DX apics - if ((pe->apic_ver & 0xf0) != 0x10) { - return 0; - } + // we cannot handle non-local 82489DX apics + if ((pe->apic_ver & 0xf0) != 0x10) { + return 0; + } - 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); - break; - case MP_LINTSRC: - tab_entry_ptr += sizeof(mp_local_interrupt_entry_t); - break; - default: - return FALSE; - } - } - return TRUE; + 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); + break; + case MP_LINTSRC: + tab_entry_ptr += sizeof(mp_local_interrupt_entry_t); + break; + default: + return FALSE; + } + } + return TRUE; } /* Search for a Floating Pointer structure */ 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; - - - while ((uintptr_t)addr < end) { - fp = (floating_pointer_struct_t*)addr; - if (*(unsigned int *)addr == FPSignature && fp->length == 1 && checksum((unsigned char*)addr, 16) == 0 && ((fp->spec_rev == 1) || (fp->spec_rev == 4))) { - return fp; - } - addr += 4; - } - return NULL; + floating_pointer_struct_t *fp; + uintptr_t end = addr + length; + + + while ((uintptr_t)addr < end) { + fp = (floating_pointer_struct_t*)addr; + if (*(unsigned int *)addr == FPSignature && fp->length == 1 && checksum((unsigned char*)addr, 16) == 0 && ((fp->spec_rev == 1) || (fp->spec_rev == 4))) { + return fp; + } + addr += 4; + } + return NULL; } /* Search for a Root System Descriptor Pointer */ rsdp_t *scan_for_rsdp(uintptr_t addr, uint32_t length) { - rsdp_t *rp; - uintptr_t end = addr + length; - - - while ((uintptr_t)addr < end) { - rp = (rsdp_t*)addr; - if (*(unsigned int *)addr == RSDPSignature && - checksum((unsigned char*)addr, rp->length) == 0) { - return rp; - } - addr += 4; - } - return NULL; + rsdp_t *rp; + uintptr_t end = addr + length; + + + while ((uintptr_t)addr < end) { + rp = (rsdp_t*)addr; + if (*(unsigned int *)addr == RSDPSignature && + checksum((unsigned char*)addr, rp->length) == 0) { + return rp; + } + addr += 4; + } + return NULL; } /* Parse a MADT table for processor entries */ int parse_madt(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; + mp_config_table_header_t *mpc = (mp_config_table_header_t*)addr; + uint8_t *tab_entry_ptr; + uint8_t *mpc_table_end; - if (checksum((unsigned char*)mpc, mpc->length) != 0) { - return FALSE; - } + if (checksum((unsigned char*)mpc, mpc->length) != 0) { + return FALSE; + } - APIC = (volatile apic_register_t*)(uintptr_t)mpc->lapic_addr; + 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) { + 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) { - madt_processor_entry_t *pe = (madt_processor_entry_t*)tab_entry_ptr; - if (pe->type == MP_PROCESSOR) { - if (pe->enabled) { - if (num_cpus < MAX_CPUS) { - cpu_num_to_apic_id[num_cpus] = pe->apic_id; + madt_processor_entry_t *pe = (madt_processor_entry_t*)tab_entry_ptr; + if (pe->type == MP_PROCESSOR) { + if (pe->enabled) { + if (num_cpus < MAX_CPUS) { + cpu_num_to_apic_id[num_cpus] = pe->apic_id; - /* the first CPU is the BSP, don't increment */ - if (found_cpus) { - num_cpus++; - } - } - found_cpus++; - } - } - tab_entry_ptr += pe->length; - } - return TRUE; + /* the first CPU is the BSP, don't increment */ + if (found_cpus) { + num_cpus++; + } + } + found_cpus++; + } + } + tab_entry_ptr += pe->length; + } + return TRUE; } /* This is where we search for SMP information in the following order @@ -501,107 +501,107 @@ int parse_madt(uintptr_t addr) { */ void smp_find_cpus() { - floating_pointer_struct_t *fp; - rsdp_t *rp; - rsdt_t *rt; - uint8_t *tab_ptr, *tab_end; - unsigned int *ptr; - unsigned int uiptr; - - if(v->fail_safe & 3) { return; } - - memset(&AP, 0, sizeof AP); - - if(v->fail_safe & 8) - { - // Search for the Floating MP structure pointer - 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) { - // Search the BIOS ESDS area - unsigned int address = *(unsigned short *)0x40E; - address <<= 4; - if (address) { - fp = scan_for_floating_ptr_struct(address, 0x400); - } - } + floating_pointer_struct_t *fp; + rsdp_t *rp; + rsdt_t *rt; + uint8_t *tab_ptr, *tab_end; + unsigned int *ptr; + unsigned int uiptr; + + if(vv->fail_safe & 3) { return; } + + memset(&AP, 0, sizeof AP); + + if(vv->fail_safe & 8) + { + // Search for the Floating MP structure pointer + 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) { + // Search the BIOS ESDS area + unsigned int address = *(unsigned short *)0x40E; + address <<= 4; + if (address) { + fp = scan_for_floating_ptr_struct(address, 0x400); + } + } - if (fp != NULL) { - // We have a floating MP pointer - // Is this a default configuration? + if (fp != NULL) { + // We have a floating MP pointer + // Is this a default configuration? - if (fp->feature[0] > 0 && fp->feature[0] <=7) { - // This is a default config so plug in the numbers - num_cpus = 2; - APIC = (volatile apic_register_t*)0xFEE00000; - cpu_num_to_apic_id[0] = 0; - cpu_num_to_apic_id[1] = 1; - return; - } + if (fp->feature[0] > 0 && fp->feature[0] <=7) { + // This is a default config so plug in the numbers + num_cpus = 2; + APIC = (volatile apic_register_t*)0xFEE00000; + cpu_num_to_apic_id[0] = 0; + cpu_num_to_apic_id[1] = 1; + return; + } - // Do we have a pointer to a MP configuration table? - if ( fp->phys_addr != 0) { - if (read_mp_config_table(fp->phys_addr)) { - // Found a good MP table, done - return; - } - } - } - } - - - /* No MP table so far, try to find an ACPI MADT table - * We try to use the MP table first since there is no way to distinguish - * real cores from hyper-threads in the MADT */ - - /* Search for the RSDP */ - rp = scan_for_rsdp(0xE0000, 0x20000); - if (rp == NULL) { + // Do we have a pointer to a MP configuration table? + if ( fp->phys_addr != 0) { + if (read_mp_config_table(fp->phys_addr)) { + // Found a good MP table, done + return; + } + } + } + } + + + /* No MP table so far, try to find an ACPI MADT table + * We try to use the MP table first since there is no way to distinguish + * real cores from hyper-threads in the MADT */ + + /* Search for the RSDP */ + rp = scan_for_rsdp(0xE0000, 0x20000); + if (rp == NULL) { /* Search the BIOS ESDS area */ unsigned int address = *(unsigned short *)0x40E; address <<= 4; - if (address) { - rp = scan_for_rsdp(address, 0x400); + if (address) { + rp = scan_for_rsdp(address, 0x400); } - } + } - if (rp == NULL) { - /* RSDP not found, give up */ - return; - } - - /* Found the RSDP, now get either the RSDT or XSDT */ - if (rp->revision >= 2) { - rt = (rsdt_t *)rp->xrsdt[0]; + if (rp == NULL) { + /* RSDP not found, give up */ + return; + } + + /* Found the RSDP, now get either the RSDT or XSDT */ + if (rp->revision >= 2) { + rt = (rsdt_t *)rp->xrsdt[0]; - if (rt == 0) { - return; - } - // Validate the XSDT - if (*(unsigned int *)rt != XSDTSignature) { - return; - } - if ( checksum((unsigned char*)rt, rt->length) != 0) { - return; - } + if (rt == 0) { + return; + } + // Validate the XSDT + if (*(unsigned int *)rt != XSDTSignature) { + return; + } + if ( checksum((unsigned char*)rt, rt->length) != 0) { + return; + } } else { - rt = (rsdt_t *)rp->rsdt; - if (rt == 0) { - return; - } - /* Validate the RSDT */ - if (*(unsigned int *)rt != RSDTSignature) { - return; - } - if ( checksum((unsigned char*)rt, rt->length) != 0) { - return; - } + rt = (rsdt_t *)rp->rsdt; + if (rt == 0) { + return; + } + /* Validate the RSDT */ + if (*(unsigned int *)rt != RSDTSignature) { + return; + } + if ( checksum((unsigned char*)rt, rt->length) != 0) { + return; + } } /* Scan the RSDT or XSDT for a pointer to the MADT */ @@ -610,62 +610,62 @@ void smp_find_cpus() while (tab_ptr < tab_end) { - uiptr = *((unsigned int *)tab_ptr); - ptr = (unsigned int *)uiptr; - - /* Check for the MADT signature */ - if (ptr && *ptr == MADTSignature) { - /* Found it, now parse it */ - if (parse_madt((uintptr_t)ptr)) { - return; - } - } - tab_ptr += 4; + uiptr = *((unsigned int *)tab_ptr); + ptr = (unsigned int *)uiptr; + + /* Check for the MADT signature */ + if (ptr && *ptr == MADTSignature) { + /* Found it, now parse it */ + if (parse_madt((uintptr_t)ptr)) { + return; + } + } + tab_ptr += 4; } } unsigned my_apic_id() { - return (APIC[APICR_ID][0]) >> 24; + return (APIC[APICR_ID][0]) >> 24; } void smp_ap_booted(unsigned cpu_num) { - AP[cpu_num].started = TRUE; + AP[cpu_num].started = TRUE; } void smp_boot_ap(unsigned cpu_num) { - unsigned timeout; - - 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+3, 0, "SMP: Boot timeout for"); - dprint(LINE_STATUS+3, COL_MID, cpu_num,2,1); - cprint(LINE_STATUS+3, 26, "Turning off SMP"); - } + unsigned timeout; + + 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+3, 0, "SMP: Boot timeout for"); + dprint(LINE_STATUS+3, COL_MID, cpu_num,2,1); + cprint(LINE_STATUS+3, 26, "Turning off SMP"); + } } 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; + 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; } /* A set of simple functions used to preserve assigned CPU ordinals since @@ -674,19 +674,19 @@ unsigned smp_my_cpu_num() int num_to_ord[MAX_CPUS]; void smp_set_ordinal(int me, int ord) { - num_to_ord[me] = ord; + num_to_ord[me] = ord; } int smp_my_ord_num(int me) { - return num_to_ord[me]; + return num_to_ord[me]; } int smp_ord_to_cpu(int me) { - int i; - for (i=0; i<MAX_CPUS; i++) { - if (num_to_ord[i] == me) return i; - } - return -1; -}
\ No newline at end of file + int i; + for (i=0; i<MAX_CPUS; i++) { + if (num_to_ord[i] == me) return i; + } + return -1; +} @@ -1,546 +1,541 @@ -/*
- * MemTest86+ V5 Specific code (GPL V2.0)
- * By Samuel DEMEULEMEESTER, sdemeule@memtest.org
- * http://www.canardpc.com - http://www.memtest.org
- */
-
-
-#include "test.h"
-#include "io.h"
-#include "pci.h"
-#include "msr.h"
-#include "spd.h"
-#include "screen_buffer.h"
-#include "jedec_id.h"
-
-#define NULL 0
-
-#define SMBHSTSTS smbusbase
-#define SMBHSTCNT smbusbase + 2
-#define SMBHSTCMD smbusbase + 3
-#define SMBHSTADD smbusbase + 4
-#define SMBHSTDAT smbusbase + 5
-
-extern void wait_keyup();
-
-int smbdev, smbfun;
-unsigned short smbusbase;
-unsigned char spd_raw[256];
-char s[] = {'/', 0, '-', 0, '\\', 0, '|', 0};
-
-static void ich5_get_smb(void)
-{
- unsigned long x;
- int result;
- result = pci_conf_read(0, smbdev, smbfun, 0x20, 2, &x);
- if (result == 0) smbusbase = (unsigned short) x & 0xFFFE;
-}
-
-static void piix4_get_smb(void)
-{
- unsigned long x;
- int result;
-
- result = pci_conf_read(0, smbdev, smbfun, 0x08, 1, &x);
-
- if(x < 0x40){
- // SB600/700
- result = pci_conf_read(0, smbdev, smbfun, 0x90, 2, &x);
- if (result == 0) smbusbase = (unsigned short) x & 0xFFFE;
- } else {
- // SB800
- sb800_get_smb();
- }
-}
-
-void sb800_get_smb(void)
-{
- int lbyte, hbyte;
-
- __outb(AMD_SMBUS_BASE_REG + 1, AMD_INDEX_IO_PORT);
- lbyte = __inb(AMD_DATA_IO_PORT);
- __outb(AMD_SMBUS_BASE_REG, AMD_INDEX_IO_PORT);
- hbyte = __inb(AMD_DATA_IO_PORT);
-
- smbusbase = lbyte;
- smbusbase <<= 8;
- smbusbase += hbyte;
- smbusbase &= 0xFFE0;
-
- if (smbusbase == 0xFFE0) { smbusbase = 0; }
-}
-
-unsigned char ich5_smb_read_byte(unsigned char adr, unsigned char cmd)
-{
- int l1, h1, l2, h2;
- unsigned long long t;
- __outb(0x1f, SMBHSTSTS); // reset SMBus Controller
- __outb(0xff, SMBHSTDAT);
- while(__inb(SMBHSTSTS) & 0x01); // wait until ready
- __outb(cmd, SMBHSTCMD);
- __outb((adr << 1) | 0x01, SMBHSTADD);
- __outb(0x48, SMBHSTCNT);
- rdtsc(l1, h1);
- //cprint(POP2_Y, POP2_X + 16, s + cmd % 8); // progress bar
- while (!(__inb(SMBHSTSTS) & 0x02)) { // wait til command finished
- rdtsc(l2, h2);
- t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / v->clks_msec;
- if (t > 10) break; // break after 10ms
- }
- return __inb(SMBHSTDAT);
-}
-
-static int ich5_read_spd(int dimmadr)
-{
- int x;
- spd_raw[0] = ich5_smb_read_byte(0x50 + dimmadr, 0);
- if (spd_raw[0] == 0xff) return -1; // no spd here
- for (x = 1; x < 256; x++) {
- spd_raw[x] = ich5_smb_read_byte(0x50 + dimmadr, (unsigned char) x);
- }
- return 0;
-}
-
-static void us15w_get_smb(void)
-{
- unsigned long x;
- int result;
- result = pci_conf_read(0, 0x1f, 0, 0x40, 2, &x);
- if (result == 0) smbusbase = (unsigned short) x & 0xFFC0;
-}
-
-unsigned char us15w_smb_read_byte(unsigned char adr, unsigned char cmd)
-{
- int l1, h1, l2, h2;
- unsigned long long t;
- //__outb(0x00, smbusbase + 1); // reset SMBus Controller
- //__outb(0x00, smbusbase + 6);
- //while((__inb(smbusbase + 1) & 0x08) != 0); // wait until ready
- __outb(0x02, smbusbase + 0); // Byte read
- __outb(cmd, smbusbase + 5); // Command
- __outb(0x07, smbusbase + 1); // Clear status
- __outb((adr << 1) | 0x01, smbusbase + 4); // DIMM address
- __outb(0x12, smbusbase + 0); // Start
- //while (((__inb(smbusbase + 1) & 0x08) == 0)) {} // wait til busy
- rdtsc(l1, h1);
- cprint(POP2_Y, POP2_X + 16, s + cmd % 8); // progress bar
- while (((__inb(smbusbase + 1) & 0x01) == 0) ||
- ((__inb(smbusbase + 1) & 0x08) != 0)) { // wait til command finished
- rdtsc(l2, h2);
- t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / v->clks_msec;
- if (t > 10) break; // break after 10ms
- }
- return __inb(smbusbase + 6);
-}
-
-static int us15w_read_spd(int dimmadr)
-{
- int x;
- spd_raw[0] = us15w_smb_read_byte(0x50 + dimmadr, 0);
- if (spd_raw[0] == 0xff) return -1; // no spd here
- for (x = 1; x < 256; x++) {
- spd_raw[x] = us15w_smb_read_byte(0x50 + dimmadr, (unsigned char) x);
- }
- return 0;
-}
-
-struct pci_smbus_controller {
- unsigned vendor;
- unsigned device;
- char *name;
- void (*get_adr)(void);
- int (*read_spd)(int dimmadr);
-};
-
-static struct pci_smbus_controller smbcontrollers[] = {
- // Intel SMBUS
- {0x8086, 0x9C22, "Intel HSW-ULT", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x8C22, "Intel HSW", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x1E22, "Intel Z77", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x1C22, "Intel P67", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x3B30, "Intel P55", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x3A60, "Intel ICH10B", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x3A30, "Intel ICH10R", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x2930, "Intel ICH9", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x283E, "Intel ICH8", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x27DA, "Intel ICH7", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x266A, "Intel ICH6", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x24D3, "Intel ICH5", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x24C3, "Intel ICH4", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x25A4, "Intel 6300ESB", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x269B, "Intel ESB2", ich5_get_smb, ich5_read_spd},
- {0x8086, 0x8119, "Intel US15W", us15w_get_smb, us15w_read_spd},
- {0x8086, 0x5032, "Intel EP80579", ich5_get_smb, ich5_read_spd},
-
- // AMD SMBUS
- {0x1002, 0x4385, "AMD SB600/700", piix4_get_smb, ich5_read_spd},
- {0x1022, 0x780B, "AMD SB800/900", sb800_get_smb, ich5_read_spd},
- {0, 0, "", NULL, NULL}
-};
-
-
-int find_smb_controller(void)
-{
- int i = 0;
- unsigned long valuev, valued;
-
- for (smbdev = 0; smbdev < 32; smbdev++) {
- for (smbfun = 0; smbfun < 8; smbfun++) {
- pci_conf_read(0, smbdev, smbfun, 0, 2, &valuev);
- if (valuev != 0xFFFF) { // if there is something look what's it..
- for (i = 0; smbcontrollers[i].vendor > 0; i++) { // check if this is a known smbus controller
- if (valuev == smbcontrollers[i].vendor) {
- pci_conf_read(0, smbdev, smbfun, 2, 2, &valued); // read the device id
- if (valued == smbcontrollers[i].device) {
- return i;
- }
- }
- }
- }
- }
- }
- return -1;
-}
-
-
-
-void get_spd_spec(void)
-{
- int index;
- int h, i, j, z;
- int k = 0;
- int module_size;
- int curcol;
- int temp_nbd;
- int tck;
-
- index = find_smb_controller();
-
- if (index == -1)
- {
- // Unknown SMBUS Controller, exit
- return;
- }
-
- smbcontrollers[index].get_adr();
- cprint(LINE_SPD-2, 0, "Memory SPD Informations");
- cprint(LINE_SPD-1, 0, "--------------------------");
-
- for (j = 0; j < 8; j++) {
- if (smbcontrollers[index].read_spd(j) == 0) {
- curcol = 1;
- if(spd_raw[2] == 0x0b){
- // We are here if DDR3 present
-
- // First print slot#, module capacity
- cprint(LINE_SPD+k, curcol, " - Slot :");
- dprint(LINE_SPD+k, curcol+8, k, 1, 0);
-
- module_size = get_ddr3_module_size(spd_raw[4] & 0xF, spd_raw[8] & 0x7, spd_raw[7] & 0x7, spd_raw[7] >> 3);
- temp_nbd = getnum(module_size); curcol += 12;
- dprint(LINE_SPD+k, curcol, module_size, temp_nbd, 0); curcol += temp_nbd;
- cprint(LINE_SPD+k, curcol, " MB"); curcol += 4;
-
- // If XMP is supported, check Tck in XMP reg
- if(spd_raw[176] == 0x0C && spd_raw[177] == 0x4A && spd_raw[12])
- {
- tck = spd_raw[186];
- } else {
- tck = spd_raw[12];
- }
-
- // Then module jedec speed
- switch(tck)
- {
- default:
- cprint(LINE_SPD+k, curcol, "DDR3-????");
- break;
- case 20:
- cprint(LINE_SPD+k, curcol, "DDR3-800");
- curcol--;
- break;
- case 15:
- cprint(LINE_SPD+k, curcol, "DDR3-1066");
- break;
- case 12:
- cprint(LINE_SPD+k, curcol, "DDR3-1333");
- break;
- case 10:
- cprint(LINE_SPD+k, curcol, "DDR3-1600");
- break;
- case 9:
- cprint(LINE_SPD+k, curcol, "DDR3-1866");
- break;
- case 8:
- cprint(LINE_SPD+k, curcol, "DDR3-2133");
- break;
- case 7:
- cprint(LINE_SPD+k, curcol, "DDR3-2400");
- break;
- case 6:
- cprint(LINE_SPD+k, curcol, "DDR3-2533");
- break;
- case 5:
- cprint(LINE_SPD+k, curcol, "DDR3-2666");
- break;
- }
-
- curcol += 10;
-
- if((spd_raw[8] >> 3) == 1) { cprint(LINE_SPD+k, curcol, "ECC"); curcol += 4; }
-
- // Then print module infos (manufacturer & part number)
- spd_raw[117] &= 0x0F; // Parity odd or even
- for (i = 0; jep106[i].cont_code < 9; i++) {
- if (spd_raw[117] == jep106[i].cont_code && spd_raw[118] == jep106[i].hex_byte) {
- // We are here if a Jedec manufacturer is detected
- cprint(LINE_SPD+k, curcol, "-"); curcol += 2;
- cprint(LINE_SPD+k, curcol, jep106[i].name);
- for(z = 0; jep106[i].name[z] != '\0'; z++) { curcol++; }
- curcol++;
- // Display module serial number
- for (h = 128; h < 146; h++) {
- cprint(LINE_SPD+k, curcol, convert_hex_to_char(spd_raw[h]));
- curcol++;
- }
-
- // Detect Week and Year of Manufacturing (Think to upgrade after 2015 !!!)
- if(curcol <= 72 && spd_raw[120] > 3 && spd_raw[120] < 16 && spd_raw[121] < 55)
- {
- cprint(LINE_SPD+k, curcol, "(W");
- dprint(LINE_SPD+k, curcol+2, spd_raw[121], 2, 0);
- if(spd_raw[121] < 10) { cprint(LINE_SPD+k, curcol+2, "0"); }
- cprint(LINE_SPD+k, curcol+4, "'");
- dprint(LINE_SPD+k, curcol+5, spd_raw[120], 2, 0);
- if(spd_raw[120] < 10) { cprint(LINE_SPD+k, curcol+5, "0"); }
- cprint(LINE_SPD+k, curcol+7, ")");
- curcol += 9;
- }
-
- // Detect XMP Memory
- if(spd_raw[176] == 0x0C && spd_raw[177] == 0x4A)
- {
- cprint(LINE_SPD+k, curcol, "*XMP*");
- }
- }
- }
- }
- // We enter this function if DDR2 is detected
- if(spd_raw[2] == 0x08){
- // First print slot#, module capacity
- cprint(LINE_SPD+k, curcol, " - Slot :");
- dprint(LINE_SPD+k, curcol+8, k, 1, 0);
-
- module_size = get_ddr2_module_size(spd_raw[31], spd_raw[5]);
- temp_nbd = getnum(module_size); curcol += 12;
- dprint(LINE_SPD+k, curcol, module_size, temp_nbd, 0); curcol += temp_nbd;
- cprint(LINE_SPD+k, curcol, " MB"); curcol += 4;
-
- // Then module jedec speed
- float ddr2_speed, byte1, byte2;
-
- byte1 = (spd_raw[9] >> 4) * 10;
- byte2 = spd_raw[9] & 0xF;
-
- ddr2_speed = 1 / (byte1 + byte2) * 10000 * 2;
-
- temp_nbd = getnum(ddr2_speed);
- cprint(LINE_SPD+k, curcol, "DDR2-"); curcol += 5;
- dprint(LINE_SPD+k, curcol, ddr2_speed, temp_nbd, 0); curcol += temp_nbd;
-
- if((spd_raw[11] >> 1) == 1) { cprint(LINE_SPD+k, curcol+1, "ECC"); curcol += 4; }
-
- // Then print module infos (manufacturer & part number)
- int ccode = 0;
-
- for(i = 64; i < 72; i++)
- {
- if(spd_raw[i] == 0x7F) { ccode++; }
- }
-
- curcol++;
-
- for (i = 0; jep106[i].cont_code < 9; i++) {
- if (ccode == jep106[i].cont_code && spd_raw[64+ccode] == jep106[i].hex_byte) {
- // We are here if a Jedec manufacturer is detected
- cprint(LINE_SPD+k, curcol, "-"); curcol += 2;
- cprint(LINE_SPD+k, curcol, jep106[i].name);
- for(z = 0; jep106[i].name[z] != '\0'; z++) { curcol++; }
- curcol++;
- // Display module serial number
- for (h = 73; h < 91; h++) {
- cprint(LINE_SPD+k, curcol, convert_hex_to_char(spd_raw[h]));
- curcol++;
- }
-
- }
- }
-
- }
- k++;
- }
- }
-}
-
-
-void show_spd(void)
-{
- int index;
- int i, j;
- int flag = 0;
- pop2up();
- wait_keyup();
- index = find_smb_controller();
- if (index == -1) {
- cprint(POP2_Y, POP2_X+1, "SMBus Controller not known");
- while (!get_key());
- wait_keyup();
- pop2down();
- return;
- }
- else cprint(POP2_Y, POP2_X+1, "SPD Data: Slot");
- smbcontrollers[index].get_adr();
- for (j = 0; j < 16; j++) {
- if (smbcontrollers[index].read_spd(j) == 0) {
- dprint(POP2_Y, POP2_X + 15, j, 2, 0);
- for (i = 0; i < 256; i++) {
- hprint2(2 + POP2_Y + i / 16, 3 + POP2_X + (i % 16) * 3, spd_raw[i], 2);
- }
- flag = 0;
- while(!flag) {
- if (get_key()) flag++;
- }
- wait_keyup();
- }
- }
- pop2down();
-}
-
-int get_ddr3_module_size(int sdram_capacity, int prim_bus_width, int sdram_width, int ranks)
-{
- int module_size;
-
- switch(sdram_capacity)
- {
- case 0:
- module_size = 256;
- break;
- case 1:
- module_size = 512;
- break;
- default:
- case 2:
- module_size = 1024;
- break;
- case 3:
- module_size = 2048;
- break;
- case 4:
- module_size = 4096;
- break;
- case 5:
- module_size = 8192;
- break;
- case 6:
- module_size = 16384;
- break;
- }
-
- module_size /= 8;
-
- switch(prim_bus_width)
- {
- case 0:
- module_size *= 8;
- break;
- case 1:
- module_size *= 16;
- break;
- case 2:
- module_size *= 32;
- break;
- case 3:
- module_size *= 64;
- break;
- }
-
- switch(sdram_width)
- {
- case 0:
- module_size /= 4;
- break;
- case 1:
- module_size /= 8;
- break;
- case 2:
- module_size /= 16;
- break;
- case 3:
- module_size /= 32;
- break;
-
- }
-
- module_size *= (ranks + 1);
-
- return module_size;
-}
-
-
-int get_ddr2_module_size(int rank_density_byte, int rank_num_byte)
-{
- int module_size;
-
- switch(rank_density_byte)
- {
- case 1:
- module_size = 1024;
- break;
- case 2:
- module_size = 2048;
- break;
- case 4:
- module_size = 4096;
- break;
- case 8:
- module_size = 8192;
- break;
- case 16:
- module_size = 16384;
- break;
- case 32:
- module_size = 128;
- break;
- case 64:
- module_size = 256;
- break;
- default:
- case 128:
- module_size = 512;
- break;
- }
-
- module_size *= (rank_num_byte & 7) + 1;
-
- return module_size;
-
-}
-
-
-struct ascii_map {
- unsigned hex_code;
- char *name;
-};
-
-
-char* convert_hex_to_char(unsigned hex_org) {
- static char buf[2] = " ";
- if (hex_org >= 0x20 && hex_org < 0x80) {
- buf[0] = hex_org;
- } else {
- //buf[0] = '\0';
- buf[0] = ' ';
- }
-
- return buf;
-}
\ No newline at end of file +/* + * MemTest86+ V5 Specific code (GPL V2.0) + * By Samuel DEMEULEMEESTER, sdemeule@memtest.org + * http://www.canardpc.com - http://www.memtest.org + */ + + +#include "test.h" +#include "io.h" +#include "pci.h" +#include "msr.h" +#include "spd.h" +#include "screen_buffer.h" +#include "jedec_id.h" + +#define NULL 0 + +#define SMBHSTSTS smbusbase +#define SMBHSTCNT smbusbase + 2 +#define SMBHSTCMD smbusbase + 3 +#define SMBHSTADD smbusbase + 4 +#define SMBHSTDAT smbusbase + 5 + +extern void wait_keyup(); + +int smbdev, smbfun; +unsigned short smbusbase; +unsigned char spd_raw[256]; +char s[] = {'/', 0, '-', 0, '\\', 0, '|', 0}; + +static void ich5_get_smb(void) +{ + unsigned long x; + int result; + result = pci_conf_read(0, smbdev, smbfun, 0x20, 2, &x); + if (result == 0) smbusbase = (unsigned short) x & 0xFFFE; +} + +static void piix4_get_smb(void) +{ + unsigned long x; + int result; + + result = pci_conf_read(0, smbdev, smbfun, 0x08, 1, &x); + + if(x < 0x40){ + // SB600/700 + result = pci_conf_read(0, smbdev, smbfun, 0x90, 2, &x); + if (result == 0) smbusbase = (unsigned short) x & 0xFFFE; + } else { + // SB800 + sb800_get_smb(); + } +} + +void sb800_get_smb(void) +{ + int lbyte, hbyte; + + __outb(AMD_SMBUS_BASE_REG + 1, AMD_INDEX_IO_PORT); + lbyte = __inb(AMD_DATA_IO_PORT); + __outb(AMD_SMBUS_BASE_REG, AMD_INDEX_IO_PORT); + hbyte = __inb(AMD_DATA_IO_PORT); + + smbusbase = lbyte; + smbusbase <<= 8; + smbusbase += hbyte; + smbusbase &= 0xFFE0; + + if (smbusbase == 0xFFE0) { smbusbase = 0; } +} + +unsigned char ich5_smb_read_byte(unsigned char adr, unsigned char cmd) +{ + int l1, h1, l2, h2; + unsigned long long t; + __outb(0x1f, SMBHSTSTS); // reset SMBus Controller + __outb(0xff, SMBHSTDAT); + while(__inb(SMBHSTSTS) & 0x01); // wait until ready + __outb(cmd, SMBHSTCMD); + __outb((adr << 1) | 0x01, SMBHSTADD); + __outb(0x48, SMBHSTCNT); + rdtsc(l1, h1); + //cprint(POP2_Y, POP2_X + 16, s + cmd % 8); // progress bar + while (!(__inb(SMBHSTSTS) & 0x02)) { // wait til command finished + rdtsc(l2, h2); + t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / vv->clks_msec; + if (t > 10) break; // break after 10ms + } + return __inb(SMBHSTDAT); +} + +static int ich5_read_spd(int dimmadr) +{ + int x; + spd_raw[0] = ich5_smb_read_byte(0x50 + dimmadr, 0); + if (spd_raw[0] == 0xff) return -1; // no spd here + for (x = 1; x < 256; x++) { + spd_raw[x] = ich5_smb_read_byte(0x50 + dimmadr, (unsigned char) x); + } + return 0; +} + +static void us15w_get_smb(void) +{ + unsigned long x; + int result; + result = pci_conf_read(0, 0x1f, 0, 0x40, 2, &x); + if (result == 0) smbusbase = (unsigned short) x & 0xFFC0; +} + +unsigned char us15w_smb_read_byte(unsigned char adr, unsigned char cmd) +{ + int l1, h1, l2, h2; + unsigned long long t; + //__outb(0x00, smbusbase + 1); // reset SMBus Controller + //__outb(0x00, smbusbase + 6); + //while((__inb(smbusbase + 1) & 0x08) != 0); // wait until ready + __outb(0x02, smbusbase + 0); // Byte read + __outb(cmd, smbusbase + 5); // Command + __outb(0x07, smbusbase + 1); // Clear status + __outb((adr << 1) | 0x01, smbusbase + 4); // DIMM address + __outb(0x12, smbusbase + 0); // Start + //while (((__inb(smbusbase + 1) & 0x08) == 0)) {} // wait til busy + rdtsc(l1, h1); + cprint(POP2_Y, POP2_X + 16, s + cmd % 8); // progress bar + while (((__inb(smbusbase + 1) & 0x01) == 0) || + ((__inb(smbusbase + 1) & 0x08) != 0)) { // wait til command finished + rdtsc(l2, h2); + t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / vv->clks_msec; + if (t > 10) break; // break after 10ms + } + return __inb(smbusbase + 6); +} + +static int us15w_read_spd(int dimmadr) +{ + int x; + spd_raw[0] = us15w_smb_read_byte(0x50 + dimmadr, 0); + if (spd_raw[0] == 0xff) return -1; // no spd here + for (x = 1; x < 256; x++) { + spd_raw[x] = us15w_smb_read_byte(0x50 + dimmadr, (unsigned char) x); + } + return 0; +} + +struct pci_smbus_controller { + unsigned vendor; + unsigned device; + char *name; + void (*get_adr)(void); + int (*read_spd)(int dimmadr); +}; + +static struct pci_smbus_controller smbcontrollers[] = + { + // Intel SMBUS + {0x8086, 0x9C22, "Intel HSW-ULT", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x8C22, "Intel HSW", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x1E22, "Intel Z77", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x1C22, "Intel P67", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x3B30, "Intel P55", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x3A60, "Intel ICH10B", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x3A30, "Intel ICH10R", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x2930, "Intel ICH9", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x283E, "Intel ICH8", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x27DA, "Intel ICH7", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x266A, "Intel ICH6", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x24D3, "Intel ICH5", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x24C3, "Intel ICH4", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x25A4, "Intel 6300ESB", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x269B, "Intel ESB2", ich5_get_smb, ich5_read_spd}, + {0x8086, 0x8119, "Intel US15W", us15w_get_smb, us15w_read_spd}, + {0x8086, 0x5032, "Intel EP80579", ich5_get_smb, ich5_read_spd}, + + // AMD SMBUS + {0x1002, 0x4385, "AMD SB600/700", piix4_get_smb, ich5_read_spd}, + {0x1022, 0x780B, "AMD SB800/900", sb800_get_smb, ich5_read_spd}, + {0, 0, "", NULL, NULL} + }; + +int find_smb_controller(void) +{ + int i = 0; + unsigned long valuev, valued; + + for (smbdev = 0; smbdev < 32; smbdev++) { + for (smbfun = 0; smbfun < 8; smbfun++) { + pci_conf_read(0, smbdev, smbfun, 0, 2, &valuev); + if (valuev != 0xFFFF) { // if there is something look what's it.. + for (i = 0; smbcontrollers[i].vendor > 0; i++) { // check if this is a known smbus controller + if (valuev == smbcontrollers[i].vendor) { + pci_conf_read(0, smbdev, smbfun, 2, 2, &valued); // read the device id + if (valued == smbcontrollers[i].device) { + return i; + } + } + } + } + } + } + return -1; +} + +void get_spd_spec(void) +{ + int index; + int h, i, j, z; + int k = 0; + int module_size; + int curcol; + int temp_nbd; + int tck; + + index = find_smb_controller(); + + if (index == -1) + { + // Unknown SMBUS Controller, exit + return; + } + + smbcontrollers[index].get_adr(); + cprint(LINE_SPD-2, 0, "Memory SPD Informations"); + cprint(LINE_SPD-1, 0, "--------------------------"); + + for (j = 0; j < 8; j++) { + if (smbcontrollers[index].read_spd(j) == 0) { + curcol = 1; + if(spd_raw[2] == 0x0b){ + // We are here if DDR3 present + + // First print slot#, module capacity + cprint(LINE_SPD+k, curcol, " - Slot :"); + dprint(LINE_SPD+k, curcol+8, k, 1, 0); + + module_size = get_ddr3_module_size(spd_raw[4] & 0xF, spd_raw[8] & 0x7, spd_raw[7] & 0x7, spd_raw[7] >> 3); + temp_nbd = getnum(module_size); curcol += 12; + dprint(LINE_SPD+k, curcol, module_size, temp_nbd, 0); curcol += temp_nbd; + cprint(LINE_SPD+k, curcol, " MB"); curcol += 4; + + // If XMP is supported, check Tck in XMP reg + if(spd_raw[176] == 0x0C && spd_raw[177] == 0x4A && spd_raw[12]) + { + tck = spd_raw[186]; + } else { + tck = spd_raw[12]; + } + + // Then module jedec speed + switch(tck) + { + default: + cprint(LINE_SPD+k, curcol, "DDR3-????"); + break; + case 20: + cprint(LINE_SPD+k, curcol, "DDR3-800"); + curcol--; + break; + case 15: + cprint(LINE_SPD+k, curcol, "DDR3-1066"); + break; + case 12: + cprint(LINE_SPD+k, curcol, "DDR3-1333"); + break; + case 10: + cprint(LINE_SPD+k, curcol, "DDR3-1600"); + break; + case 9: + cprint(LINE_SPD+k, curcol, "DDR3-1866"); + break; + case 8: + cprint(LINE_SPD+k, curcol, "DDR3-2133"); + break; + case 7: + cprint(LINE_SPD+k, curcol, "DDR3-2400"); + break; + case 6: + cprint(LINE_SPD+k, curcol, "DDR3-2533"); + break; + case 5: + cprint(LINE_SPD+k, curcol, "DDR3-2666"); + break; + } + + curcol += 10; + + if((spd_raw[8] >> 3) == 1) { cprint(LINE_SPD+k, curcol, "ECC"); curcol += 4; } + + // Then print module infos (manufacturer & part number) + spd_raw[117] &= 0x0F; // Parity odd or even + for (i = 0; jep106[i].cont_code < 9; i++) { + if (spd_raw[117] == jep106[i].cont_code && spd_raw[118] == jep106[i].hex_byte) { + // We are here if a Jedec manufacturer is detected + cprint(LINE_SPD+k, curcol, "-"); curcol += 2; + cprint(LINE_SPD+k, curcol, jep106[i].name); + for(z = 0; jep106[i].name[z] != '\0'; z++) { curcol++; } + curcol++; + // Display module serial number + for (h = 128; h < 146; h++) { + cprint(LINE_SPD+k, curcol, convert_hex_to_char(spd_raw[h])); + curcol++; + } + + // Detect Week and Year of Manufacturing (Think to upgrade after 2015 !!!) + if(curcol <= 72 && spd_raw[120] > 3 && spd_raw[120] < 16 && spd_raw[121] < 55) + { + cprint(LINE_SPD+k, curcol, "(W"); + dprint(LINE_SPD+k, curcol+2, spd_raw[121], 2, 0); + if(spd_raw[121] < 10) { cprint(LINE_SPD+k, curcol+2, "0"); } + cprint(LINE_SPD+k, curcol+4, "'"); + dprint(LINE_SPD+k, curcol+5, spd_raw[120], 2, 0); + if(spd_raw[120] < 10) { cprint(LINE_SPD+k, curcol+5, "0"); } + cprint(LINE_SPD+k, curcol+7, ")"); + curcol += 9; + } + + // Detect XMP Memory + if(spd_raw[176] == 0x0C && spd_raw[177] == 0x4A) + { + cprint(LINE_SPD+k, curcol, "*XMP*"); + } + } + } + } + // We enter this function if DDR2 is detected + if(spd_raw[2] == 0x08){ + // First print slot#, module capacity + cprint(LINE_SPD+k, curcol, " - Slot :"); + dprint(LINE_SPD+k, curcol+8, k, 1, 0); + + module_size = get_ddr2_module_size(spd_raw[31], spd_raw[5]); + temp_nbd = getnum(module_size); curcol += 12; + dprint(LINE_SPD+k, curcol, module_size, temp_nbd, 0); curcol += temp_nbd; + cprint(LINE_SPD+k, curcol, " MB"); curcol += 4; + + // Then module jedec speed + float ddr2_speed, byte1, byte2; + + byte1 = (spd_raw[9] >> 4) * 10; + byte2 = spd_raw[9] & 0xF; + + ddr2_speed = 1 / (byte1 + byte2) * 10000 * 2; + + temp_nbd = getnum(ddr2_speed); + cprint(LINE_SPD+k, curcol, "DDR2-"); curcol += 5; + dprint(LINE_SPD+k, curcol, ddr2_speed, temp_nbd, 0); curcol += temp_nbd; + + if((spd_raw[11] >> 1) == 1) { cprint(LINE_SPD+k, curcol+1, "ECC"); curcol += 4; } + + // Then print module infos (manufacturer & part number) + int ccode = 0; + + for(i = 64; i < 72; i++) + { + if(spd_raw[i] == 0x7F) { ccode++; } + } + + curcol++; + + for (i = 0; jep106[i].cont_code < 9; i++) { + if (ccode == jep106[i].cont_code && spd_raw[64+ccode] == jep106[i].hex_byte) { + // We are here if a Jedec manufacturer is detected + cprint(LINE_SPD+k, curcol, "-"); curcol += 2; + cprint(LINE_SPD+k, curcol, jep106[i].name); + for(z = 0; jep106[i].name[z] != '\0'; z++) { curcol++; } + curcol++; + // Display module serial number + for (h = 73; h < 91; h++) { + cprint(LINE_SPD+k, curcol, convert_hex_to_char(spd_raw[h])); + curcol++; + } + } + } + } + k++; + } + } +} + +void show_spd(void) +{ + int index; + int i, j; + int flag = 0; + pop2up(); + wait_keyup(); + index = find_smb_controller(); + if (index == -1) { + cprint(POP2_Y, POP2_X+1, "SMBus Controller not known"); + while (!get_key()); + wait_keyup(); + pop2down(); + return; + } + else cprint(POP2_Y, POP2_X+1, "SPD Data: Slot"); + smbcontrollers[index].get_adr(); + for (j = 0; j < 16; j++) { + if (smbcontrollers[index].read_spd(j) == 0) { + dprint(POP2_Y, POP2_X + 15, j, 2, 0); + for (i = 0; i < 256; i++) { + hprint2(2 + POP2_Y + i / 16, 3 + POP2_X + (i % 16) * 3, spd_raw[i], 2); + } + flag = 0; + while(!flag) { + if (get_key()) flag++; + } + wait_keyup(); + } + } + pop2down(); +} + +int get_ddr3_module_size(int sdram_capacity, int prim_bus_width, int sdram_width, int ranks) +{ + int module_size; + + switch(sdram_capacity) + { + case 0: + module_size = 256; + break; + case 1: + module_size = 512; + break; + default: + case 2: + module_size = 1024; + break; + case 3: + module_size = 2048; + break; + case 4: + module_size = 4096; + break; + case 5: + module_size = 8192; + break; + case 6: + module_size = 16384; + break; + } + + module_size /= 8; + + switch(prim_bus_width) + { + case 0: + module_size *= 8; + break; + case 1: + module_size *= 16; + break; + case 2: + module_size *= 32; + break; + case 3: + module_size *= 64; + break; + } + + switch(sdram_width) + { + case 0: + module_size /= 4; + break; + case 1: + module_size /= 8; + break; + case 2: + module_size /= 16; + break; + case 3: + module_size /= 32; + break; + + } + + module_size *= (ranks + 1); + + return module_size; +} + + +int get_ddr2_module_size(int rank_density_byte, int rank_num_byte) +{ + int module_size; + + switch(rank_density_byte) + { + case 1: + module_size = 1024; + break; + case 2: + module_size = 2048; + break; + case 4: + module_size = 4096; + break; + case 8: + module_size = 8192; + break; + case 16: + module_size = 16384; + break; + case 32: + module_size = 128; + break; + case 64: + module_size = 256; + break; + default: + case 128: + module_size = 512; + break; + } + + module_size *= (rank_num_byte & 7) + 1; + + return module_size; + +} + + +struct ascii_map { + unsigned hex_code; + char *name; +}; + + +char* convert_hex_to_char(unsigned hex_org) { + static char buf[2] = " "; + if (hex_org >= 0x20 && hex_org < 0x80) { + buf[0] = hex_org; + } else { + //buf[0] = '\0'; + buf[0] = ' '; + } + + return buf; +} @@ -8,13 +8,13 @@ * http://www.canardpc.com - http://www.memtest.org * Thanks to Passmark for calculate_chunk() and various comments ! */ - + #include "test.h" #include "config.h" #include "stdint.h" #include "cpuid.h" #include "smp.h" -#include <sys/io.h> +#include "io.h" extern struct cpu_ident cpu_id; extern volatile int mstr_cpu; @@ -29,47 +29,205 @@ void rand_seed( unsigned int seed1, unsigned int seed2, int me); ulong rand(int me); void poll_errors(); -static inline ulong roundup(ulong value, ulong mask) -{ - return (value + mask) & ~mask; -} +// NOTE(jcoiner): +// Defining 'STATIC' to empty string results in crashes. (It should +// work fine, of course.) I suspect relocation problems in reloc.c. +// When we declare these routines static, we use relative addresses +// for them instead of looking up their addresses in (supposedly +// relocated) global elf tables, which avoids the crashes. + +#define STATIC static +//#define STATIC -// start / end - return values for range to test +#define PREFER_C 0 + +static const void* const nullptr = 0x0; + +// Writes *start and *end with the VA range to test. +// // me - this threads CPU number // j - index into v->map for current segment we are testing // align - number of bytes to align each block to -void calculate_chunk(ulong** start, ulong** end, int me, int j, int makeMultipleOf) -{ - ulong chunk; +STATIC void calculate_chunk(ulong** start, ulong** end, int me, + int j, int makeMultipleOf) { + ulong chunk; + + // If we are only running 1 CPU then test the whole block + if (run_cpus == 1) { + *start = vv->map[j].start; + *end = vv->map[j].end; + } else { + + // Divide the current segment by the number of CPUs + chunk = (ulong)vv->map[j].end-(ulong)vv->map[j].start; + chunk /= run_cpus; + + // Round down to the nearest desired bitlength multiple + chunk = (chunk + (makeMultipleOf-1)) & ~(makeMultipleOf-1); + + // Figure out chunk boundaries + *start = (ulong*)((ulong)vv->map[j].start+(chunk*me)); + /* Set end addrs for the highest CPU num to the + * end of the segment for rounding errors */ + /* Also rounds down to boundary if needed, may miss some ram but + better than crashing or producing false errors. */ + /* This rounding probably will never happen as the segments should + be in 4096 bytes pages if I understand correctly. */ + if (me == mstr_cpu) { + *end = (ulong*)(vv->map[j].end); + } else { + *end = (ulong*)((ulong)(*start) + chunk); + (*end)--; + } + } +} +/* Call segment_fn() for each up-to-SPINSZ segment between + * 'start' and 'end'. + */ +void foreach_segment +(ulong* start, ulong* end, + int me, const void* ctx, segment_fn func) { + + ASSERT(start < end); + + // Confirm 'start' points to an even dword, and 'end' + // should point to an odd dword + ASSERT(0 == (((ulong)start) & 0x7)); + ASSERT(0x4 == (((ulong)end) & 0x7)); + + // 'end' may be exactly 0xfffffffc, right at the 4GB boundary. + // + // To avoid overflow in our loop tests and length calculations, + // use dword indices (the '_dw' vars) to avoid overflows. + ulong start_dw = ((ulong)start) >> 2; + ulong end_dw = ((ulong) end) >> 2; + + // end is always xxxxxffc, but increment end_dw to an + // address beyond the segment for easier boundary calculations. + ++end_dw; + + ulong seg_dw = start_dw; + ulong seg_end_dw = start_dw; + + int done = 0; + do { + do_tick(me); + { BAILR } + + // ensure no overflow + ASSERT((seg_end_dw + SPINSZ_DWORDS) > seg_end_dw); + seg_end_dw += SPINSZ_DWORDS; + + if (seg_end_dw >= end_dw) { + seg_end_dw = end_dw; + done++; + } + if (seg_dw == seg_end_dw) { + break; + } + + ASSERT(((ulong)seg_end_dw) <= 0x40000000); + ASSERT(seg_end_dw > seg_dw); + ulong seg_len_dw = seg_end_dw - seg_dw; + + func((ulong*)(seg_dw << 2), seg_len_dw, ctx); + + seg_dw = seg_end_dw; + } while (!done); +} - // If we are only running 1 CPU then test the whole block - if (run_cpus == 1) { - *start = v->map[j].start; - *end = v->map[j].end; - } - else{ +/* Calls segment_fn() for each segment in vv->map. + * + * Does not slice by CPU number, so it covers the entire memory. + * Contrast to sliced_foreach_segment(). + */ +STATIC void unsliced_foreach_segment +(const void* ctx, int me, segment_fn func) { + int j; + for (j=0; j<segs; j++) { + foreach_segment(vv->map[j].start, + vv->map[j].end, + me, ctx, func); + } +} - // Divide the current segment by the number of CPUs - chunk = (ulong)v->map[j].end-(ulong)v->map[j].start; - chunk /= run_cpus; - - // Round down to the nearest desired bitlength multiple - chunk = (chunk + (makeMultipleOf-1)) & ~(makeMultipleOf-1); - - // Figure out chunk boundaries - *start = (ulong*)((ulong)v->map[j].start+(chunk*me)); - /* Set end addrs for the highest CPU num to the - * end of the segment for rounding errors */ - // Also rounds down to boundary if needed, may miss some ram but better than crashing or producing false errors. - // This rounding probably will never happen as the segments should be in 4096 bytes pages if I understand correctly. - if (me == mstr_cpu) { - *end = (ulong*)(v->map[j].end); - } else { - *end = (ulong*)((ulong)(*start) + chunk); - (*end)--; - } - } +/* Calls segment_fn() for each segment to be tested by CPU 'me'. + * + * In multicore mode, slices the segments by 'me' (the CPU ordinal + * number) so that each call will cover only 1/Nth of memory. + */ +STATIC void sliced_foreach_segment +(const void *ctx, int me, segment_fn func) { + int j; + ulong *start, *end; // VAs + ulong* prev_end = 0; + for (j=0; j<segs; j++) { + calculate_chunk(&start, &end, me, j, 64); + + // Ensure no overlap among chunks + ASSERT(end > start); + if (prev_end > 0) { + ASSERT(prev_end < start); + } + prev_end = end; + + foreach_segment(start, end, me, ctx, func); + } +} + +STATIC void addr_tst1_seg(ulong* restrict buf, + ulong len_dw, const void* unused) { + // Within each segment: + // - choose a low dword offset 'off' + // - write pat to *off + // - write ~pat to addresses that are above off by + // 1, 2, 4, ... dwords up to the top of the segment. None + // should alias to the original dword. + // - write ~pat to addresses that are below off by + // 1, 2, 4, etc dwords, down to the start of the segment. None + // should alias to the original dword. If adding a given offset + // doesn't produce a single bit address flip (because it produced + // a carry) subtracting the same offset should give a single bit flip. + // - repeat this, moving off ahead in increments of 1MB; + // this covers address bits within physical memory banks, we hope? + + ulong pat; + int k; + + for (pat=0x5555aaaa, k=0; k<2; k++) { + hprint(LINE_PAT, COL_PAT, pat); + + for (ulong off_dw = 0; off_dw < len_dw; off_dw += (1 << 18)) { + buf[off_dw] = pat; + pat = ~pat; + + for (ulong more_off_dw = 1; off_dw + more_off_dw < len_dw; + more_off_dw = more_off_dw << 1) { + ASSERT(more_off_dw); // it should never get to zero + buf[off_dw + more_off_dw] = pat; + ulong bad; + if ((bad = buf[off_dw]) != ~pat) { + ad_err1(buf + off_dw, + buf + off_dw + more_off_dw, + bad, ~pat); + break; + } + } + for (ulong more_off_dw = 1; off_dw > more_off_dw; + more_off_dw = more_off_dw << 1) { + ASSERT(more_off_dw); // it should never get to zero + buf[off_dw - more_off_dw] = pat; + ulong bad; + if ((bad = buf[off_dw]) != ~pat) { + ad_err1(buf + off_dw, + buf + off_dw - more_off_dw, + bad, ~pat); + break; + } + } + } + } } /* @@ -77,100 +235,71 @@ void calculate_chunk(ulong** start, ulong** end, int me, int j, int makeMultiple */ void addr_tst1(int me) { - int i, j, k; - volatile ulong *p, *pt, *end; - ulong bad, mask, bank, p1; - - /* Test the global address bits */ - for (p1=0, j=0; j<2; j++) { - hprint(LINE_PAT, COL_PAT, p1); - - /* Set pattern in our lowest multiple of 0x20000 */ - p = (ulong *)roundup((ulong)v->map[0].start, 0x1ffff); - *p = p1; - - /* Now write pattern compliment */ - p1 = ~p1; - end = v->map[segs-1].end; - for (i=0; i<100; i++) { - mask = 4; - do { - pt = (ulong *)((ulong)p | mask); - if (pt == p) { - mask = mask << 1; - continue; - } - if (pt >= end) { - break; - } - *pt = p1; - if ((bad = *p) != ~p1) { - ad_err1((ulong *)p, (ulong *)mask, - bad, ~p1); - i = 1000; - } - mask = mask << 1; - } while(mask); - } - do_tick(me); - BAILR - } - - /* Now check the address bits in each bank */ - /* If we have more than 8mb of memory then the bank size must be */ - /* bigger than 256k. If so use 1mb for the bank size. */ - if (v->pmap[v->msegs - 1].end > (0x800000 >> 12)) { - bank = 0x100000; - } else { - bank = 0x40000; - } - for (p1=0, k=0; k<2; k++) { - hprint(LINE_PAT, COL_PAT, p1); - - for (j=0; j<segs; j++) { - p = v->map[j].start; - /* Force start address to be a multiple of 256k */ - p = (ulong *)roundup((ulong)p, bank - 1); - end = v->map[j].end; - /* Redundant checks for overflow */ - while (p < end && p > v->map[j].start && p != 0) { - *p = p1; - - p1 = ~p1; - for (i=0; i<50; i++) { - mask = 4; - do { - pt = (ulong *) - ((ulong)p | mask); - if (pt == p) { - mask = mask << 1; - continue; - } - if (pt >= end) { - break; - } - *pt = p1; - if ((bad = *p) != ~p1) { - ad_err1((ulong *)p, - (ulong *)mask, - bad,~p1); - i = 200; - } - mask = mask << 1; - } while(mask); - } - if (p + bank > p) { - p += bank; - } else { - p = end; - } - p1 = ~p1; - } - } - do_tick(me); - BAILR - p1 = ~p1; - } + unsliced_foreach_segment(nullptr, me, addr_tst1_seg); +} + +STATIC void addr_tst2_init_segment(ulong* p, + ulong len_dw, const void* unused) { + ulong* pe = p + (len_dw - 1); + + /* Original C code replaced with hand tuned assembly code + * for (; p <= pe; p++) { + * *p = (ulong)p; + * } + */ + asm __volatile__ ( + "jmp L91\n\t" + ".p2align 4,,7\n\t" + "L90:\n\t" + "addl $4,%%edi\n\t" + "L91:\n\t" + "movl %%edi,(%%edi)\n\t" + "cmpl %%edx,%%edi\n\t" + "jb L90\n\t" + : : "D" (p), "d" (pe) + ); +} + +STATIC void addr_tst2_check_segment(ulong* p, + ulong len_dw, const void* unused) { + ulong* pe = p + (len_dw - 1); + + /* Original C code replaced with hand tuned assembly code + * for (; p <= pe; p++) { + * if((bad = *p) != (ulong)p) { + * ad_err2((ulong)p, bad); + * } + * } + */ + asm __volatile__ + ( + "jmp L95\n\t" + ".p2align 4,,7\n\t" + "L99:\n\t" + "addl $4,%%edi\n\t" + "L95:\n\t" + "movl (%%edi),%%ecx\n\t" + "cmpl %%edi,%%ecx\n\t" + "jne L97\n\t" + "L96:\n\t" + "cmpl %%edx,%%edi\n\t" + "jb L99\n\t" + "jmp L98\n\t" + + "L97:\n\t" + "pushl %%edx\n\t" + "pushl %%ecx\n\t" + "pushl %%edi\n\t" + "call ad_err2\n\t" + "popl %%edi\n\t" + "popl %%ecx\n\t" + "popl %%edx\n\t" + "jmp L96\n\t" + + "L98:\n\t" + : : "D" (p), "d" (pe) + : "ecx" + ); } /* @@ -178,805 +307,776 @@ void addr_tst1(int me) */ void addr_tst2(int me) { - int j, done; - ulong *p, *pe, *end, *start; - - cprint(LINE_PAT, COL_PAT, "address "); - - /* Write each address with it's own address */ - for (j=0; j<segs; j++) { - start = v->map[j].start; - end = v->map[j].end; - pe = (ulong *)start; - p = start; - done = 0; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } - -/* Original C code replaced with hand tuned assembly code - * for (; p <= pe; p++) { - * *p = (ulong)p; - * } - */ - asm __volatile__ ( - "jmp L91\n\t" - ".p2align 4,,7\n\t" - "L90:\n\t" - "addl $4,%%edi\n\t" - "L91:\n\t" - "movl %%edi,(%%edi)\n\t" - "cmpl %%edx,%%edi\n\t" - "jb L90\n\t" - : : "D" (p), "d" (pe) - ); - p = pe + 1; - } while (!done); - } - - /* Each address should have its own address */ - for (j=0; j<segs; j++) { - start = v->map[j].start; - end = v->map[j].end; - pe = (ulong *)start; - p = start; - done = 0; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } -/* Original C code replaced with hand tuned assembly code - * for (; p <= pe; p++) { - * if((bad = *p) != (ulong)p) { - * ad_err2((ulong)p, bad); - * } - * } - */ - asm __volatile__ ( - "jmp L95\n\t" - ".p2align 4,,7\n\t" - "L99:\n\t" - "addl $4,%%edi\n\t" - "L95:\n\t" - "movl (%%edi),%%ecx\n\t" - "cmpl %%edi,%%ecx\n\t" - "jne L97\n\t" - "L96:\n\t" - "cmpl %%edx,%%edi\n\t" - "jb L99\n\t" - "jmp L98\n\t" - - "L97:\n\t" - "pushl %%edx\n\t" - "pushl %%ecx\n\t" - "pushl %%edi\n\t" - "call ad_err2\n\t" - "popl %%edi\n\t" - "popl %%ecx\n\t" - "popl %%edx\n\t" - "jmp L96\n\t" - - "L98:\n\t" - : : "D" (p), "d" (pe) - : "ecx" - ); - p = pe + 1; - } while (!done); - } + cprint(LINE_PAT, COL_PAT, "address "); + + /* Write each address with its own address */ + unsliced_foreach_segment(nullptr, me, addr_tst2_init_segment); + { BAILR } + + /* Each address should have its own address */ + unsliced_foreach_segment(nullptr, me, addr_tst2_check_segment); +} + +typedef struct { + int me; + ulong xorVal; +} movinvr_ctx; + +STATIC void movinvr_init(ulong* p, + ulong len_dw, const void* vctx) { + ulong* pe = p + (len_dw - 1); + const movinvr_ctx* ctx = (const movinvr_ctx*)vctx; + /* Original C code replaced with hand tuned assembly code */ + /* + for (; p <= pe; p++) { + *p = rand(me); + } + */ + + asm __volatile__ + ( + "jmp L200\n\t" + ".p2align 4,,7\n\t" + "L201:\n\t" + "addl $4,%%edi\n\t" + "L200:\n\t" + "pushl %%ecx\n\t" + "call rand\n\t" + "popl %%ecx\n\t" + "movl %%eax,(%%edi)\n\t" + "cmpl %%ebx,%%edi\n\t" + "jb L201\n\t" + : : "D" (p), "b" (pe), "c" (ctx->me) + : "eax" + ); +} + +STATIC void movinvr_body(ulong* p, ulong len_dw, const void* vctx) { + ulong* pe = p + (len_dw - 1); + const movinvr_ctx* ctx = (const movinvr_ctx*)vctx; + + /* Original C code replaced with hand tuned assembly code */ + + /*for (; p <= pe; p++) { + num = rand(me); + if (i) { + num = ~num; + } + if ((bad=*p) != num) { + mt86_error((ulong*)p, num, bad); + } + *p = ~num; + }*/ + + asm __volatile__ + ( + "pushl %%ebp\n\t" + + // Skip first increment + "jmp L26\n\t" + ".p2align 4,,7\n\t" + + // increment 4 bytes (32-bits) + "L27:\n\t" + "addl $4,%%edi\n\t" + + // Check this byte + "L26:\n\t" + + // Get next random number, pass in me(edx), random value returned in num(eax) + // num = rand(me); + // cdecl call maintains all registers except eax, ecx, and edx + // We maintain edx with a push and pop here using it also as an input + // we don't need the current eax value and want it to change to the return value + // we overwrite ecx shortly after this discarding its current value + "pushl %%edx\n\t" // Push function inputs onto stack + "call rand\n\t" + "popl %%edx\n\t" // Remove function inputs from stack + + // XOR the random number with xorVal(ebx), which is either 0xffffffff or 0 depending on the outer loop + // if (i) { num = ~num; } + "xorl %%ebx,%%eax\n\t" + + // Move the current value of the current position p(edi) into bad(ecx) + // (bad=*p) + "movl (%%edi),%%ecx\n\t" + + // Compare bad(ecx) to num(eax) + "cmpl %%eax,%%ecx\n\t" + + // If not equal jump the error case + "jne L23\n\t" + + // Set a new value or not num(eax) at the current position p(edi) + // *p = ~num; + "L25:\n\t" + "movl $0xffffffff,%%ebp\n\t" + "xorl %%ebp,%%eax\n\t" + "movl %%eax,(%%edi)\n\t" + + // Loop until current position p(edi) equals the end position pe(esi) + "cmpl %%esi,%%edi\n\t" + "jb L27\n\t" + "jmp L24\n" + + // Error case + "L23:\n\t" + // Must manually maintain eax, ecx, and edx as part of cdecl call convention + "pushl %%edx\n\t" + "pushl %%ecx\n\t" // Next three pushes are functions input + "pushl %%eax\n\t" + "pushl %%edi\n\t" + "call mt86_error\n\t" + "popl %%edi\n\t" // Remove function inputs from stack and restore register values + "popl %%eax\n\t" + "popl %%ecx\n\t" + "popl %%edx\n\t" + "jmp L25\n" + + "L24:\n\t" + "popl %%ebp\n\t" + :: "D" (p), "S" (pe), "b" (ctx->xorVal), + "d" (ctx->me) + : "eax", "ecx" + ); } /* * Test all of memory using a "half moving inversions" algorithm using random - * numbers and their complment as the data pattern. Since we are not able to + * numbers and their complement as the data pattern. Since we are not able to * produce random numbers in reverse order testing is only done in the forward * direction. */ void movinvr(int me) { - int i, j, done, seed1, seed2; - ulong *p; - ulong *pe; - ulong *start,*end; - ulong xorVal; - //ulong num, bad; - - /* Initialize memory with initial sequence of random numbers. */ - if (cpu_id.fid.bits.rdtsc) { - asm __volatile__ ("rdtsc":"=a" (seed1),"=d" (seed2)); - } else { - seed1 = 521288629 + v->pass; - seed2 = 362436069 - v->pass; - } - - /* Display the current seed */ - if (mstr_cpu == me) hprint(LINE_PAT, COL_PAT, seed1); - rand_seed(seed1, seed2, me); - for (j=0; j<segs; j++) { - calculate_chunk(&start, &end, me, j, 4); - pe = start; - p = start; - done = 0; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } -/* Original C code replaced with hand tuned assembly code */ -/* - for (; p <= pe; p++) { - *p = rand(me); - } - */ + int i, seed1, seed2; + + movinvr_ctx ctx; + ctx.me = me; + ctx.xorVal = 0; + + /* Initialize memory with initial sequence of random numbers. */ + if (cpu_id.fid.bits.rdtsc) { + asm __volatile__ ("rdtsc":"=a" (seed1),"=d" (seed2)); + } else { + seed1 = 521288629 + vv->pass; + seed2 = 362436069 - vv->pass; + } + + /* Display the current seed */ + if (mstr_cpu == me) hprint(LINE_PAT, COL_PAT, seed1); + rand_seed(seed1, seed2, me); + + sliced_foreach_segment(&ctx, me, movinvr_init); + { BAILR } + + /* Do moving inversions test. Check for initial pattern and then + * write the complement for each memory location. + */ + for (i=0; i<2; i++) { + rand_seed(seed1, seed2, me); + + if (i) { + ctx.xorVal = 0xffffffff; + } else { + ctx.xorVal = 0; + } + + sliced_foreach_segment(&ctx, me, movinvr_body); + { BAILR } + } +} - asm __volatile__ ( - "jmp L200\n\t" - ".p2align 4,,7\n\t" - "L201:\n\t" - "addl $4,%%edi\n\t" - "L200:\n\t" - "pushl %%ecx\n\t" \ - "call rand\n\t" - "popl %%ecx\n\t" \ - "movl %%eax,(%%edi)\n\t" - "cmpl %%ebx,%%edi\n\t" - "jb L201\n\t" - : : "D" (p), "b" (pe), "c" (me) - : "eax" - ); - p = pe + 1; - } while (!done); - } - - /* Do moving inversions test. Check for initial pattern and then - * write the complement for each memory location. - */ - for (i=0; i<2; i++) { - rand_seed(seed1, seed2, me); - for (j=0; j<segs; j++) { - calculate_chunk(&start, &end, me, j, 4); - pe = start; - p = start; - done = 0; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } -/* Original C code replaced with hand tuned assembly code */ - - /*for (; p <= pe; p++) { - num = rand(me); - if (i) { - num = ~num; - } - if ((bad=*p) != num) { - error((ulong*)p, num, bad); - } - *p = ~num; - }*/ - - if (i) { - xorVal = 0xffffffff; - } else { - xorVal = 0; - } - asm __volatile__ ( - - "pushl %%ebp\n\t" - - // Skip first increment - "jmp L26\n\t" - ".p2align 4,,7\n\t" - - // increment 4 bytes (32-bits) - "L27:\n\t" - "addl $4,%%edi\n\t" - - // Check this byte - "L26:\n\t" - - // Get next random number, pass in me(edx), random value returned in num(eax) - // num = rand(me); - // cdecl call maintains all registers except eax, ecx, and edx - // We maintain edx with a push and pop here using it also as an input - // we don't need the current eax value and want it to change to the return value - // we overwrite ecx shortly after this discarding its current value - "pushl %%edx\n\t" // Push function inputs onto stack - "call rand\n\t" - "popl %%edx\n\t" // Remove function inputs from stack - - // XOR the random number with xorVal(ebx), which is either 0xffffffff or 0 depending on the outer loop - // if (i) { num = ~num; } - "xorl %%ebx,%%eax\n\t" - - // Move the current value of the current position p(edi) into bad(ecx) - // (bad=*p) - "movl (%%edi),%%ecx\n\t" - - // Compare bad(ecx) to num(eax) - "cmpl %%eax,%%ecx\n\t" - - // If not equal jump the error case - "jne L23\n\t" - - // Set a new value or not num(eax) at the current position p(edi) - // *p = ~num; - "L25:\n\t" - "movl $0xffffffff,%%ebp\n\t" - "xorl %%ebp,%%eax\n\t" - "movl %%eax,(%%edi)\n\t" - - // Loop until current position p(edi) equals the end position pe(esi) - "cmpl %%esi,%%edi\n\t" - "jb L27\n\t" - "jmp L24\n" - - // Error case - "L23:\n\t" - // Must manually maintain eax, ecx, and edx as part of cdecl call convention - "pushl %%edx\n\t" - "pushl %%ecx\n\t" // Next three pushes are functions input - "pushl %%eax\n\t" - "pushl %%edi\n\t" - "call error\n\t" - "popl %%edi\n\t" // Remove function inputs from stack and restore register values - "popl %%eax\n\t" - "popl %%ecx\n\t" - "popl %%edx\n\t" - "jmp L25\n" - - "L24:\n\t" - "popl %%ebp\n\t" - :: "D" (p), "S" (pe), "b" (xorVal), - "d" (me) - : "eax", "ecx" - ); - p = pe + 1; - } while (!done); - } - } +typedef struct { + ulong p1; + ulong p2; +} movinv1_ctx; + +STATIC void movinv1_init(ulong* start, + ulong len_dw, const void* vctx) { + const movinv1_ctx* ctx = (const movinv1_ctx*)vctx; + + ulong p1 = ctx->p1; + ulong* p = start; + + asm __volatile__ + ( + "rep\n\t" + "stosl\n\t" + : : "c" (len_dw), "D" (p), "a" (p1) + ); +} + +STATIC void movinv1_bottom_up(ulong* start, + ulong len_dw, const void* vctx) { + const movinv1_ctx* ctx = (const movinv1_ctx*)vctx; + ulong p1 = ctx->p1; + ulong p2 = ctx->p2; + ulong* p = start; + ulong* pe = p + (len_dw - 1); + + // Original C code replaced with hand tuned assembly code + // seems broken + /*for (; p <= pe; p++) { + if ((bad=*p) != p1) { + mt86_error((ulong*)p, p1, bad); + } + *p = p2; + }*/ + + asm __volatile__ + ( + "jmp L2\n\t" + ".p2align 4,,7\n\t" + "L0:\n\t" + "addl $4,%%edi\n\t" + "L2:\n\t" + "movl (%%edi),%%ecx\n\t" + "cmpl %%eax,%%ecx\n\t" + "jne L3\n\t" + "L5:\n\t" + "movl %%ebx,(%%edi)\n\t" + "cmpl %%edx,%%edi\n\t" + "jb L0\n\t" + "jmp L4\n" + + "L3:\n\t" + "pushl %%edx\n\t" + "pushl %%ebx\n\t" + "pushl %%ecx\n\t" + "pushl %%eax\n\t" + "pushl %%edi\n\t" + "call mt86_error\n\t" + "popl %%edi\n\t" + "popl %%eax\n\t" + "popl %%ecx\n\t" + "popl %%ebx\n\t" + "popl %%edx\n\t" + "jmp L5\n" + + "L4:\n\t" + :: "a" (p1), "D" (p), "d" (pe), "b" (p2) + : "ecx" + ); +} + +STATIC void movinv1_top_down(ulong* start, + ulong len_dw, const void* vctx) { + const movinv1_ctx* ctx = (const movinv1_ctx*)vctx; + ulong p1 = ctx->p1; + ulong p2 = ctx->p2; + ulong* p = start + (len_dw - 1); + ulong* pe = start; + + //Original C code replaced with hand tuned assembly code + // seems broken + /*do { + if ((bad=*p) != p2) { + mt86_error((ulong*)p, p2, bad); + } + *p = p1; + } while (--p >= pe);*/ + + asm __volatile__ + ( + "jmp L9\n\t" + ".p2align 4,,7\n\t" + "L11:\n\t" + "subl $4, %%edi\n\t" + "L9:\n\t" + "movl (%%edi),%%ecx\n\t" + "cmpl %%ebx,%%ecx\n\t" + "jne L6\n\t" + "L10:\n\t" + "movl %%eax,(%%edi)\n\t" + "cmpl %%edi, %%edx\n\t" + "jne L11\n\t" + "jmp L7\n\t" + + "L6:\n\t" + "pushl %%edx\n\t" + "pushl %%eax\n\t" + "pushl %%ecx\n\t" + "pushl %%ebx\n\t" + "pushl %%edi\n\t" + "call mt86_error\n\t" + "popl %%edi\n\t" + "popl %%ebx\n\t" + "popl %%ecx\n\t" + "popl %%eax\n\t" + "popl %%edx\n\t" + "jmp L10\n" + + "L7:\n\t" + :: "a" (p1), "D" (p), "d" (pe), "b" (p2) + : "ecx" + ); } /* * Test all of memory using a "moving inversions" algorithm using the - * pattern in p1 and it's complement in p2. + * pattern in p1 and its complement in p2. */ void movinv1 (int iter, ulong p1, ulong p2, int me) { - int i, j, done; - ulong *p, *pe, len, *start, *end; - - /* Display the current pattern */ - if (mstr_cpu == me) hprint(LINE_PAT, COL_PAT, p1); - - /* Initialize memory with the initial pattern. */ - for (j=0; j<segs; j++) { - calculate_chunk(&start, &end, me, j, 4); - - - pe = start; - p = start; - done = 0; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - len = pe - p + 1; - if (p == pe ) { - break; - } - - //Original C code replaced with hand tuned assembly code - // seems broken - /*for (; p <= pe; p++) { - *p = p1; - }*/ - - asm __volatile__ ( - "rep\n\t" \ - "stosl\n\t" - : : "c" (len), "D" (p), "a" (p1) - ); - - p = pe + 1; - } while (!done); - } - - /* Do moving inversions test. Check for initial pattern and then - * write the complement for each memory location. Test from bottom - * up and then from the top down. */ - for (i=0; i<iter; i++) { - for (j=0; j<segs; j++) { - calculate_chunk(&start, &end, me, j, 4); - pe = start; - p = start; - done = 0; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } - - // Original C code replaced with hand tuned assembly code - // seems broken - /*for (; p <= pe; p++) { - if ((bad=*p) != p1) { - error((ulong*)p, p1, bad); - } - *p = p2; - }*/ - - asm __volatile__ ( - "jmp L2\n\t" \ - ".p2align 4,,7\n\t" \ - "L0:\n\t" \ - "addl $4,%%edi\n\t" \ - "L2:\n\t" \ - "movl (%%edi),%%ecx\n\t" \ - "cmpl %%eax,%%ecx\n\t" \ - "jne L3\n\t" \ - "L5:\n\t" \ - "movl %%ebx,(%%edi)\n\t" \ - "cmpl %%edx,%%edi\n\t" \ - "jb L0\n\t" \ - "jmp L4\n" \ - - "L3:\n\t" \ - "pushl %%edx\n\t" \ - "pushl %%ebx\n\t" \ - "pushl %%ecx\n\t" \ - "pushl %%eax\n\t" \ - "pushl %%edi\n\t" \ - "call error\n\t" \ - "popl %%edi\n\t" \ - "popl %%eax\n\t" \ - "popl %%ecx\n\t" \ - "popl %%ebx\n\t" \ - "popl %%edx\n\t" \ - "jmp L5\n" \ - - "L4:\n\t" \ - :: "a" (p1), "D" (p), "d" (pe), "b" (p2) - : "ecx" - ); - p = pe + 1; - } while (!done); - } - for (j=segs-1; j>=0; j--) { - calculate_chunk(&start, &end, me, j, 4); - pe = end; - p = end; - done = 0; - do { - do_tick(me); - BAILR - - /* Check for underflow */ - if (pe - SPINSZ < pe && pe != 0) { - pe -= SPINSZ; - } else { - pe = start; - done++; - } - - /* Since we are using unsigned addresses a - * redundent check is required */ - if (pe < start || pe > end) { - pe = start; - done++; - } - if (p == pe ) { - break; - } - - //Original C code replaced with hand tuned assembly code - // seems broken - /*do { - if ((bad=*p) != p2) { - error((ulong*)p, p2, bad); - } - *p = p1; - } while (--p >= pe);*/ - - asm __volatile__ ( - "jmp L9\n\t" - ".p2align 4,,7\n\t" - "L11:\n\t" - "subl $4, %%edi\n\t" - "L9:\n\t" - "movl (%%edi),%%ecx\n\t" - "cmpl %%ebx,%%ecx\n\t" - "jne L6\n\t" - "L10:\n\t" - "movl %%eax,(%%edi)\n\t" - "cmpl %%edi, %%edx\n\t" - "jne L11\n\t" - "jmp L7\n\t" - - "L6:\n\t" - "pushl %%edx\n\t" - "pushl %%eax\n\t" - "pushl %%ecx\n\t" - "pushl %%ebx\n\t" - "pushl %%edi\n\t" - "call error\n\t" - "popl %%edi\n\t" - "popl %%ebx\n\t" - "popl %%ecx\n\t" - "popl %%eax\n\t" - "popl %%edx\n\t" - "jmp L10\n" - - "L7:\n\t" - :: "a" (p1), "D" (p), "d" (pe), "b" (p2) - : "ecx" - ); - p = pe - 1; - } while (!done); - } - } + int i; + + /* Display the current pattern */ + if (mstr_cpu == me) hprint(LINE_PAT, COL_PAT, p1); + + movinv1_ctx ctx; + ctx.p1 = p1; + ctx.p2 = p2; + sliced_foreach_segment(&ctx, me, movinv1_init); + { BAILR } + + /* Do moving inversions test. Check for initial pattern and then + * write the complement for each memory location. Test from bottom + * up and then from the top down. */ + for (i=0; i<iter; i++) { + sliced_foreach_segment(&ctx, me, movinv1_bottom_up); + { BAILR } + + // NOTE(jcoiner): + // For the top-down pass, the original 5.01 code iterated over + // 'segs' in from n-1 down to 0, and then within each mapped segment, + // it would form the SPINSZ windows from the top down -- thus forming + // a different set of windows than the bottom-up pass, when the segment + // is not an integer number of windows. + // + // My guess is that this buys us very little additional coverage, that + // the value in going top-down happens at the word or cache-line level + // and that there's little to be gained from reversing the direction of + // the outer loops. So I'm leaving a 'direction' bit off of the + // foreach_segment() routines for now. + sliced_foreach_segment(&ctx, me, movinv1_top_down); + { BAILR } + } +} + +typedef struct { + ulong p1; + ulong lb; + ulong hb; + int sval; + int off; +} movinv32_ctx; + +STATIC void movinv32_init(ulong* restrict buf, + ulong len_dw, const void* vctx) { + const movinv32_ctx* restrict ctx = (const movinv32_ctx*)vctx; + + ulong* p = buf; + ulong* pe = buf + (len_dw - 1); + + int k = ctx->off; + ulong pat = ctx->p1; + ulong lb = ctx->lb; + int sval = ctx->sval; + + /* Original C code replaced with hand tuned assembly code + * while (p <= pe) { + * *p = pat; + * if (++k >= 32) { + * pat = lb; + * k = 0; + * } else { + * pat = pat << 1; + * pat |= sval; + * } + * p++; + * } + */ + asm __volatile__ + ( + "jmp L20\n\t" + ".p2align 4,,7\n\t" + "L923:\n\t" + "addl $4,%%edi\n\t" + "L20:\n\t" + "movl %%ecx,(%%edi)\n\t" + "addl $1,%%ebx\n\t" + "cmpl $32,%%ebx\n\t" + "jne L21\n\t" + "movl %%esi,%%ecx\n\t" + "xorl %%ebx,%%ebx\n\t" + "jmp L22\n" + "L21:\n\t" + "shll $1,%%ecx\n\t" + "orl %%eax,%%ecx\n\t" + "L22:\n\t" + "cmpl %%edx,%%edi\n\t" + "jb L923\n\t" + :: "D" (p),"d" (pe),"b" (k),"c" (pat), + "a" (sval), "S" (lb) + ); +} + +STATIC void movinv32_bottom_up(ulong* restrict buf, ulong len_dw, + const void* vctx) { + const movinv32_ctx* restrict ctx = (const movinv32_ctx*)vctx; + + ulong* p = buf; + ulong* pe = buf + (len_dw - 1); + + int k = ctx->off; + ulong pat = ctx->p1; + ulong lb = ctx->lb; + int sval = ctx->sval; + + /* Original C code replaced with hand tuned assembly code + * while (1) { + * if ((bad=*p) != pat) { + * mt86_error((ulong*)p, pat, bad); + * } + * *p = ~pat; + * if (p >= pe) break; + * p++; + * + * if (++k >= 32) { + * pat = lb; + * k = 0; + * } else { + * pat = pat << 1; + * pat |= sval; + * } + * } + */ + asm __volatile__ + ( + "pushl %%ebp\n\t" + "jmp L30\n\t" + ".p2align 4,,7\n\t" + "L930:\n\t" + "addl $4,%%edi\n\t" + "L30:\n\t" + "movl (%%edi),%%ebp\n\t" + "cmpl %%ecx,%%ebp\n\t" + "jne L34\n\t" + + "L35:\n\t" + "notl %%ecx\n\t" + "movl %%ecx,(%%edi)\n\t" + "notl %%ecx\n\t" + "incl %%ebx\n\t" + "cmpl $32,%%ebx\n\t" + "jne L31\n\t" + "movl %%esi,%%ecx\n\t" + "xorl %%ebx,%%ebx\n\t" + "jmp L32\n" + "L31:\n\t" + "shll $1,%%ecx\n\t" + "orl %%eax,%%ecx\n\t" + "L32:\n\t" + "cmpl %%edx,%%edi\n\t" + "jb L930\n\t" + "jmp L33\n\t" + + "L34:\n\t" + "pushl %%esi\n\t" + "pushl %%eax\n\t" + "pushl %%ebx\n\t" + "pushl %%edx\n\t" + "pushl %%ebp\n\t" + "pushl %%ecx\n\t" + "pushl %%edi\n\t" + "call mt86_error\n\t" + "popl %%edi\n\t" + "popl %%ecx\n\t" + "popl %%ebp\n\t" + "popl %%edx\n\t" + "popl %%ebx\n\t" + "popl %%eax\n\t" + "popl %%esi\n\t" + "jmp L35\n" + + "L33:\n\t" + "popl %%ebp\n\t" + : "=b" (k),"=c" (pat) + : "D" (p),"d" (pe),"b" (k),"c" (pat), + "a" (sval), "S" (lb) + ); +} + +STATIC void movinv32_top_down(ulong* restrict buf, + ulong len_dw, const void* vctx) { + const movinv32_ctx* restrict ctx = (const movinv32_ctx*)vctx; + + ulong* pe = buf; + ulong* p = buf + (len_dw - 1); + + int k = ctx->off; + ulong pat = ctx->p1; + ulong hb = ctx->hb; + int sval = ctx->sval; + ulong p3 = (ulong)sval << 31; + + // Advance 'k' and 'pat' to where they would have been + // at the end of the corresponding bottom_up segment. + // + // The '-1' is because we didn't advance 'k' or 'pat' + // on the final bottom_up loop, so they're off by one... + ulong mod_len = (len_dw - 1) % 32; + for (int i = 0; i < mod_len; i++) { + if (++k >= 32) { + pat = ctx->lb; + k = 0; + } else { + pat = pat << 1; + pat |= sval; + } + } + + // Increment 'k' only because the code below has an off-by-one + // interpretation of 'k' relative to the bottom_up routine. + // There it ranges from 0:31, and here it ranges from 1:32. + k++; + + /* Original C code replaced with hand tuned assembly code */ +#if PREFER_C + ulong bad; + while(1) { + if ((bad=*p) != ~pat) { + mt86_error((ulong*)p, ~pat, bad); + } + *p = pat; + if (p <= pe) break; + p--; + + if (--k <= 0) { + k = 32; + pat = hb; + } else { + pat = pat >> 1; + pat |= p3; + } + }; +#else + asm __volatile__ + ( + "pushl %%ebp\n\t" + "jmp L40\n\t" + ".p2align 4,,7\n\t" + "L49:\n\t" + "subl $4,%%edi\n\t" + "L40:\n\t" + "movl (%%edi),%%ebp\n\t" + "notl %%ecx\n\t" + "cmpl %%ecx,%%ebp\n\t" + "jne L44\n\t" + + "L45:\n\t" + "notl %%ecx\n\t" + "movl %%ecx,(%%edi)\n\t" + "decl %%ebx\n\t" + "cmpl $0,%%ebx\n\t" + "jg L41\n\t" + "movl %%esi,%%ecx\n\t" + "movl $32,%%ebx\n\t" + "jmp L42\n" + "L41:\n\t" + "shrl $1,%%ecx\n\t" + "orl %%eax,%%ecx\n\t" + "L42:\n\t" + "cmpl %%edx,%%edi\n\t" + "ja L49\n\t" + "jmp L43\n\t" + + "L44:\n\t" + "pushl %%esi\n\t" + "pushl %%eax\n\t" + "pushl %%ebx\n\t" + "pushl %%edx\n\t" + "pushl %%ebp\n\t" + "pushl %%ecx\n\t" + "pushl %%edi\n\t" + "call mt86_error\n\t" + "popl %%edi\n\t" + "popl %%ecx\n\t" + "popl %%ebp\n\t" + "popl %%edx\n\t" + "popl %%ebx\n\t" + "popl %%eax\n\t" + "popl %%esi\n\t" + "jmp L45\n" + + "L43:\n\t" + "popl %%ebp\n\t" + : : "D" (p),"d" (pe),"b" (k),"c" (pat), + "a" (p3), "S" (hb) + ); +#endif } void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off,int me) { - int i, j, k=0, n=0, done; - ulong *p, *pe, *start, *end, pat = 0, p3; - - p3 = sval << 31; - /* Display the current pattern */ - if (mstr_cpu == me) hprint(LINE_PAT, COL_PAT, p1); - - /* Initialize memory with the initial pattern. */ - for (j=0; j<segs; j++) { - calculate_chunk(&start, &end, me, j, 64); - pe = start; - p = start; - done = 0; - k = off; - pat = p1; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } - /* Do a SPINSZ section of memory */ -/* Original C code replaced with hand tuned assembly code - * while (p <= pe) { - * *p = pat; - * if (++k >= 32) { - * pat = lb; - * k = 0; - * } else { - * pat = pat << 1; - * pat |= sval; - * } - * p++; - * } - */ - asm __volatile__ ( - "jmp L20\n\t" - ".p2align 4,,7\n\t" - "L923:\n\t" - "addl $4,%%edi\n\t" - "L20:\n\t" - "movl %%ecx,(%%edi)\n\t" - "addl $1,%%ebx\n\t" - "cmpl $32,%%ebx\n\t" - "jne L21\n\t" - "movl %%esi,%%ecx\n\t" - "xorl %%ebx,%%ebx\n\t" - "jmp L22\n" - "L21:\n\t" - "shll $1,%%ecx\n\t" - "orl %%eax,%%ecx\n\t" - "L22:\n\t" - "cmpl %%edx,%%edi\n\t" - "jb L923\n\t" - : "=b" (k), "=c" (pat) - : "D" (p),"d" (pe),"b" (k),"c" (pat), - "a" (sval), "S" (lb) - ); - p = pe + 1; - } while (!done); - } - - /* Do moving inversions test. Check for initial pattern and then - * write the complement for each memory location. Test from bottom - * up and then from the top down. */ - for (i=0; i<iter; i++) { - for (j=0; j<segs; j++) { - calculate_chunk(&start, &end, me, j, 64); - pe = start; - p = start; - done = 0; - k = off; - pat = p1; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } -/* Original C code replaced with hand tuned assembly code - * while (1) { - * if ((bad=*p) != pat) { - * error((ulong*)p, pat, bad); - * } - * *p = ~pat; - * if (p >= pe) break; - * p++; - * - * if (++k >= 32) { - * pat = lb; - * k = 0; - * } else { - * pat = pat << 1; - * pat |= sval; - * } - * } - */ - asm __volatile__ ( - "pushl %%ebp\n\t" - "jmp L30\n\t" - ".p2align 4,,7\n\t" - "L930:\n\t" - "addl $4,%%edi\n\t" - "L30:\n\t" - "movl (%%edi),%%ebp\n\t" - "cmpl %%ecx,%%ebp\n\t" - "jne L34\n\t" - - "L35:\n\t" - "notl %%ecx\n\t" - "movl %%ecx,(%%edi)\n\t" - "notl %%ecx\n\t" - "incl %%ebx\n\t" - "cmpl $32,%%ebx\n\t" - "jne L31\n\t" - "movl %%esi,%%ecx\n\t" - "xorl %%ebx,%%ebx\n\t" - "jmp L32\n" - "L31:\n\t" - "shll $1,%%ecx\n\t" - "orl %%eax,%%ecx\n\t" - "L32:\n\t" - "cmpl %%edx,%%edi\n\t" - "jb L930\n\t" - "jmp L33\n\t" - - "L34:\n\t" \ - "pushl %%esi\n\t" - "pushl %%eax\n\t" - "pushl %%ebx\n\t" - "pushl %%edx\n\t" - "pushl %%ebp\n\t" - "pushl %%ecx\n\t" - "pushl %%edi\n\t" - "call error\n\t" - "popl %%edi\n\t" - "popl %%ecx\n\t" - "popl %%ebp\n\t" - "popl %%edx\n\t" - "popl %%ebx\n\t" - "popl %%eax\n\t" - "popl %%esi\n\t" - "jmp L35\n" - - "L33:\n\t" - "popl %%ebp\n\t" - : "=b" (k),"=c" (pat) - : "D" (p),"d" (pe),"b" (k),"c" (pat), - "a" (sval), "S" (lb) - ); - p = pe + 1; - } while (!done); - } - - if (--k < 0) { - k = 31; - } - for (pat = lb, n = 0; n < k; n++) { - pat = pat << 1; - pat |= sval; - } - k++; - - for (j=segs-1; j>=0; j--) { - calculate_chunk(&start, &end, me, j, 64); - p = end; - pe = end; - done = 0; - do { - do_tick(me); - BAILR - - /* Check for underflow */ - if (pe - SPINSZ < pe && pe != 0) { - pe -= SPINSZ; - } else { - pe = start; - done++; - } - /* We need this redundant check because we are - * using unsigned longs for the address. - */ - if (pe < start || pe > end) { - pe = start; - done++; - } - if (p == pe ) { - break; - } -/* Original C code replaced with hand tuned assembly code - * while(1) { - * if ((bad=*p) != ~pat) { - * error((ulong*)p, ~pat, bad); - * } - * *p = pat; - if (p >= pe) break; - p++; - * if (--k <= 0) { - * pat = hb; - * k = 32; - * } else { - * pat = pat >> 1; - * pat |= p3; - * } - * }; - */ - asm __volatile__ ( - "pushl %%ebp\n\t" - "jmp L40\n\t" - ".p2align 4,,7\n\t" - "L49:\n\t" - "subl $4,%%edi\n\t" - "L40:\n\t" - "movl (%%edi),%%ebp\n\t" - "notl %%ecx\n\t" - "cmpl %%ecx,%%ebp\n\t" - "jne L44\n\t" - - "L45:\n\t" - "notl %%ecx\n\t" - "movl %%ecx,(%%edi)\n\t" - "decl %%ebx\n\t" - "cmpl $0,%%ebx\n\t" - "jg L41\n\t" - "movl %%esi,%%ecx\n\t" - "movl $32,%%ebx\n\t" - "jmp L42\n" - "L41:\n\t" - "shrl $1,%%ecx\n\t" - "orl %%eax,%%ecx\n\t" - "L42:\n\t" - "cmpl %%edx,%%edi\n\t" - "ja L49\n\t" - "jmp L43\n\t" - - "L44:\n\t" \ - "pushl %%esi\n\t" - "pushl %%eax\n\t" - "pushl %%ebx\n\t" - "pushl %%edx\n\t" - "pushl %%ebp\n\t" - "pushl %%ecx\n\t" - "pushl %%edi\n\t" - "call error\n\t" - "popl %%edi\n\t" - "popl %%ecx\n\t" - "popl %%ebp\n\t" - "popl %%edx\n\t" - "popl %%ebx\n\t" - "popl %%eax\n\t" - "popl %%esi\n\t" - "jmp L45\n" - - "L43:\n\t" - "popl %%ebp\n\t" - : "=b" (k), "=c" (pat) - : "D" (p),"d" (pe),"b" (k),"c" (pat), - "a" (p3), "S" (hb) - ); - p = pe - 1; - } while (!done); - } - } + // First callsite: + // - p1 has 1 bit set (somewhere) + // - lb = 1 ("low bit") + // - hb = 0x80000000 ("high bit") + // - sval = 0 + // - 'off' indicates the position of the set bit in p1 + // + // Second callsite is the same, but inverted: + // - p1 has 1 bit clear (somewhere) + // - lb = 0xfffffffe + // - hb = 0x7fffffff + // - sval = 1 + // - 'off' indicates the position of the cleared bit in p1 + + movinv32_ctx ctx; + ctx.p1 = p1; + ctx.lb = lb; + ctx.hb = hb; + ctx.sval = sval; + ctx.off = off; + + /* Display the current pattern */ + if (mstr_cpu == me) hprint(LINE_PAT, COL_PAT, p1); + + sliced_foreach_segment(&ctx, me, movinv32_init); + { BAILR } + + /* Do moving inversions test. Check for initial pattern and then + * write the complement for each memory location. Test from bottom + * up and then from the top down. */ + for (int i=0; i<iter; i++) { + sliced_foreach_segment(&ctx, me, movinv32_bottom_up); + { BAILR } + + sliced_foreach_segment(&ctx, me, movinv32_top_down); + { BAILR } + } +} + +typedef struct { + int offset; + ulong p1; + ulong p2; +} modtst_ctx; + +STATIC void modtst_sparse_writes(ulong* restrict start, + ulong len_dw, const void* vctx) { + const modtst_ctx* restrict ctx = (const modtst_ctx*)vctx; + ulong p1 = ctx->p1; + ulong offset = ctx->offset; + +#if PREFER_C + for (ulong i = offset; i < len_dw; i += MOD_SZ) { + start[i] = p1; + } +#else + ulong* p = start + offset; + ulong* pe = start + len_dw; + asm __volatile__ + ( + "jmp L60\n\t" + ".p2align 4,,7\n\t" + + "L60:\n\t" + "movl %%eax,(%%edi)\n\t" + "addl $80,%%edi\n\t" + "cmpl %%edx,%%edi\n\t" + "jb L60\n\t" + :: "D" (p), "d" (pe), "a" (p1) + ); +#endif +} + +STATIC void modtst_dense_writes(ulong* restrict start, ulong len_dw, + const void* vctx) { + const modtst_ctx* restrict ctx = (const modtst_ctx*)vctx; + ulong p2 = ctx->p2; + ulong offset = ctx->offset; + + ASSERT(offset < MOD_SZ); + + ulong k = 0; +#if PREFER_C + for (ulong i = 0; i < len_dw; i++) { + if (k != offset) { + start[i] = p2; + } + if (++k >= MOD_SZ) { + k = 0; + } + } +#else + ulong* pe = start + (len_dw - 1); + asm __volatile__ + ( + "jmp L50\n\t" + ".p2align 4,,7\n\t" + + "L54:\n\t" + "addl $4,%%edi\n\t" + "L50:\n\t" + "cmpl %%ebx,%%ecx\n\t" + "je L52\n\t" + "movl %%eax,(%%edi)\n\t" + "L52:\n\t" + "incl %%ebx\n\t" + "cmpl $19,%%ebx\n\t" + "jle L53\n\t" + "xorl %%ebx,%%ebx\n\t" + "L53:\n\t" + "cmpl %%edx,%%edi\n\t" + "jb L54\n\t" + : : "D" (start), "d" (pe), "a" (p2), + "b" (k), "c" (offset) + ); +#endif +} + +STATIC void modtst_check(ulong* restrict start, + ulong len_dw, const void* vctx) { + const modtst_ctx* restrict ctx = (const modtst_ctx*)vctx; + ulong p1 = ctx->p1; + ulong offset = ctx->offset; + + ASSERT(offset < MOD_SZ); + +#if PREFER_C + ulong bad; + for (ulong i = offset; i < len_dw; i += MOD_SZ) { + if ((bad = start[i]) != p1) + mt86_error(start + i, p1, bad); + } +#else + ulong* p = start + offset; + ulong* pe = start + len_dw; + asm __volatile__ + ( + "jmp L70\n\t" + ".p2align 4,,7\n\t" + + "L70:\n\t" + "movl (%%edi),%%ecx\n\t" + "cmpl %%eax,%%ecx\n\t" + "jne L71\n\t" + "L72:\n\t" + "addl $80,%%edi\n\t" + "cmpl %%edx,%%edi\n\t" + "jb L70\n\t" + "jmp L73\n\t" + + "L71:\n\t" + "pushl %%edx\n\t" + "pushl %%ecx\n\t" + "pushl %%eax\n\t" + "pushl %%edi\n\t" + "call mt86_error\n\t" + "popl %%edi\n\t" + "popl %%eax\n\t" + "popl %%ecx\n\t" + "popl %%edx\n\t" + "jmp L72\n" + + "L73:\n\t" + : : "D" (p), "d" (pe), "a" (p1) + : "ecx" + ); +#endif } /* @@ -984,188 +1084,317 @@ void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off,int me) */ void modtst(int offset, int iter, ulong p1, ulong p2, int me) { - int j, k, l, done; - ulong *p; - ulong *pe; - ulong *start, *end; - - /* Display the current pattern */ - if (mstr_cpu == me) { - hprint(LINE_PAT, COL_PAT-2, p1); - cprint(LINE_PAT, COL_PAT+6, "-"); - dprint(LINE_PAT, COL_PAT+7, offset, 2, 1); - } - - /* Write every nth location with pattern */ - for (j=0; j<segs; j++) { - calculate_chunk(&start, &end, me, j, 4); - end -= MOD_SZ; /* adjust the ending address */ - pe = (ulong *)start; - p = start+offset; - done = 0; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } -/* Original C code replaced with hand tuned assembly code - * for (; p <= pe; p += MOD_SZ) { - * *p = p1; - * } - */ - asm __volatile__ ( - "jmp L60\n\t" \ - ".p2align 4,,7\n\t" \ - - "L60:\n\t" \ - "movl %%eax,(%%edi)\n\t" \ - "addl $80,%%edi\n\t" \ - "cmpl %%edx,%%edi\n\t" \ - "jb L60\n\t" \ - : "=D" (p) - : "D" (p), "d" (pe), "a" (p1) - ); - } while (!done); - } - - /* Write the rest of memory "iter" times with the pattern complement */ - for (l=0; l<iter; l++) { - for (j=0; j<segs; j++) { - calculate_chunk(&start, &end, me, j, 4); - pe = (ulong *)start; - p = start; - done = 0; - k = 0; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } -/* Original C code replaced with hand tuned assembly code - * for (; p <= pe; p++) { - * if (k != offset) { - * *p = p2; - * } - * if (++k > MOD_SZ-1) { - * k = 0; - * } - * } - */ - asm __volatile__ ( - "jmp L50\n\t" \ - ".p2align 4,,7\n\t" \ - - "L54:\n\t" \ - "addl $4,%%edi\n\t" \ - "L50:\n\t" \ - "cmpl %%ebx,%%ecx\n\t" \ - "je L52\n\t" \ - "movl %%eax,(%%edi)\n\t" \ - "L52:\n\t" \ - "incl %%ebx\n\t" \ - "cmpl $19,%%ebx\n\t" \ - "jle L53\n\t" \ - "xorl %%ebx,%%ebx\n\t" \ - "L53:\n\t" \ - "cmpl %%edx,%%edi\n\t" \ - "jb L54\n\t" \ - : "=b" (k) - : "D" (p), "d" (pe), "a" (p2), - "b" (k), "c" (offset) - ); - p = pe + 1; - } while (!done); - } - } - - /* Now check every nth location */ - for (j=0; j<segs; j++) { - calculate_chunk(&start, &end, me, j, 4); - pe = (ulong *)start; - p = start+offset; - done = 0; - end -= MOD_SZ; /* adjust the ending address */ - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } -/* Original C code replaced with hand tuned assembly code - * for (; p <= pe; p += MOD_SZ) { - * if ((bad=*p) != p1) { - * error((ulong*)p, p1, bad); - * } - * } - */ - asm __volatile__ ( - "jmp L70\n\t" \ - ".p2align 4,,7\n\t" \ - - "L70:\n\t" \ - "movl (%%edi),%%ecx\n\t" \ - "cmpl %%eax,%%ecx\n\t" \ - "jne L71\n\t" \ - "L72:\n\t" \ - "addl $80,%%edi\n\t" \ - "cmpl %%edx,%%edi\n\t" \ - "jb L70\n\t" \ - "jmp L73\n\t" \ - - "L71:\n\t" \ - "pushl %%edx\n\t" - "pushl %%ecx\n\t" - "pushl %%eax\n\t" - "pushl %%edi\n\t" - "call error\n\t" - "popl %%edi\n\t" - "popl %%eax\n\t" - "popl %%ecx\n\t" - "popl %%edx\n\t" - "jmp L72\n" - - "L73:\n\t" \ - : "=D" (p) - : "D" (p), "d" (pe), "a" (p1) - : "ecx" - ); - } while (!done); - } + modtst_ctx ctx; + ctx.offset = offset; + ctx.p1 = p1; + ctx.p2 = p2; + + /* Display the current pattern */ + if (mstr_cpu == me) { + hprint(LINE_PAT, COL_PAT-2, p1); + cprint(LINE_PAT, COL_PAT+6, "-"); + dprint(LINE_PAT, COL_PAT+7, offset, 2, 1); + } + + /* Write every nth location with pattern */ + sliced_foreach_segment(&ctx, me, modtst_sparse_writes); + { BAILR } + + /* Write the rest of memory "iter" times with the pattern complement */ + for (ulong i=0; i<iter; i++) { + sliced_foreach_segment(&ctx, me, modtst_dense_writes); + { BAILR } + } + + /* Now check every nth location */ + sliced_foreach_segment(&ctx, me, modtst_check); +} + +#if PREFER_C + +STATIC void movsl(ulong* dest, + ulong* src, + ulong size_in_dwords) { + /* Logically equivalent to: + + for (ulong i = 0; i < size_in_dwords; i++) + dest[i] = src[i]; + + However: the movsl instruction does the entire loop + in one instruction -- this is probably how 'memcpy' + is implemented -- so hardware makes it very fast. + + Even in PREFER_C mode, we want the brute force of movsl! + */ + asm __volatile__ + ( + "cld\n" + "jmp L1189\n\t" + + ".p2align 4,,7\n\t" + "L1189:\n\t" + + "movl %1,%%edi\n\t" // dest + "movl %0,%%esi\n\t" // src + "movl %2,%%ecx\n\t" // len in dwords + "rep\n\t" + "movsl\n\t" + + :: "g" (src), "g" (dest), "g" (size_in_dwords) + : "edi", "esi", "ecx" + ); +} +#endif // PREFER_C + +STATIC ulong block_move_normalize_len_dw(ulong len_dw) { + // The block_move test works with sets of 64-byte blocks, + // so ensure our total length is a multiple of 64. + // + // In fact, since we divide the region in half, and each half-region + // is a set of 64-byte blocks, the full region should be a multiple of 128 + // bytes. + // + // Note that there's no requirement for the start address of the region to + // be 64-byte aligned, it can be any dword. + ulong result = (len_dw >> 5) << 5; + ASSERT(result > 0); + return result; +} + +STATIC void block_move_init(ulong* restrict buf, + ulong len_dw, const void* unused_ctx) { + len_dw = block_move_normalize_len_dw(len_dw); + + // Compute 'len' in units of 64-byte chunks: + ulong len = len_dw >> 4; + + // We only need to initialize len/2, since we'll just copy + // the first half onto the second half in the move step. + len = len >> 1; + + ulong base_val = 1; +#if PREFER_C + while(len > 0) { + ulong neg_val = ~base_val; + + // Set a block of 64 bytes // first block DWORDS are: + buf[0] = base_val; // 0x00000001 + buf[1] = base_val; // 0x00000001 + buf[2] = base_val; // 0x00000001 + buf[3] = base_val; // 0x00000001 + buf[4] = neg_val; // 0xfffffffe + buf[5] = neg_val; // 0xfffffffe + buf[6] = base_val; // 0x00000001 + buf[7] = base_val; // 0x00000001 + buf[8] = base_val; // 0x00000001 + buf[9] = base_val; // 0x00000001 + buf[10] = neg_val; // 0xfffffffe + buf[11] = neg_val; // 0xfffffffe + buf[12] = base_val; // 0x00000001 + buf[13] = base_val; // 0x00000001 + buf[14] = neg_val; // 0xfffffffe + buf[15] = neg_val; // 0xfffffffe + + buf += 16; // advance to next 64-byte block + len--; + + // Rotate the bit left, including an all-zero state. + // It can't hurt to have a periodicity of 33 instead of + // a power of two. + if (base_val == 0) { + base_val = 1; + } else if (base_val & 0x80000000) { + base_val = 0; + } else { + base_val = base_val << 1; + } + } +#else + asm __volatile__ + ( + "jmp L100\n\t" + + ".p2align 4,,7\n\t" + "L100:\n\t" + + // First loop eax is 0x00000001, edx is 0xfffffffe + "movl %%eax, %%edx\n\t" + "notl %%edx\n\t" + + // Set a block of 64-bytes // First loop DWORDS are + "movl %%eax,0(%%edi)\n\t" // 0x00000001 + "movl %%eax,4(%%edi)\n\t" // 0x00000001 + "movl %%eax,8(%%edi)\n\t" // 0x00000001 + "movl %%eax,12(%%edi)\n\t" // 0x00000001 + "movl %%edx,16(%%edi)\n\t" // 0xfffffffe + "movl %%edx,20(%%edi)\n\t" // 0xfffffffe + "movl %%eax,24(%%edi)\n\t" // 0x00000001 + "movl %%eax,28(%%edi)\n\t" // 0x00000001 + "movl %%eax,32(%%edi)\n\t" // 0x00000001 + "movl %%eax,36(%%edi)\n\t" // 0x00000001 + "movl %%edx,40(%%edi)\n\t" // 0xfffffffe + "movl %%edx,44(%%edi)\n\t" // 0xfffffffe + "movl %%eax,48(%%edi)\n\t" // 0x00000001 + "movl %%eax,52(%%edi)\n\t" // 0x00000001 + "movl %%edx,56(%%edi)\n\t" // 0xfffffffe + "movl %%edx,60(%%edi)\n\t" // 0xfffffffe + + // rotate left with carry, + // second loop eax is 0x00000002 + // second loop edx is (~eax) 0xfffffffd + "rcll $1, %%eax\n\t" + + // Move current position forward 64-bytes (to start of next block) + "leal 64(%%edi), %%edi\n\t" + + // Loop until end + "decl %%ecx\n\t" + "jnz L100\n\t" + + : : "D" (buf), "c" (len), "a" (base_val) + : "edx" + ); +#endif +} + +typedef struct { + int iter; + int me; +} block_move_ctx; + +STATIC void block_move_move(ulong* restrict buf, + ulong len_dw, const void* vctx) { + const block_move_ctx* restrict ctx = (const block_move_ctx*)vctx; + ulong iter = ctx->iter; + int me = ctx->me; + + len_dw = block_move_normalize_len_dw(len_dw); + + /* Now move the data around + * First move the data up half of the segment size we are testing + * Then move the data to the original location + 32 bytes + */ + ulong half_len_dw = len_dw / 2; // Half the size of this block in DWORDS + ASSERT(half_len_dw > 8); + + ulong* mid = buf + half_len_dw; // VA at mid-point of this block. + for (int i=0; i<iter; i++) { + if (i > 0) { + // foreach_segment() called this before the 0th iteration, + // so don't tick twice in quick succession. + do_tick(me); + } + { BAILR } + +#if PREFER_C + // Move first half to 2nd half: + movsl(/*dest=*/ mid, /*src=*/ buf, half_len_dw); + + // Move the second half, less the last 8 dwords + // to the first half plus an offset of 8 dwords. + movsl(/*dest=*/ buf + 8, /*src=*/ mid, half_len_dw - 8); + + // Finally, move the last 8 dwords of the 2nd half + // to the first 8 dwords of the first half. + movsl(/*dest=*/ mid + half_len_dw - 8, /*src=*/ buf, 8); +#else + asm __volatile__ + ( + "cld\n" + "jmp L110\n\t" + + ".p2align 4,,7\n\t" + "L110:\n\t" + + // + // At the end of all this + // - the second half equals the inital value of the first half + // - the first half is right shifted 32-bytes (with wrapping) + // + + // Move first half to second half + "movl %1,%%edi\n\t" // Destination 'mid' (mid point) + "movl %0,%%esi\n\t" // Source, 'buf' (start point) + "movl %2,%%ecx\n\t" // Length, 'half_len_dw' (size of a half in DWORDS) + "rep\n\t" + "movsl\n\t" + + // Move the second half, less the last 32-bytes. To the first half, offset plus 32-bytes + "movl %0,%%edi\n\t" + "addl $32,%%edi\n\t" // Destination 'buf' plus 32 bytes + "movl %1,%%esi\n\t" // Source, 'mid' + "movl %2,%%ecx\n\t" + "subl $8,%%ecx\n\t" // Length, 'half_len_dw' + "rep\n\t" + "movsl\n\t" + + // Move last 8 DWORDS (32-bytes) of the second half to the start of the first half + "movl %0,%%edi\n\t" // Destination 'buf' + // Source, 8 DWORDS from the end of the second half, left over by the last rep/movsl + "movl $8,%%ecx\n\t" // Length, 8 DWORDS (32-bytes) + "rep\n\t" + "movsl\n\t" + + :: "g" (buf), "g" (mid), "g" (half_len_dw) + : "edi", "esi", "ecx" + ); +#endif + } +} + +STATIC void block_move_check(ulong* restrict buf, + ulong len_dw, const void* unused_ctx) { + len_dw = block_move_normalize_len_dw(len_dw); + + /* Now check the data. + * This is rather crude, we just check that the + * adjacent words are the same. + */ +#if PREFER_C + for (ulong i = 0; i < len_dw; i = i + 2) { + if (buf[i] != buf[i+1]) { + mt86_error(buf+i, buf[i], buf[i+1]); + } + } +#else + ulong* pe = buf + (len_dw - 2); + asm __volatile__ + ( + "jmp L120\n\t" + + ".p2align 4,,7\n\t" + "L124:\n\t" + "addl $8,%%edi\n\t" // Next QWORD + "L120:\n\t" + + // Compare adjacent DWORDS + "movl (%%edi),%%ecx\n\t" + "cmpl 4(%%edi),%%ecx\n\t" + "jnz L121\n\t" // Print error if they don't match + + // Loop until end of block + "L122:\n\t" + "cmpl %%edx,%%edi\n\t" + "jb L124\n" + "jmp L123\n\t" + + "L121:\n\t" + // eax not used so we don't need to save it as per cdecl + // ecx is used but not restored, however we don't need it's value anymore after this point + "pushl %%edx\n\t" + "pushl 4(%%edi)\n\t" + "pushl %%ecx\n\t" + "pushl %%edi\n\t" + "call mt86_error\n\t" + "popl %%edi\n\t" + "addl $8,%%esp\n\t" + "popl %%edx\n\t" + "jmp L122\n" + "L123:\n\t" + :: "D" (buf), "d" (pe) + : "ecx" + ); +#endif } /* @@ -1174,237 +1403,38 @@ void modtst(int offset, int iter, ulong p1, ulong p2, int me) */ void block_move(int iter, int me) { - int i, j, done; - ulong len; - ulong *p, *pe, pp; - ulong *start, *end; - - cprint(LINE_PAT, COL_PAT-2, " "); - - /* Initialize memory with the initial pattern. */ - for (j=0; j<segs; j++) { - calculate_chunk(&start, &end, me, j, 64); - - // end is always xxxxxffc, so increment so that length calculations are correct - end = end + 1; - - pe = start; - p = start; - - done = 0; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } - len = ((ulong)pe - (ulong)p) / 64; - //len++; - asm __volatile__ ( - "jmp L100\n\t" - - ".p2align 4,,7\n\t" - "L100:\n\t" - - // First loop eax is 0x00000001, edx is 0xfffffffe - "movl %%eax, %%edx\n\t" - "notl %%edx\n\t" - - // Set a block of 64-bytes // First loop DWORDS are - "movl %%eax,0(%%edi)\n\t" // 0x00000001 - "movl %%eax,4(%%edi)\n\t" // 0x00000001 - "movl %%eax,8(%%edi)\n\t" // 0x00000001 - "movl %%eax,12(%%edi)\n\t" // 0x00000001 - "movl %%edx,16(%%edi)\n\t" // 0xfffffffe - "movl %%edx,20(%%edi)\n\t" // 0xfffffffe - "movl %%eax,24(%%edi)\n\t" // 0x00000001 - "movl %%eax,28(%%edi)\n\t" // 0x00000001 - "movl %%eax,32(%%edi)\n\t" // 0x00000001 - "movl %%eax,36(%%edi)\n\t" // 0x00000001 - "movl %%edx,40(%%edi)\n\t" // 0xfffffffe - "movl %%edx,44(%%edi)\n\t" // 0xfffffffe - "movl %%eax,48(%%edi)\n\t" // 0x00000001 - "movl %%eax,52(%%edi)\n\t" // 0x00000001 - "movl %%edx,56(%%edi)\n\t" // 0xfffffffe - "movl %%edx,60(%%edi)\n\t" // 0xfffffffe - - // rotate left with carry, - // second loop eax is 0x00000002 - // second loop edx is (~eax) 0xfffffffd - "rcll $1, %%eax\n\t" - - // Move current position forward 64-bytes (to start of next block) - "leal 64(%%edi), %%edi\n\t" - - // Loop until end - "decl %%ecx\n\t" - "jnz L100\n\t" - - : "=D" (p) - : "D" (p), "c" (len), "a" (1) - : "edx" - ); - } while (!done); - } - s_barrier(); - - /* Now move the data around - * First move the data up half of the segment size we are testing - * Then move the data to the original location + 32 bytes - */ - for (j=0; j<segs; j++) { - calculate_chunk(&start, &end, me, j, 64); - - // end is always xxxxxffc, so increment so that length calculations are correct - end = end + 1; - pe = start; - p = start; - done = 0; - - do { - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } - pp = (ulong)p + (((ulong)pe - (ulong)p) / 2); // Mid-point of this block - len = ((ulong)pe - (ulong)p) / 8; // Half the size of this block in DWORDS - for(i=0; i<iter; i++) { - do_tick(me); - BAILR - asm __volatile__ ( - "cld\n" - "jmp L110\n\t" - - ".p2align 4,,7\n\t" - "L110:\n\t" - - // - // At the end of all this - // - the second half equals the inital value of the first half - // - the first half is right shifted 32-bytes (with wrapping) - // - - // Move first half to second half - "movl %1,%%edi\n\t" // Destionation, pp (mid point) - "movl %0,%%esi\n\t" // Source, p (start point) - "movl %2,%%ecx\n\t" // Length, len (size of a half in DWORDS) - "rep\n\t" - "movsl\n\t" - - // Move the second half, less the last 32-bytes. To the first half, offset plus 32-bytes - "movl %0,%%edi\n\t" - "addl $32,%%edi\n\t" // Destination, p(start-point) plus 32 bytes - "movl %1,%%esi\n\t" // Source, pp(mid-point) - "movl %2,%%ecx\n\t" - "subl $8,%%ecx\n\t" // Length, len(size of a half in DWORDS) minus 8 DWORDS (32 bytes) - "rep\n\t" - "movsl\n\t" - - // Move last 8 DWORDS (32-bytes) of the second half to the start of the first half - "movl %0,%%edi\n\t" // Destination, p(start-point) - // Source, 8 DWORDS from the end of the second half, left over by the last rep/movsl - "movl $8,%%ecx\n\t" // Length, 8 DWORDS (32-bytes) - "rep\n\t" - "movsl\n\t" - - :: "g" (p), "g" (pp), "g" (len) - : "edi", "esi", "ecx" - ); - } - p = pe; - } while (!done); - } - s_barrier(); - - /* Now check the data - * The error checking is rather crude. We just check that the - * adjacent words are the same. - */ - for (j=0; j<segs; j++) { - calculate_chunk(&start, &end, me, j, 64); - - // end is always xxxxxffc, so increment so that length calculations are correct - end = end + 1; - pe = start; - p = start; - done = 0; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } - pe-=2; /* the last dwords to test are pe[0] and pe[1] */ - asm __volatile__ ( - "jmp L120\n\t" - - ".p2align 4,,7\n\t" - "L124:\n\t" - "addl $8,%%edi\n\t" // Next QWORD - "L120:\n\t" - - // Compare adjacent DWORDS - "movl (%%edi),%%ecx\n\t" - "cmpl 4(%%edi),%%ecx\n\t" - "jnz L121\n\t" // Print error if they don't match - - // Loop until end of block - "L122:\n\t" - "cmpl %%edx,%%edi\n\t" - "jb L124\n" - "jmp L123\n\t" - - "L121:\n\t" - // eax not used so we don't need to save it as per cdecl - // ecx is used but not restored, however we don't need it's value anymore after this point - "pushl %%edx\n\t" - "pushl 4(%%edi)\n\t" - "pushl %%ecx\n\t" - "pushl %%edi\n\t" - "call error\n\t" - "popl %%edi\n\t" - "addl $8,%%esp\n\t" - "popl %%edx\n\t" - "jmp L122\n" - "L123:\n\t" - : "=D" (p) - : "D" (p), "d" (pe) - : "ecx" - ); - } while (!done); - } + cprint(LINE_PAT, COL_PAT-2, " "); + + block_move_ctx ctx; + ctx.iter = iter; + ctx.me = me; + + /* Initialize memory with the initial pattern. */ + sliced_foreach_segment(&ctx, me, block_move_init); + { BAILR } + s_barrier(); + + /* Now move the data around */ + sliced_foreach_segment(&ctx, me, block_move_move); + { BAILR } + s_barrier(); + + /* And check it. */ + sliced_foreach_segment(&ctx, me, block_move_check); +} + +typedef struct { + ulong pat; +} bit_fade_ctx; + +STATIC void bit_fade_fill_seg(ulong* restrict p, + ulong len_dw, const void* vctx) { + const bit_fade_ctx* restrict ctx = (const bit_fade_ctx*)vctx; + ulong pat = ctx->pat; + + for (ulong i = 0; i < len_dw; i++) { + p[i] = pat; + } } /* @@ -1412,157 +1442,108 @@ void block_move(int iter, int me) */ void bit_fade_fill(ulong p1, int me) { - int j, done; - ulong *p, *pe; - ulong *start,*end; - - /* Display the current pattern */ - hprint(LINE_PAT, COL_PAT, p1); - - /* Initialize memory with the initial pattern. */ - for (j=0; j<segs; j++) { - start = v->map[j].start; - end = v->map[j].end; - pe = (ulong *)start; - p = start; - done = 0; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } - for (; p < pe;) { - *p = p1; - p++; - } - p = pe + 1; - } while (!done); - } -} + /* Display the current pattern */ + hprint(LINE_PAT, COL_PAT, p1); -void bit_fade_chk(ulong p1, int me) -{ - int j, done; - ulong *p, *pe, bad; - ulong *start,*end; - - /* Make sure that nothing changed while sleeping */ - for (j=0; j<segs; j++) { - start = v->map[j].start; - end = v->map[j].end; - pe = (ulong *)start; - p = start; - done = 0; - do { - do_tick(me); - BAILR - - /* Check for overflow */ - if (pe + SPINSZ > pe && pe != 0) { - pe += SPINSZ; - } else { - pe = end; - } - if (pe >= end) { - pe = end; - done++; - } - if (p == pe ) { - break; - } - for (; p < pe;) { - if ((bad=*p) != p1) { - error((ulong*)p, p1, bad); - } - p++; - } - p = pe + 1; - } while (!done); - } + /* Initialize memory with the initial pattern. */ + bit_fade_ctx ctx; + ctx.pat = p1; + unsliced_foreach_segment(&ctx, me, bit_fade_fill_seg); } +STATIC void bit_fade_chk_seg(ulong* restrict p, + ulong len_dw, const void* vctx) { + const bit_fade_ctx* restrict ctx = (const bit_fade_ctx*)vctx; + ulong pat = ctx->pat; + + for (ulong i = 0; i < len_dw; i++) { + ulong bad; + if ((bad=p[i]) != pat) { + mt86_error(p+i, pat, bad); + } + } +} +void bit_fade_chk(ulong p1, int me) +{ + bit_fade_ctx ctx; + ctx.pat = p1; + /* Make sure that nothing changed while sleeping */ + unsliced_foreach_segment(&ctx, me, bit_fade_chk_seg); +} /* Sleep for N seconds */ -void sleep(long n, int flag, int me, int sms) +void sleep(long n, int flag, int me, + int sms /* interpret 'n' as milliseconds instead */) { - ulong sh, sl, l, h, t, ip=0; - - /* save the starting time */ - asm __volatile__( - "rdtsc":"=a" (sl),"=d" (sh)); - - /* loop for n seconds */ - while (1) { - asm __volatile__( - "rep ; nop\n\t" - "rdtsc":"=a" (l),"=d" (h)); - asm __volatile__ ( - "subl %2,%0\n\t" - "sbbl %3,%1" - :"=a" (l), "=d" (h) - :"g" (sl), "g" (sh), - "0" (l), "1" (h)); - - if (sms != 0) { - t = h * ((unsigned)0xffffffff / v->clks_msec); - t += (l / v->clks_msec); - } else { - t = h * ((unsigned)0xffffffff / v->clks_msec) / 1000; - t += (l / v->clks_msec) / 1000; - } - - /* Is the time up? */ - if (t >= n) { - break; - } - - /* Only display elapsed time if flag is set */ - if (flag == 0) { - continue; - } - - if (t != ip) { - do_tick(me); - BAILR - ip = t; - } - } + ulong sh, sl, l, h, t, ip=0; + + /* save the starting time */ + asm __volatile__( + "rdtsc":"=a" (sl),"=d" (sh)); + + /* loop for n seconds */ + while (1) { + asm __volatile__( + "rep ; nop\n\t" + "rdtsc":"=a" (l),"=d" (h)); + asm __volatile__ ( + "subl %2,%0\n\t" + "sbbl %3,%1" + :"=a" (l), "=d" (h) + :"g" (sl), "g" (sh), + "0" (l), "1" (h)); + + if (sms != 0) { + t = h * ((unsigned)0xffffffff / vv->clks_msec); + t += (l / vv->clks_msec); + } else { + t = h * ((unsigned)0xffffffff / vv->clks_msec) / 1000; + t += (l / vv->clks_msec) / 1000; + } + + /* Is the time up? */ + if (t >= n) { + break; + } + + /* Only display elapsed time if flag is set */ + if (flag == 0) { + continue; + } + + if (t != ip) { + do_tick(me); + { BAILR } + ip = t; + } + } } -/* Beep function */ - void beep(unsigned int frequency) { - - unsigned int count = 1193180 / frequency; +#if 0 + // BOZO(jcoiner) + // Removed this, we need to define outb_p() and inb_p() + // before reintroducing it. +#else + unsigned int count = 1193180 / frequency; - // Switch on the speaker - outb_p(inb_p(0x61)|3, 0x61); + // Switch on the speaker + outb_p(inb_p(0x61)|3, 0x61); - // Set command for counter 2, 2 byte write - outb_p(0xB6, 0x43); + // Set command for counter 2, 2 byte write + outb_p(0xB6, 0x43); - // Select desired Hz - outb_p(count & 0xff, 0x42); - outb((count >> 8) & 0xff, 0x42); + // Select desired Hz + outb_p(count & 0xff, 0x42); + outb((count >> 8) & 0xff, 0x42); - // Block for 100 microseconds - sleep(100, 0, 0, 1); + // Block for 100 microseconds + sleep(100, 0, 0, 1); - // Switch off the speaker - outb(inb_p(0x61)&0xFC, 0x61); + // Switch off the speaker + outb(inb_p(0x61)&0xFC, 0x61); +#endif } @@ -22,26 +22,26 @@ #define E820_NVS 4 struct e820entry { - unsigned long long addr; /* start of memory segment */ - unsigned long long size; /* size of memory segment */ - unsigned long type; /* type of memory segment */ + unsigned long long addr; /* start of memory segment */ + unsigned long long size; /* size of memory segment */ + unsigned long type; /* type of memory segment */ }; struct mem_info_t { - unsigned long e88_mem_k; /* 0x00 */ - unsigned long e801_mem_k; /* 0x04 */ - unsigned long e820_nr; /* 0x08 */ - struct e820entry e820[E820MAX]; /* 0x0c */ - /* 0x28c */ + unsigned long e88_mem_k; /* 0x00 */ + unsigned long e801_mem_k; /* 0x04 */ + unsigned long e820_nr; /* 0x08 */ + struct e820entry e820[E820MAX]; /* 0x0c */ + /* 0x28c */ }; typedef unsigned long ulong; -#define STACKSIZE (8*1024) -#define MAX_MEM 0x7FF00000 /* 8 TB */ -#define WIN_SZ 0x80000 /* 2 GB */ -#define UNMAP_SZ (0x100000-WIN_SZ) /* Size of umappped first segment */ +#define STACKSIZE_BYTES (8*1024) +#define MAX_MEM_PAGES 0x7FF00000 /* 8 TB; units are 4K pages */ +#define WIN_SZ_PAGES 0x80000 /* 2 GB; units are 4K pages */ +#define UNMAP_SZ_PAGES (0x100000-WIN_SZ_PAGES) /* Size of unmapped first segment */ -#define SPINSZ 0x4000000 /* 256 MB */ +#define SPINSZ_DWORDS 0x4000000 /* 256 MB; units are dwords (32-bit words) */ #define MOD_SZ 20 #define BAILOUT if (bail) return(1); #define BAILR if (bail) return; @@ -106,11 +106,11 @@ typedef unsigned long ulong; #define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); }) -int memcmp(const void *s1, const void *s2, ulong count); -void *memmove(void *dest, const void *src, ulong n); -int strncmp(const char *s1, const char *s2, ulong n); -int strstr(char *str1, char *str2); -int strlen(char *string); +int mt86_memcmp(const void *s1, const void *s2, ulong count); +void *mt86_memmove(void *dest, const void *src, ulong n); +int mt86_strncmp(const char *s1, const char *s2, ulong n); +int mt86_strstr(char *str1, char *str2); +int mt86_strlen(char *string); int query_linuxbios(void); int query_pcbios(void); int insertaddress(ulong); @@ -136,7 +136,12 @@ void movinvr(int cpu); void movinv32(int iter, ulong p1, ulong lb, ulong mb, int sval, int off, int cpu); void modtst(int off, int iter, ulong p1, ulong p2, int cpu); -void error(ulong* adr, ulong good, ulong bad); +#define ASSERT(n) do { \ + if (!(n)) { \ + assert_fail(__FILE__, __LINE__); \ + } } while(0) +void assert_fail(const char* file, int line_no); +void mt86_error(ulong* adr, ulong good, ulong bad); void ad_err1(ulong *adr1, ulong *adr2, ulong good, ulong bad); void ad_err2(ulong *adr, ulong bad); void do_tick(); @@ -180,9 +185,9 @@ void clear_screen(void); void paging_off(void); void show_spd(void); int map_page(unsigned long page); -void *mapping(unsigned long page_address); -void *emapping(unsigned long page_address); -int isdigit(char c); +void *mapping(unsigned long phys_page); // get VA for a physical page +void *emapping(unsigned long phys_page); +int mt86_isdigit(char c); ulong memspeed(ulong src, ulong len, int iter); unsigned long page_of(void *ptr); ulong correct_tsc(ulong el_org); @@ -191,6 +196,25 @@ void bit_fade_chk(unsigned long n, int cpu); void find_ticks_for_pass(void); void beep(unsigned int frequency); +// Expose foreach_segment here for self_test, otherwise +// it would be local to test.c: +typedef void(*segment_fn)(ulong* start, // start address + ulong len_dw, // length of segment in dwords + const void* ctx); // any context data needed +void foreach_segment(ulong* start, ulong* end, + int me, const void* ctx, segment_fn func); + + +// In self-test, DEBUGF wraps libc's printf. +// In memtest standalone, printf will be a stub +// and 'vv->debugging' is false to avoid call overhead. +int printf(const char *format, ...); +#define DEBUGF(...) { \ + if (vv->debugging) { \ + printf(__VA_ARGS__); \ + } \ + } + #define PRINTMODE_SUMMARY 0 #define PRINTMODE_ADDRESSES 1 #define PRINTMODE_PATTERNS 2 @@ -205,62 +229,63 @@ struct pair { static inline void cache_off(void) { - asm( - "push %eax\n\t" - "movl %cr0,%eax\n\t" - "orl $0x40000000,%eax\n\t" /* Set CD */ - "movl %eax,%cr0\n\t" - "wbinvd\n\t" - "pop %eax\n\t"); + asm( + "push %eax\n\t" + "movl %cr0,%eax\n\t" + "orl $0x40000000,%eax\n\t" /* Set CD */ + "movl %eax,%cr0\n\t" + "wbinvd\n\t" + "pop %eax\n\t"); } static inline void cache_on(void) { - asm( - "push %eax\n\t" - "movl %cr0,%eax\n\t" - "andl $0x9fffffff,%eax\n\t" /* Clear CD and NW */ - "movl %eax,%cr0\n\t" - "pop %eax\n\t"); + asm( + "push %eax\n\t" + "movl %cr0,%eax\n\t" + "andl $0x9fffffff,%eax\n\t" /* Clear CD and NW */ + "movl %eax,%cr0\n\t" + "pop %eax\n\t"); } struct mmap { - ulong pbase_addr; - ulong *start; - ulong *end; + ulong pbase_addr; + ulong *start; // VA of segment start + ulong *end; // VA of the last dword within the segment. }; struct pmap { - ulong start; - ulong end; + ulong start; /* phys page number of RAM segment start, + in 4K pages. */ + ulong end; // phys page number (past the end? or inclusive?) }; struct tseq { - short sel; - short cpu_sel; - short pat; - short iter; - short errors; - char *msg; + short sel; // enabled + short cpu_sel; // cpu_sel == 0 indicates end of tseq[] array + short pat; // the test # + short iter; // # of iterations to run + short errors; // error count, updated as tests run + char *msg; }; struct xadr { - ulong page; - ulong offset; + ulong page; + ulong offset; }; struct err_info { - struct xadr low_addr; - struct xadr high_addr; - unsigned long ebits; - long tbits; - short min_bits; - short max_bits; - unsigned long maxl; - unsigned long eadr; - unsigned long exor; - unsigned long cor_err; - short hdr_flag; + struct xadr low_addr; + struct xadr high_addr; + unsigned long ebits; + long tbits; + short min_bits; + short max_bits; + unsigned long maxl; + unsigned long eadr; + unsigned long exor; + unsigned long cor_err; + short hdr_flag; }; @@ -269,46 +294,49 @@ struct err_info { #define MAX_MEM_SEGMENTS E820MAX -/* Define common variables accross relocations of memtest86 */ +/* Define common variables across relocations of memtest86 */ struct vars { - int pass; - int msg_line; - int ecount; - int ecc_ecount; - int msegs; - int testsel; - int scroll_start; - int pass_ticks; - int total_ticks; - int pptr; - int tptr; - struct err_info erri; - struct pmap pmap[MAX_MEM_SEGMENTS]; - volatile struct mmap map[MAX_MEM_SEGMENTS]; - ulong plim_lower; - ulong plim_upper; - ulong clks_msec; - ulong starth; - ulong startl; - ulong snaph; - ulong snapl; - int printmode; - int numpatn; - struct pair patn [BADRAM_MAXPATNS]; - ulong test_pages; - ulong selected_pages; - ulong reserved_pages; - int check_temp; - int fail_safe; - int each_sec; - int beepmode; + int pass; + int msg_line; + int ecount; + int ecc_ecount; + int msegs; // number of entries in pmap[] + int testsel; + int scroll_start; + int pass_ticks; + int total_ticks; + int pptr; + int tptr; + struct err_info erri; + // PA ranges from e820 table: + struct pmap pmap[MAX_MEM_SEGMENTS]; + // VA mappings: + volatile struct mmap map[MAX_MEM_SEGMENTS]; + ulong plim_lower; // phys page number + ulong plim_upper; // phys page number + ulong clks_msec; + ulong starth; + ulong startl; + ulong snaph; + ulong snapl; + int printmode; + int numpatn; + struct pair patn [BADRAM_MAXPATNS]; + ulong test_pages; + ulong selected_pages; + ulong reserved_pages; + int check_temp; + int fail_safe; + int each_sec; + int beepmode; + int debugging; // Set in selftest only }; #define FIRMWARE_UNKNOWN 0 #define FIRMWARE_PCBIOS 1 #define FIRMWARE_LINUXBIOS 2 -extern struct vars * const v; +extern struct vars * const vv; extern unsigned char _start[], _end[], startup_32[]; extern unsigned char _size, _pages; @@ -14,141 +14,146 @@ extern struct cpu_ident cpu_id; static unsigned long mapped_win = 1; void paging_off(void) { - if (!cpu_id.fid.bits.pae) - return; - __asm__ __volatile__ ( - /* Disable paging */ - "movl %%cr0, %%eax\n\t" - "andl $0x7FFFFFFF, %%eax\n\t" - "movl %%eax, %%cr0\n\t" - : : - : "ax" - ); + if (!cpu_id.fid.bits.pae) + return; + __asm__ __volatile__ + ( + /* Disable paging */ + "movl %%cr0, %%eax\n\t" + "andl $0x7FFFFFFF, %%eax\n\t" + "movl %%eax, %%cr0\n\t" + : : + : "ax" + ); } static void paging_on(void *pdp) { - if (!cpu_id.fid.bits.pae) - return; - __asm__ __volatile__( - /* Load the page table address */ - "movl %0, %%cr3\n\t" - /* Enable paging */ - "movl %%cr0, %%eax\n\t" - "orl $0x80000000, %%eax\n\t" - "movl %%eax, %%cr0\n\t" - : - : "r" (pdp) - : "ax" - ); + if (!cpu_id.fid.bits.pae) + return; + __asm__ __volatile__ + ( + /* Load the page table address */ + "movl %0, %%cr3\n\t" + /* Enable paging */ + "movl %%cr0, %%eax\n\t" + "orl $0x80000000, %%eax\n\t" + "movl %%eax, %%cr0\n\t" + : + : "r" (pdp) + : "ax" + ); } static void paging_on_lm(void *pml) { - if (!cpu_id.fid.bits.pae) - return; - __asm__ __volatile__( - /* Load the page table address */ - "movl %0, %%cr3\n\t" - /* Enable paging */ - "movl %%cr0, %%eax\n\t" - "orl $0x80000000, %%eax\n\t" - "movl %%eax, %%cr0\n\t" - : - : "r" (pml) - : "ax" - ); + if (!cpu_id.fid.bits.pae) + return; + __asm__ __volatile__ + ( + /* Load the page table address */ + "movl %0, %%cr3\n\t" + /* Enable paging */ + "movl %%cr0, %%eax\n\t" + "orl $0x80000000, %%eax\n\t" + "movl %%eax, %%cr0\n\t" + : + : "r" (pml) + : "ax" + ); } int map_page(unsigned long page) { - unsigned long i; - struct pde { - unsigned long addr_lo; - unsigned long addr_hi; - }; - extern unsigned char pdp[]; - extern unsigned char pml4[]; - extern struct pde pd2[]; - unsigned long win = page >> 19; + unsigned long i; + struct pde { + unsigned long addr_lo; + unsigned long addr_hi; + }; + extern unsigned char pdp[]; + extern unsigned char pml4[]; + extern struct pde pd2[]; + unsigned long win = page >> 19; - /* Less than 2 GB so no mapping is required */ - if (win == 0) { - return 0; - } - if (cpu_id.fid.bits.pae == 0) { - /* Fail, we don't have PAE */ - return -1; - } - if (cpu_id.fid.bits.lm == 0 && (page > 0x1000000)) { - /* Fail, we want an address that is out of bounds (> 64GB) - * for PAE and no long mode (ie. 32 bit CPU). - */ - return -1; - } - /* Compute the page table entries... */ - for(i = 0; i < 1024; i++) { - /*-----------------10/30/2004 12:37PM--------------- - * 0xE3 -- - * Bit 0 = Present bit. 1 = PDE is present - * Bit 1 = Read/Write. 1 = memory is writable - * Bit 2 = Supervisor/User. 0 = Supervisor only (CPL 0-2) - * Bit 3 = Writethrough. 0 = writeback cache policy - * Bit 4 = Cache Disable. 0 = page level cache enabled - * Bit 5 = Accessed. 1 = memory has been accessed. - * Bit 6 = Dirty. 1 = memory has been written to. - * Bit 7 = Page Size. 1 = page size is 2 MBytes - * --------------------------------------------------*/ - pd2[i].addr_lo = ((win & 1) << 31) + ((i & 0x3ff) << 21) + 0xE3; - pd2[i].addr_hi = (win >> 1); - } - paging_off(); - if (cpu_id.fid.bits.lm == 1) { - paging_on_lm(pml4); - } else { - paging_on(pdp); - } - mapped_win = win; - return 0; + /* Less than 2 GB so no mapping is required */ + if (win == 0) { + return 0; + } + if (cpu_id.fid.bits.pae == 0) { + /* Fail, we don't have PAE */ + return -1; + } + if (cpu_id.fid.bits.lm == 0 && (page > 0x1000000)) { + /* Fail, we want an address that is out of bounds (> 64GB) + * for PAE and no long mode (ie. 32 bit CPU). + */ + return -1; + } + /* Compute the page table entries... */ + for(i = 0; i < 1024; i++) { + /*-----------------10/30/2004 12:37PM--------------- + * 0xE3 -- + * Bit 0 = Present bit. 1 = PDE is present + * Bit 1 = Read/Write. 1 = memory is writable + * Bit 2 = Supervisor/User. 0 = Supervisor only (CPL 0-2) + * Bit 3 = Writethrough. 0 = writeback cache policy + * Bit 4 = Cache Disable. 0 = page level cache enabled + * Bit 5 = Accessed. 1 = memory has been accessed. + * Bit 6 = Dirty. 1 = memory has been written to. + * Bit 7 = Page Size. 1 = page size is 2 MBytes + * --------------------------------------------------*/ + pd2[i].addr_lo = ((win & 1) << 31) + ((i & 0x3ff) << 21) + 0xE3; + pd2[i].addr_hi = (win >> 1); + } + paging_off(); + if (cpu_id.fid.bits.lm == 1) { + paging_on_lm(pml4); + } else { + paging_on(pdp); + } + mapped_win = win; + return 0; } -void *mapping(unsigned long page_addr) +void *mapping(unsigned long phys_page) { - void *result; - if (page_addr < 0x80000) { - /* If the address is less than 1GB directly use the address */ - result = (void *)(page_addr << 12); - } - else { - unsigned long alias; - alias = page_addr & 0x7FFFF; - alias += 0x80000; - result = (void *)(alias << 12); - } - return result; + void *result; + if (phys_page < WIN_SZ_PAGES) { + /* If the page is below 2GB, address it directly */ + result = (void *)(phys_page << 12); + } + else { + // Higher physical pages map to a virtual address + // in the 2G-4G range. + unsigned long alias; + alias = phys_page & 0x7FFFF; + alias += 0x80000; + result = (void *)(alias << 12); + } + return result; } -void *emapping(unsigned long page_addr) +void *emapping(unsigned long phys_page) { - void *result; - result = mapping(page_addr -1); - /* Fill in the low address bits */ - result = ((unsigned char *)result) + 0xffc; - return result; + void *result; + result = mapping(phys_page - 1); + /* Fill in the low address bits */ + result = ((unsigned char *)result) + 0xffc; + return result; } unsigned long page_of(void *addr) { - unsigned long page; - page = ((unsigned long)addr) >> 12; - if (page >= 0x80000) { - page &= 0x7FFFF; - page += mapped_win << 19; - } + unsigned long page; + page = ((unsigned long)addr) >> 12; + if (page >= 0x80000) { + page &= 0x7FFFF; + page += mapped_win << 19; + } #if 0 - cprint(LINE_SCROLL -2, 0, "page_of( )-> "); - hprint(LINE_SCROLL -2, 8, ((unsigned long)addr)); - hprint(LINE_SCROLL -2, 20, page); + cprint(LINE_SCROLL -2, 0, "page_of( )-> "); + hprint(LINE_SCROLL -2, 8, ((unsigned long)addr)); + hprint(LINE_SCROLL -2, 20, page); #endif - return page; + return page; } |