diff options
author | Michael Brown | 2009-09-18 05:37:20 +0200 |
---|---|---|
committer | Michael Brown | 2012-07-09 16:41:26 +0200 |
commit | 4d88f7ec4ce034fdfe9bd05a1e94f7b16e996244 (patch) | |
tree | f25204d1de3357ac4aae7c4d9f61279dff766b52 | |
parent | [import] Import version 1.40 (diff) | |
download | memtest86-4d88f7ec4ce034fdfe9bd05a1e94f7b16e996244.tar.gz memtest86-4d88f7ec4ce034fdfe9bd05a1e94f7b16e996244.tar.xz memtest86-4d88f7ec4ce034fdfe9bd05a1e94f7b16e996244.zip |
[import] Import version 1.50
http://www.memtest.org/download/1.50/memtest86+-1.50.tar.gz
-rw-r--r-- | FAQ | 310 | ||||
-rw-r--r-- | Makefile | 242 | ||||
-rw-r--r-- | bootsect.S | 54 | ||||
-rw-r--r-- | changelog | 15 | ||||
-rw-r--r-- | config.c | 55 | ||||
-rw-r--r-- | controller.c | 876 | ||||
-rw-r--r-- | defs.h | 4 | ||||
-rw-r--r-- | extra.c | 1242 | ||||
-rw-r--r-- | head.S | 141 | ||||
-rw-r--r-- | init.c | 712 | ||||
-rw-r--r-- | lib.c | 122 | ||||
-rw-r--r-- | main.c | 129 | ||||
-rw-r--r-- | memsize.c | 72 | ||||
-rw-r--r-- | mt86+_loader.asm | 6 | ||||
-rw-r--r-- | mt86+_loader.bin | bin | 784 -> 784 bytes | |||
-rw-r--r-- | pci.c | 18 | ||||
-rw-r--r--[-rwxr-xr-x] | precomp.bin | bin | 95352 -> 94472 bytes | |||
-rw-r--r-- | reloc.c | 22 | ||||
-rw-r--r-- | screen_buffer.c | 84 | ||||
-rw-r--r-- | setup.S | 8 | ||||
-rw-r--r-- | test.c | 291 | ||||
-rw-r--r-- | test.h | 21 |
22 files changed, 2498 insertions, 1926 deletions
@@ -0,0 +1,310 @@ +- What is memtest86+, what do I use it for? + + Memtest86+ is a utility designed to test whether your memory is in working + order. It repeatedly writes an enormous amount of different patterns to all + memory locations and reads them back again and verifies whether the result + of the read is the same as what was written to memory. + + There can be a multitude of reasons for running memtest, but foremost of all + is of course to test whether your memory modules might be bad. Whenever you + suspect your modules to be bad because of system crashes, lockups or reboots + it would be nice to know whether the modules are in working order. + Memtest86+ is a utility which tries to answer that question for you. + + Another common use exists in the overclocking scene. When overclocking a + system you are essentially pushing your system to the limits and at some + point it will simply give way and break. Unfortunately there isn't a clear + cut way of deciding whether a system is still working correctly. Because of + the complexity of a computer a system which is pushed to the limits doesn't + just break completely when it starts to fail, instead little errors start + showing up in many different places in the system growing more frequent and + widespread the more the system is pushed. Each one of these little errors + can lead to a crash of your system but can also go unnoticed for days or + weeks in a running system. The art so to speak of overclocking is thus to + push the system as far as it can go without introducing any such errors. As + memory is usually one of the first places these such errors start coming up + a memory test is very useful. + +- How do I get it to run? + + There are several ways to use memtest, which are described below: + + + Run from floppydisk + + Memtest86+ is directly executable by any modern x86 compatible machine, by + writing the bootable binary to a floppy disk one can boot from the disk to + run memtest. + + Simply download the appropriate package, the Pre-Compiled Bootable Binary + (.gz) package for Linux users and the Pre-Compiled package for Floppy (DOS + - Win) for Windows users. + + For Windows, unzip the package into a directory like C:\memtest, insert a + blank floppy into your a: disk drive and run the install.bat file. As the + install prompts you, to use memtest directly, leave the disk in the drive + and reboot your machine. + + For Linux, unpack the package into your home directory, insert a blank + floppy into your floppy drive and execute 'dd if=~/memtest+-1.xx.bin.gz + of=/dev/fd0 conv=osync' replacing 1.xx with the correct version number of + the memtest86+ you downloaded. To run memtest immediately reboot your + machine. + + Your machine should now boot from the disk, display the word Loading + folowed by a series of periods and then show a screen much like the + screenshots on the memtest86+ web page. The test is automatically started. + + If your machine simply boots back into Windows/Linux you will most likely + have to configure your BIOS to attempt to boot from floppy disk on + startup, refer to your computer's/mainboard's manual how to do this. + + When you are done testing simply remove the floppy and reset your + computer, if ever you want to execure the test again simply reinsert the + disk and reboot/start your computer. + + + Run from CD + + Memtest86+ is directly executable by any modern x86 compatible machine, by + writing the iso to a CD one can boot from the CD to run memtest. + + Simply download the appropriate package, the Download - Pre-Compiled + Bootable ISO (.gz) for Linux users and the Pre-Compiled Bootable ISO + (.zip) for Windows users. + + For Windows, unzip the package into a directory like C:\memtest. You will + now see a file called memtest86+-1.xx.iso in this directory. You will need + to burn this file to a CD with a CD recording program. Do note however + that you should not make a regular data CD on which you for instance write + your text documents and holiday photographs. Instead the iso file is a so + called image of a CD, it is a direct copy of a CD. Your CD recording + program will most likely have a feature called burn image or something to + that effect which you should use to burn the CD. + + For linux, unzip the package into your home directory. and execute + 'cdrecord dev=<your burner> ~/memtest86+-1.xx.iso' where you replace <your + burner> with the scsi address of your CD burner and replace 1.xx with the + correct version number of the memtest86+ your downloaded. + + When the burning completed your drive will most likely have ejected the CD + and you should have a bootable memtest86+ CD. To run the test directly + reinsert the CD and reboot your machine. + + Your machine should now boot from the CD, display the word Loading folowed + by a series of periods and then show a screen much like the screenshots on + the memtest86+ web page. The test is automatically started. + + If your machine simply boots back into Windows/Linux you will most likely + have to configure your BIOS to attempt to boot from CD-ROM drive on + startup, refer to your computer's/mainboard's manual how to do this. + + When you are done testing simply remove the CD and reset your computer, if + ever you want to execure the test again simply reinsert the CD and + reboot/start your computer. + + + Run from USB Flash drive + + FIXME + + + Run from boot manager + + FIXME + +- How long does memtest86+ run? How do I stop it? + + Memtest86+ runs indefinately unless you stop it. It does however repeat the + same tests over and over again. Memtest86+ contains a number of different + tests which each take different approaches in trying to expose any errors in + your memory. In the top right of your screen you can see the progress of + each test in the lower of the two progress bars. The topmost progress bar + shows the progress of a pass, each pass consists of all the tests in the + memtest suite. + + Thus all tests are executed in one pass, so does that mean that no errors + will show after the first pass if that pass didn't reveal any errors? Well + no, there are several reasons why errors might only show up after a number + of passes. Firstly as of this writing, the latest version of memtest also + includes a test which uses random test patterns, each pass these patterns + will of course be different. Secondly some types of errors simply don't show + up until the system has been running for a while or are very critical on a + certain timing condition, or other such conditions. + + To conclude, one successful pass of memtest will give you a pretty good idea + that your memory is ok, only in rare cases will there be errors showing + after the first pass. To be sure though simply have the test run overnight + or even for a couple of days depending on the level of importance of the + system. + +- How many errors are acceptable? + + No errors are acceptable. Even if there is just one error, something is + amiss which can cause your system to crash. Of course what the cause of the + errors is you will still have to determine. + +- What do I do when I get errors? + + Firstly, don't start drawing any conclusions. You only know that memtest86+ + is giving your errors, not what the cause is. Unfortunately it is not a + straightforward exercise to decisively test the memory in an actual system. + This is because a computer is not just built up of some memory, but also + includes many other elements such as a memory controller, cache, a cache + controller, algorithmic and logic units, etc, all of which contribute to the + machine. If there are faults in any of these other parts of the computer you + will likely also see errors showing up in memtest. + + So what to do? First verify that the BIOS settings of your machine are + correctly configured. Look up the memory timing settings applicable to the + brand and type of memory modules you have and check they match your BIOS + settings, correct them if they don't and run memtest again + + Ok, you have all the settings correctly set and you're still getting errors. + Well of course a very likely cause are the memory modules and the logical + course of action is to look into them further. + + If you are well stocked, have a few other machines at your disposal, or just + want to spend the cash for some new modules the best way to test if the + cause are your memory modules is just to replace them and test again. If you + are less fortunate though there is still something you can do. + + If you have more then one module in your system, test them one by one, if + one is consistently giving errors and another is consistently showing no + errors it's a pretty good bet that the module giving the errors is simply + defective. To exclude the possibility that a defective slot is throwing your + results, use the same slot to test each different module. + + If each module by itself shows no errors, but when you place two or more + modules into the machine at the same time you do get errors, you are most + likely stuck with a compatibility issue and unfortunately there isn't a + whole lot you can do about it. Be sure to check your computer/motherboard + manual to see if the setup you are trying is allowed, some boards require + special restrictions in the sizes of modules, the order of modules, the + placement of double sided and single sides modules and more of such things. + + If you have only one module in your system, or all modules are giving + errors, there are only very few options left. The only thing you can do + really is to try the module(s) in another slot. Finally simply try out + different orders of the memory modules, although your manual might not + mention anything on the matter sometimes there simply exist timing or other + issues which can be resolved by changing the order of your modules. And of + course test each slot by putting a single module into that slot and running + memtest on it. + + In the end if you still have not been able to localize the problem you will + have to find a replacement module to establish whether the problem lies in + your modules. See if you can borrow a module from someone else. + + When you have replaced the memory by new memory and the errors still + persist, first check if you can rule out any compatibility issues or timing + issues. If you are sure the memory should work in the system the cause of + the errors must obviously lie someplace else in the system. + + The only way to find out where, is by trial and error really. Simply start + replacing and/or removing parts of your computer one by one, running memtest + each time you changed anything, until the errors are resolved. + +- I'm getting errors in test #x, what doest that mean? + + Interpreting memtest results is as scientific an endeavour as testing + whether a person is a witch by the methods used in Monty Python's Holy + Grail. In short, don't even start, it's not going to get you anywhere. Just + interpret any error as you should any other and use the methods descibed in + the previous question to determine the cause. + +- I'm getting errors in test #5 and/or #8 and have read a lot about it. + + Yes there are just about enough discussions on the topic to fill a book, but + it all boils down to the answer given above. The only thing that can be said + is that many a times, when memory latencies are incorrectly set in the BIOS + you will experience errors in test #5 and #8. (Though #8 does not exist + anymore as of version 1.40 and might be reinstated as a different test in a + later version.) This does however NOT mean that errors in these tests are + always the cause of incorrect settings, your memory might just as well be + defective. + +- I'm getting errors in memtest on one machine, but not when I put the same + memory in another, what does that mean? + + It can mean one of two things: + - The machine that is giving the errors is defective. Errors don't just + orginate from the memory module itself, but can also be caused by + defects in the cpu, chipset, motherboard, PSU and even by timing issues + introduced by any other component in the machine. + - The machine giving the errors is imposing stricter timing than the other + which the memory module simply can't cope with. If the module should + work with the machine according to its specifications then it most + likely is defective. + +- Which memory is tested? + + As much as possible of the system memory is tested. Unfortunately memtest86+ + can usually not test all of the memory. The reason for this is that todays + processors have become so complex that they require a small amount of memory + to keep accounting data of the processor state. If memtest were to write + over these areas the state of the processor becomes invalid and it's + behaviour unpredictable. Alas it is also impossible to relocate these areas + in the memory. + + This means that a small area of your memory can not be tested by memtest. If + this part of the memory is defective you will know soon enough though as the + processor, or parts of the processor simply won't work correctly if this + part of your memory is defective. Do realise though that in very rare cases + memtest will show no errors even though the module is defective, not because + memtest can't detect the error, but because memtest can't test the area the + error is located in. + +- When I select BIOS-ALL I get many errors / my machine crashes. + + This is normal. With todays computers this option should never be selected. + See the previous question about the reason for the errors. + +- I want to use memtest on a multiboot CD, how do I do this? + + This is of course very dependent on which boot loader you use for your CD. + Below is a description of how to set up a multiboot CD including memtest+ + with isolinux, if you have experience with any other bootloader(s) please + consider writing a small description of using memtest with that bootloader + for the FAQ. + + -isolinux + + For general instructions on how to make a bootable CD with isolinux see + the syslinux website and the manual. What you need to do to get memtest + working is as follows. + + Download the Pre-Compiled Bootable Binary, the .gz if you are working + under linux, the .zip if you are working under windows. Unpack the file + from the package and rename it to an 8.3 filename with an extension other + than .bin, renaming to memtest. (without an extension) is a good choice. + + Put the file somewhere in your CD directory structure, for example in + images/memtest and edit your config file to include the following: + + label memtest + kernel /images/memtest + + If you want to boot memtest automatically insert or change a line at the + top to: + + default memtest + + If you want to display a prompt from which you can start memtest add or + change the lines at the top to: (Change the timeout to suit your needs) + + prompt 1 + timeout 200 + +- If memtest86+ shows no errors does that mean my memory is not defective? + + Of course no answers are definitive, no matter how good memtest86+ will + eventually become there is always the possibility that a particular type of + error will go unnoticed. As long as you are having no problems with the + system it will be pretty safe to say that the modules are good. If you are + having problems with the system however you will just have to check by trial + and error, ie swapping the modules for new ones and/or testing with modules + of a different brand/type. + +- When I run install.bat it doesn't write anything to floppy. + + You most likely have unpacked the memtest+-1.xx.floppy.zip file into a + folder with a long pathname and/or containing + and - signs. It seems + rawrite doesn't like that. Just move the files you unpacked to a directory + like c:\memtest and execure it from there. @@ -1,121 +1,121 @@ -# Makefile for MemTest-86 -# -# Author: Chris Brady -# Created: January 1, 1996 - -# -# Path for the floppy disk device -# -FDISK=/dev/fd0 - -CC=gcc -# -# gcc compiler options, these settings should suffice -# -CCFLAGS=-Wall -m32 -march=i486 -Os -fomit-frame-pointer -fno-builtin -ffreestanding - -AS=as -32 - -OBJS= head.o reloc.o main.o test.o init.o lib.o patn.o screen_buffer.o config.o linuxbios.o memsize.o pci.o controller.o extra.o random.o - -all: memtest.bin memtest - -reloc.o: reloc.c - $(CC) -c -m32 -march=i486 -fPIC -Wall -g -O2 -fno-strict-aliasing reloc.c - -test.o: test.c test.h defs.h config.h - $(CC) -c $(CCFLAGS) test.c - -main.o: main.c test.h defs.h - $(CC) -c $(CCFLAGS) -fPIC main.c - -init.o: init.c test.h defs.h io.h config.h controller.h pci.h - $(CC) -c $(CCFLAGS) -fPIC init.c - -linuxbios.o: linuxbios.c test.h linuxbios_tables.h defs.h config.h - $(CC) -c $(CCFLAGS) -fPIC linuxbios.c - -memsize.o: memsize.c test.h defs.h config.h - $(CC) -c $(CCFLAGS) -fPIC memsize.c - -lib.o: lib.c test.h defs.h io.h screen_buffer.h serial.h config.h - $(CC) -c $(CCFLAGS) -fPIC lib.c - -screen_buffer.o: screen_buffer.c screen_buffer.h test.h config.h - $(CC) -c $(CCFLAGS) -fPIC screen_buffer.c - -random.o: random.c - $(CC) -c $(CCFLAGS) -fPIC random.c - -patn.o: patn.c - $(CC) -c $(CCFLAGS) -fPIC patn.c - -config.o: config.c test.h controller.h screen_buffer.h - $(CC) -c $(CCFLAGS) -fPIC config.c - -pci.o: pci.c pci.h io.h - $(CC) -c $(CCFLAGS) -fPIC pci.c - -controller.o: controller.c defs.h config.h test.h pci.h controller.h - $(CC) -c $(CCFLAGS) -fPIC controller.c - -extra.o: config.c test.h screen_buffer.h extra.h - $(CC) -c $(CCFLAGS) -fPIC extra.c - -controller.s: controller.c defs.h config.h test.h pci.h controller.h - $(CC) -S $(CCFLAGS) -fPIC controller.c - -head.s: head.S - $(CC) -E -m32 -traditional $< -o $@ - -head.o: head.s - $(AS) -o $@ $< - -makedefs: makedefs.c defs.h - $(CC) $(CCFLAGS) makedefs.c -o $@ - - -# Link it statically once so I know I don't have undefined -# symbols and then link it dynamically so I have full -# relocation information -memtest_shared: $(OBJS) memtest_shared.lds Makefile - $(LD) --warn-constructors --warn-common -static -T memtest_shared.lds -o $@ $(OBJS) && \ - $(LD) -shared -Bsymbolic -T memtest_shared.lds -o $@ $(OBJS) - -memtest_shared.bin: memtest_shared - objcopy -O binary $< memtest_shared.bin - -memtest: memtest_shared.bin memtest.lds - $(LD) -s -T memtest.lds -b binary memtest_shared.bin -o $@ - -bootsect.s: bootsect.S defs.h - $(CC) -E -traditional $< -o $@ - -bootsect.o: bootsect.s - $(AS) -o $@ $< - -bootsect: bootsect.o - $(LD) -Ttext 0x00 -s --oformat binary -e _main --just-symbols=memtest_shared.o -o $@ $< - -setup.s: setup.S config.h defs.h - $(CC) -E -traditional $< -o $@ - -setup.o: setup.s - $(AS) -o $@ $< - - -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 - -clean: - rm -f *.o *.s memtest.bin bootsect setup low_mapfile high_mapfile \ - memtest memtest.out makedefs defs.lds memtest_shared memtest_shared.bin - -wormkill: - rm -f *~ - -install: all - dd <memtest.bin >$(FDISK) bs=8192 - -install-bin: - dd <precomp.bin >$(FDISK) bs=8192 +# Makefile for MemTest-86
+#
+# Author: Chris Brady
+# Created: January 1, 1996
+
+#
+# Path for the floppy disk device
+#
+FDISK=/dev/fd0
+
+CC=gcc
+#
+# gcc compiler options, these settings should suffice
+#
+CCFLAGS=-Wall -m32 -march=i486 -Os -fomit-frame-pointer -fno-builtin -ffreestanding
+
+AS=as -32
+
+OBJS= head.o reloc.o main.o test.o init.o lib.o patn.o screen_buffer.o config.o linuxbios.o memsize.o pci.o controller.o extra.o random.o
+
+all: memtest.bin memtest
+
+reloc.o: reloc.c
+ $(CC) -c -m32 -march=i486 -fPIC -Wall -g -O2 -fno-strict-aliasing reloc.c
+
+test.o: test.c test.h defs.h config.h
+ $(CC) -c $(CCFLAGS) test.c
+
+main.o: main.c test.h defs.h
+ $(CC) -c $(CCFLAGS) -fPIC main.c
+
+init.o: init.c test.h defs.h io.h config.h controller.h pci.h
+ $(CC) -c $(CCFLAGS) -fPIC init.c
+
+linuxbios.o: linuxbios.c test.h linuxbios_tables.h defs.h config.h
+ $(CC) -c $(CCFLAGS) -fPIC linuxbios.c
+
+memsize.o: memsize.c test.h defs.h config.h
+ $(CC) -c $(CCFLAGS) -fPIC memsize.c
+
+lib.o: lib.c test.h defs.h io.h screen_buffer.h serial.h config.h
+ $(CC) -c $(CCFLAGS) -fPIC lib.c
+
+screen_buffer.o: screen_buffer.c screen_buffer.h test.h config.h
+ $(CC) -c $(CCFLAGS) -fPIC screen_buffer.c
+
+random.o: random.c
+ $(CC) -c $(CCFLAGS) -fPIC random.c
+
+patn.o: patn.c
+ $(CC) -c $(CCFLAGS) -fPIC patn.c
+
+config.o: config.c test.h controller.h screen_buffer.h
+ $(CC) -c $(CCFLAGS) -fPIC config.c
+
+pci.o: pci.c pci.h io.h
+ $(CC) -c $(CCFLAGS) -fPIC pci.c
+
+controller.o: controller.c defs.h config.h test.h pci.h controller.h
+ $(CC) -c $(CCFLAGS) -fPIC controller.c
+
+extra.o: config.c test.h screen_buffer.h extra.h
+ $(CC) -c $(CCFLAGS) -fPIC extra.c
+
+controller.s: controller.c defs.h config.h test.h pci.h controller.h
+ $(CC) -S $(CCFLAGS) -fPIC controller.c
+
+head.s: head.S
+ $(CC) -E -m32 -traditional $< -o $@
+
+head.o: head.s
+ $(AS) -o $@ $<
+
+makedefs: makedefs.c defs.h
+ $(CC) $(CCFLAGS) makedefs.c -o $@
+
+
+# Link it statically once so I know I don't have undefined
+# symbols and then link it dynamically so I have full
+# relocation information
+memtest_shared: $(OBJS) memtest_shared.lds Makefile
+ $(LD) --warn-constructors --warn-common -static -T memtest_shared.lds -o $@ $(OBJS) && \
+ $(LD) -shared -Bsymbolic -T memtest_shared.lds -o $@ $(OBJS)
+
+memtest_shared.bin: memtest_shared
+ objcopy -O binary $< memtest_shared.bin
+
+memtest: memtest_shared.bin memtest.lds
+ $(LD) -s -T memtest.lds -b binary memtest_shared.bin -o $@
+
+bootsect.s: bootsect.S defs.h
+ $(CC) -E -traditional $< -o $@
+
+bootsect.o: bootsect.s
+ $(AS) -o $@ $<
+
+bootsect: bootsect.o
+ $(LD) -Ttext 0x00 -s --oformat binary -e _main --just-symbols=memtest_shared.o -o $@ $<
+
+setup.s: setup.S config.h defs.h
+ $(CC) -E -traditional $< -o $@
+
+setup.o: setup.s
+ $(AS) -o $@ $<
+
+
+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
+
+clean:
+ rm -f *.o *.s memtest.bin bootsect setup low_mapfile high_mapfile \
+ memtest memtest.out makedefs defs.lds memtest_shared memtest_shared.bin
+
+wormkill:
+ rm -f *~
+
+install: all
+ dd <memtest.bin >$(FDISK) bs=8192
+
+install-bin:
+ dd <precomp.bin >$(FDISK) bs=8192
@@ -5,7 +5,7 @@ * itself out of the way to address 0x90000, and jumps there.
*
* It then loads 'setup' directly after itself (0x90200), and the system
- * at 0x10000, using BIOS interrupts.
+ * at 0x10000, using BIOS interrupts.
*
* The loader has been made as simple as possible, and continuos
* read errors will result in a unbreakable loop. Reboot by hand. It
@@ -17,7 +17,7 @@ #include "defs.h"
ROOT_DEV = 0
-
+
.code16
.section ".bootsect", "ax", @progbits
_boot:
@@ -38,7 +38,7 @@ _main: movsw
ljmp $INITSEG, $go - _boot
-go:
+go:
movw %cs, %ax
movw $(0x4000-12), %dx # 0x4000 is arbitrary value >= length of
# bootsect + length of setup + room for stack
@@ -54,9 +54,9 @@ go: movw %ax, %es
movw %ax, %ss # put stack at INITSEG:0x4000-12.
movw %dx, %sp
-
+
/*
- * Many BIOS's default disk parameter tables will not
+ * Many BIOS's default disk parameter tables will not
* recognize multi-sector reads beyond the maximum sector number
* specified in the default diskette parameter tables - this may
* mean 7 sectors in some cases.
@@ -64,7 +64,7 @@ go: * Since single sector reads are slow and out of the question,
* we must take care of this by creating new parameter tables
* (for the first disk) in RAM. We will set the maximum sector
- * count to 18 - the most we will encounter on an HD 1.44.
+ * count to 18 - the most we will encounter on an HD 1.44.
*
* High doesn't hurt. Low does.
*
@@ -92,10 +92,10 @@ go: movw %ax, %fs
movw %ax, %gs
- xorb %ah, %ah # reset FDC
+ xorb %ah, %ah # reset FDC
xorb %dl, %dl
int $0x13
-
+
# load the setup-sectors directly after the bootblock.
# Note that 'es' is already set up.
@@ -112,7 +112,7 @@ load_setup: call print_nl
movw %sp, %bp
call print_hex
- popw %ax
+ popw %ax
xorb %dl, %dl # reset FDC
xorb %ah, %ah
@@ -140,7 +140,7 @@ ok_load_setup: int $0x13
jnc got_sectors
movb $0x09, %cl
-
+
got_sectors:
movw %cx, %cs:sectors - _boot
movw $INITSEG, %ax
@@ -151,13 +151,13 @@ got_sectors: movb $0x03, %ah # read cursor pos
xorb %bh, %bh
int $0x10
-
+
movw $9, %cx
movw $0x0007, %bx # page 0, attribute 7 (normal)
movw $msg1 - _boot, %bp
movw $0x1301, %ax # write string, move cursor
int $0x10
-
+
# ok, we've written the message, now
# we want to load the system (at 0x10000)
@@ -186,7 +186,7 @@ track: .word 0 # current track read_it:
movw %es, %ax
testw $0x0fff, %ax
-die:
+die:
jne die # es must be at 64kB boundary
xorw %bx,%bx # bx is starting address within segment
rp_read:
@@ -229,7 +229,7 @@ ok3_read: movw %ax, %es
xorw %bx, %bx
jmp rp_read
-
+
read_track:
pusha
pusha
@@ -237,7 +237,7 @@ read_track: movw $7, %bx
int $0x10
popa
-
+
movw track - _boot, %dx
movw sread - _boot, %cx
incw %cx
@@ -246,7 +246,7 @@ read_track: movb %dl, %dh
andw $0x0100, %dx
movb $2, %ah
-
+
pushw %dx # save for error dump
pushw %cx
pushw %bx
@@ -258,23 +258,23 @@ read_track: popa
ret
-bad_rt:
+bad_rt:
pushw %ax # save error code
call print_all # ah = error, al = read
-
+
xorb %ah, %ah
xorb %dl, %dl
int $0x13
addw $10, %sp
- popa
+ popa
jmp read_track
/*
- * print_all is for debugging purposes.
+ * print_all is for debugging purposes.
* It will print out all of the registers. The assumption is that this is
* called from a routine, with a stack frame like
- * dx
+ * dx
* cx
* bx
* ax
@@ -282,7 +282,7 @@ bad_rt: * ret <- sp
*
*/
-
+
print_all:
movw $5, %cx # error code + 4 registers
movw %sp, %bp
@@ -299,7 +299,7 @@ print_loop: int $0x10
movb $'X', %al
int $0x10
- movb $':', %al
+ movb $':', %al
int $0x10
no_reg:
@@ -308,18 +308,18 @@ no_reg: popw %cx
loop print_loop
ret
-
+
print_nl:
movw $0xe0d, %ax # CR
int $0x10
movb $0x0a, %al # LF
int $0x10
ret
-
+
/*
* print_hex is for debugging purposes, and prints the word
* pointed to by ss:bp in hexadecmial.
-*/
+ */
print_hex:
movw $4, %cx # 4 hex digits
@@ -334,7 +334,7 @@ print_digit: cmpb $'9', %al # check for overflow
jbe good_digit
addb $('A' - '0' - 10), %al
-
+
good_digit:
int $0x10
loop print_digit
diff --git a/changelog b/changelog new file mode 100644 index 0000000..ef70b25 --- /dev/null +++ b/changelog @@ -0,0 +1,15 @@ +Enhancements : +- Added support for Intel i945P/G (Lakeport) +- Added support for Intel i915PM/GM (Alviso) +- Added support for Intel E7520 (Lindenhurst) +- Added support for Intel E7520 (Lindenhurst-VS) +- Added support for P4 6xx serie +- Rewrite all Athlon 64 detection code (for 90nm) +- An uncached test is back in Menu 1 (Experimental) + +Bug Fixes : +- Fix Dual DDR-I not detected on i915P/G +- Fix DDR333/400 ratio error on i915P/G +- Fix i855 & DDR333 not detected +- Correct Celeron M Dothan not detected +- Other minor bug fixes @@ -38,7 +38,7 @@ void get_config() cprint(POP_Y+9, POP_X+6, "(7) Restart"); cprint(POP_Y+10, POP_X+6, "(8) Refresh Screen"); cprint(POP_Y+11, POP_X+6, "(9) Adv. Options"); - cprint(POP_Y+12,POP_X+6,"(0) Continue"); + cprint(POP_Y+12, POP_X+6, "(0) Continue"); /* Wait for key release */ /* Fooey! This nuts'es up the serial input. */ @@ -52,7 +52,8 @@ void get_config() cprint(POP_Y+4, POP_X+6, "(2) Skip Current Test"); cprint(POP_Y+5, POP_X+6, "(3) Select Test"); cprint(POP_Y+6, POP_X+6, "(4) Select Bit Fade Test"); - cprint(POP_Y+7, POP_X+6, "(0) Continue"); + cprint(POP_Y+7, POP_X+6, "(5) Select Uncached Test"); + cprint(POP_Y+8, POP_X+6, "(0) Continue"); if (v->testsel < 0) { cprint(POP_Y+3, POP_X+5, ">"); } else { @@ -63,7 +64,7 @@ void get_config() switch(get_key()) { case 2: /* Default */ - if (v->testsel == 9) { + if (v->testsel > 8) { bail++; } v->testsel = -1; @@ -82,9 +83,9 @@ void get_config() cprint(POP_Y+1, POP_X+3, "Test Selection:"); cprint(POP_Y+4, POP_X+5, - "Test Number [0-9]: "); + "Test Number [0-10]: "); i = getval(POP_Y+4, POP_X+24, 0); - if (i <= 9) { + if (i <= 10) { if (i != v->testsel) { v->pass = -1; v->test = -1; @@ -103,12 +104,24 @@ void get_config() v->test = -1; } v->testsel = 9; - find_ticks(); - sflag++; - bail++; - cprint(LINE_INFO, COL_TST, "#"); - dprint(LINE_INFO, COL_TST+1, 9, 2, 1); - break; + find_ticks(); + sflag++; + bail++; + cprint(LINE_INFO, COL_TST, "#"); + dprint(LINE_INFO, COL_TST+1, 9, 3, 1); + break; + case 6: + if (v->testsel != 10) { + v->pass = -1; + v->test = -1; + } + v->testsel = 9+1; + find_ticks(); + sflag++; + bail++; + cprint(LINE_INFO, COL_TST, "#"); + dprint(LINE_INFO, COL_TST+1, 10, 3, 1); + break; case 11: case 57: sflag++; @@ -353,7 +366,7 @@ void get_config() reprint_screen = 1; flag++; break; - case 10: + case 10: get_menu(); break; case 11: @@ -368,9 +381,9 @@ void get_config() if (prt) { printpatn(); } - if (reprint_screen){ - tty_print_screen(); - } + if (reprint_screen){ + tty_print_screen(); + } } @@ -382,11 +395,11 @@ void popup() for (i=POP_Y; i<POP_Y + POP_H; i++) { for (j=POP_X; j<POP_X + POP_W; j++) { pp = (char *)(SCREEN_ADR + (i * 160) + (j * 2)); - save[0][i-POP_Y][j-POP_X] = *pp; /* Save screen */ - set_scrn_buf(i, j, ' '); - *pp = ' '; /* Clear */ + save[0][i-POP_Y][j-POP_X] = *pp; /* Save screen */ + set_scrn_buf(i, j, ' '); + *pp = ' '; /* Clear */ pp++; - save[1][i-POP_Y][j-POP_X] = *pp; + save[1][i-POP_Y][j-POP_X] = *pp; *pp = 0x07; /* Change Background to black */ } } @@ -402,7 +415,7 @@ void popdown() for (j=POP_X; j<POP_X + POP_W; j++) { pp = (char *)(SCREEN_ADR + (i * 160) + (j * 2)); *pp = save[0][i-POP_Y][j-POP_X]; /* Restore screen */ - set_scrn_buf(i, j, save[0][i-POP_Y][j-POP_X]); + set_scrn_buf(i, j, save[0][i-POP_Y][j-POP_X]); pp++; *pp = save[1][i-POP_Y][j-POP_X]; /* Restore color */ } @@ -419,7 +432,7 @@ void popclear() for (j=POP_X; j<POP_X + POP_W; j++) { pp = (char *)(SCREEN_ADR + (i * 160) + (j * 2)); *pp = ' '; /* Clear popup */ - set_scrn_buf(i, j, ' '); + set_scrn_buf(i, j, ' '); pp++; } } diff --git a/controller.c b/controller.c index ed38e12..5d98e74 100644 --- a/controller.c +++ b/controller.c @@ -3,7 +3,7 @@ * Released under version 2 of the Gnu Public License. * By Chris Brady, cbrady@sgi.com * ---------------------------------------------------- - * MemTest86+ V1.40 Specific code (GPL V2.0) + * MemTest86+ V1.41 Specific code (GPL V2.0) * By Samuel DEMEULEMEESTER, sdemeule@memtest.org * http://www.x86-secret.com - http://www.memtest.org */ @@ -20,12 +20,12 @@ extern ulong extclock; extern struct cpu_ident cpu_id; #define rdmsr(msr,val1,val2) \ - __asm__ __volatile__("rdmsr" \ + __asm__ __volatile__("rdmsr" \ : "=a" (val1), "=d" (val2) \ : "c" (msr)) #define wrmsr(msr,val1,val2) \ - __asm__ __volatile__("wrmsr" \ + __asm__ __volatile__("wrmsr" \ : /* no outputs */ \ : "c" (msr), "a" (val1), "d" (val2)) @@ -40,7 +40,7 @@ extern struct cpu_ident cpu_id; #define ECC_UNKNOWN (~0UL) /* Unknown error correcting ability/status */ #define ECC_NONE 0 /* Doesnt support ECC (or is BIOS disabled) */ #define ECC_RESERVED __ECC_UNEXPECTED /* Reserved ECC type */ -#define ECC_DETECT __ECC_DETECT +#define ECC_DETECT __ECC_DETECT #define ECC_CORRECT (__ECC_DETECT | __ECC_CORRECT) #define ECC_CHIPKILL (__ECC_DETECT | __ECC_CORRECT | __ECC_CHIPKILL) #define ECC_SCRUB (__ECC_DETECT | __ECC_CORRECT | __ECC_SCRUB) @@ -54,12 +54,12 @@ static struct ecc_info { unsigned fn; unsigned cap; unsigned mode; -} ctrl = +} 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. + * fn 0. But just in case leave these as variables. */ .bus = 0, .dev = 0, @@ -69,19 +69,30 @@ static struct ecc_info { .mode = ECC_UNKNOWN, }; +struct pci_memory_controller { + unsigned vendor; + unsigned device; + char *name; + int tested; + void (*poll_fsb)(void); + void (*poll_timings)(void); + void (*setup_ecc)(void); + void (*poll_errors)(void); +}; + void print_timings_info(float cas, int rcd, int rp, int ras) { /* Now, we could print some additionnals timings infos) */ cprint(LINE_CPU+5, col2 +1, "/ CAS : "); col2 += 9; - + // CAS Latency (tCAS) if (cas == 1.5) { - cprint(LINE_CPU+5, col2, "1.5"); col2 += 3; + cprint(LINE_CPU+5, col2, "1.5"); col2 += 3; } else if (cas == 2.5) { - cprint(LINE_CPU+5, col2, "2.5"); col2 += 3; + cprint(LINE_CPU+5, col2, "2.5"); col2 += 3; } else { - dprint(LINE_CPU+5, col2, cas, 1, 0); col2 += 1; + dprint(LINE_CPU+5, col2, cas, 1, 0); col2 += 1; } cprint(LINE_CPU+5, col2, "-"); col2 += 1; @@ -94,14 +105,14 @@ void print_timings_info(float cas, int rcd, int rp, int ras) { dprint(LINE_CPU+5, col2, rp, 1, 0); cprint(LINE_CPU+5, col2+1, "-"); col2 +=2; - + // RAS Active to precharge (tRAS) if (ras < 9) { - dprint(LINE_CPU+5, col2, ras, 1, 0); - col2 += 2; + dprint(LINE_CPU+5, col2, ras, 1, 0); + col2 += 2; } else { - dprint(LINE_CPU+5, col2, ras, 2, 0); - col2 += 3; + dprint(LINE_CPU+5, col2, ras, 2, 0); + col2 += 3; } } @@ -122,7 +133,7 @@ void print_fsb_info(float val, const char *text_fsb) { dprint(LINE_CPU+5, col2, val*2 ,3 ,0); col2 += 3; cprint(LINE_CPU+5, col2, ")"); - col2 += 1; + col2 += 1; } static void poll_fsb_nothing(void) @@ -148,26 +159,26 @@ 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; } 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; - + /* 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 >> 17)&1){ /* Fill in the correct memory capabilites */ pci_conf_read(0, 24, 3, 0x44, 4, &nbxcfg); @@ -178,7 +189,7 @@ static void setup_amd64(void) /* 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 ); @@ -187,30 +198,30 @@ static void setup_amd64(void) static void poll_amd64(void) { - + unsigned long mcanb; unsigned long page, offset; unsigned long celog_syndrome; unsigned long mcanb_add; - + 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); - + /* Read the syndrome */ celog_syndrome = (mcanb >> 15)&0xFF; /* 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); - + /* Clear the error registers */ pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7F801EFC ); } @@ -222,13 +233,13 @@ static void poll_amd64(void) /* Parse the error location */ page = (mcanb_add >> 12); offset = (mcanb_add >> 3) & 0xFFF; - + /* Report the error */ print_ecc_err(page, offset, 0, 0, 0); - + /* Clear the error registers */ pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7F801EFC ); - + } } @@ -261,33 +272,33 @@ static void poll_amd751(void) } /* 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 +/* Still waiting for the CORRECT intel datasheet static void setup_i85x(void) { - ctrl.cap = ECC_CORRECT; - unsigned long drc; - - pci_conf_read(ctrl.bus, ctrl.dev, 1, 0x70, 4, &drc); - ctrl.mode = ((drc>>20)&1)?ECC_CORRECT:ECC_NONE; - + 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; + } */ @@ -299,7 +310,7 @@ static void setup_amd76x(void) /* 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]; + ctrl.mode = ddim[(ecc_mode_status >> 10)&3]; } static void poll_amd76x(void) @@ -363,60 +374,94 @@ static void setup_iE7xxx(void) 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); /* 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; - + /* checking and correcting enabled */ - if (((drc >> 20) & 3) == 2) { + 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 */ + /* 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 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; + + /* 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; + + /* 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; + } + + /* 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); +} + 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); - + 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 */ @@ -424,37 +469,37 @@ static void poll_iE7xxx(void) /* Parse the error location */ page = (celog_add & 0x0FFFFFC0) >> 6; - + /* 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); } - + 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); /* Parse the error location */ page = (uccelog_add & 0x0FFFFFC0) >> 6; - + /* 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); } - + /* 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) @@ -496,7 +541,7 @@ static void poll_i440gx(void) 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) { @@ -506,7 +551,7 @@ static void setup_i840(void) /* 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]; + ctrl.mode = ddim[(mchcfg >> 7)&3]; } static void poll_i840(void) @@ -549,25 +594,25 @@ static void setup_i875(void) 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)); - + /* 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); - + if (((*ptr >> 18)&1) == 1) { ctrl.mode = ECC_CORRECT; } - + /* Reseting state */ pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 0x81); - + } static void setup_i925(void) @@ -575,15 +620,23 @@ static void setup_i925(void) // Activate MMR I/O ulong dev0; - + long tolm; + // Current stepping of i925X does not support ECC ctrl.cap = ECC_CORRECT; ctrl.mode = ECC_NONE; - - pci_conf_read( 0, 0, 0, 0x54, 4, &dev0); + + pci_conf_read( 0, 0, 0, 0x54, 4, &dev0); dev0 = dev0 | 0x10000000; - pci_conf_write( 0, 0, 0, 0x54, 4, dev0); - + 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 } @@ -604,7 +657,7 @@ static void poll_i875(void) 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; @@ -703,7 +756,7 @@ static void setup_i850(void) /* 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]; + ctrl.mode = ddim[(mchcfg >> 7)&3]; } static void poll_i850(void) @@ -745,10 +798,10 @@ static void setup_i860(void) /* 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]; + 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_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, errsts & 3); } @@ -782,10 +835,62 @@ static void poll_i860(void) } } -/* ------------------ Here the code for FSB detection ------------------ */ -/* --------------------------------------------------------------------- */ +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); + 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); + + /* Parse the error location */ + page = (celog_add & 0x7FFFFFFC) >> 2; + + /* 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); + } + + 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); + + /* Parse the error location */ + page = (uccelog_add & 0x7FFFFFFC) >> 2; + + /* 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); + } + + /* Check if DRAM_NERR contains data */ + if (nerr & 0x4747) { + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 2, nerr & 0x4747); + } +} + + +/* ------------------ Here the code for FSB detection ------------------ */ +/* --------------------------------------------------------------------- */ static float athloncoef[] = {11, 11.5, 12.0, 12.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0, 10.5}; static float athloncoef2[] = {12, 19.0, 12.0, 20.0, 13.0, 13.5, 14.0, 21.0, 15.0, 22, 16.0, 16.5, 17.0, 18.0, 23.0, 24.0}; @@ -796,23 +901,23 @@ static int getP4PMmultiplier(void) unsigned int msr_lo, msr_hi; int coef; /* Find multiplier (by MSR) */ - - if (cpu_id.type == 6) { + + if (cpu_id.type == 6) { rdmsr(0x2A, msr_lo, msr_hi); coef = (msr_lo >> 22) & 0x1F; - } - else + } + else { - if (cpu_id.model < 2) + if (cpu_id.model < 2) { - rdmsr(0x2A, msr_lo, msr_hi); - coef = (msr_lo >> 8) & 0xF; - coef = p4model1ratios[coef]; - } - else + rdmsr(0x2A, msr_lo, msr_hi); + coef = (msr_lo >> 8) & 0xF; + coef = p4model1ratios[coef]; + } + else { - rdmsr(0x2C, msr_lo, msr_hi); - coef = (msr_lo >> 24) & 0x1F; + rdmsr(0x2C, msr_lo, msr_hi); + coef = (msr_lo >> 24) & 0x1F; } } return coef; @@ -829,28 +934,28 @@ static void poll_fsb_amd64(void) { float coef; coef = 10; - + /* First, got the FID by MSR */ /* First look if Cool 'n Quiet is supported to choose the best msr */ if (((cpu_id.pwrcap >> 1) & 1) == 1) { - rdmsr(0xc0010042, mcgsrl, mcgsth); - fid = (mcgsrl & 0x3F); + rdmsr(0xc0010042, mcgsrl, mcgsth); + fid = (mcgsrl & 0x3F); } else { - rdmsr(0xc0010015, mcgsrl, mcgsth); - fid = ((mcgsrl >> 24)& 0x3F); + rdmsr(0xc0010015, mcgsrl, mcgsth); + fid = ((mcgsrl >> 24)& 0x3F); } - + /* Extreme simplification. */ coef = ( fid / 2 ) + 4.0; - - /* Support for .5 coef */ - if ((fid & 1) == 1) { coef = coef + 0.5; } - + + /* Support for .5 coef */ + if ((fid & 1) == 1) { coef = coef + 0.5; } + /* Next, we need the clock ratio */ pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); temp2 = (dramchr >> 20) & 0x7; clockratio = 1; - + switch (temp2) { case 0x0: clockratio = 0.5; @@ -867,48 +972,60 @@ static void poll_fsb_amd64(void) { case 0x7: clockratio = 1; break; - } - + } + /* Compute the final DRAM Clock */ dramclock = ((extclock /1000) / coef) * clockratio; - + /* ...and print */ print_fsb_info(dramclock, "RAM : "); - + } static void poll_fsb_i925(void) { double dramclock, dramratio, fsb; - unsigned long mchcfg, mchcfg2, dev0; + unsigned long mchcfg, mchcfg2, dev0, drc, idetect; int coef = getP4PMmultiplier(); long *ptr; + 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 ((mchcfg >> 2)&1) { - if (mchcfg2 == 2) { dramratio = 0.75; } else { dramratio = 1; } + if ((drc&3) != 2) { + // We are in DDR1 Mode + if (mchcfg2 == 1) { dramratio = 0.8; } else { dramratio = 1; } } else { - switch (mchcfg2) { - case 1: - dramratio = 0.66667; - break; - case 2: - dramratio = 1; - break; - case 3: - if ((mchcfg & 1) == 0) { dramratio = 1.33334; } - else { dramratio = 1.5; } + // We are in DDR2 Mode + 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; @@ -926,18 +1043,64 @@ static void poll_fsb_i925(void) { } +static void poll_fsb_i945(void) { + + double dramclock, dramratio, fsb; + unsigned long mchcfg, dev0; + int 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; + } + + // Compute RAM Frequency + fsb = ((extclock / 1000) / coef); + dramclock = fsb * dramratio; + + // Print DRAM Freq + print_fsb_info(dramclock, "RAM : "); + + /* Print FSB (only if ECC is not enabled) */ + cprint(LINE_CPU+4, col +1, "- FSB : "); + col += 9; + dprint(LINE_CPU+4, col, fsb, 3,0); + col += 3; + cprint(LINE_CPU+4, col +1, "Mhz"); + col += 4; + +} + static void poll_fsb_i875(void) { double dramclock, dramratio, fsb; unsigned long mchcfg, smfs; int 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) == 3) { dramratio = 1; } if ((mchcfg&3) == 2) { if (smfs == 2) { dramratio = 1; } if (smfs == 1) { dramratio = 1.25; } @@ -948,25 +1111,25 @@ static void poll_fsb_i875(void) { if (smfs == 1) { dramratio = 0.8; } if (smfs == 0) { dramratio = 1; } } - if ((mchcfg&3) == 0) { dramratio = 0.75; } + if ((mchcfg&3) == 0) { dramratio = 0.75; } + - /* Compute RAM Frequency */ dramclock = ((extclock /1000) / coef) / dramratio; fsb = ((extclock /1000) / coef); - + /* Print DRAM Freq */ print_fsb_info(dramclock, "RAM : "); - + /* Print FSB (only if ECC is not enabled) */ - if ( ctrl.mode == ECC_NONE ) { - cprint(LINE_CPU+4, col +1, "- FSB : "); - col += 9; - dprint(LINE_CPU+4, col, fsb, 3,0); - col += 3; - cprint(LINE_CPU+4, col +1, "Mhz"); - col += 4; - } + if ( ctrl.mode == ECC_NONE ) { + cprint(LINE_CPU+4, col +1, "- FSB : "); + col += 9; + dprint(LINE_CPU+4, col, fsb, 3,0); + col += 3; + cprint(LINE_CPU+4, col +1, "Mhz"); + col += 4; + } } static void poll_fsb_p4(void) { @@ -983,11 +1146,11 @@ static void poll_fsb_p4(void) { col += 3; cprint(LINE_CPU+4, col +1, "Mhz"); col += 4; - + /* For synchro only chipsets */ pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); if (idetect == 0x2540 || idetect == 0x254C) { - print_fsb_info(fsb, "RAM : "); + print_fsb_info(fsb, "RAM : "); } } @@ -998,26 +1161,26 @@ static void poll_fsb_i855(void) { unsigned int msr_lo, msr_hi; ulong mchcfg, centri, idetect; int coef; - + pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); - + /* Find multiplier (by MSR) */ - + /* Is it a Pentium M ? */ if (cpu_id.type == 6) { - rdmsr(0x2A, msr_lo, msr_hi); - coef = (msr_lo >> 22) & 0x1F; - - /* Is it an i855GM or PM ? */ - if (idetect == 0x3580) { - cprint(LINE_CPU+4, col-1, "i855GM/GME "); - col += 10; } - + rdmsr(0x2A, msr_lo, msr_hi); + coef = (msr_lo >> 22) & 0x1F; + + /* Is it an i855GM or PM ? */ + if (idetect == 0x3580) { + cprint(LINE_CPU+4, col-1, "i855GM/GME "); + col += 10; + } } else { - rdmsr(0x2C, msr_lo, msr_hi); - coef = (msr_lo >> 24) & 0x1F; - cprint(LINE_CPU+4, col-1, "i852PM/GM "); - col += 9; + rdmsr(0x2C, msr_lo, msr_hi); + coef = (msr_lo >> 24) & 0x1F; + cprint(LINE_CPU+4, col-1, "i852PM/GM "); + col += 9; } fsb = ((extclock /1000) / coef); @@ -1028,31 +1191,32 @@ static void poll_fsb_i855(void) { cprint(LINE_CPU+4, col +1, "Mhz"); col += 4; /* Is it a Centrino platform or only an i855 platform ? */ - pci_conf_read( 2, 2, 0, 0x02, 2, ¢ri); + pci_conf_read( 2, 2, 0, 0x02, 2, ¢ri); if (centri == 0x1043) { cprint(LINE_CPU+4, col +1, "/ Centrino Mobile Platform"); } - else { cprint(LINE_CPU+4, col +1, "/ Mobile Platform"); } - + else { cprint(LINE_CPU+4, col +1, "/ Mobile Platform"); } + /* Compute DRAM Clock */ 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 == 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 >> 11)&1) == 0) { dramratio = 1; } + if (((mchcfg >> 10)&3) == 0) { dramratio = 1; } + else if (((mchcfg >> 10)&3) == 0) { dramratio = 1.666667; } else { dramratio = 1.333333333; } } - - + + dramclock = fsb * dramratio; - + /* ...and print */ print_fsb_info(dramclock, "RAM : "); @@ -1065,18 +1229,18 @@ static void poll_fsb_amd32(void) { unsigned long temp; double dramclock; double coef2; - + /* 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; + dramclock = (extclock /1000) / coef2; /* ...and print */ print_fsb_info(dramclock, "FSB : "); @@ -1092,55 +1256,55 @@ static void poll_fsb_nf2(void) { 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); } - + /* Compute the final FSB Clock */ - dramclock = ((extclock /1000) / coef) * (mem_n/mem_m); + dramclock = ((extclock /1000) / coef) * (mem_n/mem_m); fsb = ((extclock /1000) / coef); - + /* ...and print */ - + cprint(LINE_CPU+4, col, "/ FSB : "); col += 8; dprint(LINE_CPU+4, col, fsb, 3,0); col += 3; cprint(LINE_CPU+4, col +1, "Mhz"); - + print_fsb_info(dramclock, "RAM : "); - + } /* ------------------ Here the code for Timings detection ------------------ */ /* ------------------------------------------------------------------------- */ static void poll_timings_i925(void) { - ulong dev0, mch, drt, drc, dcc, temp; + // Thanks for CDH optis + ulong dev0, drt, drc, dcc, idetect, temp; long *ptr; - - //Read Offset 9C - pci_conf_read( 0, 0, 0, 0x9C, 1, &mch); - + //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; @@ -1154,61 +1318,59 @@ static void poll_timings_i925(void) { dcc = *ptr & 0xFFFFFFFF; //Determine DDR or DDR-II - if ((drc & 3) == 2) { - cprint(LINE_CPU+4, col +1, "- Type : DDR-II"); + cprint(LINE_CPU+4, col +1, "- Type : DDR-II"); } else { - cprint(LINE_CPU+4, col +1, "- Type : DDR-I"); + cprint(LINE_CPU+4, col +1, "- Type : DDR-I"); } // Now, detect timings cprint(LINE_CPU+5, col2 +1, "/ CAS : "); col2 += 9; - + // CAS Latency (tCAS) temp = ((drt >> 8)& 0x3); if ((drc & 3) == 2){ // Timings DDR-II - if (temp == 0x0) { cprint(LINE_CPU+5, col2, "5-"); } + if (temp == 0x0) { cprint(LINE_CPU+5, col2, "5-"); } else if (temp == 0x1) { cprint(LINE_CPU+5, col2, "4-"); } - else { cprint(LINE_CPU+5, col2, "3-"); } + else { cprint(LINE_CPU+5, col2, "3-"); } } else { // Timings DDR-I - if (temp == 0x0) { cprint(LINE_CPU+5, col2, "3-"); } + if (temp == 0x0) { cprint(LINE_CPU+5, col2, "3-"); } else if (temp == 0x1) { cprint(LINE_CPU+5, col2, "2.5-"); col2 +=2;} - else { cprint(LINE_CPU+5, col2, "2-"); } + else { cprint(LINE_CPU+5, col2, "2-"); } } col2 +=2; - + // RAS-To-CAS (tRCD) - temp = ((drt >> 4)& 0x3); - if (temp == 0x0) { cprint(LINE_CPU+5, col2, "2-"); } - else if (temp == 0x1) { cprint(LINE_CPU+5, col2, "3-"); } - else if (temp == 0x2) { cprint(LINE_CPU+5, col2, "4-"); } - else { cprint(LINE_CPU+5, col2, "5-"); } + dprint(LINE_CPU+5, col2, ((drt >> 4)& 0x3)+2, 1 ,0); + cprint(LINE_CPU+5, col2+1, "-"); col2 +=2; // RAS Precharge (tRP) - temp = (drt&0x3); - if (temp == 0x0) { cprint(LINE_CPU+5, col2, "2-"); } - else if (temp == 0x1) { cprint(LINE_CPU+5, col2, "3-"); } - else if (temp == 0x2) { cprint(LINE_CPU+5, col2, "4-"); } - else { cprint(LINE_CPU+5, col2, "5-"); } + dprint(LINE_CPU+5, col2, (drt&0x3)+2, 1 ,0); + cprint(LINE_CPU+5, col2+1, "-"); col2 +=2; - + // RAS Active to precharge (tRAS) - temp = ((drt >> 20)& 0xF); + // If Lakeport, than change tRAS computation (Thanks to CDH, again) + if (idetect == 0x2770) + temp = ((drt >> 19)& 0x1F); + else + temp = ((drt >> 20)& 0x0F); + dprint(LINE_CPU+5, col2, temp , 1 ,0); (temp < 10)?(col2 += 1):(col2 += 2); - + cprint(LINE_CPU+5, col2+1, "/"); col2 +=2; - + temp = (dcc&0x3); - if (temp == 1) { cprint(LINE_CPU+5, col2, " Dual Channel (Asymmetric)"); } + if (temp == 1) { cprint(LINE_CPU+5, col2, " Dual Channel (Asymmetric)"); } else if (temp == 2) { cprint(LINE_CPU+5, col2, " Dual Channel (Interleaved)"); } - else { cprint(LINE_CPU+5, col2, " Single Channel (64 bits)"); } - + else { cprint(LINE_CPU+5, col2, " Single Channel (64 bits)"); } + } static void poll_timings_i875(void) { @@ -1218,14 +1380,14 @@ static void poll_timings_i875(void) { float cas; int rcd, rp, ras; long *ptr, *ptr2; - + /* Read the MMR Base Address & Define the pointer */ pci_conf_read( 0, 6, 0, 0x10, 4, &dev6); - + /* Now, the PAT ritual ! (Kant and Luciano will love this) */ pci_conf_read( 0, 6, 0, 0x40, 4, &dev62); ptr2=(long*)(dev6+0x68); - + if ((dev62&0x3) == 0 && ((*ptr2 >> 14)&1) == 1) { cprint(LINE_CPU+4, col +1, "- PAT : Enabled"); } else { @@ -1233,12 +1395,12 @@ static void poll_timings_i875(void) { } /* 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; } @@ -1246,32 +1408,56 @@ static void poll_timings_i875(void) { // 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 timings print_timings_info(cas, rcd, rp, ras); - + // Print 64 or 128 bits mode - if (((*ptr2 >> 21)&1) == 1) { - cprint(LINE_CPU+5, col2, "/ Dual Channel (128 bits)"); + if (((*ptr2 >> 21)&3) > 1) { + cprint(LINE_CPU+5, col2, "/ Dual Channel (128 bits)"); } else { - cprint(LINE_CPU+5, col2, "/ Single Channel (64 bits)"); + cprint(LINE_CPU+5, col2, "/ Single Channel (64 bits)"); } } +static void poll_timings_E7520(void) { + + ulong drt, ddrcsr; + float cas; + int rcd, rp, ras; + + 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; + + print_timings_info(cas, rcd, rp, ras); + + if ((ddrcsr & 0xF) >= 0xC) { + cprint(LINE_CPU+5, col2, "/ Dual Channel (128 bits)"); + } else { + cprint(LINE_CPU+5, col2, "/ Single Channel (64 bits)"); + } +} + + static void poll_timings_i855(void) { ulong drt, temp; pci_conf_read( 0, 0, 0, 0x78, 4, &drt); - + /* Now, we could print some additionnals timings infos) */ cprint(LINE_CPU+5, col2 +1, "/ CAS : "); col2 += 9; - + // CAS Latency (tCAS) temp = ((drt >> 4)&0x1); if (temp == 0x0) { cprint(LINE_CPU+5, col2, "2.5-"); col2 += 4; } @@ -1288,12 +1474,12 @@ static void poll_timings_i855(void) { if (temp == 0x0) { cprint(LINE_CPU+5, col2, "3-"); } else { cprint(LINE_CPU+5, col2, "2-"); } col2 +=2; - + // RAS Active to precharge (tRAS) - temp = ((drt >> 9)& 0x3); - if (temp == 0x0) { cprint(LINE_CPU+5, col2, "10"); col2 +=7; } - if (temp == 0x1) { cprint(LINE_CPU+5, col2, "9"); col2 +=6; } - if (temp == 0x2) { cprint(LINE_CPU+5, col2, "8"); col2 +=5; } + temp = 7-((drt >> 9)& 0x3); + if (temp == 0x0) { cprint(LINE_CPU+5, col2, "7"); } + if (temp == 0x1) { cprint(LINE_CPU+5, col2, "6"); } + if (temp == 0x2) { cprint(LINE_CPU+5, col2, "5"); } col2 +=1; } @@ -1303,23 +1489,23 @@ static void poll_timings_E750x(void) { ulong drt, drc, temp; float cas; int rcd, rp, ras; - + 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; }; temp = ((drt >> 9) & 3); if (temp == 2) { ras = 5; } else if (temp == 1) { ras = 6; } else { ras = 7; } - + print_timings_info(cas, rcd, rp, ras); - + if (((drc >> 22)&1) == 1) { - cprint(LINE_CPU+5, col2, "/ Dual Channel (128 bits)"); + cprint(LINE_CPU+5, col2, "/ Dual Channel (128 bits)"); } else { - cprint(LINE_CPU+5, col2, "/ Single Channel (64 bits)"); + cprint(LINE_CPU+5, col2, "/ Single Channel (64 bits)"); } } @@ -1333,7 +1519,7 @@ static void poll_timings_i852(void) { /* Now, we could print some additionnals timings infos) */ cprint(LINE_CPU+5, col2 +1, "/ CAS : "); col2 += 9; - + // CAS Latency (tCAS) temp = ((drt >> 5)&0x1); if (temp == 0x0) { cprint(LINE_CPU+5, col2, "2.5-"); col2 += 4; } @@ -1352,7 +1538,7 @@ static void poll_timings_i852(void) { if (temp == 0x1) { cprint(LINE_CPU+5, col2, "3-"); } else { cprint(LINE_CPU+5, col2, "2-"); } col2 +=2; - + // RAS Active to precharge (tRAS) temp = ((drt >> 9)& 0x3); if (temp == 0x0) { cprint(LINE_CPU+5, col2, "8"); col2 +=7; } @@ -1368,19 +1554,19 @@ static void poll_timings_amd64(void) { ulong dramtlr, dramclr; int temp; int trcd, trp, tras ; - + cprint(LINE_CPU+5, col2 +1, "/ CAS : "); col2 += 9; - + pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr); pci_conf_read(0, 24, 2, 0x90, 4, &dramclr); - + // CAS Latency (tCAS) temp = (dramtlr & 0x7); if (temp == 0x1) { cprint(LINE_CPU+5, col2, "2-"); col2 +=2; } if (temp == 0x2) { cprint(LINE_CPU+5, col2, "3-"); col2 +=2; } if (temp == 0x5) { cprint(LINE_CPU+5, col2, "2.5-"); col2 +=4; } - + // RAS-To-CAS (tRCD) trcd = ((dramtlr >> 12) & 0x7); dprint(LINE_CPU+5, col2, trcd , 1 ,0); @@ -1390,23 +1576,23 @@ static void poll_timings_amd64(void) { trp = ((dramtlr >> 24) & 0x7); dprint(LINE_CPU+5, col2, trp , 1 ,0); cprint(LINE_CPU+5, col2 +1, "-"); col2 +=2; - + // RAS Active to precharge (tRAS) tras = ((dramtlr >> 20) & 0xF); if (tras < 10){ dprint(LINE_CPU+5, col2, tras , 1 ,0); col2 += 1; } else { - dprint(LINE_CPU+5, col2, tras , 2 ,0); col2 += 2; + dprint(LINE_CPU+5, col2, tras , 2 ,0); col2 += 2; } cprint(LINE_CPU+5, col2+1, "/"); col2 +=2; - + // Print 64 or 128 bits mode - + if (((dramclr >> 16)&1) == 1) { - cprint(LINE_CPU+5, col2, " Dual Channel (128 bits)"); + cprint(LINE_CPU+5, col2, " Dual Channel (128 bits)"); col2 +=24; } else { - cprint(LINE_CPU+5, col2, " Single Channel (64 bits)"); + cprint(LINE_CPU+5, col2, " Single Channel (64 bits)"); col2 +=15; } } @@ -1415,7 +1601,7 @@ static void poll_timings_nf2(void) { ulong dramtlr, dramtlr2, dramtlr3, temp; ulong dimm1p, dimm2p, dimm3p; - + 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); @@ -1425,40 +1611,40 @@ static void poll_timings_nf2(void) { cprint(LINE_CPU+5, col2 +1, "/ CAS : "); col2 += 9; - + // CAS Latency (tCAS) temp = ((dramtlr2 >> 4) & 0x7); if (temp == 0x2) { cprint(LINE_CPU+5, col2, "2-"); col2 +=2; } if (temp == 0x3) { cprint(LINE_CPU+5, col2, "3-"); col2 +=2; } if (temp == 0x6) { cprint(LINE_CPU+5, col2, "2.5-"); col2 +=4; } - + // RAS-To-CAS (tRCD) temp = ((dramtlr >> 20) & 0xF); dprint(LINE_CPU+5, col2, temp , 1 ,0); cprint(LINE_CPU+5, col2 +1, "-"); col2 +=2; - + // RAS Precharge (tRP) temp = ((dramtlr >> 28) & 0xF); dprint(LINE_CPU+5, col2, temp , 1 ,0); cprint(LINE_CPU+5, col2 +1, "-"); col2 +=2; - + // RAS Active to precharge (tRAS) temp = ((dramtlr >> 15) & 0xF); if (temp < 10){ - dprint(LINE_CPU+5, col2, temp , 1 ,0); col2 += 1; + dprint(LINE_CPU+5, col2, temp , 1 ,0); col2 += 1; } else { - dprint(LINE_CPU+5, col2, temp , 2 ,0); col2 += 2; + dprint(LINE_CPU+5, col2, temp , 2 ,0); col2 += 2; } - cprint(LINE_CPU+5, col2+1, "/"); col2 +=2; - + cprint(LINE_CPU+5, col2+1, "/"); col2 +=2; + // 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 ) { - cprint(LINE_CPU+5, col2, " Dual Channel (128 bits)"); + cprint(LINE_CPU+5, col2, " Dual Channel (128 bits)"); col2 +=24; } else { - cprint(LINE_CPU+5, col2, " Single Channel (64 bits)"); + cprint(LINE_CPU+5, col2, " Single Channel (64 bits)"); col2 +=15; } @@ -1467,50 +1653,50 @@ static void poll_timings_nf2(void) { /* static void poll_timings_kt266(void) { - ulong dramtlr, dramtlr2, temp; + ulong dramtlr, dramtlr2, temp; pci_conf_read(0, 0, 0, 0x64, 1, &dramtlr); pci_conf_read(0, 0, 0, 0x02, 2, &dramtlr2); - cprint(LINE_CPU+5, col2 +1, "/ CAS : "); - col2 += 9; - - // CAS Latency (tCAS) - temp = ((dramtlr >> 4)&3); - if (temp == 0x0) { cprint(LINE_CPU+5, col2, "1-"); col2 +=2; } - if (temp == 0x1) { cprint(LINE_CPU+5, col2, "2-"); col2 +=2; } - if (temp == 0x3) { cprint(LINE_CPU+5, col2, "3-"); col2 +=2; } - if (temp == 0x2) { cprint(LINE_CPU+5, col2, "2.5-"); col2 +=4; } - - // RAS-To-CAS (tRCD) - if (((dramtlr >> 2)&1) == 0) { cprint(LINE_CPU+5, col2, "2-"); } - else { cprint(LINE_CPU+5, col2, "3-"); } - col2 +=2; - - // RAS Precharge (tRP) - if (((dramtlr >> 7)&1) == 0) { cprint(LINE_CPU+5, col2, "2-"); } - else { cprint(LINE_CPU+5, col2, "3-"); } - col2 +=2; - - // RAS Active to precharge (tRAS) - if (dramtlr2 == 0x3099) { - if (((dramtlr >> 6)&1) == 0) { - cprint(LINE_CPU+5, col2, "5"); } - else { cprint(LINE_CPU+5, col2, "6"); } - } else { - if (((dramtlr >> 6)&1) == 0) { - cprint(LINE_CPU+5, col2, "6"); } - else { cprint(LINE_CPU+5, col2, "7"); } - } - col2 +=1; - - - cprint(LINE_CPU+5, col2+1, "/ Interleave : "); col2 +=16; - temp = dramtlr&3; - - if (temp == 0) { cprint(LINE_CPU+5, col2, "Disabled"); } - if (temp == 1) { cprint(LINE_CPU+5, col2, "2-Way"); } - if (temp == 2) { cprint(LINE_CPU+5, col2, "4-Way"); } + cprint(LINE_CPU+5, col2 +1, "/ CAS : "); + col2 += 9; + + // CAS Latency (tCAS) + temp = ((dramtlr >> 4)&3); + if (temp == 0x0) { cprint(LINE_CPU+5, col2, "1-"); col2 +=2; } + if (temp == 0x1) { cprint(LINE_CPU+5, col2, "2-"); col2 +=2; } + if (temp == 0x3) { cprint(LINE_CPU+5, col2, "3-"); col2 +=2; } + if (temp == 0x2) { cprint(LINE_CPU+5, col2, "2.5-"); col2 +=4; } + + // RAS-To-CAS (tRCD) + if (((dramtlr >> 2)&1) == 0) { cprint(LINE_CPU+5, col2, "2-"); } + else { cprint(LINE_CPU+5, col2, "3-"); } + col2 +=2; + + // RAS Precharge (tRP) + if (((dramtlr >> 7)&1) == 0) { cprint(LINE_CPU+5, col2, "2-"); } + else { cprint(LINE_CPU+5, col2, "3-"); } + col2 +=2; + + // RAS Active to precharge (tRAS) + if (dramtlr2 == 0x3099) { + if (((dramtlr >> 6)&1) == 0) { + cprint(LINE_CPU+5, col2, "5"); } + else { cprint(LINE_CPU+5, col2, "6"); } + } else { + if (((dramtlr >> 6)&1) == 0) { + cprint(LINE_CPU+5, col2, "6"); } + else { cprint(LINE_CPU+5, col2, "7"); } + } + col2 +=1; + + + cprint(LINE_CPU+5, col2+1, "/ Interleave : "); col2 +=16; + temp = dramtlr&3; + + if (temp == 0) { cprint(LINE_CPU+5, col2, "Disabled"); } + if (temp == 1) { cprint(LINE_CPU+5, col2, "2-Way"); } + if (temp == 2) { cprint(LINE_CPU+5, col2, "4-Way"); } } */ @@ -1518,53 +1704,35 @@ static void poll_timings_kt266(void) { /* ------------------ Let's continue ------------------ */ /* ---------------------------------------------------- */ - -struct pci_memory_controller { - unsigned vendor; - unsigned device; - char *name; - int tested; - void (*poll_fsb)(void); - void (*poll_timings)(void); - void (*setup_ecc)(void); - void (*poll_errors)(void); -}; - static 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", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd751, poll_amd751 }, { 0x1022, 0x700c, "AMD 762", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd76x, poll_amd76x }, { 0x1022, 0x700e, "AMD 761", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd76x, poll_amd76x }, { 0x1022, 0x1100, "AMD 8000", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, { 0x1022, 0x7454, "AMD 8000", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, - - /* Motorola */ - { 0x1057, 0x4802, "Falcon", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - - /* Apple */ - { 0x106b, 0x0001, "Bandit", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - + /* SiS */ { 0x1039, 0x0600, "SiS 600", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, { 0x1039, 0x0620, "SiS 620", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, { 0x1039, 0x5600, "SiS 5600", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0645, "SiS 645", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0646, "SiS 645DX", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0630, "SiS 630", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0650, "SiS 650", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0651, "SiS 651", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0730, "SiS 730", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0735, "SiS 735", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0740, "SiS 740", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0745, "SiS 745", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0755, "SiS 755", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, - { 0x1039, 0x0748, "SiS 748", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0655, "SiS 655", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0648, "SiS 648", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0661, "SiS 661", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0645, "SiS 645", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0646, "SiS 645DX", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0630, "SiS 630", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0650, "SiS 650", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0651, "SiS 651", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0730, "SiS 730", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0735, "SiS 735", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0740, "SiS 740", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0745, "SiS 745", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0755, "SiS 755", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, + { 0x1039, 0x0748, "SiS 748", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0655, "SiS 655", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0648, "SiS 648", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0661, "SiS 661", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, /* ALi */ { 0x10b9, 0x1531, "Aladdin 4", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, @@ -1576,14 +1744,14 @@ static struct pci_memory_controller controllers[] = { { 0x1002, 0x5831, "ATi Radeon 9100 IGP", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, { 0x1002, 0x5832, "ATi Radeon 9100 IGP", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, { 0x1002, 0x5833, "ATi Radeon 9100 IGP", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - + /* nVidia */ { 0x10de, 0x01A4, "nVidia nForce", 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, 0x00D1, "nVidia nForce3", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, { 0x10de, 0x00E1, "nForce3 250", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, { 0x10de, 0x005E, "nVidia nForce4", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, - + /* VIA */ { 0x1106, 0x0305, "VIA KT133/KT133A", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, { 0x1106, 0x0391, "vt8371", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, @@ -1618,7 +1786,7 @@ static struct pci_memory_controller controllers[] = { { 0x8086, 0x1250, "Intel i430hx", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, { 0x8086, 0x1A21, "Intel i840", 0, poll_fsb_nothing, poll_timings_nothing, setup_i840, poll_i840 }, { 0x8086, 0x1A30, "Intel i845", 0, poll_fsb_p4, poll_timings_nothing, setup_i845, poll_i845 }, - { 0x8086, 0x2560, "Intel i845E/G/PE/GE", 0, poll_fsb_p4, poll_timings_nothing, setup_i845, poll_i845 }, + { 0x8086, 0x2560, "Intel i845E/G/PE/GE", 0, poll_fsb_p4, poll_timings_nothing, setup_i845, poll_i845 }, { 0x8086, 0x2500, "Intel i820", 0, poll_fsb_nothing, poll_timings_nothing, setup_i820, poll_i820 }, { 0x8086, 0x2530, "Intel i850", 0, poll_fsb_p4, poll_timings_nothing, setup_i850, poll_i850 }, { 0x8086, 0x2531, "Intel i860", 1, poll_fsb_nothing, poll_timings_nothing, setup_i860, poll_i860 }, @@ -1635,26 +1803,30 @@ static struct pci_memory_controller controllers[] = { { 0x8086, 0x2540, "Intel E7500", 1, poll_fsb_p4, poll_timings_E750x, setup_iE7xxx, poll_iE7xxx }, { 0x8086, 0x254C, "Intel E7501", 1, poll_fsb_p4, poll_timings_E750x, setup_iE7xxx, poll_iE7xxx }, { 0x8086, 0x255d, "Intel E7205", 0, poll_fsb_p4, poll_timings_nothing, setup_iE7xxx, poll_iE7xxx }, + { 0x8086, 0x3592, "Intel E7320", 1, poll_fsb_p4, poll_timings_E7520, setup_iE7520, poll_iE7520 }, + { 0x8086, 0x3590, "Intel E7520", 1, poll_fsb_p4, poll_timings_E7520, setup_iE7520, poll_iE7520 }, { 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_i875 }, + { 0x8086, 0x2578, "Intel i875P", 0, poll_fsb_i875, poll_timings_i875, setup_i875, poll_i875 }, { 0x8086, 0x2550, "Intel E7505", 0, poll_fsb_p4, poll_timings_nothing, setup_iE7xxx, poll_iE7xxx }, { 0x8086, 0x3580, "Intel ", 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 }, }; static void print_memory_controller(void) { /* Print memory controller info */ - + int d; char *name; if (ctrl.index == 0) { return; } - + /* Print the controller name */ name = controllers[ctrl.index].name; col = 10; @@ -1662,7 +1834,7 @@ static void print_memory_controller(void) /* Now figure out how much I just printed */ while(name[col - 10] != '\0') { col++; - } + } /* Now print the memory controller capabilities */ cprint(LINE_CPU+4, col, " "); col++; if (ctrl.cap == ECC_UNKNOWN) { @@ -1709,8 +1881,8 @@ static void print_memory_controller(void) cprint(LINE_CPU+4, col +7, on?"+ ":"- "); col += 9; } - - + + /* Print advanced caracteristics */ col2 = 0; d = get_key(); @@ -2,13 +2,13 @@ * * Released under version 2 of the Gnu Public License. * By Chris Brady, cbrady@sgi.com - */ + */ #define SETUPSECS 4 /* Number of setup sectors */ /* * Caution!! There is magic in the build process. Read - * README.build-process before you change anything. + * README.build-process before you change anything. * Unlike earlier versions all of the settings are in defs.h * so the build process should be more robust. */ @@ -1,10 +1,10 @@ // This is the extra stuff added to the memtest+ from memtest.org -// Code from Eric Nelson and Wee +// Code from Eric Nelson and Wee // (Checked without vendor-specific optimization before adding) -/* extra.c - +/* extra.c - * * Released under version 2 of the Gnu Public License. - * + * */ #include "test.h" @@ -23,18 +23,19 @@ struct memory_controller { }; static struct memory_controller mem_ctr[] = { - + /* AMD 64*/ { 0x1022, 0x1100, 1, change_timing_amd64}, //AMD64 hypertransport link - + /* nVidia */ { 0x10de, 0x01E0, 0, change_timing_nf2}, // nforce2 - + /* Intel */ { 0x8086, 0x2570, 0, change_timing_i875}, //Intel i848/i865 - { 0x8086, 0x2578, 0, change_timing_i875}, //Intel i875P + { 0x8086, 0x2578, 0, change_timing_i875}, //Intel i875P { 0x8086, 0x2580, 0, change_timing_i925}, //Intel i915P/G { 0x8086, 0x2584, 0, change_timing_i925}, //Intel i925X + { 0x8086, 0x2770, 0, change_timing_i925}, //Intel Lakeport { 0x8086, 0x3580, 0, change_timing_i852}, //Intel i852GM - i855GM/GME (But not i855PM) }; @@ -58,452 +59,390 @@ void find_memctr(void) // Basically copy from the find_controller function unsigned long a64; int i= 0; int result; - + result = pci_conf_read(0, 0, 0, PCI_VENDOR_ID, 2, &vendor); result = pci_conf_read(0, 0, 0, PCI_DEVICE_ID, 2, &device); - - pci_conf_read(0, 24, 0, 0x00, 4, &a64); - + + pci_conf_read(0, 24, 0, 0x00, 4, &a64); + if( a64 == 0x11001022) { - ctrl = 0; - return; + ctrl = 0; + return; } - + if (result == 0) { for(i = 1; i < sizeof(mem_ctr)/sizeof(mem_ctr[0]); i++) { if ((mem_ctr[i].vendor == vendor) && - (mem_ctr[i].device == device)) - { + (mem_ctr[i].device == device)) + { ctrl = i; return; - } + } } } - ctrl = -1; + ctrl = -1; } void a64_parameter(void) { - ulong dramtlr, temp, l, result; - - result = pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr); - if (result == 0) + ulong dramtlr; + + if ( 0 == pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr) ) { - temp = dramtlr; - - l = ((temp>>4) & 0x0F); - switch(l){ - case 0x0 : a64.t_rct = 7; break; - case 0x1 : a64.t_rct = 8; break; - case 0x2 : a64.t_rct = 9; break; - case 0x3 : a64.t_rct = 10; break; - case 0x4 : a64.t_rct = 11; break; - case 0x5 : a64.t_rct = 12; break; - case 0x6 : a64.t_rct = 13; break; - case 0x7 : a64.t_rct = 14; break; - case 0x8 : a64.t_rct = 15; break; - case 0x9 : a64.t_rct = 16; break; - case 0xA : a64.t_rct = 17; break; - case 0xB : a64.t_rct = 18; break; - case 0xC : a64.t_rct = 19; break; - case 0xD : a64.t_rct = 20; break; - } - - l = ((temp>>16) & 0x7); - a64.t_rrd = l; - - l = ((temp>>28) & 0x1); - switch(l){ - case 0x0 : a64.t_wr = 2; break; - case 0x1 : a64.t_wr = 3; break; - } + a64.t_rct = 7 + ((dramtlr>>4) & 0x0F); + a64.t_rrd = 0 + ((dramtlr>>16) & 0x7); + a64.t_wr = 2 + ((dramtlr>>28) & 0x1); } - - result = pci_conf_read(0, 24, 2, 0x8C, 4, &dramtlr); - if (result == 0) + + if ( 0 == pci_conf_read(0, 24, 2, 0x8C, 4, &dramtlr) ) { - temp = dramtlr; - - l = ((temp>>4) & 0x07); - switch(l){ - case 0x0 : a64.t_rwt = 1; break; - case 0x1 : a64.t_rwt = 2; break; - case 0x2 : a64.t_rwt = 3; break; - case 0x3 : a64.t_rwt = 4; break; - case 0x4 : a64.t_rwt = 5; break; - case 0x5 : a64.t_rwt = 6; break; - } - - l = (temp & 0x1); - a64.t_wrt = l + 1; - - l = ((temp>>11) & 0x3); - switch(l){ - case 0x0 : a64.t_ref = 1; break; - case 0x1 : a64.t_ref = 2; break; - case 0x2 : a64.t_ref = 3; break; - } + a64.t_rwt = 1 + ((dramtlr>>4) & 0x07); + a64.t_wrt = 1 + (dramtlr & 0x1); + a64.t_ref = 1 + ((dramtlr>>11) & 0x3); } - - result = pci_conf_read(0, 24, 2, 0x90, 4, &dramtlr); - if (result == 0 ) + + if ( 0 == pci_conf_read(0, 24, 2, 0x90, 4, &dramtlr) ) { - temp = dramtlr; - - l = ((temp>>28) & 0x1); - switch(l){ - case 0x0 : a64.t_en2t = 1; break; - case 0x1 : a64.t_en2t = 2; break; - } - - l = ((temp>>14) & 0x3); - switch(l){ - case 0x0 : a64.t_rwqb = 2; break; - case 0x1 : a64.t_rwqb = 4; break; - case 0x2 : a64.t_rwqb = 8; break; - case 0x3 : a64.t_rwqb = 16; break; - } + a64.t_en2t = 1 + ((dramtlr>>28) & 0x1); + a64.t_rwqb = 2 << ((dramtlr>>14) & 0x3); } } void change_timing(int cas, int rcd, int rp, int ras) -{ - find_memctr(); +{ + find_memctr(); if ((ctrl == -1) || ( ctrl > sizeof(mem_ctr)/sizeof(mem_ctr[0]))) { - return; + return; } - else - { + mem_ctr[ctrl].change_timing(cas, rcd, rp, ras); restart(); - } } void amd64_option() { int rwt=0, wrt=0, ref=0, en2t=0, rct=0, rrd=0, rwqb=0, wr = 0, flag=0; - + if ((ctrl == -1) || ( ctrl > sizeof(mem_ctr)/sizeof(mem_ctr[0]))) { - return; + return; } - + if (mem_ctr[ctrl].worked) { - a64_parameter(); - cprint(POP_Y+1, POP_X+4, "AMD64 options"); - - cprint(POP_Y+3, POP_X+4, "(1) Rd-Wr Delay : "); - dprint(POP_Y+3, POP_X+24, a64.t_rwt, 2, 0); - - cprint(POP_Y+4, POP_X+4, "(2) Wr-Rd Delay : "); - dprint(POP_Y+4, POP_X+24, a64.t_wrt, 2, 0); - - cprint(POP_Y+5, POP_X+4, "(3) Rd/Wr Bypass : "); - dprint(POP_Y+5, POP_X+24, a64.t_rwqb, 2, 0); - - cprint(POP_Y+6, POP_X+4, "(4) Refresh Rate : "); - switch ( a64.t_ref) - { - case 1 : cprint(POP_Y+6, POP_X+23, "15.6us"); break; - case 2 : cprint(POP_Y+6, POP_X+23, " 7.8us"); break; - case 3 : cprint(POP_Y+6, POP_X+23, " 3.9us"); break; - } - cprint(POP_Y+7, POP_X+4, "(5) Command Rate :"); - dprint(POP_Y+7, POP_X+24, a64.t_en2t, 2, 0); - cprint(POP_Y+7, POP_X+26, "T "); - - cprint(POP_Y+8, POP_X+4, "(6) Row Cycle Time: "); - dprint(POP_Y+8, POP_X+24, a64.t_rct, 2, 0); - - cprint(POP_Y+9, POP_X+4, "(7) RAS-RAS Delay : "); - dprint(POP_Y+9, POP_X+24, a64.t_rrd, 2, 0); - - cprint(POP_Y+10, POP_X+4, "(8) Write Recovery: "); - dprint(POP_Y+10, POP_X+24, a64.t_wr, 2, 0); - - cprint(POP_Y+11, POP_X+4,"(0) Cancel "); - - while(!flag) - { - switch(get_key()) - { + a64_parameter(); + cprint(POP_Y+1, POP_X+4, "AMD64 options"); + + cprint(POP_Y+3, POP_X+4, "(1) Rd-Wr Delay : "); + dprint(POP_Y+3, POP_X+24, a64.t_rwt, 2, 0); + + cprint(POP_Y+4, POP_X+4, "(2) Wr-Rd Delay : "); + dprint(POP_Y+4, POP_X+24, a64.t_wrt, 2, 0); + + cprint(POP_Y+5, POP_X+4, "(3) Rd/Wr Bypass : "); + dprint(POP_Y+5, POP_X+24, a64.t_rwqb, 2, 0); + + cprint(POP_Y+6, POP_X+4, "(4) Refresh Rate : "); + switch ( a64.t_ref) + { + case 1 : cprint(POP_Y+6, POP_X+23, "15.6us"); break; + case 2 : cprint(POP_Y+6, POP_X+23, " 7.8us"); break; + case 3 : cprint(POP_Y+6, POP_X+23, " 3.9us"); break; + } + cprint(POP_Y+7, POP_X+4, "(5) Command Rate :"); + dprint(POP_Y+7, POP_X+24, a64.t_en2t, 2, 0); + cprint(POP_Y+7, POP_X+26, "T "); + + cprint(POP_Y+8, POP_X+4, "(6) Row Cycle Time: "); + dprint(POP_Y+8, POP_X+24, a64.t_rct, 2, 0); + + cprint(POP_Y+9, POP_X+4, "(7) RAS-RAS Delay : "); + dprint(POP_Y+9, POP_X+24, a64.t_rrd, 2, 0); + + cprint(POP_Y+10, POP_X+4, "(8) Write Recovery: "); + dprint(POP_Y+10, POP_X+24, a64.t_wr, 2, 0); + + cprint(POP_Y+11, POP_X+4,"(0) Cancel "); + + while(!flag) + { + switch(get_key()) + { case 2: - popclear(); - // read-to-write delay - cprint(POP_Y+3, POP_X+4, "Rd-Wr delay "); - cprint(POP_Y+4, POP_X+4, " (2 - 6 cycles)"); - cprint(POP_Y+5, POP_X+4, "Current: "); - dprint(POP_Y+5, POP_X+14, a64.t_rwt, 4, 0); - cprint(POP_Y+7, POP_X+4, "New: "); - rwt = getval(POP_Y+7, POP_X+12, 0); - amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); - break; - + popclear(); + // read-to-write delay + cprint(POP_Y+3, POP_X+4, "Rd-Wr delay "); + cprint(POP_Y+4, POP_X+4, " (2 - 6 cycles)"); + cprint(POP_Y+5, POP_X+4, "Current: "); + dprint(POP_Y+5, POP_X+14, a64.t_rwt, 4, 0); + cprint(POP_Y+7, POP_X+4, "New: "); + rwt = getval(POP_Y+7, POP_X+12, 0); + amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); + break; + case 3: - popclear(); - // read-to-write delay - cprint(POP_Y+3, POP_X+4, "Wr-Rd delay "); - cprint(POP_Y+4, POP_X+4, " (1 - 2 cycles)"); - cprint(POP_Y+5, POP_X+4, "Current: "); - dprint(POP_Y+5, POP_X+14, a64.t_wrt, 4, 0); - cprint(POP_Y+7, POP_X+4, "New: "); - wrt = getval(POP_Y+7, POP_X+12, 0); - amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); - break; - + popclear(); + // read-to-write delay + cprint(POP_Y+3, POP_X+4, "Wr-Rd delay "); + cprint(POP_Y+4, POP_X+4, " (1 - 2 cycles)"); + cprint(POP_Y+5, POP_X+4, "Current: "); + dprint(POP_Y+5, POP_X+14, a64.t_wrt, 4, 0); + cprint(POP_Y+7, POP_X+4, "New: "); + wrt = getval(POP_Y+7, POP_X+12, 0); + amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); + break; + case 4: - popclear(); - // Read write queue bypass count - cprint(POP_Y+3, POP_X+4, "Rd/Wr bypass "); - cprint(POP_Y+4, POP_X+4, " (2, 4 or 8 )"); - cprint(POP_Y+5, POP_X+4, "Current: "); - dprint(POP_Y+5, POP_X+14, a64.t_rwqb, 2, 0); - cprint(POP_Y+7, POP_X+4, "New: "); - rwqb = getval(POP_Y+7, POP_X+11, 0); - amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); - break; - + popclear(); + // Read write queue bypass count + cprint(POP_Y+3, POP_X+4, "Rd/Wr bypass "); + cprint(POP_Y+4, POP_X+4, " (2, 4 or 8 )"); + cprint(POP_Y+5, POP_X+4, "Current: "); + dprint(POP_Y+5, POP_X+14, a64.t_rwqb, 2, 0); + cprint(POP_Y+7, POP_X+4, "New: "); + rwqb = getval(POP_Y+7, POP_X+11, 0); + amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); + break; + case 5: - popclear(); - // refresh rate - cprint(POP_Y+3, POP_X+4, "Refresh rate "); - cprint(POP_Y+4, POP_X+4, "Current: "); - switch ( a64.t_ref){ - case 1 : cprint(POP_Y+4, POP_X+14, "15.6us"); break; - case 2 : cprint(POP_Y+4, POP_X+14, "7.8us "); break; - case 3 : cprint(POP_Y+4, POP_X+14, "3.9us "); break; - } - cprint(POP_Y+6, POP_X+4, "New: "); - cprint(POP_Y+7, POP_X+4, "(1) 15.6us"); - cprint(POP_Y+8, POP_X+4, "(2) 7.8us "); - cprint(POP_Y+9, POP_X+4, "(3) 3.9us "); - ref = getval(POP_Y+6, POP_X+11, 0); - amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); - break; - + popclear(); + // refresh rate + cprint(POP_Y+3, POP_X+4, "Refresh rate "); + cprint(POP_Y+4, POP_X+4, "Current: "); + switch ( a64.t_ref){ + case 1 : cprint(POP_Y+4, POP_X+14, "15.6us"); break; + case 2 : cprint(POP_Y+4, POP_X+14, "7.8us "); break; + case 3 : cprint(POP_Y+4, POP_X+14, "3.9us "); break; + } + cprint(POP_Y+6, POP_X+4, "New: "); + cprint(POP_Y+7, POP_X+4, "(1) 15.6us"); + cprint(POP_Y+8, POP_X+4, "(2) 7.8us "); + cprint(POP_Y+9, POP_X+4, "(3) 3.9us "); + ref = getval(POP_Y+6, POP_X+11, 0); + amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); + break; + case 6: - popclear(); - //Enable 2T command and addressing - cprint(POP_Y+3, POP_X+4, "Command rate:"); - cprint(POP_Y+5, POP_X+4, "(1) 1T "); //only supoprted by CG revision and later - cprint(POP_Y+6, POP_X+4, "(2) 2T "); - en2t = getval(POP_Y+3, POP_X+22, 0); - amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); - break; - + popclear(); + //Enable 2T command and addressing + cprint(POP_Y+3, POP_X+4, "Command rate:"); + cprint(POP_Y+5, POP_X+4, "(1) 1T "); //only supoprted by CG revision and later + cprint(POP_Y+6, POP_X+4, "(2) 2T "); + en2t = getval(POP_Y+3, POP_X+22, 0); + amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); + break; + case 7: - popclear(); - //Row cycle time - cprint(POP_Y+3, POP_X+4, "Row cycle time: "); - cprint(POP_Y+4, POP_X+4, " (7 - 20 cycles)"); - cprint(POP_Y+5, POP_X+4, "Current: "); - dprint(POP_Y+5, POP_X+14, a64.t_rct, 4, 0); - cprint(POP_Y+7, POP_X+4, "New: "); - rct = getval(POP_Y+7, POP_X+12, 0); - amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); - break; - + popclear(); + //Row cycle time + cprint(POP_Y+3, POP_X+4, "Row cycle time: "); + cprint(POP_Y+4, POP_X+4, " (7 - 20 cycles)"); + cprint(POP_Y+5, POP_X+4, "Current: "); + dprint(POP_Y+5, POP_X+14, a64.t_rct, 4, 0); + cprint(POP_Y+7, POP_X+4, "New: "); + rct = getval(POP_Y+7, POP_X+12, 0); + amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); + break; + case 8: - popclear(); - //Active-to-Active RAS Delay - cprint(POP_Y+3, POP_X+4, "RAS-RAS Delay: "); - cprint(POP_Y+4, POP_X+4, " (2 - 4 cycles)"); - cprint(POP_Y+5, POP_X+4, "Current: "); - dprint(POP_Y+5, POP_X+14, a64.t_rrd, 2, 0); - cprint(POP_Y+7, POP_X+4, "New: "); - rrd = getval(POP_Y+7, POP_X+12, 0); - amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); - break; - + popclear(); + //Active-to-Active RAS Delay + cprint(POP_Y+3, POP_X+4, "RAS-RAS Delay: "); + cprint(POP_Y+4, POP_X+4, " (2 - 4 cycles)"); + cprint(POP_Y+5, POP_X+4, "Current: "); + dprint(POP_Y+5, POP_X+14, a64.t_rrd, 2, 0); + cprint(POP_Y+7, POP_X+4, "New: "); + rrd = getval(POP_Y+7, POP_X+12, 0); + amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); + break; + case 9: - popclear(); - //Active-to-Active RAS Delay - cprint(POP_Y+3, POP_X+4, "Write Recovery: "); - cprint(POP_Y+4, POP_X+4, " (2 - 3 cycles)"); - cprint(POP_Y+5, POP_X+4, "Current: "); - dprint(POP_Y+5, POP_X+14, a64.t_wr, 2, 0); - cprint(POP_Y+7, POP_X+4, "New: "); - wr = getval(POP_Y+7, POP_X+12, 0); - amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); - break; - + popclear(); + //Active-to-Active RAS Delay + cprint(POP_Y+3, POP_X+4, "Write Recovery: "); + cprint(POP_Y+4, POP_X+4, " (2 - 3 cycles)"); + cprint(POP_Y+5, POP_X+4, "Current: "); + dprint(POP_Y+5, POP_X+14, a64.t_wr, 2, 0); + cprint(POP_Y+7, POP_X+4, "New: "); + wr = getval(POP_Y+7, POP_X+12, 0); + amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); + break; + case 11: case 57: - flag++; - /* 0/CR - Cancel */ - break; + flag++; + /* 0/CR - Cancel */ + break; } - } + } } } void get_option() { int cas =0, rp=0, rcd=0, ras=0, sflag = 0 ; - + while(!sflag) - { - switch(get_key()) - { - case 2: - popclear(); - cas = get_cas(); - popclear(); - - cprint(POP_Y+3, POP_X+8, "tRCD: "); - rcd = getval(POP_Y+3, POP_X+15, 0); - popclear(); - - cprint(POP_Y+3, POP_X+8, "tRP: "); - rp = getval(POP_Y+3, POP_X+15, 0); - popclear(); - - cprint(POP_Y+3, POP_X+8, "tRAS: "); - ras = getval(POP_Y+3, POP_X+15, 0); - popclear(); - change_timing(cas, rcd, rp, ras); - break; - - case 3: - popclear(); - cas = get_cas(); - change_timing(cas, 0, 0, 0); - sflag++; - break; - - - case 4: - popclear(); - cprint(POP_Y+3, POP_X+8, "tRCD: "); - rcd =getval(POP_Y+3, POP_X+15, 0); - change_timing(0, rcd, 0, 0); - sflag++; - break; - - case 5: - popclear(); - cprint(POP_Y+3, POP_X+8, "tRP: "); - rp =getval(POP_Y+3, POP_X+15, 0); - change_timing(0, 0, rp, 0); - sflag++; - break; - - case 6: - popclear(); - cprint(POP_Y+3, POP_X+8, "tRAS: "); - ras =getval(POP_Y+3, POP_X+15, 0); - change_timing(0, 0, 0, ras); - sflag++; - break; - - case 7: - popclear(); - amd64_option(); - sflag++; - popclear(); - break; - - case 8: - break; - - case 11: - case 57: - sflag++; + { + switch(get_key()) + { + case 2: + popclear(); + cas = get_cas(); + popclear(); + + cprint(POP_Y+3, POP_X+8, "tRCD: "); + rcd = getval(POP_Y+3, POP_X+15, 0); + popclear(); + + cprint(POP_Y+3, POP_X+8, "tRP: "); + rp = getval(POP_Y+3, POP_X+15, 0); + popclear(); + + cprint(POP_Y+3, POP_X+8, "tRAS: "); + ras = getval(POP_Y+3, POP_X+15, 0); + popclear(); + change_timing(cas, rcd, rp, ras); + break; + + case 3: + popclear(); + cas = get_cas(); + change_timing(cas, 0, 0, 0); + sflag++; + break; + + case 4: + popclear(); + cprint(POP_Y+3, POP_X+8, "tRCD: "); + rcd =getval(POP_Y+3, POP_X+15, 0); + change_timing(0, rcd, 0, 0); + sflag++; + break; + + case 5: + popclear(); + cprint(POP_Y+3, POP_X+8, "tRP: "); + rp =getval(POP_Y+3, POP_X+15, 0); + change_timing(0, 0, rp, 0); + sflag++; + break; + + case 6: + popclear(); + cprint(POP_Y+3, POP_X+8, "tRAS: "); + ras =getval(POP_Y+3, POP_X+15, 0); + change_timing(0, 0, 0, ras); + sflag++; + break; + + case 7: + popclear(); + amd64_option(); + sflag++; + popclear(); + break; + + case 8: + break; + + case 11: + case 57: + sflag++; /* 0/CR - Cancel */ - break; - } + break; + } } } void get_option_1() { int rp=0, rcd=0, ras=0, sflag = 0 ; - + while(!sflag) - { - switch(get_key()) - { - case 2: - popclear(); - cprint(POP_Y+3, POP_X+8, "tRCD: "); - rcd = getval(POP_Y+3, POP_X+15, 0); - popclear(); - - cprint(POP_Y+3, POP_X+8, "tRP: "); - rp = getval(POP_Y+3, POP_X+15, 0); - popclear(); - - cprint(POP_Y+3, POP_X+8, "tRAS: "); - ras = getval(POP_Y+3, POP_X+15, 0); - popclear(); - change_timing(0, rcd, rp, ras); - break; - - case 3: - popclear(); - cprint(POP_Y+3, POP_X+8, "tRCD: "); - rcd =getval(POP_Y+3, POP_X+15, 0); - change_timing(0, rcd, 0, 0); - break; - - case 4: - popclear(); - cprint(POP_Y+3, POP_X+8, "tRP: "); - rp =getval(POP_Y+3, POP_X+15, 0); - change_timing(0, 0, rp, 0); - break; - - case 5: - popclear(); - cprint(POP_Y+3, POP_X+8, "tRAS: "); - ras =getval(POP_Y+3, POP_X+15, 0); - change_timing(0, 0, 0, ras); - break; - - case 6: - popclear(); - amd64_option(); - sflag++; - popclear(); - break; - - case 7: - break; - - case 11: - case 57: - sflag++; + { + switch(get_key()) + { + case 2: + popclear(); + cprint(POP_Y+3, POP_X+8, "tRCD: "); + rcd = getval(POP_Y+3, POP_X+15, 0); + popclear(); + + cprint(POP_Y+3, POP_X+8, "tRP: "); + rp = getval(POP_Y+3, POP_X+15, 0); + popclear(); + + cprint(POP_Y+3, POP_X+8, "tRAS: "); + ras = getval(POP_Y+3, POP_X+15, 0); + popclear(); + change_timing(0, rcd, rp, ras); + break; + + case 3: + popclear(); + cprint(POP_Y+3, POP_X+8, "tRCD: "); + rcd =getval(POP_Y+3, POP_X+15, 0); + change_timing(0, rcd, 0, 0); + break; + + case 4: + popclear(); + cprint(POP_Y+3, POP_X+8, "tRP: "); + rp =getval(POP_Y+3, POP_X+15, 0); + change_timing(0, 0, rp, 0); + break; + + case 5: + popclear(); + cprint(POP_Y+3, POP_X+8, "tRAS: "); + ras =getval(POP_Y+3, POP_X+15, 0); + change_timing(0, 0, 0, ras); + break; + + case 6: + popclear(); + amd64_option(); + sflag++; + popclear(); + break; + + case 7: + break; + + case 11: + case 57: + sflag++; /* 0/CR - Cancel */ - break; - } + break; + } } } void get_menu(void) -{ +{ int menu ; - + find_memctr(); disclaimer(); - + switch(ctrl) { case 0: menu = 2; break; case 1: case 2: - case 3: + case 3: case 4: menu = 0; break; case 5: menu = 1; break; case 6: menu = 0; break; default: menu = -1; break; } - + if (menu == -1) { popclear(); @@ -514,11 +453,11 @@ void get_menu(void) cprint(POP_Y+3, POP_X+5, "(1) Modify All "); cprint(POP_Y+4, POP_X+5, "(2) Modify tCAS "); cprint(POP_Y+5, POP_X+5, "(3) Modify tRCD "); - cprint(POP_Y+6, POP_X+5, "(4) Modify tRP "); - cprint(POP_Y+7, POP_X+5, "(5) Modify tRAS "); + cprint(POP_Y+6, POP_X+5, "(4) Modify tRP "); + cprint(POP_Y+7, POP_X+5, "(5) Modify tRAS "); cprint(POP_Y+8, POP_X+5, "(0) Cancel"); wait_keyup(); - get_option(); + get_option(); } else if (menu == 1) { @@ -529,10 +468,10 @@ void get_menu(void) cprint(POP_Y+6, POP_X+5, "(4) Modify tRAS "); cprint(POP_Y+7, POP_X+5, "(0) Cancel"); wait_keyup(); - get_option(); + get_option(); } else // AMD64 special menu - { + { cprint(POP_Y+1, POP_X+2, "Modify Timing:"); cprint(POP_Y+3, POP_X+5, "(1) Modify All "); cprint(POP_Y+4, POP_X+5, "(2) Modify tRCD "); @@ -541,68 +480,65 @@ void get_menu(void) cprint(POP_Y+7, POP_X+5, "(5) AMD64 Options"); cprint(POP_Y+8, POP_X+5, "(0) Cancel"); wait_keyup(); - get_option_1(); + get_option_1(); } -} +} int get_cas(void) -{ +{ int i852=0, cas=0; ulong drc, ddr; long *ptr; - + switch(ctrl) { case 0: ddr = 1; break; case 1: case 2: case 3: ddr = 1; break; - case 4: - pci_conf_read( 0, 0, 0, 0x44, 4, &ddr); + case 4: + pci_conf_read( 0, 0, 0, 0x44, 4, &ddr); + ddr &= 0xFFFFC000; ptr=(long*)(ddr+0x120); - drc = *ptr & 0xFFFFFFFF; - + drc = *ptr; + if ((drc & 3) == 2) ddr = 2; else ddr = 1; break; case 5: ddr = 2; break; case 6: ddr = 1; i852 = 1; break; - default: ddr = 1; + default: ddr = 1; } - + if (ddr == 1) { - cprint(POP_Y+3, POP_X+8, "tCAS: "); - cprint(POP_Y+5, POP_X+8, "(1) CAS 2.5 "); - cprint(POP_Y+6, POP_X+8, "(2) CAS 2 "); - if(!i852) { - cprint(POP_Y+7, POP_X+8, "(3) CAS 3 "); - } - cas = getval(POP_Y+3, POP_X+15, 0); - popclear(); + cprint(POP_Y+3, POP_X+8, "tCAS: "); + cprint(POP_Y+5, POP_X+8, "(1) CAS 2.5 "); + cprint(POP_Y+6, POP_X+8, "(2) CAS 2 "); + if(!i852) { + cprint(POP_Y+7, POP_X+8, "(3) CAS 3 "); + } + cas = getval(POP_Y+3, POP_X+15, 0); } else if (ddr == 2) - { - cprint(POP_Y+3, POP_X+8, "tCAS: "); - cprint(POP_Y+5, POP_X+8, "(1) CAS 4 "); - cprint(POP_Y+6, POP_X+8, "(2) CAS 3 "); - cprint(POP_Y+7, POP_X+8, "(3) CAS 5 "); - cas = getval(POP_Y+3, POP_X+15, 0); - popclear(); + { + cprint(POP_Y+3, POP_X+8, "tCAS: "); + cprint(POP_Y+5, POP_X+8, "(1) CAS 4 "); + cprint(POP_Y+6, POP_X+8, "(2) CAS 3 "); + cprint(POP_Y+7, POP_X+8, "(3) CAS 5 "); + cas = getval(POP_Y+3, POP_X+15, 0); } - else + else { + cas = -1; + } + popclear(); - return(-1); - } - return (cas); } void disclaimer(void) { - ulong j = 0; - if ((ctrl == -1) || ( ctrl > sizeof(mem_ctr)/sizeof(mem_ctr[0]))) { popclear(); @@ -612,229 +548,284 @@ void disclaimer(void) get_key(); wait_keyup(); popclear(); - return; } - - if (claim == 0) + else if (claim == 0) { + ulong j = 0; + while (j<500000) { - cprint(POP_Y+1, POP_X+3, "Disclaimer : "); - cprint(POP_Y+3, POP_X+3, "Modifying timing may "); - cprint(POP_Y+4, POP_X+3, "cause system instability"); - cprint(POP_Y+5, POP_X+3, "proceed at your own risk"); - j++; + cprint(POP_Y+1, POP_X+3, "Disclaimer : "); + cprint(POP_Y+3, POP_X+3, "Modifying timing may "); + cprint(POP_Y+4, POP_X+3, "cause system instability"); + cprint(POP_Y+5, POP_X+3, "proceed at your own risk"); + j++; } + claim = 1; popclear(); } - else return; - claim = claim +1; -} +} -///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// // here we go for the exciting timing change part... // ///////////////////////////////////////////////////////// void change_timing_i852(int cas, int rcd, int rp, int ras) { - ulong dramtlr, temp; + ulong dramtlr; ulong int1, int2; - + pci_conf_read(0, 0, 1, 0x60, 4, &dramtlr); - + // CAS Latency (tCAS) int1 = dramtlr & 0xFF9F; - if (cas == 2) { int2 = int1 ^ 0x20; } + if (cas == 2) { int2 = int1 ^ 0x20; } else if (cas == 1) { int2 = int1; } - else { int2 = dramtlr; } - - temp = int2; - + else { int2 = dramtlr; } + + // RAS-To-CAS (tRCD) int1 = int2 & 0xFFF3; - if (rcd == 2) { int2 = int1 ^ 0x8; } + if (rcd == 2) { int2 = int1 ^ 0x8; } else if (rcd == 3) { int2 = int1 ^ 0x4; } else if (rcd == 4) { int2 = int1; } - else { int2 = temp;} + // else { int2 = int2; } + - temp = int2; - // RAS Precharge (tRP) int1 = int2 & 0xFFFC; - if (rp == 2) { int2 = int1 ^ 0x2; } + if (rp == 2) { int2 = int1 ^ 0x2; } else if (rp == 3) { int2 = int1 ^ 0x1; } else if (rp == 4) { int2 = int1; } - else { int2 = temp;} + // else { int2 = int2; } + - temp = int2; - // RAS Active to precharge (tRAS) int1 = int2 & 0xF9FF; - if (ras == 5) { int2 = int1 ^ 0x0600; } + if (ras == 5) { int2 = int1 ^ 0x0600; } else if (ras == 6) { int2 = int1 ^ 0x0400; } else if (ras == 7) { int2 = int1 ^ 0x0200; } else if (ras == 8) { int2 = int1; } - else { int2 = temp;} - + // else { int2 = int2; } + pci_conf_write(0, 0, 1, 0x60, 4, int2); __delay(500); } void change_timing_i925(int cas, int rcd, int rp, int ras) { - ulong int1, dev0, temp= 0x0; + ulong int1, dev0, temp; long *ptr; - + //read MMRBAR pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); - + dev0 &= 0xFFFFC000; + ptr=(long*)(dev0+0x114); temp = *ptr; - + // RAS-To-CAS (tRCD) int1 = temp | 0x70; - if (rcd == 2) { temp = int1 ^ 0x70; } + if (rcd == 2) { temp = int1 ^ 0x70; } else if (rcd == 3) { temp = int1 ^ 0x60; } else if (rcd == 4) { temp = int1 ^ 0x50; } else if (rcd == 5) { temp = int1 ^ 0x40; } - else { temp = temp;} + // else { temp = temp;} //RAS precharge (tRP) int1 = temp | 0x7; - if (rp == 2){ temp = int1 ^ 0x7 ;} + if (rp == 2) { temp = int1 ^ 0x7; } else if (rp == 3) { temp = int1 ^ 0x6; } else if (rp == 4) { temp = int1 ^ 0x5; } else if (rp == 5) { temp = int1 ^ 0x4; } - else { temp = temp;} - - // RAS Active to precharge (tRAS) - int1 = temp | 0xF00000; - if (ras == 4) { temp = int1 ^ 0xB00000; } - else if (ras == 5) { temp = int1 ^ 0xA00000; } - else if (ras == 6) { temp = int1 ^ 0x900000; } - else if (ras == 7) { temp = int1 ^ 0x800000; } - else if (ras == 8) { temp = int1 ^ 0x700000; } - else if (ras == 9) { temp = int1 ^ 0x600000; } - else if (ras == 10) { temp = int1 ^ 0x500000; } - else if (ras == 11) { temp = int1 ^ 0x400000; } - else if (ras == 12) { temp = int1 ^ 0x300000; } - else if (ras == 13) { temp = int1 ^ 0x200000; } - else if (ras == 14) { temp = int1 ^ 0x100000; } - else if (ras == 15) { temp = int1 ^ 0x000000; } - else { temp = temp;} + // else { temp = temp;} + + if (mem_ctr[ctrl].device == 0x2770 ) // Lakeport? + { + // RAS Active to precharge (tRAS) + int1 = temp | 0xF80000; // bits 23:19 + if (ras == 4) { temp = int1 ^ 0xD80000; } + else if (ras == 5) { temp = int1 ^ 0xD00000; } + else if (ras == 6) { temp = int1 ^ 0xC80000; } + else if (ras == 7) { temp = int1 ^ 0xC00000; } + else if (ras == 8) { temp = int1 ^ 0xB80000; } + else if (ras == 9) { temp = int1 ^ 0xB00000; } + else if (ras == 10) { temp = int1 ^ 0xA80000; } + else if (ras == 11) { temp = int1 ^ 0xA00000; } + else if (ras == 12) { temp = int1 ^ 0x980000; } + else if (ras == 13) { temp = int1 ^ 0x900000; } + else if (ras == 14) { temp = int1 ^ 0x880000; } + else if (ras == 15) { temp = int1 ^ 0x800000; } + // else { temp = temp;} + } + else + { + // RAS Active to precharge (tRAS) + int1 = temp | 0xF00000; // bits 23:20 + if (ras == 4) { temp = int1 ^ 0xB00000; } + else if (ras == 5) { temp = int1 ^ 0xA00000; } + else if (ras == 6) { temp = int1 ^ 0x900000; } + else if (ras == 7) { temp = int1 ^ 0x800000; } + else if (ras == 8) { temp = int1 ^ 0x700000; } + else if (ras == 9) { temp = int1 ^ 0x600000; } + else if (ras == 10) { temp = int1 ^ 0x500000; } + else if (ras == 11) { temp = int1 ^ 0x400000; } + else if (ras == 12) { temp = int1 ^ 0x300000; } + else if (ras == 13) { temp = int1 ^ 0x200000; } + else if (ras == 14) { temp = int1 ^ 0x100000; } + else if (ras == 15) { temp = int1 ^ 0x000000; } + // else { temp = temp;} + } // CAS Latency (tCAS) int1 = temp | 0x0300; - if (cas == 1) { temp = int1 ^ 0x200; } // cas 2.5 + if (cas == 1) { temp = int1 ^ 0x200; } // cas 2.5 else if (cas == 2) { temp = int1 ^ 0x100; } else if (cas == 3) { temp = int1 ^ 0x300; } - else temp = temp; - + // else { temp = temp;} + + *ptr = temp; + __delay(500); + return; +} + +void change_timing_Lakeport(int cas, int rcd, int rp, int ras) +{ + ulong int1, dev0, temp; + long *ptr; + + //read MMRBAR + pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); + dev0 &= 0xFFFFC000; + + ptr=(long*)(dev0+0x114); + temp = *ptr; + + // RAS-To-CAS (tRCD) + int1 = temp | 0x70; + if (rcd == 2) { temp = int1 ^ 0x70; } + else if (rcd == 3) { temp = int1 ^ 0x60; } + else if (rcd == 4) { temp = int1 ^ 0x50; } + else if (rcd == 5) { temp = int1 ^ 0x40; } + // else { temp = temp;} + + //RAS precharge (tRP) + int1 = temp | 0x7; + if (rp == 2) { temp = int1 ^ 0x7; } + else if (rp == 3) { temp = int1 ^ 0x6; } + else if (rp == 4) { temp = int1 ^ 0x5; } + else if (rp == 5) { temp = int1 ^ 0x4; } + // else { temp = temp;} + + + // CAS Latency (tCAS) + int1 = temp | 0x0300; + if (cas == 1) { temp = int1 ^ 0x200; } // cas 2.5 + else if (cas == 2) { temp = int1 ^ 0x100; } + else if (cas == 3) { temp = int1 ^ 0x300; } + // else { temp = temp;} + *ptr = temp; __delay(500); return; } void change_timing_i875(int cas, int rcd, int rp, int ras){ - - ulong int1, dev6, temp= 0x0; + + ulong int1, dev6, temp; long *ptr; - + /* Read the MMR Base Address & Define the pointer from the BAR6 overflow register */ pci_conf_read( 0, 6, 0, 0x10, 4, &dev6); - + ptr=(long*)(dev6+0x60); - + temp = *ptr; - + // RAS-To-CAS (tRCD) int1 = temp | 0xC; - if (rcd == 2) { temp = int1 ^ 0x4; } + if (rcd == 2) { temp = int1 ^ 0x4; } else if (rcd == 3) { temp = int1 ^ 0x8; } else if (rcd == 4) { temp = int1 ^ 0xC; } else if (rcd == 5) { temp = int1 ^ 0xC; } - else { temp = temp;} + // else { temp = temp;} + - //RAS precharge (tRP) int1 = temp | 0x3; - if (rp == 2){ temp = int1 ^ 0x1 ;} + if (rp == 2) { temp = int1 ^ 0x1; } else if (rp == 3) { temp = int1 ^ 0x2; } else if (rp == 4) { temp = int1 ^ 0x3; } else if (rp == 5) { temp = int1 ^ 0x3; } - else { temp = temp;} + // else { temp = temp;} + - // RAS Active to precharge (tRAS) int1 = temp | 0x380; - if (ras == 5) { temp = int1 ^ 0x100; } + if (ras == 5) { temp = int1 ^ 0x100; } else if (ras == 6) { temp = int1 ^ 0x180; } else if (ras == 7) { temp = int1 ^ 0x200; } else if (ras == 8) { temp = int1 ^ 0x280; } else if (ras == 9) { temp = int1 ^ 0x300; } else if (ras == 10) { temp = int1 ^ 0x380; } - else { temp = temp;} + // else { temp = temp;} // CAS Latency (tCAS) int1 = temp | 0x60; - if (cas == 1) { temp = int1 ^ 0x60; } // cas 2.5 + if (cas == 1) { temp = int1 ^ 0x60; } // cas 2.5 else if (cas == 2) { temp = int1 ^ 0x40; } else if (cas == 3) { temp = int1 ^ 0x20; } - else { temp = temp; } - + // else { temp = temp; } + *ptr = temp; - __delay(500); + __delay(500); return; } void change_timing_nf2(int cas, int rcd, int rp, int ras) { - ulong dramtlr, dramtlr2, temp = 0x0; + ulong dramtlr, dramtlr2; ulong int1, int2; - + pci_conf_read(0, 0, 1, 0x90, 4, &dramtlr); pci_conf_read(0, 0, 1, 0xA0, 4, &dramtlr2); - - + + // CAS Latency (tCAS) int1 = dramtlr2 | 0x0070; - if (cas == 1) // cas = 2.5 - { int2 = int1 ^ 0x10; } + if (cas == 1) { int2 = int1 ^ 0x10; } // cas = 2.5 else if (cas == 2) { int2 = int1 ^ 0x50; } else if (cas == 3) { int2 = int1 ^ 0x40; } - else { int2 = dramtlr2; } - + else { int2 = dramtlr2; } + pci_conf_write(0, 0, 1, 0xA0, 4, int2); - + // RAS-To-CAS (tRCD) - + int1 = dramtlr | 0x700000; - if (rcd == 2) { int2 = int1 ^ 0x500000; } + if (rcd == 2) { int2 = int1 ^ 0x500000; } else if (rcd == 3) { int2 = int1 ^ 0x400000; } else if (rcd == 4) { int2 = int1 ^ 0x300000; } else if (rcd == 5) { int2 = int1 ^ 0x200000; } else if (rcd == 6) { int2 = int1 ^ 0x100000; } - else { int2 = dramtlr;} - - temp = int2; - - + else { int2 = dramtlr;} + + // RAS Precharge (tRP) - int1 = temp | 0x70000000; - if (rp == 2) { int2 = int1 ^ 0x50000000; } + int1 = int2 | 0x70000000; + if (rp == 2) { int2 = int1 ^ 0x50000000; } else if (rp == 3) { int2 = int1 ^ 0x40000000; } else if (rp == 4) { int2 = int1 ^ 0x30000000; } else if (rp == 5) { int2 = int1 ^ 0x20000000; } else if (rp == 6) { int2 = int1 ^ 0x10000000; } - else { int2 = temp;} - - temp = int2; - + // else { int2 = int2;} + + // RAS Active to precharge (tRAS) - int1 = temp | 0x78000; - if (ras == 4) { int2 = int1 ^ 0x58000; } + int1 = int2 | 0x78000; + if (ras == 4) { int2 = int1 ^ 0x58000; } else if (ras == 5) { int2 = int1 ^ 0x50000; } else if (ras == 6) { int2 = int1 ^ 0x48000; } else if (ras == 7) { int2 = int1 ^ 0x40000; } @@ -845,72 +836,70 @@ void change_timing_nf2(int cas, int rcd, int rp, int ras) { else if (ras == 12) { int2 = int1 ^ 0x18000; } else if (ras == 13) { int2 = int1 ^ 0x10000; } else if (ras == 14) { int2 = int1 ^ 0x08000; } - else { int2 = temp;} - - temp = int2; - - pci_conf_write(0, 0, 1, 0x90, 4, temp); + // else { int2 = int2;} + + + pci_conf_write(0, 0, 1, 0x90, 4, int2); __delay(500); } void change_timing_amd64(int cas, int rcd, int rp, int ras) { - ulong dramtlr, temp ; - ulong int1= 0x0; - + ulong dramtlr; + ulong int1= 0x0; + pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr); - - temp = dramtlr; - + // RAS-To-CAS (tRCD) - int1 = temp | 0x7000; - if (rcd == 2) { temp = int1 ^ 0x5000; } - else if (rcd == 3) { temp = int1 ^ 0x4000; } - else if (rcd == 4) { temp = int1 ^ 0x3000; } - else if (rcd == 5) { temp = int1 ^ 0x2000; } - else if (rcd == 6) { temp = int1 ^ 0x1000; } - else if (rcd == 1) { temp = int1 ^ 0x6000; } - else { temp = temp;} - - + int1 = dramtlr | 0x7000; + if (rcd == 2) { dramtlr = int1 ^ 0x5000; } + else if (rcd == 3) { dramtlr = int1 ^ 0x4000; } + else if (rcd == 4) { dramtlr = int1 ^ 0x3000; } + else if (rcd == 5) { dramtlr = int1 ^ 0x2000; } + else if (rcd == 6) { dramtlr = int1 ^ 0x1000; } + else if (rcd == 1) { dramtlr = int1 ^ 0x6000; } + // else { dramtlr = dramtlr;} + + //RAS precharge (tRP) - int1 = temp | 0x7000000; - if (rp == 2){ temp = int1 ^ 0x5000000; } - else if (rp == 3) { temp = int1 ^ 0x4000000; } - else if (rp == 1) { temp = int1 ^ 0x6000000; } - else if (rp == 4) { temp = int1 ^ 0x3000000; } - else if (rp == 5) { temp = int1 ^ 0x2000000; } - else if (rp == 6) { temp = int1 ^ 0x1000000; } - else { temp = temp;} - - + int1 = dramtlr | 0x7000000; + if (rp == 2) { dramtlr = int1 ^ 0x5000000; } + else if (rp == 3) { dramtlr = int1 ^ 0x4000000; } + else if (rp == 1) { dramtlr = int1 ^ 0x6000000; } + else if (rp == 4) { dramtlr = int1 ^ 0x3000000; } + else if (rp == 5) { dramtlr = int1 ^ 0x2000000; } + else if (rp == 6) { dramtlr = int1 ^ 0x1000000; } + // else { dramtlr = dramtlr;} + + // RAS Active to precharge (tRAS) - int1 = temp | 0xF00000; - if (ras == 5) { temp = int1 ^ 0xA00000; } - else if (ras == 6) { temp = int1 ^ 0x900000; } - else if (ras == 7) { temp = int1 ^ 0x800000; } - else if (ras == 8) { temp = int1 ^ 0x700000; } - else if (ras == 9) { temp = int1 ^ 0x600000; } - else if (ras == 10) { temp = int1 ^ 0x500000; } - else if (ras == 11) { temp = int1 ^ 0x400000; } - else if (ras == 12) { temp = int1 ^ 0x300000; } - else if (ras == 13) { temp = int1 ^ 0x200000; } - else if (ras == 14) { temp = int1 ^ 0x100000; } - else { temp = temp;} + int1 = dramtlr | 0xF00000; + if (ras == 5) { dramtlr = int1 ^ 0xA00000; } + else if (ras == 6) { dramtlr = int1 ^ 0x900000; } + else if (ras == 7) { dramtlr = int1 ^ 0x800000; } + else if (ras == 8) { dramtlr = int1 ^ 0x700000; } + else if (ras == 9) { dramtlr = int1 ^ 0x600000; } + else if (ras == 10) { dramtlr = int1 ^ 0x500000; } + else if (ras == 11) { dramtlr = int1 ^ 0x400000; } + else if (ras == 12) { dramtlr = int1 ^ 0x300000; } + else if (ras == 13) { dramtlr = int1 ^ 0x200000; } + else if (ras == 14) { dramtlr = int1 ^ 0x100000; } + // else { dramtlr = dramtlr;} + // CAS Latency (tCAS) - int1 = temp | 0x7; // some changes will cause the system hang, tried Draminit to no avail - if (cas == 1) { temp = int1 ^ 0x2; } // cas 2.5 - else if (cas == 2) { temp = int1 ^ 0x6; } - else if (cas == 3) { temp = int1 ^ 0x5; } - else if (cas == 4) { temp = int1 ^ 0x7; } //cas 1.5 on a64 - else { temp = temp; } - + int1 = dramtlr | 0x7; // some changes will cause the system hang, tried Draminit to no avail + if (cas == 1) { dramtlr = int1 ^ 0x2; } // cas 2.5 + else if (cas == 2) { dramtlr = int1 ^ 0x6; } + else if (cas == 3) { dramtlr = int1 ^ 0x5; } + else if (cas == 4) { dramtlr = int1 ^ 0x7; } //cas 1.5 on a64 + // else { dramtlr = dramtlr; } + // pci_conf_read(0, 24, 2, 0x90, 4, &dramcr);// use dram init - pci_conf_write(0, 24, 2, 0x88, 4, temp); + pci_conf_write(0, 24, 2, 0x88, 4, dramtlr); __delay(500); - + //////////////////////////////////////////////////////////////// // trying using the draminit, but do not work } @@ -931,98 +920,93 @@ void __delay(ulong loops) void amd64_tweak(int rwt, int wrt, int ref, int en2t, int rct, int rrd, int rwqb, int wr) { - ulong dramtlr, temp ; - ulong int1= 0x0; - + ulong dramtlr; + ulong int1= 0x0; + pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr); - - temp = dramtlr; - + // Row Cycle time - int1 = temp | 0xF0; - if (rct == 7) { temp = int1 ^ 0xF0; } - else if (rct == 8) { temp = int1 ^ 0xE0; } - else if (rct == 9) { temp = int1 ^ 0xD0; } - else if (rct == 10) { temp = int1 ^ 0xC0; } - else if (rct == 11) { temp = int1 ^ 0xB0; } - else if (rct == 12) { temp = int1 ^ 0xA0; } - else if (rct == 13) { temp = int1 ^ 0x90; } - else if (rct == 14) { temp = int1 ^ 0x80; } - else if (rct == 15) { temp = int1 ^ 0x70; } - else if (rct == 16) { temp = int1 ^ 0x60; } - else if (rct == 17) { temp = int1 ^ 0x50; } - else if (rct == 18) { temp = int1 ^ 0x40; } - else if (rct == 19) { temp = int1 ^ 0x30; } - else if (rct == 20) { temp = int1 ^ 0x20; } - else { temp = temp;} - + int1 = dramtlr | 0xF0; + if (rct == 7 ) { dramtlr = int1 ^ 0xF0; } + else if (rct == 8 ) { dramtlr = int1 ^ 0xE0; } + else if (rct == 9 ) { dramtlr = int1 ^ 0xD0; } + else if (rct == 10) { dramtlr = int1 ^ 0xC0; } + else if (rct == 11) { dramtlr = int1 ^ 0xB0; } + else if (rct == 12) { dramtlr = int1 ^ 0xA0; } + else if (rct == 13) { dramtlr = int1 ^ 0x90; } + else if (rct == 14) { dramtlr = int1 ^ 0x80; } + else if (rct == 15) { dramtlr = int1 ^ 0x70; } + else if (rct == 16) { dramtlr = int1 ^ 0x60; } + else if (rct == 17) { dramtlr = int1 ^ 0x50; } + else if (rct == 18) { dramtlr = int1 ^ 0x40; } + else if (rct == 19) { dramtlr = int1 ^ 0x30; } + else if (rct == 20) { dramtlr = int1 ^ 0x20; } + // else { dramtlr = dramtlr;} + //Active-avtive ras-ras delay - int1 = temp | 0x70000; - if (rrd == 2){ temp = int1 ^ 0x50000; } // 2 bus clocks - else if (rrd == 3) { temp = int1 ^ 0x40000; } //3 bus clocks - else if (rrd == 4) { temp = int1 ^ 0x30000; } //4 bus clocks - else { temp = temp;} + int1 = dramtlr | 0x70000; + if (rrd == 2) { dramtlr = int1 ^ 0x50000; } // 2 bus clocks + else if (rrd == 3) { dramtlr = int1 ^ 0x40000; } // 3 bus clocks + else if (rrd == 4) { dramtlr = int1 ^ 0x30000; } // 4 bus clocks + // else { dramtlr = dramtlr;} //Write recovery time - int1 = temp | 0x10000000; - if (wr == 2){ temp = int1 ^ 0x10000000; } // 2 bus clocks - else if (wr == 3) { temp = int1 ^ 0x00000000; } //3 bus clocks - else { temp = temp;} - - pci_conf_write(0, 24, 2, 0x88, 4, temp); + int1 = dramtlr | 0x10000000; + if (wr == 2) { dramtlr = int1 ^ 0x10000000; } // 2 bus clocks + else if (wr == 3) { dramtlr = int1 ^ 0x00000000; } // 3 bus clocks + // else { dramtlr = dramtlr;} + + pci_conf_write(0, 24, 2, 0x88, 4, dramtlr); __delay(500); - ////////////////////////////////////////////// - + ////////////////////////////////////////////// + pci_conf_read(0, 24, 2, 0x8C, 4, &dramtlr); - - temp = dramtlr; - + // Write-to read delay - int1 = temp | 0x1; - if (wrt == 2) { temp = int1 ^ 0x0; } - else if (wrt == 1) { temp = int1 ^ 0x1; } - else { temp = temp;} - + int1 = dramtlr | 0x1; + if (wrt == 2) { dramtlr = int1 ^ 0x0; } + else if (wrt == 1) { dramtlr = int1 ^ 0x1; } + // else { dramtlr = dramtlr;} + // Read-to Write delay - int1 = temp | 0x70; - if (rwt == 1) { temp = int1 ^ 0x70; } - else if (rwt == 2) { temp = int1 ^ 0x60; } - else if (rwt == 3) { temp = int1 ^ 0x50; } - else if (rwt == 4) { temp = int1 ^ 0x40; } - else if (rwt == 5) { temp = int1 ^ 0x30; } - else if (rwt == 6) { temp = int1 ^ 0x20; } - else { temp = temp;} - + int1 = dramtlr | 0x70; + if (rwt == 1) { dramtlr = int1 ^ 0x70; } + else if (rwt == 2) { dramtlr = int1 ^ 0x60; } + else if (rwt == 3) { dramtlr = int1 ^ 0x50; } + else if (rwt == 4) { dramtlr = int1 ^ 0x40; } + else if (rwt == 5) { dramtlr = int1 ^ 0x30; } + else if (rwt == 6) { dramtlr = int1 ^ 0x20; } + // else { dramtlr = dramtlr;} + //Refresh Rate - int1 = temp | 0x1800; - if (ref == 1){ temp = int1 ^ 0x1800; } // 15.6us - else if (ref == 2) { temp = int1 ^ 0x1000; } //7.8us - else if (ref == 3) { temp = int1 ^ 0x0800; } //3.9us - else { temp = temp;} + int1 = dramtlr | 0x1800; + if (ref == 1) { dramtlr = int1 ^ 0x1800; } // 15.6us + else if (ref == 2) { dramtlr = int1 ^ 0x1000; } // 7.8us + else if (ref == 3) { dramtlr = int1 ^ 0x0800; } // 3.9us + // else { dramtlr = dramtlr;} - pci_conf_write(0, 24, 2, 0x8c, 4, temp); + pci_conf_write(0, 24, 2, 0x8c, 4, dramtlr); __delay(500); ///////////////////////////////////// - + pci_conf_read(0, 24, 2, 0x90, 4, &dramtlr); - temp = dramtlr; - + // Enable 2t command - int1 = temp | 0x10000000; - if (en2t == 2) { temp = int1 ^ 0x00000000; } // 2T - else if (en2t == 1) { temp = int1 ^ 0x10000000; } // 1T - else { temp = temp;} + int1 = dramtlr | 0x10000000; + if (en2t == 2) { dramtlr = int1 ^ 0x00000000; } // 2T + else if (en2t == 1) { dramtlr = int1 ^ 0x10000000; } // 1T + // else { dramtlr = dramtlr;} // Read Write queue bypass count - int1 = temp | 0xC000; - if (rwqb == 2) { temp = int1 ^ 0xC000; } - else if (rwqb == 4) { temp = int1 ^ 0x8000; } - else if (rwqb == 8) { temp = int1 ^ 0x4000; } - else if (rwqb == 16) { temp = int1 ^ 0x0000; } - else { temp = temp;} - - pci_conf_write(0, 24, 2, 0x90, 4, temp); + int1 = dramtlr | 0xC000; + if (rwqb == 2) { dramtlr = int1 ^ 0xC000; } + else if (rwqb == 4) { dramtlr = int1 ^ 0x8000; } + else if (rwqb == 8) { dramtlr = int1 ^ 0x4000; } + else if (rwqb == 16) { dramtlr = int1 ^ 0x0000; } + // else { dramtlr = dramtlr;} + + pci_conf_write(0, 24, 2, 0x90, 4, dramtlr); __delay(500); - restart(); + restart(); } @@ -28,7 +28,8 @@ #define X86_CAPABILITY 8 #define X86_VENDOR_ID 12 #define X86_CACHE 24 -#define X86_PWRCAP 40 +#define X86_PWRCAP 40 +#define X86_EXT 44 .code32 .globl startup_32 @@ -42,7 +43,7 @@ startup_32: movl $(LOW_TEST_ADR + _GLOBAL_OFFSET_TABLE_), %esp leal stack_top@GOTOFF(%esp), %esp 0: - + /* Load the GOT pointer */ call 0f 0: popl %ebx @@ -82,7 +83,7 @@ flush: movl $KERNEL_DS, %eax movl $0, zerobss@GOTOFF(%ebx) zerobss_done: -/* +/* * Clear the video display */ cmpl $1, clear_display@GOTOFF(%ebx) @@ -263,7 +264,7 @@ clear_display_done: movl %edx,4(%edi) addl $8,%edi - /* Now that it is initialized load the interrupt descritor table */ + /* Now that it is initialized load the interrupt descriptor table */ leal idt@GOTOFF(%ebx), %eax movl %eax, 2 + idt_descr@GOTOFF(%ebx) lidt idt_descr@GOTOFF(%ebx) @@ -272,7 +273,7 @@ clear_display_done: leal cpu_id@GOTOFF(%ebx), %esi movl %ebx, %edi - + movl $-1, X86_CPUID(%esi) # -1 for no CPUID initially /* check if it is 486 or 386. */ @@ -330,6 +331,7 @@ have_cpuid: movl $1, %eax # Use the CPUID instruction to get CPU type cpuid + # # CDH start # Check FPU, initialize if present @@ -337,12 +339,13 @@ have_cpuid: testl $1, %edx # FPU available? jz no_fpu finit - + no_fpu: # # CDH end # + movl %eax, X86_EXT(%esi) #save complete extended CPUID to X86_EXT movb %al, %cl # save reg for future use andb $0x0f, %ah # mask processor family movb %ah, X86(%esi) @@ -359,10 +362,10 @@ have_cpuid: movl $0, X86_CACHE+12(%esi) movl X86_VENDOR_ID+8(%esi), %eax - cmpl $0x6c65746e,%eax # Is this an Intel CPU? + cmpl $0x6c65746e,%eax # Is this an Intel CPU? "GenuineIntel" jne not_intel movb %bl, X86_PWRCAP(%esi) # Store BrandID in AMD PWRCAP if the CPU is from Intel - movl $2, %eax # Use the CPUID instruction to get cache info + movl $2, %eax # Use the CPUID instruction to get cache info cpuid movl %eax, X86_CACHE(%esi) movl %ebx, X86_CACHE+4(%esi) @@ -372,10 +375,10 @@ have_cpuid: not_intel: movl X86_VENDOR_ID+8(%esi),%eax - cmpl $0x444d4163, %eax # Is this an AMD CPU? + cmpl $0x444d4163, %eax # Is this an AMD CPU? "AuthenticAMD" jne not_amd - movl $0x80000005, %eax # Use the CPUID instruction to get cache info + movl $0x80000005, %eax # Use the CPUID instruction to get cache info cpuid movl %ecx, X86_CACHE(%esi) movl %edx, X86_CACHE+4(%esi) @@ -388,17 +391,55 @@ not_intel: not_amd: movl X86_VENDOR_ID+8(%esi), %eax - cmpl $0x64616374, %eax # Is this a Cyrix CPU? - jne id_done + cmpl $0x3638784D, %eax # Is this a Transmeta CPU? "GenuineTMx86" + jne not_transmeta + + movl $0x80000000, %eax # Use the CPUID instruction to check for cache info + cpuid + cmp $6, %al # Is cache info available? + jb id_done + + movl $0x80000005, %eax # Use the CPUID instruction to get L1 cache info + cpuid + movl %ecx, X86_CACHE(%esi) + movl %edx, X86_CACHE+4(%esi) + movl $0x80000006, %eax # Use the CPUID instruction to get L2 cache info + cpuid + movl %ecx, X86_CACHE+8(%esi) + +not_transmeta: + movl X86_VENDOR_ID+8(%esi), %eax + cmpl $0x64616574, %eax # Is this a Via/Cyrix CPU? "CyrixInstead" + jne not_cyrix movl X86_CPUID(%esi), %eax # get CPUID level cmpl $2, %eax # Is there cache information available ? jne id_done - movl $2, %eax # Use the CPUID instruction to get cache info + movl $2, %eax # Use the CPUID instruction to get cache info cpuid movl %edx, X86_CACHE(%esi) +not_cyrix: + movl X86_VENDOR_ID+8(%esi), %eax + cmpl $0x736C7561, %eax # Is this a Via/Centaur CPU "CentaurHauls" + jne not_centaur + + movl $0x80000000, %eax # Use the CPUID instruction to check for cache info + cpuid + cmp $6, %al # Is cache info available? + jb id_done + + movl $0x80000005, %eax # Use the CPUID instruction to get L1 cache info + cpuid + movl %ecx, X86_CACHE(%esi) + movl %edx, X86_CACHE+4(%esi) + movl $0x80000006, %eax # Use the CPUID instruction to get L2 cache info + cpuid + movl %ecx, X86_CACHE+8(%esi) + + +not_centaur: id_done: movl %edi, %ebx /* Restore GOT pointer */ @@ -421,97 +462,97 @@ vec1: pushl $0 /* error code */ pushl $1 /* vector */ jmp int_hand - + vec2: pushl $0 /* error code */ pushl $2 /* vector */ jmp int_hand - + vec3: pushl $0 /* error code */ pushl $3 /* vector */ jmp int_hand - + vec4: pushl $0 /* error code */ pushl $4 /* vector */ jmp int_hand - + vec5: pushl $0 /* error code */ pushl $5 /* vector */ jmp int_hand - + vec6: pushl $0 /* error code */ pushl $6 /* vector */ jmp int_hand - + vec7: pushl $0 /* error code */ pushl $7 /* vector */ jmp int_hand - + vec8: /* error code */ pushl $8 /* vector */ jmp int_hand - + vec9: pushl $0 /* error code */ pushl $9 /* vector */ jmp int_hand - + vec10: /* error code */ pushl $10 /* vector */ jmp int_hand - + vec11: /* error code */ pushl $11 /* vector */ jmp int_hand - + vec12: /* error code */ pushl $12 /* vector */ jmp int_hand - + vec13: /* error code */ pushl $13 /* vector */ jmp int_hand - + vec14: /* error code */ pushl $14 /* vector */ jmp int_hand - + vec15: pushl $0 /* error code */ pushl $15 /* vector */ jmp int_hand - + vec16: pushl $0 /* error code */ pushl $16 /* vector */ jmp int_hand - + vec17: /* error code */ pushl $17 /* vector */ jmp int_hand - + vec18: pushl $0 /* error code */ pushl $18 /* vector */ jmp int_hand - + vec19: pushl $0 /* error code */ pushl $19 /* vector */ jmp int_hand - + int_hand: pushl %eax pushl %ebx @@ -522,13 +563,13 @@ int_hand: pushl %ebp /* original stack pointer */ - leal 20(%esp), %eax + leal 20(%esp), %eax pushl %eax - + pushl %esp /* pointer to structure on the stack */ call inter addl $8, %esp - + popl %ebp popl %esi popl %edi @@ -541,7 +582,7 @@ int_hand: /* * The interrupt descriptor table has room for 32 idt's */ -.align 4 +.align 4 .word 0 idt_descr: .word 20*8-1 # idt contains 32 entries @@ -597,7 +638,7 @@ maxdepth \depth-1 .endif .endm -maxdepth +maxdepth .balign 4096 .globl pd0 @@ -611,7 +652,7 @@ pd1: .balign 4096 .globl pd2 -pd2: +pd2: ptes64 0x0000000080000000 .balign 4096 @@ -626,10 +667,10 @@ pdp: .long 0 .long pd1 + 1 .long 0 - + .long pd2 + 1 .long 0 - + .long pd3 + 1 .long 0 .previous @@ -658,7 +699,7 @@ query_pcbios: /* Fixup protected code pointer */ leal prot@GOTOFF(%ebx), %eax movl %eax, protptr@GOTOFF(%ebx) - + /* Compute the gdt fixup */ movl %esi, %eax shll $16, %eax # Base low @@ -684,7 +725,7 @@ query_pcbios: /* Fixup the gdt_descr */ leal gdt@GOTOFF(%ebx), %eax movl %eax, 2 + gdt_descr@GOTOFF(%ebx) - + lidt idt_real@GOTOFF(%ebx) /* Don't disable the a20 line */ @@ -701,7 +742,7 @@ query_pcbios: leal stack@GOTOFF(%ebx), %ecx /* Compute the address of meminfo */ leal mem_info@GOTOFF(%ebx), %edi - + /* switch to 16bit mode */ ljmp $REAL_CS, $1f - RSTART 1: @@ -711,7 +752,7 @@ query_pcbios: movl %cr0,%eax andl $~((1 << 31)|(1<<0)),%eax movl %eax,%cr0 - + /* make intersegment jmp to flush the processor pipeline * and reload %cs:%eip (to clear upper 16 bits of %eip). */ @@ -823,7 +864,7 @@ meme801: jne e801usecxdx # which report their extended cmpw $0x0, %dx # memory in AX/BX rather than jne e801usecxdx # CX/DX. The spec I have read - movw %ax, %cx # seems to indicate AX/BX + movw %ax, %cx # seems to indicate AX/BX movw %bx, %dx # are more reasonable anyway... e801usecxdx: @@ -855,18 +896,18 @@ mem88: movw $0x5304, %ax # Disconnect first just in case xorw %bx, %bx int $0x15 # ignore return code - + movw $0x5301, %ax # Real Mode connect xorw %bx, %bx int $0x15 jc done_apm_bios # error - + movw $0x5308, %ax # Disable APM mov $0xffff, %bx xorw %cx, %cx int $0x15 - -done_apm_bios: + +done_apm_bios: #endif /* O.k. the BIOS query is done switch back to protected mode */ @@ -911,7 +952,7 @@ prot: popl %ebx movl $1, %eax ret - + realptr: .word real - RSTART .word 0x0000 @@ -3,7 +3,7 @@ * Released under version 2 of the Gnu Public License. * By Chris Brady, cbrady@sgi.com * ---------------------------------------------------- - * MemTest86+ V1.40 Specific code (GPL V2.0) + * MemTest86+ V1.50 Specific code (GPL V2.0) * By Samuel DEMEULEMEESTER, sdemeule@memtest.org * http://www.x86-secret.com - http://www.memtest.org */ @@ -36,11 +36,11 @@ static void display_init(void) volatile char *pp; 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"); + serial_echo_print("\x1B[LINE_SCROLL;24r"); /* Set scroll area row 7-23 */ + serial_echo_print("\x1B[H\x1B[2J"); /* Clear Screen */ + serial_echo_print("\x1B[37m\x1B[44m"); + serial_echo_print("\x1B[0m"); + serial_echo_print("\x1B[37m\x1B[44m"); /* Clear screen & set background to blue */ for(i=0, pp=(char *)(SCREEN_ADR); i<80*24; i++) { @@ -49,22 +49,22 @@ static void display_init(void) } /* Make the name background red */ - for(i=0, pp=(char *)(SCREEN_ADR+1); i<TITLE_WIDTH; i++, pp+=2) { - *pp = 0x20; - } - cprint(0, 0, " Memtest86 v1.40 "); + for(i=0, pp=(char *)(SCREEN_ADR+1); i<TITLE_WIDTH; i++, pp+=2) { + *pp = 0x20; + } + cprint(0, 0, " Memtest86 v1.50 "); - for(i=0, pp=(char *)(SCREEN_ADR+1); i<2; i++, pp+=30) { - *pp = 0xA4; - } - cprint(0, 15, "+"); + 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; + *pp = 0x71; } - serial_echo_print("[0m"); + serial_echo_print("\x1B[0m"); } /* @@ -78,12 +78,12 @@ void init(void) /* Turn on cache */ set_cache(1); - + /* Setup the display */ display_init(); /* Determine the memory map */ - if ((firmware == FIRMWARE_UNKNOWN) && + if ((firmware == FIRMWARE_UNKNOWN) && (memsz_mode != SZ_MODE_PROBE)) { if (query_linuxbios()) { firmware = FIRMWARE_LINUXBIOS; @@ -97,7 +97,7 @@ void init(void) /* setup pci */ pci_init(); - + /* setup beep mode */ beepmode = BEEP_MODE; @@ -113,7 +113,7 @@ void init(void) cprint(LINE_CPU+4, 0, "Chipset : "); cpu_type(); - + /* Find the memory controller (inverted from standard) */ find_controller(); @@ -155,9 +155,10 @@ void paging_off(void) "movl %%cr0, %%eax\n\t" "andl $0x7FFFFFFF, %%eax\n\t" "movl %%eax, %%cr0\n\t" - /* Disable pae */ + /* Disable pae and pse */ "movl %%cr4, %%eax\n\t" - "andl $0xFFFFFFDF, %%eax\n\t" + "and $0xCF, %%al\n\t" + "movl %%eax, %%cr4\n\t" : : : "ax" @@ -210,6 +211,17 @@ int map_page(unsigned long page) } /* 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 = ((window & 1) << 31) + ((i & 0x3ff) << 21) + 0xE3; pd2[i].addr_hi = (window >> 1); } @@ -258,7 +270,7 @@ unsigned long page_of(void *addr) cprint(LINE_SCROLL -2, 0, "page_of( )-> "); hprint(LINE_SCROLL -2, 8, ((unsigned long)addr)); hprint(LINE_SCROLL -2, 20, page); -#endif +#endif return page; } @@ -266,7 +278,7 @@ unsigned long page_of(void *addr) /* * Find CPU type and cache sizes */ - + void cpu_type(void) { @@ -387,13 +399,13 @@ void cpu_type(void) l2_cache = (cpu_id.cache_info[11] << 8); l2_cache += cpu_id.cache_info[10]; break; - case 13: - cprint(LINE_CPU, 0, "AMD K6-III+"); - off = 11; - l1_cache = cpu_id.cache_info[3]; - l1_cache += cpu_id.cache_info[7]; - l2_cache = (cpu_id.cache_info[11] << 8); - l2_cache += cpu_id.cache_info[10]; + case 13: + cprint(LINE_CPU, 0, "AMD K6-III+"); + off = 11; + l1_cache = cpu_id.cache_info[3]; + l1_cache += cpu_id.cache_info[7]; + l2_cache = (cpu_id.cache_info[11] << 8); + l2_cache += cpu_id.cache_info[10]; break; } break; @@ -416,23 +428,23 @@ void cpu_type(void) l2_cache = (cpu_id.cache_info[11] << 8); l2_cache += cpu_id.cache_info[10]; if (l2_cache == 64) { - cprint(LINE_CPU, 0, "AMD Duron (0.18)"); - } else { - cprint(LINE_CPU, 0, "Athlon XP (0.18)"); + cprint(LINE_CPU, 0, "AMD Duron (0.18)"); + } else { + cprint(LINE_CPU, 0, "Athlon XP (0.18)"); } off = 16; break; case 8: case 10: - l2_cache = (cpu_id.cache_info[11] << 8); - l2_cache += cpu_id.cache_info[10]; - if (l2_cache == 64) { - cprint(LINE_CPU, 0, "AMD Duron (0.13)"); - } else { - cprint(LINE_CPU, 0, "Athlon XP (0.13)"); + l2_cache = (cpu_id.cache_info[11] << 8); + l2_cache += cpu_id.cache_info[10]; + if (l2_cache == 64) { + cprint(LINE_CPU, 0, "AMD Duron (0.13)"); + } else { + cprint(LINE_CPU, 0, "Athlon XP (0.13)"); } off = 16; - break; + break; case 3: case 7: cprint(LINE_CPU, 0, "AMD Duron"); @@ -454,317 +466,353 @@ void cpu_type(void) case 15: l1_cache = cpu_id.cache_info[3]; l1_cache += cpu_id.cache_info[7]; - l2_cache = (cpu_id.cache_info[11] << 8); - l2_cache += cpu_id.cache_info[10]; + l2_cache = (cpu_id.cache_info[11] << 8); + l2_cache += cpu_id.cache_info[10]; switch(cpu_id.model) { default: cprint(LINE_CPU, 0, "AMD Athlon 64"); - off = 13; - break; + off = 13; + break; case 5: cprint(LINE_CPU, 0, "AMD Opteron (0.13)"); - off = 18; - break; - case 4: - case 12: - if (l2_cache == 256) { - cprint(LINE_CPU, 0, "AMD Sempron (0.13)"); - off = 18; - } else { - cprint(LINE_CPU, 0, "Athlon 64 (0.13)"); - off = 16; - } - break; - case 15: + off = 18; + break; + case 4: + case 12: + if (l2_cache == 256) { + cprint(LINE_CPU, 0, "AMD Sempron (0.13)"); + off = 18; + } else { + cprint(LINE_CPU, 0, "Athlon 64 (0.13)"); + off = 16; + } + break; + case 15: + if ((cpu_id.ext >> 16) & 1) { cprint(LINE_CPU, 0, "Athlon 64 (0.09)"); - off = 16; - break; - + } else { + cprint(LINE_CPU, 0, "Athlon 64 (0.13)"); + } + off = 16; + break; } break; } break; - /* Intel Processors */ + /* Intel or Transmeta Processors */ case 'G': - if (cpu_id.type == 4) { - switch(cpu_id.model) { - case 0: - case 1: - cprint(LINE_CPU, 0, "Intel 486DX"); - off = 11; - break; - case 2: - cprint(LINE_CPU, 0, "Intel 486SX"); - off = 11; - break; - case 3: - cprint(LINE_CPU, 0, "Intel 486DX2"); - off = 12; - break; - case 4: - cprint(LINE_CPU, 0, "Intel 486SL"); - off = 11; - break; - case 5: - cprint(LINE_CPU, 0, "Intel 486SX2"); - off = 12; - break; - case 7: - cprint(LINE_CPU, 0, "Intel 486DX2-WB"); - off = 15; - break; - case 8: - cprint(LINE_CPU, 0, "Intel 486DX4"); - off = 12; - break; - case 9: - cprint(LINE_CPU, 0, "Intel 486DX4-WB"); - off = 15; - break; + if ( cpu_id.vend_id[7] == 'T' ) { /* GenuineTMx86 */ + if (cpu_id.type == 5) { + cprint(LINE_CPU, 0, "TM 5x00"); + off = 7; + } else if (cpu_id.type == 15) { + cprint(LINE_CPU, 0, "TM 8x00"); + off = 7; + } + l1_cache = cpu_id.cache_info[3] + cpu_id.cache_info[7]; + l2_cache = (cpu_id.cache_info[11]*256) + cpu_id.cache_info[10]; + } else { /* GenuineIntel */ + if (cpu_id.type == 4) { + switch(cpu_id.model) { + case 0: + case 1: + cprint(LINE_CPU, 0, "Intel 486DX"); + off = 11; + break; + case 2: + cprint(LINE_CPU, 0, "Intel 486SX"); + off = 11; + break; + case 3: + cprint(LINE_CPU, 0, "Intel 486DX2"); + off = 12; + break; + case 4: + cprint(LINE_CPU, 0, "Intel 486SL"); + off = 11; + break; + case 5: + cprint(LINE_CPU, 0, "Intel 486SX2"); + off = 12; + break; + case 7: + cprint(LINE_CPU, 0, "Intel 486DX2-WB"); + off = 15; + break; + case 8: + cprint(LINE_CPU, 0, "Intel 486DX4"); + off = 12; + break; + case 9: + cprint(LINE_CPU, 0, "Intel 486DX4-WB"); + off = 15; + break; + } + /* Since we can't get CPU speed or cache info return */ + return; } - /* Since we can't get CPU speed or cache info return */ - return; - } - /* Get the cache info */ - for (i=0; i<16; i++) { + /* Get the cache info */ + for (i=0; i<16; i++) { #ifdef CPUID_DEBUG - dprint(12,i*3,cpu_id.cache_info[i],2,1); + dprint(12,i*3,cpu_id.cache_info[i],2,1); #endif - switch(cpu_id.cache_info[i]) { - case 0x6: - case 0xa: - case 0x66: - l1_cache += 8; - break; - case 0x8: - case 0xc: - case 0x67: - case 0x60: - l1_cache += 16; - break; - case 0x68: - case 0x2c: - case 0x30: - l1_cache += 32; - break; - case 0x40: - l2_cache = 0; - break; - case 0x41: - case 0x79: - case 0x39: - case 0x3b: - l2_cache = 128; - break; - case 0x42: - case 0x7a: - case 0x82: - case 0x3c: - l2_cache = 256; - break; - case 0x43: - case 0x7b: - case 0x83: - case 0x86: - l2_cache = 512; - break; - case 0x44: - case 0x7c: - case 0x84: - case 0x87: - l2_cache = 1024; - break; - case 0x45: - case 0x7d: - case 0x85: - l2_cache = 2048; - break; - } - } - - switch(cpu_id.type) { - case 5: - switch(cpu_id.model) { - case 0: - case 1: - case 2: - case 3: - case 7: - cprint(LINE_CPU, 0, "Pentium"); - if (l1_cache == 0) { - l1_cache = 8; - } - off = 7; - break; - case 4: - case 8: - cprint(LINE_CPU, 0, "Pentium-MMX"); - if (l1_cache == 0) { - l1_cache = 16; + switch(cpu_id.cache_info[i]) { + case 0x6: + case 0xa: + case 0x66: + l1_cache += 8; + break; + case 0x8: + case 0xc: + case 0x67: + case 0x60: + l1_cache += 16; + break; + case 0x68: + case 0x2c: + case 0x30: + l1_cache += 32; + break; + case 0x40: + l2_cache = 0; + break; + case 0x41: + case 0x79: + case 0x39: + case 0x3b: + l2_cache = 128; + break; + case 0x42: + case 0x7a: + case 0x82: + case 0x3c: + l2_cache = 256; + break; + case 0x43: + case 0x7b: + case 0x83: + case 0x86: + l2_cache = 512; + break; + case 0x44: + case 0x7c: + case 0x84: + case 0x87: + l2_cache = 1024; + break; + case 0x45: + case 0x7d: + case 0x85: + l2_cache = 2048; + break; } - off = 11; - break; } - break; - case 6: - switch(cpu_id.model) { - case 0: - case 1: - cprint(LINE_CPU, 0, "Pentium Pro"); - off = 11; - break; - case 3: - cprint(LINE_CPU, 0, "Pentium II"); - off = 10; - break; + + switch(cpu_id.type) { case 5: - if (l2_cache == 0) { - cprint(LINE_CPU, 0, "Celeron"); + switch(cpu_id.model) { + case 0: + case 1: + case 2: + case 3: + case 7: + cprint(LINE_CPU, 0, "Pentium"); + if (l1_cache == 0) { + l1_cache = 8; + } off = 7; - } else { - cprint(LINE_CPU, 0, "Pentium II"); - off = 10; + break; + case 4: + case 8: + cprint(LINE_CPU, 0, "Pentium-MMX"); + if (l1_cache == 0) { + l1_cache = 16; + } + off = 11; + break; } break; case 6: - if (l2_cache == 128) { - cprint(LINE_CPU, 0, "Celeron"); - off = 7; - } else { + switch(cpu_id.model) { + case 0: + case 1: + cprint(LINE_CPU, 0, "Pentium Pro"); + off = 11; + break; + case 3: cprint(LINE_CPU, 0, "Pentium II"); off = 10; + break; + case 5: + if (l2_cache == 0) { + cprint(LINE_CPU, 0, "Celeron"); + off = 7; + } else { + cprint(LINE_CPU, 0, "Pentium II"); + off = 10; + } + break; + case 6: + if (l2_cache == 128) { + cprint(LINE_CPU, 0, "Celeron"); + off = 7; + } else { + cprint(LINE_CPU, 0, "Pentium II"); + off = 10; + } + break; + case 7: + case 8: + case 10: + case 11: + if (l2_cache == 128) { + cprint(LINE_CPU, 0, "Celeron"); + off = 7; + } else { + cprint(LINE_CPU, 0, "Pentium III"); + off = 11; + } + break; + case 9: + if (l2_cache == 512) { + cprint(LINE_CPU, 0, "Celeron M (0.13)"); + } else { + cprint(LINE_CPU, 0, "Pentium M (0.13)"); + } + off = 16; + break; + case 13: + if (l2_cache == 1024) { + cprint(LINE_CPU, 0, "Celeron M (0.09)"); + } else { + cprint(LINE_CPU, 0, "Pentium M (0.09)"); + } + off = 16; + break; } break; - case 7: - case 8: - case 10: - case 11: - if (l2_cache == 128) { - cprint(LINE_CPU, 0, "Celeron"); - off = 7; - } else { - cprint(LINE_CPU, 0, "Pentium III"); - off = 11; + case 15: + switch(cpu_id.model) { + case 0: + case 1: + if (l2_cache == 128) { + cprint(LINE_CPU, 0, "Celeron (0.18)"); + off = 14; + } else if (cpu_id.pwrcap == 0x0B) { + cprint(LINE_CPU, 0, "Xeon DP (0.18)"); + off = 14; + } else if (cpu_id.pwrcap == 0x0C) { + cprint(LINE_CPU, 0, "Xeon MP (0.18)"); + off = 14; + } else { + cprint(LINE_CPU, 0, "Pentium 4 (0.18)"); + off = 16; + } + break; + case 2: + if (l2_cache == 128) { + cprint(LINE_CPU, 0, "Celeron (0.13)"); + off = 14; + } else if (cpu_id.pwrcap == 0x0B) { + cprint(LINE_CPU, 0, "Xeon DP (0.13)"); + off = 14; + } else if (cpu_id.pwrcap == 0x0C) { + cprint(LINE_CPU, 0, "Xeon MP (0.13)"); + off = 14; + } else { + cprint(LINE_CPU, 0, "Pentium 4 (0.13)"); + off = 16; + } + break; + case 3: + case 4: + case 5: + if (l2_cache == 256) { + cprint(LINE_CPU, 0, "Celeron (0.09)"); + off = 14; + } else if (cpu_id.pwrcap == 0x0B) { + cprint(LINE_CPU, 0, "Xeon DP (0.09)"); + off = 14; + } else if (cpu_id.pwrcap == 0x0C) { + cprint(LINE_CPU, 0, "Xeon MP (0.09)"); + off = 14; + } else { + cprint(LINE_CPU, 0, "Pentium 4 (0.09)"); + off = 16; + } + break; } break; - case 9: - if (l2_cache == 512) { - cprint(LINE_CPU, 0, "Celeron M (0.13)"); - } else { - cprint(LINE_CPU, 0, "Pentium M (0.13)"); - } - off = 16; - break; - case 13: - if (l2_cache == 512) { - cprint(LINE_CPU, 0, "Celeron M (0.09)"); - } else { - cprint(LINE_CPU, 0, "Pentium M (0.09)"); - } - off = 16; - break; } - break; - case 15: - switch(cpu_id.model) { - case 0: - case 1: - if (l2_cache == 128) { - cprint(LINE_CPU, 0, "Celeron (0.18)"); - off = 14; - } else if (cpu_id.pwrcap == 0x0B) { - cprint(LINE_CPU, 0, "Xeon DP (0.18)"); - off = 14; - } else if (cpu_id.pwrcap == 0x0C) { - cprint(LINE_CPU, 0, "Xeon MP (0.18)"); - off = 14; - } else { - cprint(LINE_CPU, 0, "Pentium 4 (0.18)"); - off = 16; - } - break; - case 2: - if (l2_cache == 128) { - cprint(LINE_CPU, 0, "Celeron (0.13)"); - off = 14; - } else if (cpu_id.pwrcap == 0x0B) { - cprint(LINE_CPU, 0, "Xeon DP (0.13)"); - off = 14; - } else if (cpu_id.pwrcap == 0x0C) { - cprint(LINE_CPU, 0, "Xeon MP (0.13)"); - off = 14; - } else { - cprint(LINE_CPU, 0, "Pentium 4 (0.13)"); - off = 16; - } - break; - case 3: - case 4: - case 5: - if (l2_cache == 256) { - cprint(LINE_CPU, 0, "Celeron (0.09)"); - off = 14; - } else if (cpu_id.pwrcap == 0x0B) { - cprint(LINE_CPU, 0, "Xeon DP (0.09)"); - off = 14; - } else if (cpu_id.pwrcap == 0x0C) { - cprint(LINE_CPU, 0, "Xeon MP (0.09)"); - off = 14; - } else { - cprint(LINE_CPU, 0, "Pentium 4 (0.09)"); - off = 16; - } - break; - } - break; - } break; - /* VIA/Cyrix Processors with CPUID */ + /* VIA/Cyrix/Centaur Processors with CPUID */ case 'C': - switch(cpu_id.type) { - case 5: - switch(cpu_id.model) { - case 0: - cprint(LINE_CPU, 0, "Cyrix 6x86MX/MII"); - off = 16; - break; - case 4: - cprint(LINE_CPU, 0, "Cyrix GXm"); - off = 9; - break; - } - return; - break; - case 6: // VIA C3 - switch(cpu_id.model) { - case 6: - cprint(LINE_CPU, 0, "Cyrix III"); - off = 9; + if ( cpu_id.vend_id[1] == 'e' ) { /* CentaurHauls */ + switch(cpu_id.type){ + case 5: + cprint(LINE_CPU, 0, "Centaur 5x86"); + off = 12; break; - case 7: + case 6: // VIA C3 if (cpu_id.step < 8) { - cprint(LINE_CPU, 0, "VIA C3 Samuel2"); off = 14; + cprint(LINE_CPU, 0, "VIA C3 Samuel2"); + off = 14; } else { - cprint(LINE_CPU, 0, "VIA C3 Ezra-T"); off = 13; - } - break; - case 8: - cprint(LINE_CPU, 0, "VIA C3 Ezra-T"); - off = 13; + cprint(LINE_CPU, 0, "Via C3 Eden"); + off = 11; + } break; - case 9: - cprint(LINE_CPU, 0, "VIA C3 Nehemiah"); - off = 15; + } + l1_cache = cpu_id.cache_info[3] + cpu_id.cache_info[7]; + l2_cache = cpu_id.cache_info[11]; + } else { /* CyrixInstead */ + switch(cpu_id.type) { + case 5: + switch(cpu_id.model) { + case 0: + cprint(LINE_CPU, 0, "Cyrix 6x86MX/MII"); + off = 16; + break; + case 4: + cprint(LINE_CPU, 0, "Cyrix GXm"); + off = 9; + break; + } + return; + + case 6: // VIA C3 + switch(cpu_id.model) { + case 6: + cprint(LINE_CPU, 0, "Cyrix III"); + off = 9; + break; + case 7: + if (cpu_id.step < 8) { + cprint(LINE_CPU, 0, "VIA C3 Samuel2"); + off = 14; + } else { + cprint(LINE_CPU, 0, "VIA C3 Ezra-T"); + off = 13; + } + break; + case 8: + cprint(LINE_CPU, 0, "VIA C3 Ezra-T"); + off = 13; + break; + case 9: + cprint(LINE_CPU, 0, "VIA C3 Nehemiah"); + off = 15; + break; + } + // L1 = L2 = 64 KB from Cyrix III to Nehemiah + l1_cache = 64; + l2_cache = 64; break; } - // L1 = L2 = 64 KB from Cyrix III to Nehemiah - l1_cache = 64; - l2_cache = 64; - break; } break; @@ -846,9 +894,9 @@ void cpu_type(void) } /* Record the starting time */ - asm __volatile__ ("rdtsc":"=a" (v->startl),"=d" (v->starth)); - v->snapl = v->startl; - v->snaph = v->starth; + asm __volatile__ ("rdtsc":"=a" (v->startl),"=d" (v->starth)); + v->snapl = v->startl; + v->snaph = v->starth; v->rdtsc = 1; if (l1_cache == 0) { l1_cache = 66; } if (l2_cache == 0) { l1_cache = 666; } @@ -898,7 +946,7 @@ static void cacheable(void) /* #define TICKS 5 * 11832 (count = 6376)*/ /* #define TICKS (65536 - 12752) */ /* #define TICKS (65536 - 8271) */ -#define TICKS 59659 +#define TICKS 59659 /* Program counter to 50 ms = 59659 clks */ /* Returns CPU clock in khz */ static int cpuspeed(void) @@ -907,7 +955,7 @@ static int cpuspeed(void) /* Setup timer */ outb((inb(0x61) & ~0x02) | 0x01, 0x61); - outb(0xb0, 0x43); + outb(0xb0, 0x43); outb(TICKS & 0xff, 0x42); outb(TICKS >> 8, 0x42); @@ -949,11 +997,11 @@ static ulong memspeed(ulong src, ulong len, int iter) for (i=0; i<iter; i++) { asm __volatile__ ( "movl %0,%%esi\n\t" \ - "movl %1,%%edi\n\t" \ - "movl %2,%%ecx\n\t" \ - "cld\n\t" \ - "rep\n\t" \ - "movsl\n\t" \ + "movl %1,%%edi\n\t" \ + "movl %2,%%ecx\n\t" \ + "cld\n\t" \ + "rep\n\t" \ + "movsl\n\t" \ :: "g" (src), "g" (dst), "g" (0) : "esi", "edi", "ecx" ); @@ -973,10 +1021,10 @@ static ulong memspeed(ulong src, ulong len, int iter) asm __volatile__ ( "movl %0,%%esi\n\t" \ "movl %1,%%edi\n\t" \ - "movl %2,%%ecx\n\t" \ - "cld\n\t" \ - "rep\n\t" \ - "movsl\n\t" \ + "movl %2,%%ecx\n\t" \ + "cld\n\t" \ + "rep\n\t" \ + "movsl\n\t" \ :: "g" (src), "g" (dst), "g" (wlen) : "esi", "edi", "ecx" ); @@ -984,13 +1032,13 @@ static ulong memspeed(ulong src, ulong len, int iter) /* Now measure the speed */ asm __volatile__ ("rdtsc":"=a" (st_low),"=d" (st_high)); for (i=0; i<iter; i++) { - asm __volatile__ ( + asm __volatile__ ( "movl %0,%%esi\n\t" \ - "movl %1,%%edi\n\t" \ - "movl %2,%%ecx\n\t" \ - "cld\n\t" \ - "rep\n\t" \ - "movsl\n\t" \ + "movl %1,%%edi\n\t" \ + "movl %2,%%ecx\n\t" \ + "cld\n\t" \ + "rep\n\t" \ + "movsl\n\t" \ :: "g" (src), "g" (dst), "g" (wlen) : "esi", "edi", "ecx" ); @@ -16,8 +16,8 @@ short serial_cons = SERIAL_CONSOLE_DEFAULT; char buf[18]; struct ascii_map_str { - int ascii; - int keycode; + int ascii; + int keycode; }; char *codes[] = { @@ -93,7 +93,7 @@ void *memmove(void *dest, const void *src, ulong n) * Scroll the error message area of the screen as needed * Starts at line LINE_SCROLL and ends at line 23 */ -void scroll(void) +void scroll(void) { int i, j; char *s, tmp; @@ -106,23 +106,23 @@ void scroll(void) while (slock) { check_input(); } - for (i=LINE_SCROLL; i<23; i++) { + 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); + 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, ' '); + set_scrn_buf(23, j, ' '); s += 2; } - tty_print_region(LINE_SCROLL, 0, 23, 79); - } + tty_print_region(LINE_SCROLL, 0, 23, 79); + } } /* @@ -137,37 +137,37 @@ void cprint(int y, int x, const char *text) for (i=0; text[i]; i++) { *dptr = text[i]; dptr += 2; - } - tty_print_line(y, x, text); + } + tty_print_line(y, x, text); } -void itoa(char s[], int n) +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; + } } /* @@ -233,16 +233,16 @@ void dprint(int y, int x, ulong val, int len, int right) continue; } if (k == 0 && flag == 0) { - continue; + continue; } buf[i++] = k + '0'; val -= k * j; } else { - if (flag == 0 && i < len-1) { - buf[i++] = '0'; - } else { - buf[i++] = ' '; - } + if (flag == 0 && i < len-1) { + buf[i++] = '0'; + } else { + buf[i++] = ' '; + } } flag++; } @@ -259,12 +259,12 @@ void hprint2(int y,int x, unsigned long val, int digits) unsigned long j; int i, idx, flag = 0; - for (i=0, idx=0; i<8; i++) { - j = val >> (28 - (4 * i)); + 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'; + buf[idx++] = j + '0'; flag++; } else { buf[idx++] = '0'; @@ -273,14 +273,14 @@ void hprint2(int y,int x, unsigned long val, int digits) buf[idx++] = j + 'a' - 10; flag++; } - } + } if (digits > 8) { digits = 8; } if (flag > digits) { digits = flag; } - buf[idx] = 0; + buf[idx] = 0; cprint(y,x,buf + (idx - digits)); } @@ -297,7 +297,7 @@ void hprint(int y, int x, unsigned long val) */ void xprint(int y,int x, ulong val) { - ulong j; + ulong j; j = (val & 0xffc00000) >> 20; dprint(y, x, j, 4, 0); @@ -308,7 +308,7 @@ void xprint(int y,int x, ulong val) j = val & 0x3ff; dprint(y, x+10, j, 4, 0); } - + /* Handle an interrupt */ void inter(struct eregs *trap_regs) { @@ -330,10 +330,10 @@ void inter(struct eregs *trap_regs) #endif /* clear scrolling region */ - pp=(char *)(SCREEN_ADR+(2*80*(LINE_SCROLL-2))); - for(i=0; i<2*80*(24-LINE_SCROLL-2); i++, pp+=2) { - *pp = ' '; - } + pp=(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"); @@ -393,7 +393,7 @@ void inter(struct eregs *trap_regs) } } -void set_cache(int val) +void set_cache(int val) { extern struct cpu_ident cpu_id; /* 386's don't have a cache */ @@ -403,7 +403,7 @@ void set_cache(int val) } switch(val) { case 0: - cache_off(); + cache_off(); cprint(LINE_INFO, COL_CACHE, "off"); break; case 1: @@ -415,7 +415,7 @@ void set_cache(int val) int get_key() { int c; - + c = inb(0x64); if ((c & 1) == 0) { if (serial_cons) { @@ -442,7 +442,7 @@ void check_input(void) if ((c = get_key())) { switch(c & 0x7f) { - case 1: + case 1: /* "ESC" key was pressed, bail out. */ cprint(LINE_RANGE, COL_MID+23, "Halting... "); @@ -496,7 +496,7 @@ ulong getval(int x, int y, int result_shift) buf[i] = ' '; } buf[sizeof(buf)/sizeof(buf[0]) -1] = '\0'; - + wait_keyup(); done = 0; n = 0; @@ -550,7 +550,7 @@ ulong getval(int x, int y, int result_shift) } /* Don't allow anything to be entered after a suffix */ if (n > 0 && ( - (buf[n-1] == 'p') || (buf[n-1] == 'g') || + (buf[n-1] == 'p') || (buf[n-1] == 'g') || (buf[n-1] == 'm') || (buf[n-1] == 'k'))) { buf[n] = ' '; } @@ -618,7 +618,7 @@ 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++; @@ -645,7 +645,7 @@ void ttyprint(int y, int x, const char *p) void serial_echo_init(void) { int comstat, hi, lo; - + /* read the Divisor Latch */ comstat = serial_echo_inb(UART_LCR); serial_echo_outb(comstat | UART_LCR_DLAB, UART_LCR); @@ -668,7 +668,7 @@ void serial_echo_init(void) comstat = serial_echo_inb(UART_RX); /* COM? RBR */ serial_echo_outb(0x00, UART_IER); /* Disable all interrupts */ - clear_screen_buf(); + clear_screen_buf(); return; } @@ -701,9 +701,9 @@ void serial_echo_print(const char *p) */ struct ascii_map_str ser_map[] = /*ascii keycode ascii keycode*/ -{ +{ /* Special cases come first so I can leave - * their ``normal'' mapping in the table, + * their "normal" mapping in the table, * without it being activated. */ { 27, 0x01}, /* ^[/ESC -> ESC */ @@ -2,27 +2,32 @@ * * Released under version 2 of the Gnu Public License. * By Chris Brady + * ---------------------------------------------------- + * MemTest86+ V1.50 Specific code (GPL V2.0) + * By Samuel DEMEULEMEESTER, sdemeule@memtest.org + * http://www.x86-secret.com - http://www.memtest.org */ #include "test.h" #include "defs.h" #undef TEST_TIMES -#define DEFTESTS 9 +#define DEFTESTS 11 extern void bzero(); const struct tseq tseq[] = { - {0, 5, 3, 0, 0, "[Address test, walking ones, no cache]"}, - {1, 6, 3, 2, 0, "[Address test, own address] "}, - {1, 0, 3, 14, 0, "[Moving inversions, ones & zeros] "}, - {1, 1, 2, 80, 0, "[Moving inversions, 8 bit pattern] "}, - {1, 10, 60, 300, 0,"[Moving inversions, random pattern] "}, - {1, 7, 64, 66, 0, "[Block move, 64 moves] "}, - {1, 2, 2, 320, 0, "[Moving inversions, 32 bit pattern] "}, - {1, 9, 40, 120, 0, "[Random number sequence] "}, - {1, 3, 4, 240, 0, "[Modulo 20, ones & zeros] "}, - {1, 8, 1, 2, 0, "[Bit fade test, 90 min, 2 patterns] "}, - {0, 0, 0, 0, 0, NULL} + {1, 5, 3, 0, 0, "[Address test, walking ones] "}, + {1, 6, 3, 2, 0, "[Address test, own address] "}, + {1, 0, 3, 14, 0, "[Moving inversions, ones & zeros] "}, + {1, 1, 2, 80, 0, "[Moving inversions, 8 bit pattern] "}, + {1, 10, 60, 300, 0, "[Moving inversions, random pattern] "}, + {1, 7, 64, 66, 0, "[Block move, 64 moves] "}, + {1, 2, 2, 320, 0, "[Moving inversions, 32 bit pattern] "}, + {1, 9, 40, 120, 0, "[Random number sequence] "}, + {1, 3, 4, 240, 0, "[Modulo 20, ones & zeros] "}, + {1, 8, 1, 2, 0, "[Bit fade test, 90 min, 2 patterns] "}, + {0, 4, 3, 2, 0, "[[Moving inversions, 0 & 1, uncached] "}, + {0, 0, 0, 0, 0, NULL} }; char firsttime = 0; @@ -37,7 +42,7 @@ int test_ticks; int nticks; static int window = 0; -static struct pmap windows[] = +static struct pmap windows[] = { { 0/* Written at startup */, 0x100000 }, { 0, RES_START >> 12 }, @@ -117,7 +122,7 @@ static void run_at(unsigned long addr) start = (unsigned long) &_start; len = _end - _start; - if ( ((start < addr) && ((start + len) >= addr)) || + if ( ((start < addr) && ((start + len) >= addr)) || ((addr < start) && ((addr + len) >= start))) { /* Handle overlap by doing an extra relocation */ if (addr + len < HIGH_TEST_ADR) { @@ -132,7 +137,7 @@ static void run_at(unsigned long addr) void do_test(void) { - int i = 0, j = 0; + int i = 0; unsigned long chunks; unsigned long lo, hi; @@ -148,7 +153,7 @@ void do_test(void) if ((ulong)&_start != LOW_TEST_ADR) { restart(); } - windows[0].start = + windows[0].start = ( LOW_TEST_ADR + (_end - _start) + 4095) >> 12; init(); firsttime = 1; @@ -172,13 +177,13 @@ void do_test(void) cprint(LINE_RANGE, COL_MID+14, " - "); aprint(LINE_RANGE, COL_MID+17, hi); aprint(LINE_RANGE, COL_MID+23, v->selected_pages); - cprint(LINE_RANGE, COL_MID+28, + cprint(LINE_RANGE, COL_MID+28, ((ulong)&_start == LOW_TEST_ADR)?" ":" Relocated"); - + #ifdef TEST_TIMES { ulong l, h, t; - + asm __volatile__ ( "rdtsc\n\t" "subl %%ebx,%%eax\n\t" @@ -219,7 +224,6 @@ void do_test(void) len = v->map[i].end - v->map[i].start; chunks += (len + SPINSZ -1)/SPINSZ; } - test_ticks = find_ticks_for_test(chunks, v->test); nticks = 0; v->tptr = 0; @@ -228,40 +232,32 @@ void do_test(void) /* Now do the testing according to the selected pattern */ case 0: /* Moving inversions, all ones and zeros */ - p1 = 0; - p2 = ~p1; - movinv1(tseq[v->test].iter,p1,p2); - BAILOUT; - - /* Switch patterns */ - p2 = p1; - p1 = ~p2; - movinv1(tseq[v->test].iter,p1,p2); - BAILOUT; - break; - case 1: /* Moving inversions, 8 bit wide walking ones and zeros. */ - p0 = 0x80; - for (i=0; i<8; i++, p0=p0>>1) { - p1 = p0 | (p0<<8) | (p0<<16) | (p0<<24); - p2 = ~p1; - movinv1(tseq[v->test].iter,p1,p2); - BAILOUT; + case 4: + if (tseq[v->test].pat == 1) + p0 = 0x80808080; + else + p0 = 0; + + for ( ; ; ) { + movinv1(tseq[v->test].iter,p0,~p0); + BAILOUT; + /* Switch patterns */ - p2 = p1; - p1 = ~p2; - movinv1(tseq[v->test].iter,p1,p2); + movinv1(tseq[v->test].iter,~p0,p0); BAILOUT + if ( !((unsigned char)(p0 >>= 1) & 0x7F) ) + break; } break; + case 2: /* Moving inversions, 32 bit shifting pattern, very long */ for (i=0, p1=1; p1; p1=p1<<1, i++) { movinv32(tseq[v->test].iter,p1, 1, 0x80000000, 0, i); BAILOUT - movinv32(tseq[v->test].iter,~p1, 0xfffffffe, - 0x7fffffff, 1, i); + movinv32(tseq[v->test].iter,~p1, 0xfffffffe, 0x7fffffff, 1, i); BAILOUT } break; @@ -281,23 +277,6 @@ void do_test(void) } break; - case 4: /* Modulo X check, 8 bit pattern */ - p0 = 0x80; - for (j=0; j<8; j++, p0=p0>>1) { - p1 = p0 | (p0<<8) | (p0<<16) | (p0<<24); - for (i=0; i<MOD_SZ; i++) { - p2 = ~p1; - modtst(i, tseq[v->test].iter, p1, p2); - BAILOUT - - /* Switch patterns */ - p2 = p1; - p1 = ~p2; - modtst(i, tseq[v->test].iter, p1, p2); - BAILOUT - } - } - break; case 5: /* Address test, walking ones */ addr_tst1(); BAILOUT; @@ -312,12 +291,14 @@ void do_test(void) block_move(tseq[v->test].iter); BAILOUT; break; + case 8: /* Bit fade test */ if (window == 0 ) { bit_fade(); } BAILOUT; break; + case 9: /* Random Data Sequence */ for (i=0; i < tseq[v->test].iter; i++) { movinvr(); @@ -352,15 +333,15 @@ void do_test(void) * The lower limit is less than START_ADR * - There is more than 1 meg of memory */ - if (windows[window].start < + if (windows[window].start < (LOW_TEST_ADR + (_end - _start)) >> 12) { - if (v->pmap[v->msegs-1].end > + if (v->pmap[v->msegs-1].end > (((HIGH_TEST_ADR + (_end - _start)) >> 12) +1)) { /* We need the high copy and we have enough * memory so use it. */ run_at(HIGH_TEST_ADR); - } else { + } else { /* We can't use this window so skip it */ goto skip_window; } @@ -376,7 +357,7 @@ void do_test(void) skip_test: v->test++; bail_test: - /* Revert to the default mapping + /* Revert to the default mapping * and enable the cache. */ paging_off(); @@ -385,7 +366,7 @@ void do_test(void) window = 0; cprint(LINE_PAT, COL_PAT-3, " "); /* If this was the last test then we finished a pass */ - if (v->test >= DEFTESTS || v->testsel >= 0) { + if (v->test >= 9 || v->testsel >= 0) { v->pass++; dprint(LINE_INFO, COL_PASS, v->pass, 5, 0); v->test = 0; @@ -394,7 +375,7 @@ void do_test(void) cprint(0, COL_MID+8, " "); } - + /* We always start a pass with the low copy */ run_at(LOW_TEST_ADR); } @@ -413,10 +394,10 @@ void restart() v->ecount = 0; v->ecc_ecount = 0; - /* Clear the screen */ - for(i=0, pp=(char *)(SCREEN_ADR+0); i<80*24; i++, pp+=2) { - *pp = ' '; - } + /* Clear the screen */ + for(i=0, pp=(char *)(SCREEN_ADR+0); i<80*24; i++, pp+=2) { + *pp = ' '; + } run_at(LOW_TEST_ADR); } @@ -447,7 +428,7 @@ void find_ticks(void) if (i != v->testsel) { continue; } - } + } v->pass_ticks += find_ticks_for_test(chunks, i); } } @@ -527,11 +508,11 @@ static void compute_segments(int win) cprint(LINE_SCROLL+(2*i+1), 44, "i="); hprint(LINE_SCROLL+(2*i+1), 46, i); - - cprint(LINE_SCROLL+(2*i+2), 0, + + cprint(LINE_SCROLL+(2*i+2), 0, " " " "); - cprint(LINE_SCROLL+(2*i+3), 0, + cprint(LINE_SCROLL+(2*i+3), 0, " " " "); #endif @@ -105,7 +105,7 @@ static void sort_pmap(void) if (i != j) { struct pmap temp; temp = v->pmap[i]; - memmove(&v->pmap[j], &v->pmap[j+1], + memmove(&v->pmap[j], &v->pmap[j+1], (i -j)* sizeof(temp)); v->pmap[j] = temp; } @@ -186,7 +186,7 @@ static void memsize_820(int res) cprint(LINE_INFO, COL_MMAP, "e820-Std"); } } - + static void memsize_801(void) { ulong mem_size; @@ -216,7 +216,7 @@ static void memsize_801(void) /* * Sanitize the BIOS e820 map. * - * Some e820 responses include overlapping entries. The following + * Some e820 responses include overlapping entries. The following * replaces the original e820 map with a new one, removing overlaps. * */ @@ -374,7 +374,7 @@ static int sanitize_e820_map(struct e820entry *orig_map, struct e820entry *new_b /* move forward only if the new size was non-zero */ if (new_bios[new_bios_entry].size != 0) if (++new_bios_entry >= E820MAX) - break; /* no more space left for new bios entries */ + break; /* no more space left for new bios entries */ } if (current_type != 0) { new_bios[new_bios_entry].addr = change_point[chgidx]->addr; @@ -397,8 +397,8 @@ static void memsize_probe(void) * must be limited. The max address is found by checking for * memory wrap from 1MB to 4GB. */ p1 = (ulong)&magic; - m_lim = 0xfffffffc; - for (p2 = 0x100000; p2; p2 <<= 1) { + m_lim = 0xfffffffc; + for (p2 = 0x100000; p2; p2 <<= 1) { p = (ulong *)(p1 + p2); if (*p == 0x1234569) { m_lim = --p2; @@ -415,7 +415,7 @@ static void memsize_probe(void) v->pmap[i].start = ((ulong)&_end + (1 << 12) - 1) >> 12; p = (ulong *)(v->pmap[i].start << 12); - /* Limit search for memory to m_lim and make sure we don't + /* Limit search for memory to m_lim and make sure we don't * overflow the 32 bit size of p. */ while ((ulong)p < m_lim && (ulong)p >= (ulong)&_end) { /* @@ -482,34 +482,34 @@ fstart: * We then check that at least one bit changed in each byte before * believing that it really is memory. */ -static int check_ram(void) +static int check_ram(void) { - int s; - - p1 = *p; - - /* write the complement */ - *p = ~p1; - p2 = *p; - s = 0; - - /* Now make sure a bit changed in each byte */ - if ((0xff & p1) != (0xff & p2)) { - s++; - } - if ((0xff00 & p1) != (0xff00 & p2)) { - s++; - } - if ((0xff0000 & p1) != (0xff0000 & p2)) { - s++; - } - if ((0xff000000 & p1) != (0xff000000 & p2)) { - s++; - } - if (s == 4) { - /* RAM at this address */ - return 1; - } - - return 0; + int s; + + p1 = *p; + + /* write the complement */ + *p = ~p1; + p2 = *p; + s = 0; + + /* Now make sure a bit changed in each byte */ + if ((0xff & p1) != (0xff & p2)) { + s++; + } + if ((0xff00 & p1) != (0xff00 & p2)) { + s++; + } + if ((0xff0000 & p1) != (0xff0000 & p2)) { + s++; + } + if ((0xff000000 & p1) != (0xff000000 & p2)) { + s++; + } + if (s == 4) { + /* RAM at this address */ + return 1; + } + + return 0; } diff --git a/mt86+_loader.asm b/mt86+_loader.asm index be83381..3006078 100644 --- a/mt86+_loader.asm +++ b/mt86+_loader.asm @@ -12,8 +12,8 @@ ; The good thing is that you get a single file which can be ; compressed, for example with http://upx.sf.net/ (UPX). -%define fullsize (95352 + buffer - exeh) - ; 95352 is the size of memtest86+ V1.40, adjust as needed! +%define fullsize (94472 + buffer - exeh) + ; 94472 is the size of memtest86+ V1.50, adjust as needed! %define stacksize 2048 %define stackpara ((stacksize + 15) / 16) @@ -50,7 +50,7 @@ start: ; entry point ; if you use obj + linker, use "..start:" mov ds,ax ; *** mov es,ax ; *** - ; test if we have 386 or better: + ; test if we have 386 or better: pushf ; save flags xor ax,ax push ax diff --git a/mt86+_loader.bin b/mt86+_loader.bin Binary files differindex 1725ec7..9528ecc 100644 --- a/mt86+_loader.bin +++ b/mt86+_loader.bin @@ -32,7 +32,7 @@ int pci_conf_read(unsigned bus, unsigned dev, unsigned fn, unsigned reg, unsigne case PCI_CONF_TYPE_2: outb(0xF0 | (fn << 1), 0xCF8); outb(bus, 0xCFA); - + switch(len) { case 1: *value = inb(PCI_CONF2_ADDRESS(dev, reg)); result = 0; break; case 2: *value = inw(PCI_CONF2_ADDRESS(dev, reg)); result = 0; break; @@ -64,7 +64,7 @@ int pci_conf_write(unsigned bus, unsigned dev, unsigned fn, unsigned reg, unsign case PCI_CONF_TYPE_2: outb(0xF0 | (fn << 1), 0xCF8); outb(bus, 0xCFA); - + switch(len) { case 1: outb(value, PCI_CONF2_ADDRESS(dev, reg)); result = 0; break; case 2: outw(value, PCI_CONF2_ADDRESS(dev, reg)); result = 0; break; @@ -97,18 +97,21 @@ static int pci_sanity_check(void) static int pci_check_direct(void) { - unsigned int tmp; + unsigned char tmpCFB; + unsigned int tmpCF8; /* Check if configuration type 1 works. */ pci_conf_type = PCI_CONF_TYPE_1; + tmpCFB = inb(0xCFB); outb(0x01, 0xCFB); - tmp = inl(0xCF8); + tmpCF8 = inl(0xCF8); outl(0x80000000, 0xCF8); if ((inl(0xCF8) == 0x80000000) && (pci_sanity_check() == 0)) { - outl(tmp, 0xCF8); + outl(tmpCF8, 0xCF8); + outb(tmpCFB, 0xCFB); return 0; } - outl(tmp, 0xCF8); + outl(tmpCF8, 0xCF8); /* Check if configuration type 2 works. */ pci_conf_type = PCI_CONF_TYPE_2; @@ -116,9 +119,12 @@ static int pci_check_direct(void) outb(0x00, 0xCF8); outb(0x00, 0xCFA); if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00 && (pci_sanity_check() == 0)) { + outb(tmpCFB, 0xCFB); return 0; } + outb(tmpCFB, 0xCFB); + /* Nothing worked return an error */ pci_conf_type = PCI_CONF_TYPE_NONE; return -1; diff --git a/precomp.bin b/precomp.bin Binary files differindex 052eff0..ee6c0be 100755..100644 --- a/precomp.bin +++ b/precomp.bin @@ -22,7 +22,7 @@ bootstrap relocation instead of general-purpose relocation. */ #define RTLD_BOOTSTRAP -struct link_map +struct link_map { ElfW(Addr) l_addr; /* Current load address */ ElfW(Addr) ll_addr; /* Last load address */ @@ -127,7 +127,7 @@ elf_get_dynamic_info(ElfW(Dyn) *dyn, ElfW(Addr) l_addr, { if (! dyn) return; - + while (dyn->d_tag != DT_NULL) { if (dyn->d_tag < DT_NUM) @@ -142,8 +142,8 @@ elf_get_dynamic_info(ElfW(Dyn) *dyn, ElfW(Addr) l_addr, assert (! "bad dynamic tag"); ++dyn; } - - if (info[DT_PLTGOT] != NULL) + + 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; @@ -194,7 +194,7 @@ elf_dynamic_do_rel (struct link_map *map, 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)); @@ -221,32 +221,32 @@ void _dl_start(void) /* 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(); 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. + * data access using the global offset table. */ #if !ELF_MACHINE_NO_REL - elf_dynamic_do_rel(&map, + 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, + 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, + 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, + elf_dynamic_do_rela(&map, map.l_info[DT_JMPREL]->d_un.d_ptr, map.l_info[DT_PLTRELSZ]->d_un.d_val); } diff --git a/screen_buffer.c b/screen_buffer.c index d56ae88..44635a7 100644 --- a/screen_buffer.c +++ b/screen_buffer.c @@ -1,14 +1,14 @@ -/* --*- C -*-- - * +/* --*- C -*-- + * * By Jani Averbach, Jaa@iki.fi, 2001 - * + * * Released under version 2 of the Gnu Public License. * - * $Author: jaa $ - * $Revision: 1.10 $ - * $Date: 2001/03/29 09:00:30 $ + * $Author: jaa $ + * $Revision: 1.10 $ + * $Date: 2001/03/29 09:00:30 $ * $Source: /home/raid/cvs/memtest86/screen_buffer.c,v $ (for CVS) - * + * */ #include "test.h" #include "screen_buffer.h" @@ -18,7 +18,7 @@ #define SCREEN_Y 25 #define Y_SIZE SCREEN_Y /* - * X-size should by one of by screen size, + * X-size should by one of by screen size, * so that there is room for ending '\0' */ #define X_SIZE SCREEN_X+1 @@ -41,8 +41,8 @@ char get_scrn_buf(const int y, const int x) { - CHECK_BOUNDS(y,x); - return screen_buf[y][x]; + CHECK_BOUNDS(y,x); + return screen_buf[y][x]; } @@ -51,43 +51,43 @@ set_scrn_buf(const int y, const int x, const char val) { - CHECK_BOUNDS(y,x); - screen_buf[y][x] = val; + CHECK_BOUNDS(y,x); + screen_buf[y][x] = val; } void clear_screen_buf() { - int y, x; - - for (y=0; y < SCREEN_Y; ++y){ - for (x=0; x < SCREEN_X; ++x){ - CHECK_BOUNDS(y,x); - screen_buf[y][x] = ' '; - } - CHECK_BOUNDS(y,SCREEN_X); - screen_buf[y][SCREEN_X] = '\0'; - } + int y, x; + + for (y=0; y < SCREEN_Y; ++y){ + for (x=0; x < SCREEN_X; ++x){ + CHECK_BOUNDS(y,x); + screen_buf[y][x] = ' '; + } + CHECK_BOUNDS(y,SCREEN_X); + screen_buf[y][SCREEN_X] = '\0'; + } } -void tty_print_region(const int pi_top, +void tty_print_region(const int pi_top, const int pi_left, const int pi_bottom, const int pi_right) { - int y; - char tmp; + int y; + char tmp; + + for (y=pi_top; y < pi_bottom; ++y){ + CHECK_BOUNDS(y, pi_right); - for (y=pi_top; y < pi_bottom; ++y){ - CHECK_BOUNDS(y, pi_right); - - tmp = screen_buf[y][pi_right]; - screen_buf[y][pi_right] = '\0'; + tmp = screen_buf[y][pi_right]; + screen_buf[y][pi_right] = '\0'; - CHECK_BOUNDS(y, pi_left); - ttyprint(y, pi_left, &(screen_buf[y][pi_left])); + CHECK_BOUNDS(y, pi_left); + ttyprint(y, pi_left, &(screen_buf[y][pi_left])); - screen_buf[y][pi_right] = tmp; - } + screen_buf[y][pi_right] = tmp; + } } void tty_print_line( @@ -112,23 +112,23 @@ void tty_print_line( void tty_print_screen(void) { #ifdef SCRN_DEBUG - int i; + int i; - for (i=0; i < SCREEN_Y; ++i) - ttyprint(i,0, padding); + for (i=0; i < SCREEN_Y; ++i) + ttyprint(i,0, padding); #endif /* SCRN_DEBUG */ - tty_print_region(0, 0, SCREEN_Y, SCREEN_X); + tty_print_region(0, 0, SCREEN_Y, SCREEN_X); } void print_error(char *pstr) { #ifdef SCRN_DEBUG - ttyprint(0,0, padding); + ttyprint(0,0, padding); #endif /* SCRN_DEBUG */ - ttyprint(0,35, pstr); - - while(1); + ttyprint(0,35, pstr); + + while(1); } @@ -13,7 +13,7 @@ .section ".setup", "ax", @progbits
.globl start
start:
-# ok, the read went well
+# ok, the read went well
# now we want to move to protected mode ...
@@ -31,10 +31,10 @@ start: # that was painless, now we enable A20
call empty_8042
-
+
movb $0xD1, %al # command write
outb %al, $0x64
- call empty_8042
+ call empty_8042
movb $0xDF, %al # A20 on
outb %al, $0x60
@@ -72,7 +72,7 @@ empty_8042: call delay
inb $0x60, %al # read it
jmp empty_8042
-
+
no_output:
testb $2, %al # is input buffer full?
jnz empty_8042 # yes - loop
@@ -8,7 +8,7 @@ * By Samuel DEMEULEMEESTER, sdemeule@memtest.org * http://www.x86-secret.com - http://www.memtest.org */ - + #include "test.h" #include "config.h" #include <sys/io.h> @@ -42,12 +42,12 @@ void addr_tst1() /* Test the global address bits */ for (p1=0, j=0; j<2; j++) { - hprint(LINE_PAT, COL_PAT, p1); + 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; @@ -65,7 +65,7 @@ void addr_tst1() *pt = p1; if ((bad = *p) != ~p1) { ad_err1((ulong *)p, (ulong *)mask, - bad, ~p1); + bad, ~p1); i = 1000; } mask = mask << 1; @@ -84,7 +84,7 @@ void addr_tst1() bank = 0x40000; } for (p1=0, k=0; k<2; k++) { - hprint(LINE_PAT, COL_PAT, p1); + hprint(LINE_PAT, COL_PAT, p1); for (j=0; j<segs; j++) { p = v->map[j].start; @@ -110,8 +110,8 @@ void addr_tst1() *pt = p1; if ((bad = *p) != ~p1) { ad_err1((ulong *)p, - (ulong *)mask, - bad,~p1); + (ulong *)mask, + bad,~p1); i = 200; } mask = mask << 1; @@ -140,7 +140,7 @@ void addr_tst2() volatile ulong *pe; volatile ulong *end, *start; - cprint(LINE_PAT, COL_PAT, " "); + cprint(LINE_PAT, COL_PAT, " "); /* Write each address with it's own address */ for (j=0; j<segs; j++) { @@ -227,7 +227,7 @@ void addr_tst2() "cmpl %%edx,%%edi\n\t" "jb L91\n\t" "jmp L94\n\t" - + "L93:\n\t" "pushl %%edx\n\t" "pushl %%ecx\n\t" @@ -271,7 +271,7 @@ void movinvr() } /* Display the current seed */ - hprint(LINE_PAT, COL_PAT, seed1); + hprint(LINE_PAT, COL_PAT, seed1); rand_seed(seed1, seed2); for (j=0; j<segs; j++) { start = v->map[j].start; @@ -300,19 +300,19 @@ void movinvr() } */ - asm __volatile__ ( - "jmp L200\n\t" - ".p2align 4,,7\n\t" - "L200:\n\t" - "call rand\n\t" + asm __volatile__ ( + "jmp L200\n\t" + ".p2align 4,,7\n\t" + "L200:\n\t" + "call rand\n\t" "movl %%eax,(%%edi)\n\t" - "addl $4,%%edi\n\t" - "cmpl %%ebx,%%edi\n\t" - "jb L200\n\t" - : "=D" (p) - : "D" (p), "b" (pe) + "addl $4,%%edi\n\t" + "cmpl %%ebx,%%edi\n\t" + "jb L200\n\t" + : "=D" (p) + : "D" (p), "b" (pe) : "eax" - ); + ); do_tick(); BAILR @@ -417,7 +417,7 @@ void movinv1(int iter, ulong p1, ulong p2) volatile ulong *start,*end; /* Display the current pattern */ - hprint(LINE_PAT, COL_PAT, p1); + hprint(LINE_PAT, COL_PAT, p1); /* Initialize memory with the initial pattern. */ for (j=0; j<segs; j++) { @@ -603,12 +603,15 @@ void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off) int i, j, k=0, done; volatile ulong *pe; volatile ulong *start, *end; - ulong pat = 0, p3; + ulong pat = 0; - p3 = sval << 31; +/* CDH start + * ulong p3 = sval << 31; + * CDH end + */ /* Display the current pattern */ - hprint(LINE_PAT, COL_PAT, p1); + hprint(LINE_PAT, COL_PAT, p1); /* Initialize memory with the initial pattern. */ for (j=0; j<segs; j++) { @@ -651,24 +654,18 @@ void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off) "jmp L20\n\t" ".p2align 4,,7\n\t" +/* CDH start */ "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" + "incb %%bl\n\t" "addl $4,%%edi\n\t" + "roll $1,%%ecx\n\t" "cmpl %%edx,%%edi\n\t" "jb L20\n\t" - : "=b" (k), "=D" (p) - : "D" (p),"d" (pe),"b" (k),"c" (pat), - "a" (sval), "S" (lb) + "andb $31,%%bl\n\t" + : "=b" (k), "=D" (p), "=c" (pat) + : "D" (p),"d" (pe),"b" (k),"c" (pat) +/* CDH end */ ); do_tick(); BAILR @@ -727,24 +724,18 @@ void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off) "cmpl %%ecx,%%ebp\n\t" "jne L34\n\t" +/* CDH start */ "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" "addl $4,%%edi\n\t" + "incb %%bl\n\t" + "roll $1,%%ecx\n\t" "cmpl %%edx,%%edi\n\t" "jb L30\n\t" "jmp L33\n\t" +/* CDH end */ "L34:\n\t" \ "pushl %%esi\n\t" @@ -764,11 +755,13 @@ void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off) "popl %%esi\n\t" "jmp L35\n" +/* CDH start */ "L33:\n\t" + "andb $31,%%bl\n\t" "popl %%ebp\n\t" - : "=b" (k), "=D" (p) - : "D" (p),"d" (pe),"b" (k),"c" (pat), - "a" (sval), "S" (lb) + : "=b" (k), "=D" (p), "=c" (pat) + : "D" (p),"d" (pe),"b" (k),"c" (pat) +/* CDH end */ ); do_tick(); BAILR @@ -778,13 +771,26 @@ void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off) /* Since we already adjusted k and the pattern this * code backs both up one step */ - pat = lb; - if ( 0 != (k = (k-1) & 31) ) { - pat = (pat << k); - if ( sval ) - pat |= ((sval << k) - 1); - } - k++; +/* CDH start */ +/* Original C code replaced with hand tuned assembly code + * pat = lb; + * if ( 0 != (k = (k-1) & 31) ) { + * pat = (pat << k); + * if ( sval ) + * pat |= ((sval << k) - 1); + * } + * k++; + */ + asm __volatile__ ( + "decl %%ecx\n\t" + "andl $31,%%ecx\n\t" + "roll %%cl,%%ebx\n\t" + "incb %%cl\n\t" + : "=c" (k), "=b" (pat) + : "c" (k), "b" (lb) + ); +/* CDH end */ + for (j=segs-1; j>=0; j--) { start = v->map[j].start; end = v->map[j].end; @@ -824,7 +830,7 @@ void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off) "pushl %%ebp\n\t" "addl $4,%%edi\n\t" "jmp L40\n\t" - + ".p2align 4,,7\n\t" "L40:\n\t" "subl $4,%%edi\n\t" @@ -833,22 +839,16 @@ void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off) "cmpl %%ecx,%%ebp\n\t" "jne L44\n\t" +/* CDH start */ "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" + "decb %%bl\n\t" + "rorl $1,%%ecx\n\t" "cmpl %%edx,%%edi\n\t" "ja L40\n\t" "jmp L43\n\t" +/* CDH end */ "L44:\n\t" \ "pushl %%esi\n\t" @@ -868,12 +868,14 @@ void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off) "popl %%esi\n\t" "jmp L45\n" +/* CDH start */ "L43:\n\t" + "andb $31,%%bl\n\t" "subl $4,%%edi\n\t" "popl %%ebp\n\t" : "=b" (k), "=D" (p), "=c" (pat) - : "D" (p),"d" (pe),"b" (k),"c" (pat), - "a" (p3), "S" (hb) + : "D" (p),"d" (pe),"b" (k),"c" (pat) +/* CDH end */ ); do_tick(); BAILR @@ -892,9 +894,9 @@ void modtst(int offset, int iter, ulong p1, ulong p2) volatile ulong *start, *end; /* Display the current pattern */ - hprint(LINE_PAT, COL_PAT-2, p1); + hprint(LINE_PAT, COL_PAT-2, p1); cprint(LINE_PAT, COL_PAT+6, "-"); - dprint(LINE_PAT, COL_PAT+7, offset, 2, 1); + dprint(LINE_PAT, COL_PAT+7, offset, 2, 1); /* Write every nth location with pattern */ for (j=0; j<segs; j++) { @@ -1062,13 +1064,13 @@ void modtst(int offset, int iter, ulong p1, ulong p2) BAILR } while (!done); } - cprint(LINE_PAT, COL_PAT, " "); + cprint(LINE_PAT, COL_PAT, " "); } /* - * Test memory using block moves + * Test memory using block moves * Adapted from Robert Redelmeier's burnBX test */ void block_move(int iter) @@ -1078,7 +1080,7 @@ void block_move(int iter) volatile ulong p, pe, pp; volatile ulong start, end; - cprint(LINE_PAT, COL_PAT-2, " "); + cprint(LINE_PAT, COL_PAT-2, " "); /* Initialize memory with the initial pattern. */ for (j=0; j<segs; j++) { @@ -1146,7 +1148,7 @@ void block_move(int iter) } while (!done); } - /* Now move the data around + /* 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 */ @@ -1213,7 +1215,7 @@ void block_move(int iter) } while (!done); } - /* Now check the data + /* Now check the data * The error checking is rather crude. We just check that the * adjacent words are the same. */ @@ -1324,7 +1326,7 @@ void bit_fade() pe = start; p = start; for (p=end; p<end; p++) { - if ((bad=*p) != p1) { + if ((bad=*p) != p1) { error((ulong*)p, p1, bad); } } @@ -1352,8 +1354,7 @@ void error(ulong *adr, ulong good, ulong 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 - dir - * 810, 815 and 820 chipsets. It is possible that we will skip + * 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) { @@ -1378,7 +1379,7 @@ void error(ulong *adr, ulong good, ulong bad) } else if (v->printmode == PRINTMODE_PATTERNS) { print_err_counts(); - if (patnchg) { + if (patnchg) { printpatn(); } } @@ -1434,7 +1435,7 @@ void ad_err2(ulong *adr, ulong bad) print_err(adr, (ulong)adr, bad, ((ulong)adr) ^ bad); } else if (v->printmode == PRINTMODE_PATTERNS) { print_err_counts(); - if (patnchg) { + if (patnchg) { printpatn(); } } @@ -1451,12 +1452,12 @@ void print_hdr(void) static void update_err_counts(void) { ++(v->ecount); - + if (beepmode){ - beep(600); - beep(1000); + beep(600); + beep(1000); } - + tseq[v->test].errors++; } @@ -1464,20 +1465,20 @@ static void print_err_counts(void) { int i; char *pp; - + dprint(LINE_INFO, COL_ERR, v->ecount, 6, 0); dprint(LINE_INFO, COL_ECC_ERR, v->ecc_ecount, 6, 0); /* Paint the error messages on the screen red to provide a vivid */ - /* indicator that an error has occured */ + /* indicator that an error has occured */ if (v->msg_line < 24) { for(i=0, pp=(char *)((SCREEN_ADR+v->msg_line*160+1)); i<76; i++, pp+=2) { *pp = 0x47; } } - - + + } static void common_err(ulong page, ulong offset) @@ -1502,14 +1503,14 @@ static void common_err(ulong page, ulong offset) /* * Print an individual error */ -void print_err( ulong *adr, ulong good, ulong bad, ulong xor) +void print_err( ulong *adr, ulong good, ulong bad, ulong xor) { ulong page, offset; page = page_of(adr); offset = ((unsigned long)adr) & 0xFFF; common_err(page, offset); - + ecount = 1; hprint(v->msg_line, 36, good); @@ -1523,7 +1524,7 @@ void print_err( ulong *adr, ulong good, ulong bad, ulong xor) /* * Print an ecc error */ -void print_ecc_err(unsigned long page, unsigned long offset, +void print_ecc_err(unsigned long page, unsigned long offset, int corrected, unsigned short syndrome, int channel) { if (!corrected) {update_err_counts();} @@ -1533,10 +1534,10 @@ void print_ecc_err(unsigned long page, unsigned long offset, } common_err(page, offset); - cprint(v->msg_line, 36, + cprint(v->msg_line, 36, corrected?"corrected ": "uncorrected "); hprint2(v->msg_line, 60, syndrome, 4); - cprint(v->msg_line, 68, "ECC"); + cprint(v->msg_line, 68, "ECC"); dprint(v->msg_line, 74, channel, 2, 0); } @@ -1544,7 +1545,7 @@ void print_ecc_err(unsigned long page, unsigned long offset, /* * Print a parity error message */ -void parity_err( unsigned long edi, unsigned long esi) +void parity_err( unsigned long edi, unsigned long esi) { unsigned long addr; @@ -1568,36 +1569,36 @@ void parity_err( unsigned long edi, unsigned long esi) */ void printpatn (void) { - int idx=0; - int x; + int idx=0; + int x; /* Check for keyboard input */ check_input(); - if (v->numpatn == 0) - return; + if (v->numpatn == 0) + return; - scroll(); + scroll(); - cprint (v->msg_line, 0, "badram="); - x=7; + cprint (v->msg_line, 0, "badram="); + x=7; - for (idx = 0; idx < v->numpatn; idx++) { + 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; - } + 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; + } } - + /* * Show progress by displaying elapsed time and update bar graphs */ @@ -1608,7 +1609,7 @@ void do_tick(void) /* FIXME only print serial error messages from the tick handler */ if (v->ecount) { - print_err_counts(); + print_err_counts(); } nticks++; @@ -1624,7 +1625,7 @@ void do_tick(void) cprint(1, COL_MID+9+v->tptr, "#"); v->tptr++; } - + pct = 100*v->total_ticks/v->pass_ticks; dprint(0, COL_MID+4, pct, 3, 0); i = (BAR_SIZE * pct) / 100; @@ -1674,7 +1675,7 @@ void sleep(int n, int sms) { int i, ip; ulong sh, sl, l, h, t; - + ip = 0; /* save the starting time */ asm __volatile__( @@ -1690,15 +1691,15 @@ void sleep(int n, int sms) :"=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); + 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; + t = h * ((unsigned)0xffffffff / v->clks_msec) / 1000; + t += (l / v->clks_msec) / 1000; } - + /* Is the time up? */ if (t >= n) { break; @@ -1706,23 +1707,23 @@ void sleep(int n, int sms) /* Display the elapsed time on the screen */ if (sms == 0) { - - i = t % 60; - dprint(LINE_TIME, COL_TIME+9, i%10, 1, 0); - dprint(LINE_TIME, COL_TIME+8, i/10, 1, 0); + + i = t % 60; + dprint(LINE_TIME, COL_TIME+9, i%10, 1, 0); + dprint(LINE_TIME, COL_TIME+8, i/10, 1, 0); if (i != ip) { - check_input(); - ip = i; + check_input(); + ip = i; } - 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); - BAILR + 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); + BAILR } } } @@ -1732,20 +1733,20 @@ void sleep(int n, int sms) void beep(unsigned int frequency) { unsigned int count = 1193180 / frequency; - + // Switch on the speaker outb_p(inb_p(0x61)|3, 0x61); - + // 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); - + // Block for 100 microseconds sleep(100, 1); - + // Switch off the speaker outb(inb_p(0x61)&0xFC, 0x61); } @@ -96,7 +96,7 @@ int query_pcbios(void); int insertaddress(ulong); void printpatn(void); void printpatn(void); -void itoa(char s[], int n); +void itoa(char s[], int n); void reverse(char *p); void serial_echo_init(void); void serial_echo_print(const char *s); @@ -139,7 +139,7 @@ void beep(unsigned int frequency); void block_move(int iter); void find_ticks(void); void print_err(ulong *adr, ulong good, ulong bad, ulong xor); -void print_ecc_err(ulong page, ulong offset, int corrected, +void print_ecc_err(ulong page, ulong offset, int corrected, unsigned short syndrome, int channel); void mem_size(void); void adj_mem(void); @@ -185,8 +185,8 @@ 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" + "andl $0x9fffffff,%eax\n\t" /* Clear CD and NW */ + "movl %eax,%cr0\n\t" "pop %eax\n\t"); } @@ -194,10 +194,10 @@ static inline void reboot(void) { asm( "movl %cr0,%eax\n\t" - "andl $0x00000011,%eax\n\t" - "orl $0x60000000,%eax\n\t" - "movl %eax,%cr0\n\t" - "movl %eax,%cr3\n\t" + "andl $0x00000011,%eax\n\t" + "orl $0x60000000,%eax\n\t" + "movl %eax,%cr0\n\t" + "movl %eax,%cr3\n\t" "movl %cr0,%ebx\n\t" "andl $0x60000000,%ebx\n\t" "jz f\n\t" @@ -243,6 +243,7 @@ struct cpu_ident { char vend_id[12]; unsigned char cache_info[16]; long pwrcap; + long ext; }; #define X86_FEATURE_PAE (0*32+ 6) /* Physical Address Extensions */ @@ -266,7 +267,7 @@ struct vars { int total_ticks; int pptr; int tptr; - int beepmode; + int beepmode; struct pmap pmap[MAX_MEM_SEGMENTS]; struct mmap map[MAX_MEM_SEGMENTS]; ulong plim_lower; @@ -276,7 +277,7 @@ struct vars { ulong startl; ulong snaph; ulong snapl; - ulong extclock; + ulong extclock; int printmode; int numpatn; struct pair patn [BADRAM_MAXPATNS]; |