summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2009-09-18 05:37:20 +0200
committerMichael Brown2012-07-09 16:41:26 +0200
commit4d88f7ec4ce034fdfe9bd05a1e94f7b16e996244 (patch)
treef25204d1de3357ac4aae7c4d9f61279dff766b52
parent[import] Import version 1.40 (diff)
downloadmemtest86-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--FAQ310
-rw-r--r--Makefile242
-rw-r--r--bootsect.S54
-rw-r--r--changelog15
-rw-r--r--config.c55
-rw-r--r--controller.c876
-rw-r--r--defs.h4
-rw-r--r--extra.c1242
-rw-r--r--head.S141
-rw-r--r--init.c712
-rw-r--r--lib.c122
-rw-r--r--main.c129
-rw-r--r--memsize.c72
-rw-r--r--mt86+_loader.asm6
-rw-r--r--mt86+_loader.binbin784 -> 784 bytes
-rw-r--r--pci.c18
-rw-r--r--[-rwxr-xr-x]precomp.binbin95352 -> 94472 bytes
-rw-r--r--reloc.c22
-rw-r--r--screen_buffer.c84
-rw-r--r--setup.S8
-rw-r--r--test.c291
-rw-r--r--test.h21
22 files changed, 2498 insertions, 1926 deletions
diff --git a/FAQ b/FAQ
new file mode 100644
index 0000000..f962443
--- /dev/null
+++ b/FAQ
@@ -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.
diff --git a/Makefile b/Makefile
index f8498ec..d680dd9 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/bootsect.S b/bootsect.S
index 982775d..facd00a 100644
--- a/bootsect.S
+++ b/bootsect.S
@@ -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
diff --git a/config.c b/config.c
index 1435d6f..9cd9731 100644
--- a/config.c
+++ b/config.c
@@ -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, &centri);
+ pci_conf_read( 2, 2, 0, 0x02, 2, &centri);
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();
diff --git a/defs.h b/defs.h
index 3a27bee..b3b1caf 100644
--- a/defs.h
+++ b/defs.h
@@ -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.
*/
diff --git a/extra.c b/extra.c
index 41e94dc..e7afff2 100644
--- a/extra.c
+++ b/extra.c
@@ -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();
}
diff --git a/head.S b/head.S
index 49a3e3d..36db092 100644
--- a/head.S
+++ b/head.S
@@ -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
diff --git a/init.c b/init.c
index 28000fc..96aff5e 100644
--- a/init.c
+++ b/init.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.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("INE_SCROLL;24r"); /* Set scroll area row 7-23 */
- serial_echo_print(""); /* Clear Screen */
- serial_echo_print("");
- serial_echo_print("");
- serial_echo_print("");
+ 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("");
+ 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"
);
diff --git a/lib.c b/lib.c
index 05b8371..d357b53 100644
--- a/lib.c
+++ b/lib.c
@@ -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 */
diff --git a/main.c b/main.c
index ac970bc..15b156c 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/memsize.c b/memsize.c
index 2447a29..ce7e177 100644
--- a/memsize.c
+++ b/memsize.c
@@ -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
index 1725ec7..9528ecc 100644
--- a/mt86+_loader.bin
+++ b/mt86+_loader.bin
Binary files differ
diff --git a/pci.c b/pci.c
index 02ad6c2..1aad707 100644
--- a/pci.c
+++ b/pci.c
@@ -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
index 052eff0..ee6c0be 100755..100644
--- a/precomp.bin
+++ b/precomp.bin
Binary files differ
diff --git a/reloc.c b/reloc.c
index 39016b2..374b495 100644
--- a/reloc.c
+++ b/reloc.c
@@ -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);
}
diff --git a/setup.S b/setup.S
index 2e1cfa6..48e7773 100644
--- a/setup.S
+++ b/setup.S
@@ -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
diff --git a/test.c b/test.c
index 1da798c..fae2308 100644
--- a/test.c
+++ b/test.c
@@ -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);
}
diff --git a/test.h b/test.h
index a09fb1f..124ac9a 100644
--- a/test.h
+++ b/test.h
@@ -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];