summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2009-09-18 05:37:36 +0200
committerMichael Brown2012-07-09 16:41:25 +0200
commit87e047292b0d563504fe4162596b11be132cbf1a (patch)
treeb824296717675ecfcd825cb5229dcedd2269b7e8
parent[import] Import version 1.30 (diff)
downloadmemtest86-87e047292b0d563504fe4162596b11be132cbf1a.tar.gz
memtest86-87e047292b0d563504fe4162596b11be132cbf1a.tar.xz
memtest86-87e047292b0d563504fe4162596b11be132cbf1a.zip
[import] Import version 1.40
http://www.memtest.org/download/1.40/memtest86+-1.40.tar.gz
-rw-r--r--Makefile5
-rw-r--r--README1663
-rw-r--r--README.build-process78
-rw-r--r--bootsect.S750
-rw-r--r--changelog7
-rw-r--r--config.c264
-rw-r--r--controller.c19
-rw-r--r--head.S14
-rw-r--r--[-rwxr-xr-x]init.c12
-rw-r--r--lib.c16
-rw-r--r--main.c109
-rwxr-xr-xmakeiso.sh39
-rw-r--r--memsize.c72
-rw-r--r--memtest.bin.lds30
-rw-r--r--memtest.lds22
-rw-r--r--memtest_shared.lds104
-rw-r--r--mt86+_loader.asm4
-rw-r--r--mt86+_loader.binbin784 -> 784 bytes
-rwxr-xr-xprecomp.binbin99516 -> 95352 bytes
-rw-r--r--random.c31
-rw-r--r--setup.S230
-rw-r--r--stdint.h (renamed from stdin.h)2
-rw-r--r--test.c231
-rw-r--r--test.h76
24 files changed, 1939 insertions, 1839 deletions
diff --git a/Makefile b/Makefile
index f7dcf1d..f8498ec 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ CCFLAGS=-Wall -m32 -march=i486 -Os -fomit-frame-pointer -fno-builtin -ffreestand
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
+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
@@ -44,6 +44,9 @@ lib.o: lib.c test.h defs.h io.h screen_buffer.h serial.h config.h
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
diff --git a/README b/README
index 598a3e2..dccbfd0 100644
--- a/README
+++ b/README
@@ -1,813 +1,850 @@
- ===================
- = MemTest-86 v3.0 =
- ===================
-
-Table of Contents
-=================
- 1) Introduction
- 2) Licensing
- 3) Installation
- 4) Serial Port Console
- 5) Online Commands
- 6) Memory Sizing
- 7) Error Display
- 8) Trouble-shooting Memory Errors
- 9) Execution Time
- 10) Memory Testing Philosophy
- 11) Memtest86 Test Algorithms
- 12) Individual Test Descriptions
- 13) Problem Reporting - Contact Information
- 14) Known Problems
- 15) Planned Features List
- 16) Change Log
- 17) Acknowledgments
-
-
-1) Introduction
-===============
-Memtest86 is thorough, stand alone memory test for Intel i386 architecture
-systems. BIOS based memory tests are only a quick check and often miss
-failures that are detected by Memtest86.
-
-For updates go to the Memtest86 web page:
-
- http://www.memtest86.com
-
-To report problems or provide feedback send email to:
-
- cbrady@cray.com
-
-
-2) Licensing
-============
-Memtest86 is released under the terms of the Gnu Public License (GPL). Other
-than the provisions of the GPL there are no restrictions for use, private or
-commercial. See: http://www.gnu.org/licenses/gpl.html for details.
-
-
-3) Installation (Linux Only)
-============================
-Memtest86 is a stand alone program and can be loaded from either a disk
-partition or from a floppy disk.
-
-To build Memtest86:
- 1) Review the Makefile and adjust options as needed.
- 2) Type "make"
-
-This creates a file named "memtest.bin" which is a bootable image. This
-image file may be copied to a floppy disk or lilo may be used to boot this
-image from a hard disk partition.
-
-To create a Memtest86 bootdisk
- 1) Insert a blank write enabled floppy disk.
- 2) As root, Type "make install"
-
-To boot from a disk partition via lilo
- 1) Copy the image file to a permanent location (ie. /memtest).
- 2) Add an entry in the lilo config file (usually /etc/lilo.conf) to boot
- memtest86. Only the image and label fields need to be specified.
- The following is a sample lilo entry for booting memtest86:
-
- image = /memtest
- label = memtest
-
- 3) As root, type "lilo"
-
- At the lilo prompt enter memtest to boot memtest86.
-
-If you encounter build problems a binary image has been included (precomp.bin).
-To create a boot-disk with this pre-built image do the following:
- 1) Insert a blank write enabled floppy disk.
- 2) Type "make install-bin"
-
-If you have problems with memory sizing an option is available to get
-the memory size from the BIOS. To enable this option uncomment the
-define for BIOS_MEMSZ in config.h and then rebuild and install the test.
-
-
-4) Serial Console
-=================
-Memtest86 can be used on PC's equipped with a serial port for the console.
-By default serial port console support is not enabled since it slows
-down testing. To enable change the SERIAL_CONSOLE_DEFAULT define in
-config.h from a zero to a one. The serial console baud rate may also
-be set in config.h with the SERIAL_BAUD_RATE define. The other serial
-port settings are no parity, 8 data bits, 1 stop bit. All of the features
-used by memtest86 are accessible via the serial console. However, the
-screen sometimes is garbled when the online commands are used.
-
-
-5) Online Commands
-==================
-Memtest86 has a limited number of online commands. Online commands
-provide control over caching, test selection, address range and error
-scrolling. A help bar is displayed at the bottom of the screen listing
-the available on-line commands.
-
- Command Description
-
- ESC Exits the test and does a warm restart via the BIOS.
-
- c Enters test configuration menu
- Menu options are:
- 1) Cache mode
- 2) Test selection
- 3) Address Range
- 4) Memory Sizing
- 5) Error Summary
- 6) Error Report Mode
- 7) ECC Mode
- 8) Restart Test
- 9) Reprint Screen
-
- SP Set scroll lock (Stops scrolling of error messages)
- Note: Testing is stalled when the scroll lock is
- set and the scroll region is full.
-
- CR Clear scroll lock (Enables error message scrolling)
-
-
-6) Memory Sizing
-================
-The BIOS in modern PC's will often reserve several sections of memory for
-it's use and also to communicate information to the operating system (ie.
-ACPI tables). It is just as important to test these reserved memory blocks
-as it is for the remainder of memory. For proper operation all of memory
-needs to function properly regardless of what the eventual use is. For
-this reason Memtest86 has been designed to test as much memory as is
-possible.
-
-However, safely and reliably detecting all of the available memory has been
-problematic. Versions of Memtest86 prior to v2.9 would probe to find where
-memory is. This works for the vast majority of motherboards but is not 100%
-reliable. Sometimes the memory size is incorrect and worse probing the wrong
-places can in some cases cause the test to hang or crash.
-
-Starting in version 2.9 alternative methods are available for determining the
-memory size. By default the test attempts to get the memory size from the
-BIOS using the "e820" method. With "e820" the BIOS provides a table of memory
-segments and identifies what they will be used for. By default Memtest86
-will test all of the ram marked as available and also the area reserved for
-the ACPI tables. This is safe since the test does not use the ACPI tables
-and the "e820" specifications state that this memory may be reused after the
-tables have been copied. Although this is a safe default some memory will
-not be tested.
-
-Two additional options are available through online configuration options.
-The first option (BIOS-All) also uses the "e820" method to obtain a memory
-map. However, when this option is selected all of the reserved memory
-segments are tested, regardless of what their intended use is. The only
-exception is memory segments that begin above 3gb. Testing has shown that
-these segments are typically not safe to test. The BIOS-All option is more
-thorough but could be unstable with some motherboards.
-
-The second option for memory sizing is the traditional "Probe" method.
-This is a very thorough but not entirely safe method. In the majority of
-cases the BIOS-All and Probe methods will return the same memory map.
-
-For older BIOS's that do not support the "e820" method there are two
-additional methods (e801 and e88) for getting the memory size from the
-BIOS. These methods only provide the amount of extended memory that is
-available, not a memory table. When the e801 and e88 methods are used
-the BIOS-All option will not be available.
-
-The MemMap field on the display shows what memory size method is in use.
-Also the RsvdMem field shows how much memory is reserved and is not being
-tested.
-
-
-7) Error Information
-======================
-Memtest has two options for reporting errors. The default is to report
-individual errors. In BadRAM Patterns mode patterns are created for
-use with the Linux BadRAM feature. This slick feature allows Linux to
-avoid bad memory pages. Details about the BadRAM feature can be found at:
-
- http://home.zonnet.nl/vanrein/badram
-
-For individual errors the following information is displayed when a memory
-error is detected. An error message is only displayed for errors with a
-different address or failing bit pattern. All displayed values are in
-hexadecimal.
-
- Tst: Test number
- Failing Address : Failing memory address
- Good: Expected data pattern
- Bad: Failing data pattern
- Err-Bits: Exclusive or of good and bad data (this shows the
- position of the failing bit(s))
- Count: Number of consecutive errors with the same address
- and failing bits
-
-In BadRAM Patterns mode, Lines are printed in a form badram=F1,M1,F2,M2.
-In each F/M pair, the F represents a fault address, and the corresponding M
-is a bitmask for that address. These patterns state that faults have
-occurred in addresses that equal F on all "1" bits in M. Such a pattern may
-capture more errors that actually exist, but at least all the errors are
-captured. These patterns have been designed to capture regular patterns of
-errors caused by the hardware structure in a terse syntax.
-
-The BadRAM patterns are `grown' increment-ally rather than `designed' from an
-overview of all errors. The number of pairs is constrained to five for a
-number of practical reasons. As a result, handcrafting patterns from the
-output in address printing mode may, in exceptional cases, yield better
-results.
-
-
-8) Trouble-shooting Memory Errors
-================================
-Please be aware that not all errors reported by Memtest86 are due to
-bad memory. The test implicitly tests the CPU, L1 and L2 caches as well as
-the motherboard. It is impossible for the test to determine what causes
-the failure to occur. Most failures will be due to a problem with memory.
-When it is not, the only option is to replace parts until the failure is
-corrected.
-
-Once a memory error has been detected, determining the failing SIMM/DIMM
-module is not a clear cut procedure. With the large number of motherboard
-vendors and possible combinations of simm slots it would be difficult if
-not impossible to assemble complete information about how a particular
-error would map to a failing memory module. However, there are steps
-that may be taken to determine the failing module. Here are three
-techniques that you may wish to use:
-
-1) Removing modules
-This is simplest method for isolating a failing modules, but may only be
-employed when one or more modules can be removed from the system. By
-selectively removing modules from the system and then running the test
-you will be able to find the bad module(s). Be sure to note exactly which
-modules are in the system when the test passes and when the test fails.
-
-2) Rotating modules
-When none of the modules can be removed then you may wish to rotate modules
-to find the failing one. This technique can only be used if there are
-three or more modules in the system. Change the location of two modules
-at a time. For example put the module from slot 1 into slot 2 and put
-the module from slot 2 in slot 1. Run the test and if either the failing
-bit or address changes then you know that the failing module is one of the
-ones just moved. By using several combinations of module movement you
-should be able to determine which module is failing.
-
-3) Replacing modules
-If you are unable to use either of the previous techniques then you are
-left to selective replacement of modules to find the failure.
-
-4) Avoiding allocation
-The printing mode for BadRAM patterns is intended to construct boot time
-parameters for a Linux kernel that is compiled with BadRAM support. This
-work-around makes it possible for Linux to reliably run on your average damaged
-RAM (or clearly panic if it cannot). For more information on BadRAM support
-for Linux, sail to
-
- http://home.zonnet.nl/vanrein/badram
-
-Sometimes memory errors show up due to component incompatibility. A memory
-DIMM/SIMM may work fine in one system and not in another. This is not
-uncommon and is a source of confusion. The components are not necessarily
-bad but certain combinations may need to be avoided.
-
-I am often asked about the reliability of errors reported by Mestest86.
-In the vast majority of cases errors reported by the test are valid.
-There are some systems that cause Memtest86 to be confused about the size of
-memory and it will try to test non-existent memory. This will cause a large
-number of consecutive addresses to be reported as bad and generally there
-will be many bits in error. If you have a relatively small number of
-failing addresses and only one or two bits in error you can be certain
-that the errors are valid. Also intermittent errors are always valid.
-
-All valid memory errors should be corrected. It is possible that a
-particular error will never show up in normal operation. However, operating
-with marginal memory is risky and can result in data loss and even
-disk corruption. You can be sure that Murphy will get you if you know
-about a memory error and ignore it.
-
-Memtest86 can not diagnose many types of PC failures. For example a
-faulty CPU that causes Windows to crash will most likely just cause
-Memtest86 to crash in the same way.
-
-
-9) Execution Time
-==================
-The time required for a complete pass of Memtest86 will vary greatly
-depending on CPU speed, memory speed and memory size. Here are the
-execution times from a Cleron-366 with 64MB of SDRAM:
-
- Test 0: 0:05
- Test 1: 0:18
- Test 2: 1:02
- Test 3: 1:38
- Test 4: 8:05
- Test 5: 1:40
- Test 6: 4:24
- Test 7: 6:04
-
- Total Time for Default tests: 23:16
-
- Test 8: 12:30
- Test 9: 49:30
- Test 10: 30:34
- Test 11: 3:29:40
-
- Total Time for All tests: 5:25:30
-
-
-10) Memory Testing Philosophy
-============================
-There are many good approaches for testing memory. However, many tests
-simply throw some patterns at memory without much thought or knowledge
-of the memory architecture or how errors can best be detected. This
-works fine for hard memory failures but does little to find intermittent
-errors. The BIOS based memory tests are useless for finding intermittent
-memory errors.
-
-Memory chips consist of a large array of tightly packed memory cells,
-one for each bit of data. The vast majority of the intermittent failures
-are a result of interaction between these memory cells. Often writing a
-memory cell can cause one of the adjacent cells to be written with the
-same data. An effective memory test should attempt to test for this
-condition. Therefore, an ideal strategy for testing memory would be
-the following:
-
- 1) write a cell with a zero
- 2) write all of the adjacent cells with a one, one or more times
- 3) check that the first cell still has a zero
-
-It should be obvious that this strategy requires an exact knowledge
-of how the memory cells are laid out on the chip. In addition there is a
-never ending number of possible chip layouts for different chip types
-and manufacturers making this strategy impractical. However, there
-are testing algorithms that can approximate this ideal strategy.
-
-
-11) Memtest86 Test Algorithms
-============================
-Memtest86 uses two algorithms that provide a reasonable approximation
-of the ideal test strategy above. The first of these strategies is called
-moving inversions. The moving inversion test works as follows:
-
- 1) Fill memory with a pattern
- 2) Starting at the lowest address
- 2a check that the pattern has not changed
- 2b write the patterns complement
- 2c increment the address
- repeat 2a - 2c
- 3) Starting at the highest address
- 3a check that the pattern has not changed
- 3b write the patterns complement
- 3c decrement the address
- repeat 3a - 3c
-
-This this algorithm is a good approximation of an ideal memory test but
-there are some limitations. Most high density chips today store data
-4 to 16 bits wide. With chips that are more than one bit wide it
-is impossible to selectively read or write just one bit. This means
-that we cannot guarantee that all adjacent cells have been tested
-for interaction. In this case the best we can do is to use some
-patterns to insure that all adjacent cells have at least been written
-with all possible one and zero combinations.
-
-It can also be seen that caching, buffering and out of order execution
-will interfere with the moving inversions algorithm and make less effective.
-It is possible to turn off cache but the memory buffering in new high
-performance chips can not be disabled. To address this limitation a new
-algorithm I call Modulo-X was created. This algorithm is not affected by
-cache or buffering. The algorithm works as follows:
- 1) For starting offsets of 0 - 20 do
- 1a write every 20th location with a pattern
- 1b write all other locations with the patterns complement
- repeat 1b one or more times
- 1c check every 20th location for the pattern
-
-This algorithm accomplishes nearly the same level of adjacency testing
-as moving inversions but is not affected by caching or buffering. Since
-separate write passes (1a, 1b) and the read pass (1c) are done for all of
-memory we can be assured that all of the buffers and cache have been
-flushed between passes. The selection of 20 as the stride size was somewhat
-arbitrary. Larger strides may be more effective but would take longer to
-execute. The choice of 20 seemed to be a reasonable compromise between
-speed and thoroughness.
-
-
-12) Individual Test Descriptions
-===============================
-Memtest86 executes a series of numbered test sections to check for
-errors. These test sections consist of a combination of test
-algorithm, data pattern and caching. The execution order for these tests
-were arranged so that errors will be detected as rapidly as possible.
-Tests 8, 9, 10 and 11 are very long running extended tests and are only
-executed when extended testing is selected. The extended tests have a
-low probability of finding errors that were missed by the default tests.
-A description of each of the test sections follows:
-
-Test 0 [Address test, walking ones, no cache]
- Tests all address bits in all memory banks by using a walking ones
- address pattern. Errors from this test are not used to calculate
- BadRAM patterns.
-
-Test 1 [Moving Inv, ones&zeros, cached]
- This test uses the moving inversions algorithm with patterns of only
- ones and zeros. Cache is enabled even though it interferes to some
- degree with the test algorithm. With cache enabled this test does not
- take long and should quickly find all "hard" errors and some more
- subtle errors. This section is only a quick check.
-
-Test 2 [Address test, own address, no cache]
- Each address is written with its own address and then is checked
- for consistency. In theory previous tests should have caught any
- memory addressing problems. This test should catch any addressing
- errors that somehow were not previously detected.
-
-Test 3 [Moving inv, 8 bit pat, cached]
- This is the same as test zero but uses a 8 bit wide pattern of
- "walking" ones and zeros. This test will better detect subtle errors
- in "wide" memory chips. A total of 20 data patterns are used.
-
-Test 4 [Moving inv, 32 bit pat, cached]
- This is a variation of the moving inversions algorithm that
- shifts the data pattern left one bit for each successive address.
- The starting bit position is shifted left for each pass. To use
- all possible data patterns 32 passes are required. This test is
- very effective at detecting data sensitive errors in "wide" memory
- chips.
-
-Test 5 [Block move, 64 moves, cached]
- This test stresses memory by using block move (movsl) instructions
- and is based on Robert Redelmeier's burnBX test. Memory is initialized
- with shifting patterns that are inverted every 8 bytes. Then 4MB blocks
- of memory are moved around using the movsl instruction. After the moves
- are completed the data patterns are checked. Because the data is checked
- only after the memory moves are completed it is not possible to know
- where the error occurred. The addresses reported are only for where the
- bad pattern was found. Since the moves are constrained to a 8MB segment
- of memory the failing address will always be lest than 8MB away from the
- reported address. Errors from this test are not used to calculate
- BadRAM patterns.
-
-Test 6 [Modulo 20, ones&zeros, cached]
- Using the Modulo-X algorithm should uncover errors that are not
- detected by moving inversions due to cache and buffering interference
- with the the algorithm. As with test one only ones and zeros are
- used for data patterns.
-
-Test 7 [Moving inv, ones&zeros, no cache]
- This is the same as test one but without cache. With cache off
- there will be much less interference with the test algorithm.
- However, the execution time is much, much longer. This test may
- find very subtle errors missed by tests one and two.
-
-Test 8 [Block move, 512 moves, cached]
- This is the same as test #5 except that we do a lot more memory moves
- before checking memory. Errors from this test are not used to calculate
- BadRAM patterns.
-
-Test 9 [Moving inv, 8 bit pat, no cache]
- This is the first extended test. By using an 8 bit pattern with
- cache off this test should be effective in detecting all types of
- errors. However, it takes a very long time to execute and there is
- a low probability that it will detect errors not found by the previous
- tests.
-
-Test 10 [Modulo 20, 8 bit, cached]
- This is the first test to use the modulo 20 algorithm with a data
- pattern other than ones and zeros. This combination of algorithm and
- data pattern should be quite effective. However, it's very long
- execution time relegates it to the extended test section.
-
-Test 11 [Moving inv, 32 bit pat, no cache]
- This test should be the most effective in finding errors that are
- data pattern sensitive. However, without cache it's execution time
- is excessively long.
-
-
-13) Problem Reporting - Contact Information
-===========================================
-Due to the growing popularity of Memtest86 I am being inundated by,
-questions, feedback, problem reports and requests for enhancements.
-Memtest86 is a side project and often my day job interferes with Memtest86
-support. To help me keep up with this project, please use the following
-guidelines.
-
-Problems/Bugs:
-Before submitting a problem report please check the Known Problems section
-to see if this problem has already been reported. Be sure to include the
-version number and also any details that may be relevant.
-
-Memtest86 sometimes just dies with no hints as to what went wrong.
-Without any details it is nearly impossible to fix these failures. Fixing
-these problems will require debugging assistance on your part. There is
-no point in reporting these failures unless you have a Linux system and
-would be willing to assist me in finding the failure.
-
-Enhancements:
-If you would like to request an enhancement please see if is already on
-the Planned Features List before sending your request. All requests will
-be considered, but not all can be implemented. If you are be interested in
-contributing code please contact me so that the integration can be
-co-ordinated.
-
-Feedback:
-I have received a lot of feedback about the effectiveness of various
-tests. I am still interested in hearing about failures that only a single
-test was able to detect. Of course, gratitude, praise and cash are always
-accepted.
-
-Chris Brady, Email: cbrady@cray.com
-
-
-14) Known Problems
-==================
-Sometimes when booting from a floppy disk the following messages scroll up
-on the screen:
- X:8000
- AX:0212
- BX:8600
- CX:0201
- DX:0000
-This the BIOS reporting floppy disk read errors. Either re-write or toss
-the floppy disk.
-
-Memtest86 has no support for multiple CPUs. Memtest86 should run
-without problems, but it will only use one CPU.
-
-Memtest86 can not diagnose many types of PC failures. For example a
-faulty CPU that causes Windows to crash will most likely just cause
-Memtest86 to crash in the same way.
-
-There have been numerous reports of errors in only tests 5 and 8 on Athlon
-systems. Often the memory works in a different system or the vendor insists
-that it is good. In these cases the memory is not necessarily bad but is
-not able to operate reliably at Athlon speeds. Sometimes more conservative
-memory timings on the motherboard will correct these errors. In other
-cases the only option is to replace the memory with better quality, higher
-speed memory. Don't buy cheap memory and expect it to work with an Athlon!
-
-Memtest86 supports all types of memory. If fact the test has absolutely
-no knowledge of the memory type nor does it need to. This not a problem
-or bug but is listed here due to the many questions I get about this issue.
-
-Changes in the compiler and loader have caused problems with
-Memtest86 resulting in both build failures and errors in execution. A
-binary image (precomp.bin) of the test is included and may be used if
-problems are encountered.
-
-15) Planned Features List
-=========================
-This is a list of enhancements planned for future releases of Memtest86.
-There is no timetable for when these will be implemented, if ever.
-
- - Option to allow printing of error information on an attached printer.
- - Option to write error information to a floppy disk.
- - Supply Memtest in RPM format.
- - Read and display RAM SPD information.
-
-
-16) Change Log
-==============
-Enhancements in v3.0 (22/May/2002) Provided by Eric Biederman
-
- Testing of more than 2gb of memory is at last fixed (tested with 6Gb)
-
- The infrastructure is to poll ecc error reporting chipset regisets,
- and the support has been done for some chipsets.
-
- Uses dynamic relocation information records to make itself PIC
- instead of requiring 2 copies of memtest86 in the binary.
-
- The serial console code does not do redundant writes to the serial port
- Very little slow down at 9600 baud.
-
- You can press ^l or just l to get a screen refresh, when you are
- connecting and unconnecting a serial cable.
-
- Netbooting is working again
-
- LinuxBIOS support (To get the memory size)
-
- Many bugfixes and code cleanup.
-
-Enhancements in v2.9 (29/Feb/2002)
-
- The memory sizing code has been completely rewritten. By default
- Memtest86 gets a memory map from the BIOS that is now used to find
- available memory. A new online configuration option provides three
- choices for how memory will be sized, including the old "probe" method.
- The default mode generally will not test all of memory, but should be more
- stable. See the "Memory Sizing" section for details.
-
- Testing of more than 2gb of memory should now work. A number of bugs
- were found and corrected that prevented testing above 2gb. Testing
- with more than 2gb has been limited and there could be problems with a
- full 4gb of memory.
-
- Memory is divided into segments for testing. This allow for frequent
- progress updates and responsiveness to interactive commands. The
- memory segment size has been increased from 8 to 32mb. This should
- improve testing effectivness but progress reports will be less frequent.
-
- Minor bug fixes.
-
-Enhancements in v2.8 (18/Oct/2001)
- Eric Biederman reworked the build process making it far simpler and also
- to produce a network bootable ELF image.
-
- Re-wrote the memory and cache speed detection code. Previously the
- reported numbers were inaccurate for intel CPU's and completely wrong
- for Athlon/Duron CPU's.
-
- By default the serial console is disabled since this was slowing
- down testing.
-
- Added CPU detection for Pentium 4.
-
-
-Enhancements in v2.7 (12/Jul/2001)
- Expanded workaround for errors caused by BIOS USB keyboard support to
- include test #5.
-
- Re-worked L1 / L2 cache detection code to provide clearer reporting.
-
- Fixed an obvious bug in the computation of cache and memory speeds.
-
- Changed on-line menu to stay in the menu between option selections.
-
- Fixed bugs in the test restart and redraw code.
-
- Adjusted code size to fix compilation problems with RedHat 7.1.
-
- Misc updates to the documentation.
-
-Enhancements in v2.6 (25/May/2001)
- Added workaround for errors caused by BIOS USB keyboard support.
-
- Fixed problems with reporting of 1 GHZ + processor speeds.
-
- Fixed Duron cache detection.
-
- Added screen buffer so that menus will work correctly from a serial
- console.
-
- The Memtest86 image is now built in ELF format.
-
-Enhancements in v2.5 (14/Dec/00)
- Enhanced CPU and cache detection to correctly identify Duron CPU
- and K6-III 1MB cache.
-
- Added code to report cache-able memory size.
-
- Added limited support for parity memory.
-
- Support was added to allow use of on-line commands from a serial
- port.
-
- Dropped option for changing refresh rates. This was not useful
- and did not work on newer motherboards.
-
- Improved fatal exception reporting to include a register and stack
- dump.
-
- The pass number is now displayed in the error report.
-
- Fixed a bug that crashed the test when selecting one of the extended
- tests.
-
-Enhancements in v2.4
- The error report format was reworked for better clarity and now
- includes a decimal address in megabytes.
-
- A new memory move test was added (from Robert Redelmeier's CPU-Burn)
-
- The test sequence and iterations were modified.
-
- Fixed scrolling problems with the BadRAM patterns.
-
-
-Enhancements in v2.3
- A progress meter was added to replace the spinner and dots.
-
- Measurement and reporting of memory and cache performance
- was added.
-
- Support for creating BadRAM patterns was added.
-
- All of the test routines were rewritten in assembler to
- improve both test performance and speed.
-
- The screen layout was reworked to hopefully be more readable.
-
- An error summary option was added to the online commands.
-
-
-Enhancements in v2.2
- Added two new address tests
-
- Added an on-line command for setting test address range
-
- Optimized test code for faster execution (-O3, -funroll-loops and
- -fomit-frame-pointer)
-
- Added and elapsed time counter.
-
- Adjusted menu options for better consistency
-
-
-Enhancements in v2.1
- Fixed a bug in the CPU detection that caused the test to
- hang or crash with some 486 and Cryrix CPU's
-
- Added CPU detection for Cyrix CPU's
-
- Extended and improved CPU detection for Intel and AMD CPU's
-
- Added a compile time option (BIOS_MEMSZ) for obtaining the last
- memory address from the BIOS. This should fix problems with memory
- sizing on certain motherboards. This option is not enabled by default.
- It may be enabled be default in a future release.
-
-Enhancements in v2.0
- Added new Modulo-20 test algorithm.
-
- Added a 32 bit shifting pattern to the moving inversions algorithm.
-
- Created test sections to specify algorithm, pattern and caching.
-
- Improved test progress indicators.
-
- Created popup menus for configuration.
-
- Added menu for test selection.
-
- Added CPU and cache identification.
-
- Added a "bail out" feature to quit the current test when it does not
- fit the test selection parameters.
-
- Re-arranged the screen layout and colors.
-
- Created local include files for I/O and serial interface definitions
- rather than using the sometimes incompatible system include files.
-
- Broke up the "C" source code into four separate source modules.
-
-Enhancements in v1.5
- Some additional changes were made to fix obscure memory sizing
- problems.
-
- The 4 bit wide data pattern was increased to 8 bits since 8 bit
- wide memory chips are becoming more common.
-
- A new test algorithm was added to improve detection of data
- pattern sensitive errors.
-
-
-Enhancements in v1.4
- Changes to the memory sizing code to avoid problems with some
- motherboards where memtest would find more memory than actually
- exists.
-
- Added support for a console serial port. (thanks to Doug Sisk)
-
- On-line commands are now available for configuring Memtest86 on
- the fly (see On-line Commands).
-
-
-Enhancements in v1.3
- Scrolling of memory errors is now provided. Previously, only one screen
- of error information was displayed.
-
- Memtest86 can now be booted from any disk via lilo.
-
- Testing of up to 4gb of memory has been fixed is now enabled by default.
- This capability was clearly broken in v1.2a and should work correctly
- now but has not been fully tested (4gb PC's are a bit rare).
-
- The maximum memory size supported by the motherboard is now being
- calculated correctly. In previous versions there were cases where not
- all of memory would be tested and the maximum memory size supported
- was incorrect.
-
- For some types of failures the good and bad values were reported to be
- same with an Xor value of 0. This has been fixed by retaining the data
- read from memory and not re-reading the bad data in the error reporting
- routine.
-
- APM (advanced power management) is now disabled by Memtest86. This
- keeps the screen from blanking while the test is running.
-
- Problems with enabling & disabling cache on some motherboards have been
- corrected.
-
-17) Acknowledgments
-===================
-The initial versions of the source files bootsect.S, setup.S, head.S and
-build.c are from the Linux 1.2.1 kernel and have been heavily modified.
-
-Doug Sisk provided code to support a console connected via a serial port.
-
-Code to create BadRAM patterns was provided by Rick van Rein.
-
-Tests 5 and 8 are based on Robert Redelmeier's burnBX test.
-
-Screen buffer code was provided by Jani Averbach.
-
-Eric Biederman provided all of the feature content for version 3.0
-plus many bugfixes and significant code cleanup.
+ ====================
+ = MemTest-86 v3.2 =
+ = Nov 11, 2004 =
+ = Chris Brady =
+ ====================
+
+Table of Contents
+=================
+ 1) Introduction
+ 2) Licensing
+ 3) Installation
+ 4) Serial Port Console
+ 5) Online Commands
+ 6) Memory Sizing
+ 7) Error Display
+ 8) Trouble-shooting Memory Errors
+ 9) Execution Time
+ 10) Memory Testing Philosophy
+ 11) Memtest86 Test Algorithms
+ 12) Individual Test Descriptions
+ 13) Problem Reporting - Contact Information
+ 14) Known Problems
+ 15) Planned Features List
+ 16) Change Log
+ 17) Donations
+ 18) Acknowledgments
+
+
+1) Introduction
+===============
+Memtest86 is thorough, stand alone memory test for Intel/AMD x86 architecture
+systems. BIOS based memory tests are only a quick check and often miss
+failures that are detected by Memtest86.
+
+For updates go to the Memtest86 web page:
+
+ http://www.memtest86.com
+
+
+2) Licensing
+============
+Memtest86 is released under the terms of the Gnu Public License (GPL). Other
+than the provisions of the GPL there are no restrictions for use, private or
+commercial. See: http://www.gnu.org/licenses/gpl.html for details.
+Explicit permission for inclusion of Memtest86 in software compilations and
+publications is hereby granted.
+
+
+3) Installation (Linux Only)
+============================
+Memtest86 is a stand alone program and can be loaded from either a disk
+partition or from a floppy disk.
+
+To build Memtest86:
+ 1) Review the Makefile and adjust options as needed.
+ 2) Type "make"
+
+This creates a file named "memtest.bin" which is a bootable image. This
+image file may be copied to a floppy disk or lilo may be used to boot this
+image from a hard disk partition.
+
+To create a Memtest86 bootdisk
+ 1) Insert a blank write enabled floppy disk.
+ 2) As root, Type "make install"
+
+To boot from a disk partition via lilo
+ 1) Copy the image file to a permanent location (ie. /memtest).
+ 2) Add an entry in the lilo config file (usually /etc/lilo.conf) to boot
+ memtest86. Only the image and label fields need to be specified.
+ The following is a sample lilo entry for booting memtest86:
+
+ image = /memtest
+ label = memtest
+
+ 3) As root, type "lilo"
+
+ At the lilo prompt enter memtest to boot memtest86.
+
+If you encounter build problems a binary image has been included (precomp.bin).
+To create a boot-disk with this pre-built image do the following:
+ 1) Insert a blank write enabled floppy disk.
+ 2) Type "make install-precomp"
+
+
+4) Serial Console
+=================
+Memtest86 can be used on PC's equipped with a serial port for the console.
+By default serial port console support is not enabled since it slows
+down testing. To enable change the SERIAL_CONSOLE_DEFAULT define in
+config.h from a zero to a one. The serial console baud rate may also
+be set in config.h with the SERIAL_BAUD_RATE define. The other serial
+port settings are no parity, 8 data bits, 1 stop bit. All of the features
+used by memtest86 are accessible via the serial console. However, the
+screen sometimes is garbled when the online commands are used.
+
+
+5) Online Commands
+==================
+Memtest86 has a limited number of online commands. Online commands
+provide control over caching, test selection, address range and error
+scrolling. A help bar is displayed at the bottom of the screen listing
+the available on-line commands.
+
+ Command Description
+
+ ESC Exits the test and does a warm restart via the BIOS.
+
+ c Enters test configuration menu
+ Menu options are:
+ 1) Cache mode
+ 2) Test selection
+ 3) Address Range
+ 4) Memory Sizing
+ 5) Error Summary
+ 6) Error Report Mode
+ 7) ECC Mode
+ 8) Restart
+ 9) Adv. Options
+
+ SP Set scroll lock (Stops scrolling of error messages)
+ Note: Testing is stalled when the scroll lock is
+ set and the scroll region is full.
+
+ CR Clear scroll lock (Enables error message scrolling)
+
+
+6) Memory Sizing
+================
+The BIOS in modern PC's will often reserve several sections of memory for
+it's use and also to communicate information to the operating system (ie.
+ACPI tables). It is just as important to test these reserved memory blocks
+as it is for the remainder of memory. For proper operation all of memory
+needs to function properly regardless of what the eventual use is. For
+this reason Memtest86 has been designed to test as much memory as is
+possible.
+
+However, safely and reliably detecting all of the available memory has been
+problematic. Versions of Memtest86 prior to v2.9 would probe to find where
+memory is. This works for the vast majority of motherboards but is not 100%
+reliable. Sometimes the memory size is incorrect and worse probing the wrong
+places can in some cases cause the test to hang or crash.
+
+Starting in version 2.9 alternative methods are available for determining the
+memory size. By default the test attempts to get the memory size from the
+BIOS using the "e820" method. With "e820" the BIOS provides a table of memory
+segments and identifies what they will be used for. By default Memtest86
+will test all of the ram marked as available and also the area reserved for
+the ACPI tables. This is safe since the test does not use the ACPI tables
+and the "e820" specifications state that this memory may be reused after the
+tables have been copied. Although this is a safe default some memory will
+not be tested.
+
+Two additional options are available through online configuration options.
+The first option (BIOS-All) also uses the "e820" method to obtain a memory
+map. However, when this option is selected all of the reserved memory
+segments are tested, regardless of what their intended use is. The only
+exception is memory segments that begin above 3gb. Testing has shown that
+these segments are typically not safe to test. The BIOS-All option is more
+thorough but could be unstable with some motherboards.
+
+The second option for memory sizing is the traditional "Probe" method.
+This is a very thorough but not entirely safe method. In the majority of
+cases the BIOS-All and Probe methods will return the same memory map.
+
+For older BIOS's that do not support the "e820" method there are two
+additional methods (e801 and e88) for getting the memory size from the
+BIOS. These methods only provide the amount of extended memory that is
+available, not a memory table. When the e801 and e88 methods are used
+the BIOS-All option will not be available.
+
+The MemMap field on the display shows what memory size method is in use.
+Also the RsvdMem field shows how much memory is reserved and is not being
+tested.
+
+
+7) Error Information
+======================
+Memtest has two options for reporting errors. The default is to report
+individual errors. In BadRAM Patterns mode patterns are created for
+use with the Linux BadRAM feature. This slick feature allows Linux to
+avoid bad memory pages. Details about the BadRAM feature can be found at:
+
+ http://home.zonnet.nl/vanrein/badram
+
+For individual errors the following information is displayed when a memory
+error is detected. An error message is only displayed for errors with a
+different address or failing bit pattern. All displayed values are in
+hexadecimal.
+
+ Tst: Test number
+ Failing Address : Failing memory address
+ Good: Expected data pattern
+ Bad: Failing data pattern
+ Err-Bits: Exclusive or of good and bad data (this shows the
+ position of the failing bit(s))
+ Count: Number of consecutive errors with the same address
+ and failing bits
+
+In BadRAM Patterns mode, Lines are printed in a form badram=F1,M1,F2,M2.
+In each F/M pair, the F represents a fault address, and the corresponding M
+is a bitmask for that address. These patterns state that faults have
+occurred in addresses that equal F on all "1" bits in M. Such a pattern may
+capture more errors that actually exist, but at least all the errors are
+captured. These patterns have been designed to capture regular patterns of
+errors caused by the hardware structure in a terse syntax.
+
+The BadRAM patterns are `grown' increment-ally rather than `designed' from an
+overview of all errors. The number of pairs is constrained to five for a
+number of practical reasons. As a result, handcrafting patterns from the
+output in address printing mode may, in exceptional cases, yield better
+results.
+
+
+8) Trouble-shooting Memory Errors
+================================
+Please be aware that not all errors reported by Memtest86 are due to
+bad memory. The test implicitly tests the CPU, L1 and L2 caches as well as
+the motherboard. It is impossible for the test to determine what causes
+the failure to occur. Most failures will be due to a problem with memory.
+When it is not, the only option is to replace parts until the failure is
+corrected.
+
+Once a memory error has been detected, determining the failing
+module is not a clear cut procedure. With the large number of motherboard
+vendors and possible combinations of simm slots it would be difficult if
+not impossible to assemble complete information about how a particular
+error would map to a failing memory module. However, there are steps
+that may be taken to determine the failing module. Here are three
+techniques that you may wish to use:
+
+1) Removing modules
+This is simplest method for isolating a failing modules, but may only be
+employed when one or more modules can be removed from the system. By
+selectively removing modules from the system and then running the test
+you will be able to find the bad module(s). Be sure to note exactly which
+modules are in the system when the test passes and when the test fails.
+
+2) Rotating modules
+When none of the modules can be removed then you may wish to rotate modules
+to find the failing one. This technique can only be used if there are
+three or more modules in the system. Change the location of two modules
+at a time. For example put the module from slot 1 into slot 2 and put
+the module from slot 2 in slot 1. Run the test and if either the failing
+bit or address changes then you know that the failing module is one of the
+ones just moved. By using several combinations of module movement you
+should be able to determine which module is failing.
+
+3) Replacing modules
+If you are unable to use either of the previous techniques then you are
+left to selective replacement of modules to find the failure.
+
+4) Avoiding allocation
+The printing mode for BadRAM patterns is intended to construct boot time
+parameters for a Linux kernel that is compiled with BadRAM support. This
+work-around makes it possible for Linux to reliably run on defective
+RAM. For more information on BadRAM support
+for Linux, sail to
+
+ http://home.zonnet.nl/vanrein/badram
+
+Sometimes memory errors show up due to component incompatibility. A memory
+module may work fine in one system and not in another. This is not
+uncommon and is a source of confusion. The components are not necessarily
+bad but certain combinations may need to be avoided.
+
+I am often asked about the reliability of errors reported by Mestest86.
+In the vast majority of cases errors reported by the test are valid.
+There are some systems that cause Memtest86 to be confused about the size of
+memory and it will try to test non-existent memory. This will cause a large
+number of consecutive addresses to be reported as bad and generally there
+will be many bits in error. If you have a relatively small number of
+failing addresses and only one or two bits in error you can be certain
+that the errors are valid. Also intermittent errors are always valid.
+
+All valid memory errors should be corrected. It is possible that a
+particular error will never show up in normal operation. However, operating
+with marginal memory is risky and can result in data loss and even
+disk corruption. You can be sure that Murphy will get you if you know
+about a memory error and ignore it.
+
+Memtest86 can not diagnose many types of PC failures. For example a
+faulty CPU that causes Windows to crash will most likely just cause
+Memtest86 to crash in the same way.
+
+
+9) Execution Time
+==================
+The time required for a complete pass of Memtest86 will vary greatly
+depending on CPU speed, memory speed and memory size. Memtest86 executes
+indefinitely. The pass counter increments each time that all of the
+selected tests have been run. Generally a single pass is sufficient to
+catch all but the most obscure errors. However, for complete confidence
+when intermittent errors are suspected testing for a longer period is advised.
+
+10) Memory Testing Philosophy
+=============================
+There are many good approaches for testing memory. However, many tests
+simply throw some patterns at memory without much thought or knowledge
+of memory architecture or how errors can best be detected. This
+works fine for hard memory failures but does little to find intermittent
+errors. BIOS based memory tests are useless for finding intermittent
+memory errors.
+
+Memory chips consist of a large array of tightly packed memory cells,
+one for each bit of data. The vast majority of the intermittent failures
+are a result of interaction between these memory cells. Often writing a
+memory cell can cause one of the adjacent cells to be written with the
+same data. An effective memory test attempts to test for this
+condition. Therefore, an ideal strategy for testing memory would be
+the following:
+
+ 1) write a cell with a zero
+ 2) write all of the adjacent cells with a one, one or more times
+ 3) check that the first cell still has a zero
+
+It should be obvious that this strategy requires an exact knowledge
+of how the memory cells are laid out on the chip. In addition there is a
+never ending number of possible chip layouts for different chip types
+and manufacturers making this strategy impractical. However, there
+are testing algorithms that can approximate this ideal strategy.
+
+
+11) Memtest86 Test Algorithms
+=============================
+Memtest86 uses two algorithms that provide a reasonable approximation
+of the ideal test strategy above. The first of these strategies is called
+moving inversions. The moving inversion test works as follows:
+
+ 1) Fill memory with a pattern
+ 2) Starting at the lowest address
+ 2a check that the pattern has not changed
+ 2b write the patterns complement
+ 2c increment the address
+ repeat 2a - 2c
+ 3) Starting at the highest address
+ 3a check that the pattern has not changed
+ 3b write the patterns complement
+ 3c decrement the address
+ repeat 3a - 3c
+
+This algorithm is a good approximation of an ideal memory test but
+there are some limitations. Most high density chips today store data
+4 to 16 bits wide. With chips that are more than one bit wide it
+is impossible to selectively read or write just one bit. This means
+that we cannot guarantee that all adjacent cells have been tested
+for interaction. In this case the best we can do is to use some
+patterns to insure that all adjacent cells have at least been written
+with all possible one and zero combinations.
+
+It can also be seen that caching, buffering and out of order execution
+will interfere with the moving inversions algorithm and make less effective.
+It is possible to turn off cache but the memory buffering in new high
+performance chips can not be disabled. To address this limitation a new
+algorithm I call Modulo-X was created. This algorithm is not affected by
+cache or buffering. The algorithm works as follows:
+ 1) For starting offsets of 0 - 20 do
+ 1a write every 20th location with a pattern
+ 1b write all other locations with the patterns complement
+ repeat 1b one or more times
+ 1c check every 20th location for the pattern
+
+This algorithm accomplishes nearly the same level of adjacency testing
+as moving inversions but is not affected by caching or buffering. Since
+separate write passes (1a, 1b) and the read pass (1c) are done for all of
+memory we can be assured that all of the buffers and cache have been
+flushed between passes. The selection of 20 as the stride size was somewhat
+arbitrary. Larger strides may be more effective but would take longer to
+execute. The choice of 20 seemed to be a reasonable compromise between
+speed and thoroughness.
+
+
+12) Individual Test Descriptions
+================================
+Memtest86 executes a series of numbered test sections to check for
+errors. These test sections consist of a combination of test
+algorithm, data pattern and caching. The execution order for these tests
+were arranged so that errors will be detected as rapidly as possible.
+A description of each of the test sections follows:
+
+Test 0 [Address test, walking ones, no cache]
+ Tests all address bits in all memory banks by using a walking ones
+ address pattern. Errors from this test are not used to calculate
+ BadRAM patterns.
+
+Test 1 [Address test, own address]
+ Each address is written with its own address and then is checked
+ for consistency. In theory previous tests should have caught any
+ memory addressing problems. This test should catch any addressing
+ errors that somehow were not previously detected.
+
+Test 2 [Moving inversions, ones&zeros]
+ This test uses the moving inversions algorithm with patterns of all
+ ones and zeros. Cache is enabled even though it interferes to some
+ degree with the test algorithm. With cache enabled this test does not
+ take long and should quickly find all "hard" errors and some more
+ subtle errors. This section is only a quick check.
+
+Test 3 [Moving inversions, 8 bit pat]
+ This is the same as test 1 but uses a 8 bit wide pattern of
+ "walking" ones and zeros. This test will better detect subtle errors
+ in "wide" memory chips. A total of 20 data patterns are used.
+
+Test 4 [Moving inversions, random pattern]
+ Test 4 uses the same algorithm as test 1 but the data pattern is a
+ random number and it's complement. This test is particularly effective
+ in finding difficult to detect data sensitive errors. A total of 60
+ patterns are used. The random number sequence is different with each pass
+ so multiple passes increase effectiveness.
+
+Test 5 [Block move, 64 moves]
+ This test stresses memory by using block move (movsl) instructions
+ and is based on Robert Redelmeier's burnBX test. Memory is initialized
+ with shifting patterns that are inverted every 8 bytes. Then 4MB blocks
+ of memory are moved around using the movsl instruction. After the moves
+ are completed the data patterns are checked. Because the data is checked
+ only after the memory moves are completed it is not possible to know
+ where the error occurred. The addresses reported are only for where the
+ bad pattern was found. Since the moves are constrained to a 8MB segment
+ of memory the failing address will always be lest than 8MB away from the
+ reported address. Errors from this test are not used to calculate
+ BadRAM patterns.
+
+Test 6 [Moving inversions, 32 bit pat]
+ This is a variation of the moving inversions algorithm that shifts the data
+ pattern left one bit for each successive address. The starting bit position
+ is shifted left for each pass. To use all possible data patterns 32 passes
+ are required. This test is quite effective at detecting data sensitive
+ errors but the execution time is long.
+
+Test 7 [Random number sequence]
+ This test writes a series of random numbers into memory. By resetting the
+ seed for the random number the same sequence of number can be created for
+ a reference. The initial pattern is checked and then complemented and
+ checked again on the next pass. However, unlike the moving inversions test
+ writing and checking can only be done in the forward direction.
+
+Test 8 [Modulo 20, ones&zeros]
+ Using the Modulo-X algorithm should uncover errors that are not
+ detected by moving inversions due to cache and buffering interference
+ with the the algorithm. All ones and zeros are used for data patterns.
+
+Test 9 [Bit fade test, 90 min, 2 patterns]
+ The bit fade test initializes all of memory with a pattern and then
+ sleeps for 90 minutes. Then memory is examined to see if any memory bits
+ have changed. All ones and all zero patterns are used. This test takes
+ 3 hours to complete. The Bit Fade test is not included in the normal test
+ sequence and must be run manually via the runtime configuration menu.
+
+
+13) Problem Reporting - Contact Information
+===========================================
+Due to the growing popularity of Memtest86 (more than 200,000 downloads per
+month) I have been inundated by, questions, feedback, problem reports and
+requests for enhancements. I simply do not have time to repond to ANY Memtest86
+emails. Bug reports and suggestions are welcome but will typically not be
+responded to.
+
+*** NOTE: *** The Keyword MEM86 must appear in the subject of all emails or
+the message will be automaticly deleted before it gets to me. This thanks to
+spam and viruses!
+
+Problems/Bugs:
+Before submitting a problem report please check the Known Problems section
+to see if this problem has already been reported. Be sure to include the
+version number and also any details that may be relevant.
+
+Chris Brady, Email: bugs@memtest86.com
+
+With some PC's Memtest86 will just die with no hints as to what went wrong.
+Without any details it is impossible to fix these failures. Fixing these
+problems will require debugging on your part. There is no point in reporting
+these failures unless you have a Linux system and would be willing to debug
+the failure.
+
+Enhancements:
+If you would like to request an enhancement please see if is already on
+the Planned Features List before sending your request. All requests will
+be considered, but not all can be implemented. If you are be interested in
+contributing code please contact me so that the integration can be
+co-ordinated.
+
+Chris Brady, Email: enhance@memtest86.com
+
+Questions:
+Unfortunately, I do not have time to respond to any questions or provide
+assistance with troubleshooting problems. Please read the Troubleshooting
+and Known Problems sections for assistance with problems. These sections have
+the answers for the questions that I have answers to. If there is not an
+answer for your problem in these sections it is probably not something I can
+help you with.
+
+
+
+14) Known Problems
+==================
+Sometimes when booting from a floppy disk the following messages scroll up
+on the screen:
+ X:8000
+ AX:0212
+ BX:8600
+ CX:0201
+ DX:0000
+This the BIOS reporting floppy disk read errors. Either re-write or toss
+the floppy disk.
+
+Memtest86 has no support for multiple CPUs. Memtest86 should run
+without problems, but it will only use one CPU.
+
+Memtest86 can not diagnose many types of PC failures. For example a
+faulty CPU that causes Windows to crash will most likely just cause
+Memtest86 to crash in the same way.
+
+There have been numerous reports of errors in only tests 5 and 8 on Athlon
+systems. Often the memory works in a different system or the vendor insists
+that it is good. In these cases the memory is not necessarily bad but is
+not able to operate reliably at Athlon speeds. Sometimes more conservative
+memory timings on the motherboard will correct these errors. In other
+cases the only option is to replace the memory with better quality, higher
+speed memory. Don't buy cheap memory and expect it to work with an Athlon!
+
+Memtest86 supports all types of memory. If fact the test has absolutely
+no knowledge of the memory type nor does it need to. This not a problem
+or bug but is listed here due to the many questions I get about this issue.
+
+Changes in the compiler and loader have caused problems with
+Memtest86 resulting in both build failures and errors in execution. A
+binary image (precomp.bin) of the test is included and may be used if
+problems are encountered.
+
+15) Planned Features List
+=========================
+This is a list of enhancements planned for future releases of Memtest86.
+There is no timetable for when these will be implemented, if ever.
+
+ - Option to allow printing of error information on an attached printer.
+ - Option to write error information to a floppy disk.
+ - Supply Memtest in RPM format.
+ - Read and display RAM SPD information.
+
+
+16) Change Log
+==============
+Enhancements in v3.2 (11/Nov/2004)
+
+ Added two new, highly effective tests that use random number patterns
+ (tests 4 and 6).
+
+ Reworked the online commands:
+ - Changed wording for better clarity
+ - Dropped Cache Mode menu
+
+ Updated CPU detection for newer AMD, Intel and Cyrix CPUs.
+
+ Reworked test sequence:
+ - Dropped ineffective non cached tests (Numbers 7-11)
+ - Changed cache mode to cached for test 2
+ - Fixed bug that did not allow tsome tests to be skipped
+ - Added bailout for Bit fade test
+
+ Error reports are highlighted in red to provide a more vivid error
+ indication.
+
+ Added support for a large number of additional chipsets. (from Memtest86+
+ v1.30)
+
+ Added an advanced setup feature that with new chiset allows memory timings
+ to be altered from inside Memtest86. (from Memtest86+ v1.30)
+
+
+Enhancements in v3.1 (11/Mar/2004)
+
+ Added processor detection for newer AMD processors.
+
+ Added new "Bit Fade" extended test.
+
+ Fixed a complile time bug with gcc version 3.x.
+
+ E7500 memory controller ECC support
+
+ Added support for 16bit ECC syndromes
+
+ Option to keep the serial port baud rate of the boot loader
+
+
+Enhancements in v3.0 (22/May/2002) Provided by Eric Biederman
+
+ Testing of more than 2gb of memory is at last fixed (tested with 6Gb)
+
+ The infrastructure is to poll ecc error reporting chipset regisets,
+ and the support has been done for some chipsets.
+
+ Uses dynamic relocation information records to make itself PIC
+ instead of requiring 2 copies of memtest86 in the binary.
+
+ The serial console code does not do redundant writes to the serial port
+ Very little slow down at 9600 baud.
+
+ You can press ^l or just l to get a screen refresh, when you are
+ connecting and unconnecting a serial cable.
+
+ Netbooting is working again
+
+ LinuxBIOS support (To get the memory size)
+
+ Many bugfixes and code cleanup.
+
+Enhancements in v2.9 (29/Feb/2002)
+
+ The memory sizing code has been completely rewritten. By default
+ Memtest86 gets a memory map from the BIOS that is now used to find
+ available memory. A new online configuration option provides three
+ choices for how memory will be sized, including the old "probe" method.
+ The default mode generally will not test all of memory, but should be more
+ stable. See the "Memory Sizing" section for details.
+
+ Testing of more than 2gb of memory should now work. A number of bugs
+ were found and corrected that prevented testing above 2gb. Testing
+ with more than 2gb has been limited and there could be problems with a
+ full 4gb of memory.
+
+ Memory is divided into segments for testing. This allow for frequent
+ progress updates and responsiveness to interactive commands. The
+ memory segment size has been increased from 8 to 32mb. This should
+ improve testing effectivness but progress reports will be less frequent.
+
+ Minor bug fixes.
+
+Enhancements in v2.8 (18/Oct/2001)
+ Eric Biederman reworked the build process making it far simpler and also
+ to produce a network bootable ELF image.
+
+ Re-wrote the memory and cache speed detection code. Previously the
+ reported numbers were inaccurate for intel CPU's and completely wrong
+ for Athlon/Duron CPU's.
+
+ By default the serial console is disabled since this was slowing
+ down testing.
+
+ Added CPU detection for Pentium 4.
+
+
+Enhancements in v2.7 (12/Jul/2001)
+ Expanded workaround for errors caused by BIOS USB keyboard support to
+ include test #5.
+
+ Re-worked L1 / L2 cache detection code to provide clearer reporting.
+
+ Fixed an obvious bug in the computation of cache and memory speeds.
+
+ Changed on-line menu to stay in the menu between option selections.
+
+ Fixed bugs in the test restart and redraw code.
+
+ Adjusted code size to fix compilation problems with RedHat 7.1.
+
+ Misc updates to the documentation.
+
+Enhancements in v2.6 (25/May/2001)
+ Added workaround for errors caused by BIOS USB keyboard support.
+
+ Fixed problems with reporting of 1 GHZ + processor speeds.
+
+ Fixed Duron cache detection.
+
+ Added screen buffer so that menus will work correctly from a serial
+ console.
+
+ The Memtest86 image is now built in ELF format.
+
+Enhancements in v2.5 (14/Dec/00)
+ Enhanced CPU and cache detection to correctly identify Duron CPU
+ and K6-III 1MB cache.
+
+ Added code to report cache-able memory size.
+
+ Added limited support for parity memory.
+
+ Support was added to allow use of on-line commands from a serial
+ port.
+
+ Dropped option for changing refresh rates. This was not useful
+ and did not work on newer motherboards.
+
+ Improved fatal exception reporting to include a register and stack
+ dump.
+
+ The pass number is now displayed in the error report.
+
+ Fixed a bug that crashed the test when selecting one of the extended
+ tests.
+
+Enhancements in v2.4
+ The error report format was reworked for better clarity and now
+ includes a decimal address in megabytes.
+
+ A new memory move test was added (from Robert Redelmeier's CPU-Burn)
+
+ The test sequence and iterations were modified.
+
+ Fixed scrolling problems with the BadRAM patterns.
+
+
+Enhancements in v2.3
+ A progress meter was added to replace the spinner and dots.
+
+ Measurement and reporting of memory and cache performance
+ was added.
+
+ Support for creating BadRAM patterns was added.
+
+ All of the test routines were rewritten in assembler to
+ improve both test performance and speed.
+
+ The screen layout was reworked to hopefully be more readable.
+
+ An error summary option was added to the online commands.
+
+
+Enhancements in v2.2
+ Added two new address tests
+
+ Added an on-line command for setting test address range
+
+ Optimized test code for faster execution (-O3, -funroll-loops and
+ -fomit-frame-pointer)
+
+ Added and elapsed time counter.
+
+ Adjusted menu options for better consistency
+
+
+Enhancements in v2.1
+ Fixed a bug in the CPU detection that caused the test to
+ hang or crash with some 486 and Cryrix CPU's
+
+ Added CPU detection for Cyrix CPU's
+
+ Extended and improved CPU detection for Intel and AMD CPU's
+
+ Added a compile time option (BIOS_MEMSZ) for obtaining the last
+ memory address from the BIOS. This should fix problems with memory
+ sizing on certain motherboards. This option is not enabled by default.
+ It may be enabled be default in a future release.
+
+Enhancements in v2.0
+ Added new Modulo-20 test algorithm.
+
+ Added a 32 bit shifting pattern to the moving inversions algorithm.
+
+ Created test sections to specify algorithm, pattern and caching.
+
+ Improved test progress indicators.
+
+ Created popup menus for configuration.
+
+ Added menu for test selection.
+
+ Added CPU and cache identification.
+
+ Added a "bail out" feature to quit the current test when it does not
+ fit the test selection parameters.
+
+ Re-arranged the screen layout and colors.
+
+ Created local include files for I/O and serial interface definitions
+ rather than using the sometimes incompatible system include files.
+
+ Broke up the "C" source code into four separate source modules.
+
+Enhancements in v1.5
+ Some additional changes were made to fix obscure memory sizing
+ problems.
+
+ The 4 bit wide data pattern was increased to 8 bits since 8 bit
+ wide memory chips are becoming more common.
+
+ A new test algorithm was added to improve detection of data
+ pattern sensitive errors.
+
+
+Enhancements in v1.4
+ Changes to the memory sizing code to avoid problems with some
+ motherboards where memtest would find more memory than actually
+ exists.
+
+ Added support for a console serial port. (thanks to Doug Sisk)
+
+ On-line commands are now available for configuring Memtest86 on
+ the fly (see On-line Commands).
+
+
+Enhancements in v1.3
+ Scrolling of memory errors is now provided. Previously, only one screen
+ of error information was displayed.
+
+ Memtest86 can now be booted from any disk via lilo.
+
+ Testing of up to 4gb of memory has been fixed is now enabled by default.
+ This capability was clearly broken in v1.2a and should work correctly
+ now but has not been fully tested (4gb PC's are a bit rare).
+
+ The maximum memory size supported by the motherboard is now being
+ calculated correctly. In previous versions there were cases where not
+ all of memory would be tested and the maximum memory size supported
+ was incorrect.
+
+ For some types of failures the good and bad values were reported to be
+ same with an Xor value of 0. This has been fixed by retaining the data
+ read from memory and not re-reading the bad data in the error reporting
+ routine.
+
+ APM (advanced power management) is now disabled by Memtest86. This
+ keeps the screen from blanking while the test is running.
+
+ Problems with enabling & disabling cache on some motherboards have been
+ corrected.
+
+
+17) Donations
+=============
+With considerable reluctance I am resorting to a low key solicitation for
+donations. It never has been my intent to profit from this program and I am
+pleased that Memtest86 has been helpful. However, the time required to
+support this program has grown significantly. I also have the modest
+cost of hosting this web-site that I would like to recover. So if you find
+Memtest86 useful and you feel inclined to make a small PayPal donation please
+do so. Use "cbrady@memtest86.com" for the recipient.
+
+
+18) Acknowledgments
+===================
+Memtest86 was developed by Chris Brady with the resources and assistance
+listed below:
+
+- The initial versions of the source files bootsect.S, setup.S, head.S and
+ build.c are from the Linux 1.2.1 kernel and have been heavily modified.
+
+- Doug Sisk provided code to support a console connected via a serial port.
+
+- Code to create BadRAM patterns was provided by Rick van Rein.
+
+- Tests 5 and 8 are based on Robert Redelmeier's burnBX test.
+
+- Screen buffer code was provided by Jani Averbach.
+
+- Eric Biederman provided all of the feature content for version 3.0
+ plus many bugfixes and significant code cleanup.
+
+- Major enhancements to hardware detection and reporting in version 3.2
+ provided by Samuel Demeulemeester (from Memtest86+ v1.11).
diff --git a/README.build-process b/README.build-process
index 19edfcf..37ca48a 100644
--- a/README.build-process
+++ b/README.build-process
@@ -1,39 +1,39 @@
-During memory testing memtest86 relocates itself in memory so it can test the
-memory it was previously running from. memtest86 is compiled as position mostly
-independent code. Some relocations records must be processed to achieve the
-affect of position independent code. A 16 bit loader is prepended to memtest86
-so it can be loaded from a floppy, or from lilo.
-
-In restructuring the build process I had several goals. Maintainability and
-comprehsibility of the build process. Simplicity of the toolset. And the
-ability to build images bootable by both the legacy x86 bootloader,
-and images bootable by bootloaders that directly load static ELF images.
-
-With the ability to proecess relocation records, memtest.bin has been
-reduced in size from 84480 bytes to 49308 bytes. And now only requires one copy
-of memtest86. A reduction in size of 35K. And the build process can now ignore
-the size of memtest86.
-
-BIOS calls have been moved from setup.S to head.S making bootsect.S and
-setup.S exclusively for booting.
-
-memtest86 is built in three stages. In the first stage the relocatable object
-files are built as with any program. In the second stage the relocatable object
-files are linked together into memtest_shared, a shared library version
-of memtest86. In the third stage a raw memory image of memtest_shared is formed
-and linked into memtest.bin, and memtest.
-
-memtest.bin is the floppy/lilo bootable target.
-
-memtest is the ELF bootable target.
-
-Another major change is now data in the bss segment is also preserved
-when memtest86 is relocated, and memtest86 can be relocated to any address.
-
-The one thing to watch out for is pointers to data inside of memtest86. Except
-for constant pointers to static data there is not enough information to generate
-relocation records for pointers so they will not change when memtest86 is
-relocated, which might lead to nasty surpises.
-
-Eric Biederman <ebiederman@lnxi.com>
-
+During memory testing memtest86 relocates itself in memory so it can test the
+memory it was previously running from. memtest86 is compiled as position mostly
+independent code. Some relocations records must be processed to achieve the
+affect of position independent code. A 16 bit loader is prepended to memtest86
+so it can be loaded from a floppy, or from lilo.
+
+In restructuring the build process I had several goals. Maintainability and
+comprehsibility of the build process. Simplicity of the toolset. And the
+ability to build images bootable by both the legacy x86 bootloader,
+and images bootable by bootloaders that directly load static ELF images.
+
+With the ability to proecess relocation records, memtest.bin has been
+reduced in size from 84480 bytes to 49308 bytes. And now only requires one copy
+of memtest86. A reduction in size of 35K. And the build process can now ignore
+the size of memtest86.
+
+BIOS calls have been moved from setup.S to head.S making bootsect.S and
+setup.S exclusively for booting.
+
+memtest86 is built in three stages. In the first stage the relocatable object
+files are built as with any program. In the second stage the relocatable object
+files are linked together into memtest_shared, a shared library version
+of memtest86. In the third stage a raw memory image of memtest_shared is formed
+and linked into memtest.bin, and memtest.
+
+memtest.bin is the floppy/lilo bootable target.
+
+memtest is the ELF bootable target.
+
+Another major change is now data in the bss segment is also preserved
+when memtest86 is relocated, and memtest86 can be relocated to any address.
+
+The one thing to watch out for is pointers to data inside of memtest86. Except
+for constant pointers to static data there is not enough information to generate
+relocation records for pointers so they will not change when memtest86 is
+relocated, which might lead to nasty surpises.
+
+Eric Biederman <ebiederman@lnxi.com>
+
diff --git a/bootsect.S b/bootsect.S
index ee3bd90..982775d 100644
--- a/bootsect.S
+++ b/bootsect.S
@@ -1,375 +1,375 @@
-/*
- * bootsect.s Copyright (C) 1991, 1992 Linus Torvalds
- *
- * bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
- * 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.
- *
- * The loader has been made as simple as possible, and continuos
- * read errors will result in a unbreakable loop. Reboot by hand. It
- * loads pretty fast by getting whole tracks at a time whenever possible.
- *
- * 1-Jan-96 Modified by Chris Brady for use as a boot loader for MemTest-86.
- */
-
-#include "defs.h"
-
-ROOT_DEV = 0
-
-.code16
-.section ".bootsect", "ax", @progbits
-_boot:
-
-
-# ld86 requires an entry symbol. This may as well be the usual one.
-.globl _main
-_main:
- movw $BOOTSEG, %ax
- movw %ax, %ds
- movw $INITSEG, %ax
- movw %ax, %es
- movw $256, %cx
- subw %si, %si
- subw %di, %di
- cld
- rep
- movsw
- ljmp $INITSEG, $go - _boot
-
-go:
- movw %cs, %ax
- movw $(0x4000-12), %dx # 0x4000 is arbitrary value >= length of
- # bootsect + length of setup + room for stack
- # 12 is disk parm size
-
-# bde - changed 0xff00 to 0x4000 to use debugger at 0x6400 up (bde). We
-# wouldn't have to worry about this if we checked the top of memory. Also
-# my BIOS can be configured to put the wini drive tables in high memory
-# instead of in the vector table. The old stack might have clobbered the
-# drive table.
-
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %ss # put stack at INITSEG:0x4000-12.
- movw %dx, %sp
-
-/*
- * 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.
- *
- * 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.
- *
- * High doesn't hurt. Low does.
- *
- * Segments are as follows: ds=es=ss=cs - INITSEG,
- * fs = 0, gs = parameter table segment
- */
- pushw $0
- popw %fs
- movw $0x78, %bx # fs:bx is parameter table address
- lgs %fs:(%bx),%si # gs:si is source
-
- movw %dx, %di # es:di is destination
- movw $6, %cx # copy 12 bytes
- cld
-
- rep movsw %gs:(%si), (%di)
-
- movw %dx, %di
- movb $18, 4(%di) # patch sector count
-
- movw %di, %fs:(%bx)
- movw %es, %fs:2(%bx)
-
- movw %cs, %ax
- movw %ax, %fs
- movw %ax, %gs
-
- 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.
-
-load_setup:
- xorw %dx, %dx # drive 0, head 0
- movw $0x0002, %cx # sector 2, track 0
- movw $0x0200, %bx # address = 512, in INITSEG
- movw $(0x0200 + SETUPSECS), %ax # service 2, nr of sectors
- # (assume all on head 0, track 0)
- int $0x13 # read it
- jnc ok_load_setup # ok - continue
-
- pushw %ax # dump error code
- call print_nl
- movw %sp, %bp
- call print_hex
- popw %ax
-
- xorb %dl, %dl # reset FDC
- xorb %ah, %ah
- int $0x13
- jmp load_setup
-
-ok_load_setup:
-
-# Get disk drive parameters, specifically nr of sectors/track
-
-
-/* It seems that there is no BIOS call to get the number of sectors. Guess
- * 18 sectors if sector 18 can be read, 15 if sector 15 can be read.
- * Otherwise guess 9
- */
-
- xorw %dx, %dx # drive 0, head 0
- movw $0x0012, %cx # sector 18, track 0
- movw $(0x200+(SETUPSECS*0x200)), %bx # address after setup (es = cs)
- movw $0x0201, %ax # service 2, 1 sector
- int $0x13
- jnc got_sectors
- movb $0x0f, %cl # sector 15
- movw $0x0201, %ax # service 2, 1 sector
- int $0x13
- jnc got_sectors
- movb $0x09, %cl
-
-got_sectors:
- movw %cx, %cs:sectors - _boot
- movw $INITSEG, %ax
- movw %ax, %es
-
-# Print some inane message
-
- 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)
-
- movw $TSTLOAD, %ax
- movw %ax, %es # segment of 0x010000
- call read_it
- call kill_motor
- call print_nl
-
-# after that (everyting loaded), we jump to
-# the setup-routine loaded directly after
-# the bootblock:
-
- ljmp $SETUPSEG,$0
-
-# This routine loads the system at address 0x10000, making sure
-# no 64kB boundaries are crossed. We try to load it as fast as
-# possible, loading whole tracks whenever we can.
-#
-# in: es - starting address segment (normally 0x1000)
-#
-sread: .word 1+SETUPSECS # sectors read of current track
-head: .word 0 # current head
-track: .word 0 # current track
-
-read_it:
- movw %es, %ax
- testw $0x0fff, %ax
-die:
- jne die # es must be at 64kB boundary
- xorw %bx,%bx # bx is starting address within segment
-rp_read:
- movw %es, %ax
- subw $TSTLOAD, %ax # have we loaded all yet?
- cmpw syssize - _boot, %ax
- jbe ok1_read
- ret
-ok1_read:
- movw %cs:sectors - _boot, %ax
- subw sread - _boot, %ax
- movw %ax, %cx
- shlw $9, %cx
- addw %bx, %cx
- jnc ok2_read
- je ok2_read
- xorw %ax, %ax
- subw %bx, %ax
- shrw $9, %ax
-ok2_read:
- call read_track
- movw %ax, %cx
- add sread - _boot, %ax
- cmpw %cs:sectors - _boot, %ax
- jne ok3_read
- movw $1, %ax
- subw head - _boot, %ax
- jne ok4_read
- incw track - _boot
-ok4_read:
- movw %ax, head - _boot
- xorw %ax, %ax
-ok3_read:
- movw %ax, sread - _boot
- shlw $9, %cx
- addw %cx, %bx
- jnc rp_read
- movw %es, %ax
- addb $0x10, %ah
- movw %ax, %es
- xorw %bx, %bx
- jmp rp_read
-
-read_track:
- pusha
- pusha
- movw $0xe2e, %ax # loading... message 2e = .
- movw $7, %bx
- int $0x10
- popa
-
- movw track - _boot, %dx
- movw sread - _boot, %cx
- incw %cx
- movb %dl, %ch
- movw head - _boot, %dx
- movb %dl, %dh
- andw $0x0100, %dx
- movb $2, %ah
-
- pushw %dx # save for error dump
- pushw %cx
- pushw %bx
- pushw %ax
-
- int $0x13
- jc bad_rt
- addw $8, %sp
- popa
- ret
-
-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
- jmp read_track
-
-/*
- * 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
- * cx
- * bx
- * ax
- * error
- * ret <- sp
- *
-*/
-
-print_all:
- movw $5, %cx # error code + 4 registers
- movw %sp, %bp
-
-print_loop:
- pushw %cx # save count left
- call print_nl # nl for readability
-
- cmpb 5, %cl # see if register name is needed
- jae no_reg
-
- movw $(0xe05 + 'A' - 1), %ax
- subb %cl, %al
- int $0x10
- movb $'X', %al
- int $0x10
- movb $':', %al
- int $0x10
-
-no_reg:
- addw $2, %bp # next register
- call print_hex # print it
- 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
- movw (%bp), %dx # load word into dx
-
-print_digit:
- rolw $4, %dx # rotate so that lowest 4 bits are used
- movb $0xe, %ah
- movb %dl, %al # mask off so we have only next nibble
- andb $0xf, %al
- addb $'0', %al # convert to 0-based digit
- cmpb $'9', %al # check for overflow
- jbe good_digit
- addb $('A' - '0' - 10), %al
-
-good_digit:
- int $0x10
- loop print_digit
- ret
-
-
-/*
- * This procedure turns off the floppy drive motor, so
- * that we enter the kernel in a known state, and
- * don't have to worry about it later.
- */
-kill_motor:
- pushw %dx
- movw $0x3f2, %dx
- xorb %al, %al
- outb %al, %dx
- popw %dx
- ret
-
-sectors:
- .word 0
-
-msg1:
- .byte 13,10
- .ascii "Loading"
-
-.org 497
-setup_sects:
- .byte SETUPSECS
-.org 500
-syssize:
- .word _syssize
-.org 508
-root_dev:
- .word ROOT_DEV
-boot_flag:
- .word 0xAA55
-_eboot:
+/*
+ * bootsect.s Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
+ * 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.
+ *
+ * The loader has been made as simple as possible, and continuos
+ * read errors will result in a unbreakable loop. Reboot by hand. It
+ * loads pretty fast by getting whole tracks at a time whenever possible.
+ *
+ * 1-Jan-96 Modified by Chris Brady for use as a boot loader for MemTest-86.
+ */
+
+#include "defs.h"
+
+ROOT_DEV = 0
+
+.code16
+.section ".bootsect", "ax", @progbits
+_boot:
+
+
+# ld86 requires an entry symbol. This may as well be the usual one.
+.globl _main
+_main:
+ movw $BOOTSEG, %ax
+ movw %ax, %ds
+ movw $INITSEG, %ax
+ movw %ax, %es
+ movw $256, %cx
+ subw %si, %si
+ subw %di, %di
+ cld
+ rep
+ movsw
+ ljmp $INITSEG, $go - _boot
+
+go:
+ movw %cs, %ax
+ movw $(0x4000-12), %dx # 0x4000 is arbitrary value >= length of
+ # bootsect + length of setup + room for stack
+ # 12 is disk parm size
+
+# bde - changed 0xff00 to 0x4000 to use debugger at 0x6400 up (bde). We
+# wouldn't have to worry about this if we checked the top of memory. Also
+# my BIOS can be configured to put the wini drive tables in high memory
+# instead of in the vector table. The old stack might have clobbered the
+# drive table.
+
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %ss # put stack at INITSEG:0x4000-12.
+ movw %dx, %sp
+
+/*
+ * 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.
+ *
+ * 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.
+ *
+ * High doesn't hurt. Low does.
+ *
+ * Segments are as follows: ds=es=ss=cs - INITSEG,
+ * fs = 0, gs = parameter table segment
+ */
+ pushw $0
+ popw %fs
+ movw $0x78, %bx # fs:bx is parameter table address
+ lgs %fs:(%bx),%si # gs:si is source
+
+ movw %dx, %di # es:di is destination
+ movw $6, %cx # copy 12 bytes
+ cld
+
+ rep movsw %gs:(%si), (%di)
+
+ movw %dx, %di
+ movb $18, 4(%di) # patch sector count
+
+ movw %di, %fs:(%bx)
+ movw %es, %fs:2(%bx)
+
+ movw %cs, %ax
+ movw %ax, %fs
+ movw %ax, %gs
+
+ 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.
+
+load_setup:
+ xorw %dx, %dx # drive 0, head 0
+ movw $0x0002, %cx # sector 2, track 0
+ movw $0x0200, %bx # address = 512, in INITSEG
+ movw $(0x0200 + SETUPSECS), %ax # service 2, nr of sectors
+ # (assume all on head 0, track 0)
+ int $0x13 # read it
+ jnc ok_load_setup # ok - continue
+
+ pushw %ax # dump error code
+ call print_nl
+ movw %sp, %bp
+ call print_hex
+ popw %ax
+
+ xorb %dl, %dl # reset FDC
+ xorb %ah, %ah
+ int $0x13
+ jmp load_setup
+
+ok_load_setup:
+
+# Get disk drive parameters, specifically nr of sectors/track
+
+
+/* It seems that there is no BIOS call to get the number of sectors. Guess
+ * 18 sectors if sector 18 can be read, 15 if sector 15 can be read.
+ * Otherwise guess 9
+ */
+
+ xorw %dx, %dx # drive 0, head 0
+ movw $0x0012, %cx # sector 18, track 0
+ movw $(0x200+(SETUPSECS*0x200)), %bx # address after setup (es = cs)
+ movw $0x0201, %ax # service 2, 1 sector
+ int $0x13
+ jnc got_sectors
+ movb $0x0f, %cl # sector 15
+ movw $0x0201, %ax # service 2, 1 sector
+ int $0x13
+ jnc got_sectors
+ movb $0x09, %cl
+
+got_sectors:
+ movw %cx, %cs:sectors - _boot
+ movw $INITSEG, %ax
+ movw %ax, %es
+
+# Print some inane message
+
+ 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)
+
+ movw $TSTLOAD, %ax
+ movw %ax, %es # segment of 0x010000
+ call read_it
+ call kill_motor
+ call print_nl
+
+# after that (everyting loaded), we jump to
+# the setup-routine loaded directly after
+# the bootblock:
+
+ ljmp $SETUPSEG,$0
+
+# This routine loads the system at address 0x10000, making sure
+# no 64kB boundaries are crossed. We try to load it as fast as
+# possible, loading whole tracks whenever we can.
+#
+# in: es - starting address segment (normally 0x1000)
+#
+sread: .word 1+SETUPSECS # sectors read of current track
+head: .word 0 # current head
+track: .word 0 # current track
+
+read_it:
+ movw %es, %ax
+ testw $0x0fff, %ax
+die:
+ jne die # es must be at 64kB boundary
+ xorw %bx,%bx # bx is starting address within segment
+rp_read:
+ movw %es, %ax
+ subw $TSTLOAD, %ax # have we loaded all yet?
+ cmpw syssize - _boot, %ax
+ jbe ok1_read
+ ret
+ok1_read:
+ movw %cs:sectors - _boot, %ax
+ subw sread - _boot, %ax
+ movw %ax, %cx
+ shlw $9, %cx
+ addw %bx, %cx
+ jnc ok2_read
+ je ok2_read
+ xorw %ax, %ax
+ subw %bx, %ax
+ shrw $9, %ax
+ok2_read:
+ call read_track
+ movw %ax, %cx
+ add sread - _boot, %ax
+ cmpw %cs:sectors - _boot, %ax
+ jne ok3_read
+ movw $1, %ax
+ subw head - _boot, %ax
+ jne ok4_read
+ incw track - _boot
+ok4_read:
+ movw %ax, head - _boot
+ xorw %ax, %ax
+ok3_read:
+ movw %ax, sread - _boot
+ shlw $9, %cx
+ addw %cx, %bx
+ jnc rp_read
+ movw %es, %ax
+ addb $0x10, %ah
+ movw %ax, %es
+ xorw %bx, %bx
+ jmp rp_read
+
+read_track:
+ pusha
+ pusha
+ movw $0xe2e, %ax # loading... message 2e = .
+ movw $7, %bx
+ int $0x10
+ popa
+
+ movw track - _boot, %dx
+ movw sread - _boot, %cx
+ incw %cx
+ movb %dl, %ch
+ movw head - _boot, %dx
+ movb %dl, %dh
+ andw $0x0100, %dx
+ movb $2, %ah
+
+ pushw %dx # save for error dump
+ pushw %cx
+ pushw %bx
+ pushw %ax
+
+ int $0x13
+ jc bad_rt
+ addw $8, %sp
+ popa
+ ret
+
+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
+ jmp read_track
+
+/*
+ * 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
+ * cx
+ * bx
+ * ax
+ * error
+ * ret <- sp
+ *
+*/
+
+print_all:
+ movw $5, %cx # error code + 4 registers
+ movw %sp, %bp
+
+print_loop:
+ pushw %cx # save count left
+ call print_nl # nl for readability
+
+ cmpb 5, %cl # see if register name is needed
+ jae no_reg
+
+ movw $(0xe05 + 'A' - 1), %ax
+ subb %cl, %al
+ int $0x10
+ movb $'X', %al
+ int $0x10
+ movb $':', %al
+ int $0x10
+
+no_reg:
+ addw $2, %bp # next register
+ call print_hex # print it
+ 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
+ movw (%bp), %dx # load word into dx
+
+print_digit:
+ rolw $4, %dx # rotate so that lowest 4 bits are used
+ movb $0xe, %ah
+ movb %dl, %al # mask off so we have only next nibble
+ andb $0xf, %al
+ addb $'0', %al # convert to 0-based digit
+ cmpb $'9', %al # check for overflow
+ jbe good_digit
+ addb $('A' - '0' - 10), %al
+
+good_digit:
+ int $0x10
+ loop print_digit
+ ret
+
+
+/*
+ * This procedure turns off the floppy drive motor, so
+ * that we enter the kernel in a known state, and
+ * don't have to worry about it later.
+ */
+kill_motor:
+ pushw %dx
+ movw $0x3f2, %dx
+ xorb %al, %al
+ outb %al, %dx
+ popw %dx
+ ret
+
+sectors:
+ .word 0
+
+msg1:
+ .byte 13,10
+ .ascii "Loading"
+
+.org 497
+setup_sects:
+ .byte SETUPSECS
+.org 500
+syssize:
+ .word _syssize
+.org 508
+root_dev:
+ .word ROOT_DEV
+boot_flag:
+ .word 0xAA55
+_eboot:
diff --git a/changelog b/changelog
deleted file mode 100644
index 86e7dca..0000000
--- a/changelog
+++ /dev/null
@@ -1,7 +0,0 @@
-- Added on-fly timings change on some chipsets
- (Thanks to Eric and Wee for this part)
-- Added i852/855 on-fly timing change
-- Added support for VIA K8T890
-- Added a "Fast" Mode (with MTRR & L1/L2 Caches)
-- Correct a bug (Disable MTRR for stronger test)
-- Some bug fixes \ No newline at end of file
diff --git a/config.c b/config.c
index 97c81da..1435d6f 100644
--- a/config.c
+++ b/config.c
@@ -1,28 +1,23 @@
-/* config.c - MemTest-86 Version 3.0
+/* config.c - MemTest-86 Version 3.2
*
* Released under version 2 of the Gnu Public License.
- * By Chris Brady, cbrady@sgi.com
+ * By Chris Brady
* ----------------------------------------------------
- * MemTest86+ V1.30 Specific code (GPL V2.0)
+ * MemTest86+ V2.00 Specific code (GPL V2.0)
* By Samuel DEMEULEMEESTER, sdemeule@memtest.org
* http://www.x86-secret.com - http://www.memtest.org
*/
-
#include "test.h"
#include "screen_buffer.h"
#include "controller.h"
-#include "extra.h"
#define ITER 20
extern int bail, beepmode;
extern struct tseq tseq[];
-/* extern struct vars *v; */
extern short e820_nr;
extern char memsz_mode;
-int fast_mode;
-
-char save[POP_H][POP_W];
+char save[2][POP_H][POP_W];
void get_config()
{
@@ -34,170 +29,86 @@ void get_config()
wait_keyup();
while(!flag) {
cprint(POP_Y+1, POP_X+2, "Configuration:");
- cprint(POP_Y+3, POP_X+6, "(1) Cache Mode");
- cprint(POP_Y+4, POP_X+6, "(2) Test Selection");
- cprint(POP_Y+5, POP_X+6, "(3) Address Range");
- cprint(POP_Y+6, POP_X+6, "(4) Memory Sizing");
- cprint(POP_Y+7, POP_X+6, "(5) Error Summary");
- cprint(POP_Y+8, POP_X+6, "(6) Error Report Mode");
- cprint(POP_Y+9, POP_X+6, "(7) ECC Mode");
- cprint(POP_Y+10, POP_X+6, "(8) Restart Test");
+ cprint(POP_Y+3, POP_X+6, "(1) Test Selection");
+ cprint(POP_Y+4, POP_X+6, "(2) Address Range");
+ cprint(POP_Y+5, POP_X+6, "(3) Memory Sizing");
+ cprint(POP_Y+6, POP_X+6, "(4) Error Summary");
+ cprint(POP_Y+7, POP_X+6, "(5) Error Report Mode");
+ cprint(POP_Y+8, POP_X+6, "(6) ECC Mode");
+ 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) Exit");
+ cprint(POP_Y+12,POP_X+6,"(0) Continue");
/* Wait for key release */
/* Fooey! This nuts'es up the serial input. */
sflag = 0;
switch(get_key()) {
case 2:
- /* 1 - Set cache mode */
- popclear();
- cprint(POP_Y+1, POP_X+2, "Cache Mode:");
- cprint(POP_Y+3, POP_X+6, "(1) Test Controlled");
- cprint(POP_Y+4, POP_X+6, "(2) Always On");
- cprint(POP_Y+5, POP_X+6, "(3) Always Off");
- cprint(POP_Y+6, POP_X+6, "(0) Cancel");
- cprint(POP_Y+3+v->cache_flag, POP_X+5, ">");
- wait_keyup();
- while (!sflag) {
- switch(get_key()) {
- case 2:
- /* test controled */
- v->cache_flag = 0;
- set_cache(tseq[v->test].cache);
- find_ticks();
- sflag++;
- break;
- case 3:
- /* Cache on */
- v->cache_flag = 1;
- if (tseq[v->test].cache == 0) {
- bail++;
- }
- set_cache(1);
- find_ticks();
- sflag++;
- break;
- case 4:
- /* Cache off */
- v->cache_flag = 2;
- if (tseq[v->test].cache == 1) {
- bail++;
- }
- find_ticks();
- sflag++;
- break;
- case 11:
- case 57:
- sflag++;
- break;
- }
- }
- popclear();
- break;
- case 3:
- /* 2 - Test Selection */
+ /* 1 - Test Selection */
popclear();
cprint(POP_Y+1, POP_X+2, "Test Selection:");
cprint(POP_Y+3, POP_X+6, "(1) Default Tests");
- cprint(POP_Y+4, POP_X+6, "(2) Quick Tests");
- cprint(POP_Y+5, POP_X+6, "(3) Extended Tests");
- cprint(POP_Y+6, POP_X+6, "(4) All Tests");
- cprint(POP_Y+7, POP_X+6, "(5) Skip Current Test");
- cprint(POP_Y+8, POP_X+6, "(6) Select Test");
- cprint(POP_Y+9, POP_X+6, "(7) Print mode");
- cprint(POP_Y+10, POP_X+6, "(0) Cancel");
+ 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");
if (v->testsel < 0) {
- if (fast_mode == 1) {
- cprint(POP_Y+4, POP_X+5, ">");
- } else {
- if (v->xtst_flag == 0) {
- cprint(POP_Y+3, POP_X+5, ">");
- } else {
- cprint(POP_Y+4+v->xtst_flag, POP_X+5, ">");
- }
- }
+ cprint(POP_Y+3, POP_X+5, ">");
} else {
- cprint(POP_Y+8, POP_X+5, ">");
+ cprint(POP_Y+5, POP_X+5, ">");
}
wait_keyup();
while (!sflag) {
switch(get_key()) {
case 2:
/* Default */
- v->xtst_flag = 0;
- fast_mode = 0;
- if (v->test > DEFTESTS) {
+ if (v->testsel == 9) {
bail++;
}
v->testsel = -1;
find_ticks();
sflag++;
- cprint(LINE_INFO, COL_TST, " Std");
+ cprint(LINE_INFO, COL_TST, "Std");
break;
case 3:
- /* Fast */
- v->xtst_flag = 0;
- fast_mode = 1;
- if (v->test > DEFTESTS) {
- bail++;
- }
- v->testsel = -1;
- v->pass = 0;
- v->ecount = 0;
- find_ticks();
- sflag++;
- cprint(LINE_INFO, COL_TST, "Fast");
- break;
- case 4:
- /* Extended */
- v->xtst_flag = 1;
- fast_mode = 0;
- if (v->test <= DEFTESTS) {
- bail++;
- }
- v->testsel = -1;
- find_ticks();
- sflag++;
- cprint(LINE_INFO, COL_TST, " Ext");
- break;
- case 5:
- /* All */
- fast_mode = 0;
- v->xtst_flag = 2;
- v->testsel = -1;
- find_ticks();
- sflag++;
- cprint(LINE_INFO, COL_TST, " All");
- break;
- case 6:
/* Skip test */
bail++;
sflag++;
break;
- case 7:
+ case 4:
/* Select test */
popclear();
- cprint(POP_Y+1, POP_X+2,
+ cprint(POP_Y+1, POP_X+3,
"Test Selection:");
- cprint(POP_Y+3, POP_X+4,
- "Test Number [0-12]: ");
- i = getval(POP_Y+3, POP_X+24, 0);
- if (i <= 12) {
+ cprint(POP_Y+4, POP_X+5,
+ "Test Number [0-9]: ");
+ i = getval(POP_Y+4, POP_X+24, 0);
+ if (i <= 9) {
if (i != v->testsel) {
- v->pass = 0;
- v->ecount = 0;
+ v->pass = -1;
+ v->test = -1;
}
v->testsel = i;
}
- v->test = -1;
- v->pass = -1;
find_ticks();
sflag++;
bail++;
- cprint(LINE_INFO, COL_TST, " #");
+ cprint(LINE_INFO, COL_TST, "#");
dprint(LINE_INFO, COL_TST+1, i, 2, 1);
break;
+ case 5:
+ if (v->testsel != 9) {
+ v->pass = -1;
+ 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;
case 11:
case 57:
sflag++;
@@ -206,14 +117,14 @@ void get_config()
}
popclear();
break;
- case 4:
- /* 3 - Address Range */
+ case 3:
+ /* 2 - Address Range */
popclear();
cprint(POP_Y+1, POP_X+2, "Test Address Range:");
cprint(POP_Y+3, POP_X+6, "(1) Set Lower Limit");
cprint(POP_Y+4, POP_X+6, "(2) Set Upper Limit");
cprint(POP_Y+5, POP_X+6, "(3) Test All Memory");
- cprint(POP_Y+6, POP_X+6, "(0) Cancel");
+ cprint(POP_Y+6, POP_X+6, "(0) Continue");
wait_keyup();
while (!sflag) {
switch(get_key()) {
@@ -266,26 +177,26 @@ void get_config()
break;
case 11:
case 57:
- /* 0/CR - Cancel */
+ /* 0/CR - Continue */
sflag++;
break;
}
}
popclear();
break;
- case 5:
- /* 4 - Memory Sizing */
+ case 4:
+ /* 3 - Memory Sizing */
popclear();
cprint(POP_Y+1, POP_X+2, "Memory Sizing:");
cprint(POP_Y+3, POP_X+6, "(1) BIOS - Std");
if (e820_nr) {
cprint(POP_Y+4, POP_X+6, "(2) BIOS - All");
cprint(POP_Y+5, POP_X+6, "(3) Probe");
- cprint(POP_Y+6, POP_X+6, "(0) Cancel");
+ cprint(POP_Y+6, POP_X+6, "(0) Continue");
cprint(POP_Y+2+memsz_mode, POP_X+5, ">");
} else {
cprint(POP_Y+4, POP_X+6, "(3) Probe");
- cprint(POP_Y+5, POP_X+6, "(0) Cancel");
+ cprint(POP_Y+5, POP_X+6, "(0) Continue");
if (memsz_mode == SZ_MODE_BIOS) {
cprint(POP_Y+3, POP_X+5, ">");
} else {
@@ -336,15 +247,15 @@ void get_config()
break;
case 11:
case 57:
- /* 0/CR - Cancel */
+ /* 0/CR - Continue */
sflag++;
break;
}
}
popclear();
break;
- case 6:
- /* 5 - Show error summary */
+ case 5:
+ /* 4 - Show error summary */
popclear();
for (i=0; tseq[i].msg != NULL; i++) {
cprint(POP_Y+1+i, POP_X+2, "Test:");
@@ -357,8 +268,8 @@ void get_config()
while (get_key() == 0);
popclear();
break;
- case 7:
- /* 6 - Printing Mode */
+ case 6:
+ /* 5 - Printing Mode */
popclear();
cprint(POP_Y+1, POP_X+2, "Printing Mode:");
cprint(POP_Y+3, POP_X+6, "(1) Individual Errors");
@@ -392,24 +303,24 @@ void get_config()
/* Set Beep On Error mode */
beepmode = !beepmode;
sflag++;
- break;
+ break;
case 11:
case 57:
- /* 0/CR - Cancel */
+ /* 0/CR - Continue */
sflag++;
break;
}
}
popclear();
break;
- case 8:
- /* 7 - ECC Polling Mode */
+ case 7:
+ /* 6 - ECC Polling Mode */
popclear();
cprint(POP_Y+1, POP_X+2, "ECC Polling Mode:");
cprint(POP_Y+3, POP_X+6, "(1) Recommended");
cprint(POP_Y+4, POP_X+6, "(2) On");
cprint(POP_Y+5, POP_X+6, "(3) Off");
- cprint(POP_Y+6, POP_X+6, "(0) Cancel");
+ cprint(POP_Y+6, POP_X+6, "(0) Continue");
wait_keyup();
while(!sflag) {
switch(get_key()) {
@@ -427,52 +338,28 @@ void get_config()
break;
case 11:
case 57:
- /* 0/CR - Cancel */
+ /* 0/CR - Continue */
sflag++;
break;
}
}
popclear();
break;
- case 9:
+ case 8:
wait_keyup();
restart();
break;
- case 10: // experimental extra options
- popclear();
- cprint(POP_Y+1, POP_X+2, "Adv. Options :");
- cprint(POP_Y+3, POP_X+5, "(1) Modify Timing ");
- cprint(POP_Y+4, POP_X+5, "(2) Reprint Screen");
- cprint(POP_Y+5, POP_X+5, "(0) Cancel ");
- wait_keyup();
- while(!sflag)
- {
- switch(get_key())
- {
- case 2:
- popclear();
- get_menu();
- case 3:
- reprint_screen = 1;
- sflag++;
- flag++;
- break;
- //prime();
- case 4:
- break;
- case 11:
- case 57:
- /* 0/CR - Cancel */
- sflag++;
- break;
- }
- }
- popclear();
+ case 9:
+ reprint_screen = 1;
+ flag++;
+ break;
+ case 10:
+ get_menu();
break;
case 11:
case 57:
case 28:
- /* 0/CR/SP - Cancel */
+ /* 0/CR/SP - Continue */
flag++;
break;
}
@@ -495,10 +382,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[i-POP_Y][j-POP_X] = get_scrn_buf(i, j); /* Save screen */
+ 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;
*pp = 0x07; /* Change Background to black */
}
}
@@ -513,10 +401,10 @@ void popdown()
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));
- *pp = save[i-POP_Y][j-POP_X]; /* Restore screen */
- set_scrn_buf(i, j, save[i-POP_Y][j-POP_X]);
+ *pp = save[0][i-POP_Y][j-POP_X]; /* Restore screen */
+ set_scrn_buf(i, j, save[0][i-POP_Y][j-POP_X]);
pp++;
- *pp = 0x17; /* Reset background color */
+ *pp = save[1][i-POP_Y][j-POP_X]; /* Restore color */
}
}
tty_print_region(POP_Y, POP_X, POP_Y+POP_H, POP_X+POP_W);
@@ -530,7 +418,7 @@ void popclear()
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));
- *pp = ' '; /* Clear screen */
+ *pp = ' '; /* Clear popup */
set_scrn_buf(i, j, ' ');
pp++;
}
diff --git a/controller.c b/controller.c
index 81fdf6b..ed38e12 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.30 Specific code (GPL V2.0)
+ * MemTest86+ V1.40 Specific code (GPL V2.0)
* By Samuel DEMEULEMEESTER, sdemeule@memtest.org
* http://www.x86-secret.com - http://www.memtest.org
*/
@@ -279,6 +279,17 @@ static void poll_amd751(void)
}
}
+/* 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;
+
+}
+*/
static void setup_amd76x(void)
{
@@ -873,9 +884,9 @@ static void poll_fsb_i925(void) {
int coef = getP4PMmultiplier();
long *ptr;
-
/* Find dramratio */
pci_conf_read( 0, 0, 0, 0x44, 4, &dev0);
+ dev0 = dev0 & 0xFFFFC000;
ptr=(long*)(dev0+0xC00);
mchcfg = *ptr & 0xFFFF;
dramratio = 1;
@@ -899,7 +910,7 @@ static void poll_fsb_i925(void) {
}
// Compute RAM Frequency
- fsb = ((extclock /1000) / coef);
+ fsb = ((extclock / 1000) / coef);
dramclock = fsb * dramratio;
// Print DRAM Freq
@@ -1625,7 +1636,7 @@ static struct pci_memory_controller controllers[] = {
{ 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, 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 },
diff --git a/head.S b/head.S
index 28772c3..49a3e3d 100644
--- a/head.S
+++ b/head.S
@@ -329,6 +329,20 @@ have_cpuid:
movl $1, %eax # Use the CPUID instruction to get CPU type
cpuid
+
+ #
+ # CDH start
+ # Check FPU, initialize if present
+ #
+ testl $1, %edx # FPU available?
+ jz no_fpu
+ finit
+
+ no_fpu:
+ #
+ # CDH end
+ #
+
movb %al, %cl # save reg for future use
andb $0x0f, %ah # mask processor family
movb %ah, X86(%esi)
diff --git a/init.c b/init.c
index 6a61c76..28000fc 100755..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.30 Specific code (GPL V2.0)
+ * MemTest86+ V1.40 Specific code (GPL V2.0)
* By Samuel DEMEULEMEESTER, sdemeule@memtest.org
* http://www.x86-secret.com - http://www.memtest.org
*/
@@ -52,7 +52,7 @@ static void display_init(void)
for(i=0, pp=(char *)(SCREEN_ADR+1); i<TITLE_WIDTH; i++, pp+=2) {
*pp = 0x20;
}
- cprint(0, 0, " Memtest86 v1.30 ");
+ cprint(0, 0, " Memtest86 v1.40 ");
for(i=0, pp=(char *)(SCREEN_ADR+1); i<2; i++, pp+=30) {
*pp = 0xA4;
@@ -78,7 +78,7 @@ void init(void)
/* Turn on cache */
set_cache(1);
-
+
/* Setup the display */
display_init();
@@ -702,6 +702,7 @@ void cpu_type(void)
break;
case 3:
case 4:
+ case 5:
if (l2_cache == 256) {
cprint(LINE_CPU, 0, "Celeron (0.09)");
off = 14;
@@ -896,7 +897,8 @@ static void cacheable(void)
/* #define TICKS 5 * 11832 (count = 6376)*/
/* #define TICKS (65536 - 12752) */
-#define TICKS (65536 - 8271)
+/* #define TICKS (65536 - 8271) */
+#define TICKS 59659
/* Returns CPU clock in khz */
static int cpuspeed(void)
@@ -927,7 +929,7 @@ static int cpuspeed(void)
if (loops < 4 || end_low < 50000) {
return(-1);
}
- v->clks_msec = end_low/48;
+ v->clks_msec = end_low/50;
return(v->clks_msec);
}
diff --git a/lib.c b/lib.c
index 148f932..05b8371 100644
--- a/lib.c
+++ b/lib.c
@@ -403,22 +403,12 @@ void set_cache(int val)
}
switch(val) {
case 0:
- if (fast_mode != 1) {
- cache_off();
- if (v->cache_flag) {
- cprint(LINE_INFO, COL_CACHE, "OFF");
- } else {
- cprint(LINE_INFO, COL_CACHE, "off");
- }
- }
+ cache_off();
+ cprint(LINE_INFO, COL_CACHE, "off");
break;
case 1:
cache_on();
- if (v->cache_flag) {
- cprint(LINE_INFO, COL_CACHE, " ON");
- } else {
- cprint(LINE_INFO, COL_CACHE, " on");
- }
+ cprint(LINE_INFO, COL_CACHE, " on");
break;
}
}
diff --git a/main.c b/main.c
index 77182a9..ac970bc 100644
--- a/main.c
+++ b/main.c
@@ -1,30 +1,27 @@
-/* main.c - MemTest-86 Version 3.0
+/* main.c - MemTest-86 Version 3.2
*
* Released under version 2 of the Gnu Public License.
- * By Chris Brady, cbrady@sgi.com
+ * By Chris Brady
*/
+
#include "test.h"
#include "defs.h"
#undef TEST_TIMES
+#define DEFTESTS 9
extern void bzero();
-extern int fast_mode;
const struct tseq tseq[] = {
{0, 5, 3, 0, 0, "[Address test, walking ones, no cache]"},
- {1, 0, 3, 14, 0, "[Moving inv, ones & zeros, cached] "},
- {0, 6, 3, 2, 0, "[Address test, own address, no cache] "},
- {1, 1, 2, 80, 0, "[Moving inv, 8 bit pattern, cached] "},
- {1, 2, 2, 320, 0, "[Moving inv, 32 bit pattern, cached] "},
- {1, 7, 64, 66, 0, "[Block move, 64 moves, cached] "},
- {1, 3, 4, 240, 0, "[Modulo 20, ones & zeros, cached] "},
- {0, 0, 2, 10, 0, "[Moving inv, ones & zeros, no cache] "},
-
- {1, 7, 512, 514, 0,"[Block move, 512 moves, cached] "},
- {0, 1, 2, 80, 0, "[Moving inv, 8 bit pattern, no cache] "},
- {1, 4, 2, 1280, 0, "[Modulo 20, 8 bit pattern , cached] "},
- {0, 2, 2, 320, 0, "[Moving inv, 32 bit pattern, no cache]"},
- {1, 8, 1, 1, 0, "[Bit fade test, 90 min, 2 patterns] "},
+ {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}
};
@@ -208,32 +205,7 @@ void do_test(void)
#endif
/* Now setup the test parameters based on the current test number */
/* Figure out the next test to run */
- if (v->testsel < 0) {
- switch(v->xtst_flag) {
- case 0: /* Default tests */
- if (v->test > DEFTESTS) {
- goto skip_test;
- }
- break;
- case 1: /* Extended tests */
- if ((v->test <= DEFTESTS) || (v->test > DEFTESTS2)) {
- goto skip_test;
- }
- break;
- case 2: /* All tests */
- if (v->test > DEFTESTS2) {
- goto skip_test;
- }
- break;
- }
-
- /* May skip this test if the cache settings have been */
- /* overridden */
- if ((v->cache_flag == 1 && tseq[v->test].cache == 0) ||
- (v->cache_flag == 2 && tseq[v->test].cache == 1)) {
- goto skip_test;
- }
- } else {
+ if (v->testsel >= 0) {
v->test = v->testsel;
}
dprint(LINE_TST, COL_MID+6, v->test, 2, 1);
@@ -265,6 +237,7 @@ void do_test(void)
p2 = p1;
p1 = ~p2;
movinv1(tseq[v->test].iter,p1,p2);
+ BAILOUT;
break;
case 1: /* Moving inversions, 8 bit wide walking ones and zeros. */
@@ -323,23 +296,41 @@ void do_test(void)
modtst(i, tseq[v->test].iter, p1, p2);
BAILOUT
}
- BAILOUT
}
break;
case 5: /* Address test, walking ones */
addr_tst1();
+ BAILOUT;
break;
case 6: /* Address test, own address */
addr_tst2();
+ BAILOUT;
break;
case 7: /* Block move test */
block_move(tseq[v->test].iter);
+ BAILOUT;
break;
-
case 8: /* Bit fade test */
- if (window == 0 ) { bit_fade(); }
+ if (window == 0 ) {
+ bit_fade();
+ }
+ BAILOUT;
+ break;
+ case 9: /* Random Data Sequence */
+ for (i=0; i < tseq[v->test].iter; i++) {
+ movinvr();
+ BAILOUT;
+ }
+ break;
+ case 10: /* Random Data */
+ for (i=0; i < tseq[v->test].iter; i++) {
+ p1 = rand();
+ p2 = ~p1;
+ movinv1(2,p1,p2);
+ BAILOUT;
+ }
break;
}
skip_window:
@@ -394,7 +385,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 (tseq[v->test].msg == NULL || v->testsel >= 0) {
+ if (v->test >= DEFTESTS || v->testsel >= 0) {
v->pass++;
dprint(LINE_INFO, COL_PASS, v->pass, 5, 0);
v->test = 0;
@@ -414,12 +405,13 @@ void restart()
int i;
volatile char *pp;
- /* clear all of the variables */
+ /* clear variables */
firsttime = 0;
- fast_mode = 0;
- for (i=0, pp=(char *)v; i<sizeof(struct vars); i++, pp++) {
- *pp = 0;
- }
+ v->test = 0;
+ v->pass = 0;
+ v->msg_line = 0;
+ v->ecount = 0;
+ v->ecc_ecount = 0;
/* Clear the screen */
for(i=0, pp=(char *)(SCREEN_ADR+0); i<80*24; i++, pp+=2) {
@@ -448,24 +440,13 @@ void find_ticks(void)
}
compute_segments(window);
window = 0;
- for (v->pass_ticks=0, i=0; tseq[i].msg != NULL; i++) {
+ for (v->pass_ticks=0, i=0; i<DEFTESTS != NULL; i++) {
/* Test to see if this test is selected for execution */
if (v->testsel >= 0) {
if (i != v->testsel) {
continue;
}
- } else {
- if (v->xtst_flag == 0 && i > DEFTESTS) {
- break;
- }
- if (v->xtst_flag == 1 && i <= DEFTESTS) {
- continue;
- }
- if ((v->cache_flag == 1 && tseq[i].cache == 0) ||
- (v->cache_flag == 2 && tseq[i].cache == 1)) {
- continue;
- }
}
v->pass_ticks += find_ticks_for_test(chunks, i);
}
@@ -566,5 +547,3 @@ static void compute_segments(int win)
}
}
}
-
-
diff --git a/makeiso.sh b/makeiso.sh
new file mode 100755
index 0000000..580df07
--- /dev/null
+++ b/makeiso.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# check to see if the correct tools are installed
+for X in wc mkisofs
+do
+ if [ "$(which $X)" = "" ]; then
+ echo "makeiso.sh error: $X is not in your path." >&2
+ exit 1
+ elif [ ! -x $(which $X) ]; then
+ echo "makeiso.sh error: $X is not executable." >&2
+ exit 1
+ fi
+done
+
+#check to see if memtest.bin is present
+if [ ! -w memtest.bin ]; then
+ echo "makeiso.sh error: cannot find memtest.bin, did you compile it?" >&2
+ exit 1
+fi
+
+# enlarge the size of memtest.bin
+SIZE=$(wc -c memtest.bin | awk '{print $1}')
+FILL=$((1474560 - $SIZE))
+dd if=/dev/zero of=fill.tmp bs=$FILL count=1
+cat memtest.bin fill.tmp >memtest.img
+rm -f fill.tmp
+
+echo "generating iso image ..."
+
+mkdir "cd"
+mkdir "cd/boot"
+mv memtest.img cd/boot
+cd cd
+mkisofs -b boot/memtest.img -c boot/boot.catalog -o memtest.iso .
+mv memtest.iso ..
+cd ..
+rm -rf cd
+
+echo "done"
diff --git a/memsize.c b/memsize.c
index a0947b0..2447a29 100644
--- a/memsize.c
+++ b/memsize.c
@@ -1,7 +1,7 @@
-/* memsize.c - MemTest-86 Version 3.0
+/* memsize.c - MemTest-86 Version 3.2
*
* Released under version 2 of the Gnu Public License.
- * By Chris Brady, cbrady@sgi.com
+ * By Chris Brady
*/
#include "test.h"
@@ -20,7 +20,6 @@ extern ulong p1, p2;
extern volatile ulong *p;
static void sort_pmap(void);
-static void sanitize_pmap(void);
static int check_ram(void);
static void memsize_bios(int res);
static void memsize_820(int res);
@@ -71,7 +70,6 @@ void mem_size(void)
}
/* Guarantee that pmap entries are in ascending order */
sort_pmap();
- sanitize_pmap();
v->plim_lower = 0;
v->plim_upper = v->pmap[v->msegs-1].end;
@@ -113,62 +111,6 @@ static void sort_pmap(void)
}
}
}
-
-static void remove_pmap_region(unsigned long res_start, unsigned long res_end)
-{
- /* Ensure a range of addresses is absent from the pmap */
- int i;
- for(i = 0; i < v->msegs; i++) {
- unsigned long start, end;
- start = v->pmap[i].start;
- end = v->pmap[i].end;
- if ((start < res_start) && (end > res_start)) {
- /* If the tail of the range overlaps the region, truncate it */
- v->pmap[i].end = res_start;
- if ((end > res_end) && (v->msegs < MAX_MEM_SEGMENTS)) {
- /* If the tail extends past the end of the region
- * insert a new pmap entry for the tail.
- */
- memmove(&v->pmap[i+2], &v->pmap[i + 1],
- ((v->msegs - 1) - i) *sizeof(v->pmap[0]));
- v->msegs += 1;
- i += 1;
- start = res_start;
- v->pmap[i].start = start;
- v->pmap[i].end = end;
- }
- else {
- end = res_start;
- }
- }
- if ((start >= res_start) && (end <= res_end)) {
- /* If the range is completely contained in the region remove it */
- memmove(&v->pmap[i], &v->pmap[i+1],
- ((v->msegs - 1) - i) * sizeof(v->pmap[0]));
- v->msegs -= 1;
- i -= 1;
- }
- else if ((start < res_end) && (end > res_end)) {
- /* If the start is in the middle of the region increment it */
- start = res_end;
- v->pmap[i].start = start;
- }
- }
-}
-
-static void sanitize_pmap(void)
-{
- /* Remove any questionable addresses from the memory map */
- /* Unless we really trust the BIOS don't test 640-1M */
- if (firmware != FIRMWARE_LINUXBIOS) {
- remove_pmap_region(RES_START >> 12 , (RES_END + 4095) >> 12);
- }
- /* Never test where our video buffer lives */
- remove_pmap_region(SCREEN_ADR >> 12, (SCREEN_END_ADR + 4095) >> 12);
-}
-
-
-
static void memsize_linuxbios(void)
{
int i, n;
@@ -213,6 +155,16 @@ static void memsize_820(int res)
start = nm[i].addr;
end = start + nm[i].size;
+ /* Don't ever use memory between 640 and 1024k */
+ if (start > RES_START && start < RES_END) {
+ if (end < RES_END) {
+ continue;
+ }
+ start = RES_END;
+ }
+ if (end > RES_START && end < RES_END) {
+ end = RES_START;
+ }
v->pmap[n].start = (start + 4095) >> 12;
v->pmap[n].end = end >> 12;
v->test_pages += v->pmap[n].end - v->pmap[n].start;
diff --git a/memtest.bin.lds b/memtest.bin.lds
index 702cdb1..699d2aa 100644
--- a/memtest.bin.lds
+++ b/memtest.bin.lds
@@ -1,15 +1,15 @@
-OUTPUT_FORMAT("binary")
-OUTPUT_ARCH("i386")
-
-ENTRY(_main);
-SECTIONS {
- . = 0;
- .bootsect : { *(.bootsect) }
- .setup : { *(.setup) }
- .memtest : {
- _start = . ;
- *(.data)
- _end = . ;
- }
- _syssize = (_end - _start + 15) >> 4;
-}
+OUTPUT_FORMAT("binary")
+OUTPUT_ARCH("i386")
+
+ENTRY(_main);
+SECTIONS {
+ . = 0;
+ .bootsect : { *(.bootsect) }
+ .setup : { *(.setup) }
+ .memtest : {
+ _start = . ;
+ *(.data)
+ _end = . ;
+ }
+ _syssize = (_end - _start + 15) >> 4;
+}
diff --git a/memtest.lds b/memtest.lds
index bbb190a..1d661b3 100644
--- a/memtest.lds
+++ b/memtest.lds
@@ -1,11 +1,11 @@
-OUTPUT_FORMAT("elf32-i386");
-OUTPUT_ARCH(i386);
-
-ENTRY(_start);
-SECTIONS {
- . = 0x10000;
- _start = . ;
- .data : {
- *(.data)
- }
-}
+OUTPUT_FORMAT("elf32-i386");
+OUTPUT_ARCH(i386);
+
+ENTRY(_start);
+SECTIONS {
+ . = 0x10000;
+ _start = . ;
+ .data : {
+ *(.data)
+ }
+}
diff --git a/memtest_shared.lds b/memtest_shared.lds
index dc88711..d4576a2 100644
--- a/memtest_shared.lds
+++ b/memtest_shared.lds
@@ -1,52 +1,52 @@
-OUTPUT_FORMAT("elf32-i386");
-OUTPUT_ARCH(i386);
-
-ENTRY(startup_32);
-SECTIONS {
- . = 0;
- .text : {
- _start = .;
- *(.text)
- *(.text.*)
- *(.plt)
- _etext = . ;
- } = 0x9090
- .rodata : {
- *(.rodata)
- *(.rodata.*)
- }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .hash : { *(.hash) }
- .dynamic : { *(.dynamic) }
-
- .rel.text : { *(.rel.text .rel.text.*) }
- .rel.rodata : { *(.rel.rodata .rel.rodata.*) }
- .rel.data : { *(.rel.data .rel.data.*) }
- .rel.got : { *(.rel.got .rel.got.*) }
- .rel.plt : { *(.rel.plt .rel.plt.*) }
-
- . = ALIGN(4);
- .data : {
- _data = .;
- *(.data)
- *(.data.*)
- }
- .got : {
- *(.got.plt)
- *(.got)
- _edata = . ;
- }
- . = ALIGN(4);
- .bss : {
- _bss = .;
- *(.dynbss)
- *(.bss)
- *(.bss.*)
- *(COMMON)
- /* _end must be at least 256 byte aligned */
- . = ALIGN(256);
- _end = .;
- }
- /DISCARD/ : { *(*) }
-}
+OUTPUT_FORMAT("elf32-i386");
+OUTPUT_ARCH(i386);
+
+ENTRY(startup_32);
+SECTIONS {
+ . = 0;
+ .text : {
+ _start = .;
+ *(.text)
+ *(.text.*)
+ *(.plt)
+ _etext = . ;
+ } = 0x9090
+ .rodata : {
+ *(.rodata)
+ *(.rodata.*)
+ }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .hash : { *(.hash) }
+ .dynamic : { *(.dynamic) }
+
+ .rel.text : { *(.rel.text .rel.text.*) }
+ .rel.rodata : { *(.rel.rodata .rel.rodata.*) }
+ .rel.data : { *(.rel.data .rel.data.*) }
+ .rel.got : { *(.rel.got .rel.got.*) }
+ .rel.plt : { *(.rel.plt .rel.plt.*) }
+
+ . = ALIGN(4);
+ .data : {
+ _data = .;
+ *(.data)
+ *(.data.*)
+ }
+ .got : {
+ *(.got.plt)
+ *(.got)
+ _edata = . ;
+ }
+ . = ALIGN(4);
+ .bss : {
+ _bss = .;
+ *(.dynbss)
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ /* _end must be at least 256 byte aligned */
+ . = ALIGN(256);
+ _end = .;
+ }
+ /DISCARD/ : { *(*) }
+}
diff --git a/mt86+_loader.asm b/mt86+_loader.asm
index 4eab61e..be83381 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 (99516 + buffer - exeh)
- ; 995126 is the size of memtest86+ V1.30, adjust as needed!
+%define fullsize (95352 + buffer - exeh)
+ ; 95352 is the size of memtest86+ V1.40, adjust as needed!
%define stacksize 2048
%define stackpara ((stacksize + 15) / 16)
diff --git a/mt86+_loader.bin b/mt86+_loader.bin
index 6dc11aa..1725ec7 100644
--- a/mt86+_loader.bin
+++ b/mt86+_loader.bin
Binary files differ
diff --git a/precomp.bin b/precomp.bin
index 8838740..052eff0 100755
--- a/precomp.bin
+++ b/precomp.bin
Binary files differ
diff --git a/random.c b/random.c
new file mode 100644
index 0000000..a0a19c7
--- /dev/null
+++ b/random.c
@@ -0,0 +1,31 @@
+/* concatenation of following two 16-bit multiply with carry generators */
+/* x(n)=a*x(n-1)+carry mod 2^16 and y(n)=b*y(n-1)+carry mod 2^16, */
+/* number and carry packed within the same 32 bit integer. */
+/******************************************************************/
+
+unsigned int rand( void ); /* returns a random 32-bit integer */
+void rand_seed( unsigned int, unsigned int ); /* seed the generator */
+
+/* return a random float >= 0 and < 1 */
+#define rand_float ((double)rand() / 4294967296.0)
+
+static unsigned int SEED_X = 521288629;
+static unsigned int SEED_Y = 362436069;
+
+
+unsigned int rand ()
+ {
+ static unsigned int a = 18000, b = 30903;
+
+ SEED_X = a*(SEED_X&65535) + (SEED_X>>16);
+ SEED_Y = b*(SEED_Y&65535) + (SEED_Y>>16);
+
+ return ((SEED_X<<16) + (SEED_Y&65535));
+ }
+
+
+void rand_seed( unsigned int seed1, unsigned int seed2 )
+ {
+ if (seed1) SEED_X = seed1; /* use default seeds if parameter is 0 */
+ if (seed2) SEED_Y = seed2;
+ }
diff --git a/setup.S b/setup.S
index 9a3450f..2e1cfa6 100644
--- a/setup.S
+++ b/setup.S
@@ -1,115 +1,115 @@
-/*
- * setup.s is responsible for getting the system data from the BIOS,
- * and putting them into the appropriate places in system memory.
- * both setup.s and system has been loaded by the bootblock.
- *
- * 1-Jan-96 Modified by Chris Brady for use as a boot/loader for memtest-86.
- */
-
-#define __ASSEMBLY__
-#include "defs.h"
-
-.code16
-.section ".setup", "ax", @progbits
-.globl start
-start:
-# ok, the read went well
-# now we want to move to protected mode ...
-
-
- cli # no interrupts allowed #
- movb $0x80, %al # disable NMI for the bootup sequence
- outb %al, $0x70
-
-# The system will move itself to its rightful place.
-
- push %cs
- pop %ds
- lidt idt_48 - start # load idt with 0,0
- lgdt gdt_48 - start # load gdt with whatever appropriate
-
-# that was painless, now we enable A20
-
- call empty_8042
-
- movb $0xD1, %al # command write
- outb %al, $0x64
- call empty_8042
-
- movb $0xDF, %al # A20 on
- outb %al, $0x60
- call empty_8042
-
-/*
- * Note that the short jump isn't strictly needed, althought there are
- * reasons why it might be a good idea. It won't hurt in any case.
- */
- movw $0x0001, %ax # protected mode (PE) bit
- lmsw %ax # This is it#
- jmp flush_instr
-flush_instr:
- movw $KERNEL_DS, %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %ss
- movw %ax, %fs
- movw %ax, %gs
-
-data32 ljmp $KERNEL_CS, $(TSTLOAD <<4) # jmp offset 2000 of segment 0x10 (cs)
-
-/*
- * This routine checks that the keyboard command queue is empty
- * (after emptying the output buffers)
- *
- * No timeout is used - if this hangs there is something wrong with
- * the machine, and we probably couldn't proceed anyway.
- */
-empty_8042:
- call delay
- inb $0x64, %al # 8042 status port
- testb $1, %al # output buffer?
- jz no_output
- call delay
- inb $0x60, %al # read it
- jmp empty_8042
-
-no_output:
- testb $2, %al # is input buffer full?
- jnz empty_8042 # yes - loop
- ret
-#
-# Delay is needed after doing i/o
-#
-delay:
- .word 0x00eb # jmp $+2
- ret
-
-gdt:
- .word 0,0,0,0 # dummy
-
- .word 0,0,0,0 # unused
-
- .word 0x7FFF # limit 128mb
- .word 0x0000 # base address=0
- .word 0x9A00 # code read/exec
- .word 0x00C0 # granularity=4096, 386
-
- .word 0x7FFF # limit 128mb
- .word 0x0000 # base address=0
- .word 0x9200 # data read/write
- .word 0x00C0 # granularity=4096, 386
-
-idt_48:
- .word 0 # idt limit=0
- .long 0 # idt base=0L
-
-gdt_48:
- .word 0x800 # gdt limit=2048, 256 GDT entries
- .word 512+gdt - start,0x9 # gdt base = 0X9xxxx
-
-msg1:
- .asciz "Setup.S\r\n"
-
- /* Pad setup to the proper size */
- .org (SETUPSECS*512)
-
+/*
+ * setup.s is responsible for getting the system data from the BIOS,
+ * and putting them into the appropriate places in system memory.
+ * both setup.s and system has been loaded by the bootblock.
+ *
+ * 1-Jan-96 Modified by Chris Brady for use as a boot/loader for memtest-86.
+ */
+
+#define __ASSEMBLY__
+#include "defs.h"
+
+.code16
+.section ".setup", "ax", @progbits
+.globl start
+start:
+# ok, the read went well
+# now we want to move to protected mode ...
+
+
+ cli # no interrupts allowed #
+ movb $0x80, %al # disable NMI for the bootup sequence
+ outb %al, $0x70
+
+# The system will move itself to its rightful place.
+
+ push %cs
+ pop %ds
+ lidt idt_48 - start # load idt with 0,0
+ lgdt gdt_48 - start # load gdt with whatever appropriate
+
+# that was painless, now we enable A20
+
+ call empty_8042
+
+ movb $0xD1, %al # command write
+ outb %al, $0x64
+ call empty_8042
+
+ movb $0xDF, %al # A20 on
+ outb %al, $0x60
+ call empty_8042
+
+/*
+ * Note that the short jump isn't strictly needed, althought there are
+ * reasons why it might be a good idea. It won't hurt in any case.
+ */
+ movw $0x0001, %ax # protected mode (PE) bit
+ lmsw %ax # This is it#
+ jmp flush_instr
+flush_instr:
+ movw $KERNEL_DS, %ax
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %ss
+ movw %ax, %fs
+ movw %ax, %gs
+
+data32 ljmp $KERNEL_CS, $(TSTLOAD <<4) # jmp offset 2000 of segment 0x10 (cs)
+
+/*
+ * This routine checks that the keyboard command queue is empty
+ * (after emptying the output buffers)
+ *
+ * No timeout is used - if this hangs there is something wrong with
+ * the machine, and we probably couldn't proceed anyway.
+ */
+empty_8042:
+ call delay
+ inb $0x64, %al # 8042 status port
+ testb $1, %al # output buffer?
+ jz no_output
+ call delay
+ inb $0x60, %al # read it
+ jmp empty_8042
+
+no_output:
+ testb $2, %al # is input buffer full?
+ jnz empty_8042 # yes - loop
+ ret
+#
+# Delay is needed after doing i/o
+#
+delay:
+ .word 0x00eb # jmp $+2
+ ret
+
+gdt:
+ .word 0,0,0,0 # dummy
+
+ .word 0,0,0,0 # unused
+
+ .word 0x7FFF # limit 128mb
+ .word 0x0000 # base address=0
+ .word 0x9A00 # code read/exec
+ .word 0x00C0 # granularity=4096, 386
+
+ .word 0x7FFF # limit 128mb
+ .word 0x0000 # base address=0
+ .word 0x9200 # data read/write
+ .word 0x00C0 # granularity=4096, 386
+
+idt_48:
+ .word 0 # idt limit=0
+ .long 0 # idt base=0L
+
+gdt_48:
+ .word 0x800 # gdt limit=2048, 256 GDT entries
+ .word 512+gdt - start,0x9 # gdt base = 0X9xxxx
+
+msg1:
+ .asciz "Setup.S\r\n"
+
+ /* Pad setup to the proper size */
+ .org (SETUPSECS*512)
+
diff --git a/stdin.h b/stdint.h
index e3a08e1..58d7519 100644
--- a/stdin.h
+++ b/stdint.h
@@ -49,4 +49,4 @@ typedef long long int intmax_t;
typedef unsigned long long uintmax_t;
-#endif /* I386_STDINT_H */ \ No newline at end of file
+#endif /* I386_STDINT_H */
diff --git a/test.c b/test.c
index f5075b8..1da798c 100644
--- a/test.c
+++ b/test.c
@@ -1,8 +1,14 @@
-/* test.c - MemTest-86 Version 3.0
+
+/* test.c - MemTest-86 Version 3.2
*
* Released under version 2 of the Gnu Public License.
* By Chris Brady, cbrady@sgi.com
+ * ----------------------------------------------------
+ * MemTest86+ V2.00 Specific code (GPL V2.0)
+ * 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>
@@ -111,8 +117,8 @@ void addr_tst1()
mask = mask << 1;
} while(mask);
}
- if (p + bank > p) {
- p += bank;
+ if (p + bank/4 > p) {
+ p += bank/4;
} else {
p = end;
}
@@ -244,6 +250,162 @@ void addr_tst2()
}
/*
+ * Test all of memory using a "half moving inversions" algorithm using random
+ * numbers and their complment as the data pattern. Since we are not able to
+ * produce random numbers in reverse order testing is only done in the forward
+ * direction.
+ */
+void movinvr()
+{
+ int i, j, done, seed1, seed2;
+ volatile ulong *pe;
+ volatile ulong *start,*end;
+ ulong num;
+
+ /* Initialize memory with initial sequence of random numbers. */
+ if (v->rdtsc) {
+ asm __volatile__ ("rdtsc":"=a" (seed1),"=d" (seed2));
+ } else {
+ seed1 = 521288629 + v->pass;
+ seed2 = 362436069 - v->pass;
+ }
+
+ /* Display the current seed */
+ hprint(LINE_PAT, COL_PAT, seed1);
+ rand_seed(seed1, seed2);
+ for (j=0; j<segs; j++) {
+ start = v->map[j].start;
+ end = v->map[j].end;
+ pe = start;
+ p = start;
+ done = 0;
+ do {
+ /* Check for overflow */
+ if (pe + SPINSZ > pe) {
+ pe += SPINSZ;
+ } else {
+ pe = end;
+ }
+ if (pe >= end) {
+ pe = end;
+ done++;
+ }
+ if (p == pe ) {
+ break;
+ }
+/* Original C code replaced with hand tuned assembly code */
+/*
+ for (; p < pe; p++) {
+ *p = rand();
+ }
+ */
+
+ 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)
+ : "eax"
+ );
+
+ do_tick();
+ BAILR
+ } while (!done);
+ }
+
+ /* Do moving inversions test. Check for initial pattern and then
+ * write the complement for each memory location. Test from bottom
+ * up and then from the top down. */
+ for (i=0; i<2; i++) {
+ rand_seed(seed1, seed2);
+ for (j=0; j<segs; j++) {
+ start = v->map[j].start;
+ end = v->map[j].end;
+ pe = start;
+ p = start;
+ done = 0;
+ do {
+ /* Check for overflow */
+ if (pe + SPINSZ > pe) {
+ pe += SPINSZ;
+ } else {
+ pe = end;
+ }
+ if (pe >= end) {
+ pe = end;
+ done++;
+ }
+ if (p == pe ) {
+ break;
+ }
+/* Original C code replaced with hand tuned assembly code */
+/*
+ for (; p < pe; p++) {
+ num = rand();
+ if (i) {
+ num = ~num;
+ }
+ if ((bad=*p) != num) {
+ error((ulong*)p, num, bad);
+ }
+ *p = ~num;
+ }
+*/
+ if (i) {
+ num = 0xffffffff;
+ } else {
+ num = 0;
+ }
+ asm __volatile__ (
+ "jmp L26\n\t" \
+
+ ".p2align 4,,7\n\t" \
+ "L26:\n\t" \
+ "call rand\n\t"
+ "xorl %%ebx,%%eax\n\t" \
+ "movl (%%edi),%%ecx\n\t" \
+ "cmpl %%eax,%%ecx\n\t" \
+ "jne L23\n\t" \
+ "L25:\n\t" \
+ "movl $0xffffffff,%%edx\n\t" \
+ "xorl %%edx,%%eax\n\t" \
+ "movl %%eax,(%%edi)\n\t" \
+ "addl $4,%%edi\n\t" \
+ "cmpl %%esi,%%edi\n\t" \
+ "jb L26\n\t" \
+ "jmp L24\n" \
+
+ "L23:\n\t" \
+ "pushl %%esi\n\t" \
+ "pushl %%ecx\n\t" \
+ "pushl %%eax\n\t" \
+ "pushl %%edi\n\t" \
+ "call error\n\t" \
+ "popl %%edi\n\t" \
+ "popl %%eax\n\t" \
+ "popl %%ecx\n\t" \
+ "popl %%esi\n\t" \
+ "jmp L25\n" \
+
+ "L24:\n\t" \
+ : "=D" (p)
+ : "D" (p), "S" (pe), "b" (num)
+ : "eax", "ecx", "edx"
+ );
+ do_tick();
+ BAILR
+ } while (!done);
+ }
+ }
+}
+
+/*
* Test all of memory using a "moving inversions" algorithm using the
* pattern in p1 and it's complement in p2.
*/
@@ -438,10 +600,10 @@ void movinv1(int iter, ulong p1, ulong p2)
void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off)
{
- int i, j, k=0, n = 0, done;
+ int i, j, k=0, done;
volatile ulong *pe;
volatile ulong *start, *end;
- ulong pat, p3;
+ ulong pat = 0, p3;
p3 = sval << 31;
@@ -616,13 +778,12 @@ 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
*/
- if (--k < 0) {
- k = 31;
- }
- for (pat = lb, n = 0; n < k; n++) {
- pat = pat << 1;
- pat |= sval;
- }
+ pat = lb;
+ if ( 0 != (k = (k-1) & 31) ) {
+ pat = (pat << k);
+ if ( sval )
+ pat |= ((sval << k) - 1);
+ }
k++;
for (j=segs-1; j>=0; j--) {
start = v->map[j].start;
@@ -731,9 +892,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++) {
@@ -901,8 +1062,11 @@ void modtst(int offset, int iter, ulong p1, ulong p2)
BAILR
} while (!done);
}
+ cprint(LINE_PAT, COL_PAT, " ");
}
+
+
/*
* Test memory using block moves
* Adapted from Robert Redelmeier's burnBX test
@@ -1120,6 +1284,7 @@ void block_move(int iter)
/*
* Test memory for bit fade.
*/
+#define STIME 5400
void bit_fade()
{
int j;
@@ -1127,6 +1292,9 @@ void bit_fade()
volatile ulong bad;
volatile ulong *start,*end;
+ test_ticks += (STIME * 2);
+ v->pass_ticks += (STIME * 2);
+
/* Do -1 and 0 patterns */
p1 = 0;
while (1) {
@@ -1147,7 +1315,7 @@ void bit_fade()
BAILR
}
/* Snooze for 90 minutes */
- sleep (5400, 0);
+ sleep (STIME, 0);
/* Make sure that nothing changed while sleeping */
for (j=0; j<segs; j++) {
@@ -1184,7 +1352,8 @@ 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
- * 810, 815 and 820 chipsets. It is possible that we will skip
+ dir
+ * 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) {
@@ -1201,7 +1370,7 @@ void error(ulong *adr, ulong good, ulong bad)
/* Don't display duplicate errors */
if ((ulong)adr == (ulong)v->eadr && xor == v->exor) {
print_err_counts();
- dprint(v->msg_line, 62, ++ecount, 5, 0);
+ dprint(v->msg_line, 66, ++ecount, 5, 0);
return;
}
print_err(adr, good, bad, xor);
@@ -1272,11 +1441,9 @@ void ad_err2(ulong *adr, ulong bad)
}
void print_hdr(void)
{
- static int header = -1;
- if (header == 1) {
+ if ((v->ecount)>1) {
return;
}
- header = 1;
cprint(LINE_HEADER, 0, "Tst Pass Failing Address Good Bad Err-Bits Count Chan");
cprint(LINE_HEADER+1, 0,"--- ---- ----------------------- -------- -------- -------- ----- ----");
}
@@ -1295,8 +1462,22 @@ static void update_err_counts(void)
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 */
+ 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)
@@ -1304,13 +1485,11 @@ static void common_err(ulong page, ulong offset)
ulong mb;
/* Check for keyboard input */
+ print_hdr();
check_input();
-
+ scroll();
print_err_counts();
- print_hdr();
-
- scroll();
mb = page >> 8;
dprint(v->msg_line, 0, v->test, 3, 0);
dprint(v->msg_line, 4, v->pass, 5, 0);
@@ -1428,8 +1607,10 @@ void do_tick(void)
ulong h, l, t;
/* FIXME only print serial error messages from the tick handler */
+ if (v->ecount) {
print_err_counts();
-
+ }
+
nticks++;
v->total_ticks++;
diff --git a/test.h b/test.h
index bdc9378..a09fb1f 100644
--- a/test.h
+++ b/test.h
@@ -1,13 +1,14 @@
-/* test.h - MemTest-86 Version 3.0
+/* test.h - MemTest-86 Version 3.2
*
* Released under version 2 of the Gnu Public License.
- * By Chris Brady, cbrady@sgi.com
+ * By Chris Brady
* ----------------------------------------------------
- * MemTest86+ V1.30 Specific code (GPL V2.0)
+ * MemTest86+ V2.00 Specific code (GPL V2.0)
* By Samuel DEMEULEMEESTER, sdemeule@memtest.org
* http://www.x86-secret.com - http://www.memtest.org
*/
+
#define E88 0x00
#define E801 0x04
#define E820NR 0x08 /* # entries in E820MAP */
@@ -39,8 +40,6 @@ struct mem_info_t {
typedef unsigned long ulong;
#define SPINSZ 0x800000
-#define DEFTESTS 7
-#define DEFTESTS2 11
#define MOD_SZ 20
#define BAILOUT if (bail) goto skip_test;
#define BAILR if (bail) return;
@@ -70,14 +69,13 @@ typedef unsigned long ulong;
#define COL_ERR 63
#define COL_ECC_ERR 72
#define LINE_HEADER 12
-#define LINE_SCROLL 14
+#define LINE_SCROLL 14
#define BAR_SIZE (78-COL_MID-9)
#define POP_W 30
-#define POP_H 13
-#define POP_X 16
-// #define POP_X (80-POP_W-2)/2
-#define POP_Y 10
+#define POP_H 15
+#define POP_X 16
+#define POP_Y 8
#define NULL 0
/* memspeed operations */
@@ -111,12 +109,15 @@ void xprint(int y,int x,ulong val);
void aprint(int y,int x,ulong page);
void dprint(int y,int x,ulong val,int len, int right);
void movinv1(int iter, ulong p1, ulong p2);
+void movinvr();
void movinv32(int iter, ulong p1, ulong lb, ulong mb, int sval, int off);
void modtst(int off, int iter, ulong p1, ulong p2);
void error(ulong* adr, ulong good, ulong bad);
void ad_err1(ulong *adr1, ulong *adr2, ulong good, ulong bad);
void ad_err2(ulong *adr, ulong bad);
void do_tick(void);
+void rand_seed(int seed1, int seed2);
+ulong rand();
void init(void);
struct eregs;
void inter(struct eregs *trap_regs);
@@ -128,6 +129,7 @@ void popup(void);
void popdown(void);
void popclear(void);
void get_config(void);
+void get_menu(void);
void get_printmode(void);
void addr_tst1(void);
void addr_tst2(void);
@@ -170,52 +172,32 @@ struct pair {
static inline void cache_off(void)
{
- asm(
- "pusha\n\t"
+ asm(
+ "push %eax\n\t"
"movl %cr0,%eax\n\t"
- "orl $0x40000000,%eax\n\t" /* Set CD */
- "andl $0x6FFFFFFF,%eax\n\t" /* Clear NW */
- "movl %eax,%cr0\n\t" /* Set CR0 */
- "wbinvd\n\t" /* Invalidate Cache */
- "movl $0x01, %eax\n\t" /* Put 1 in eax */
- "cpuid\n\t" /* cpuid */
- "andl $0x01000, %edx\n\t" /* MTRR available ? */
- "jz CB1\n\t" /* No, go to end */
- "movl $0x02FF, %ecx\n\t" /* Yes, disable it */
- "rdmsr\n\t"
- "andl $0xFFFFF3FF,%eax\n\t"
- "wrmsr\n\t"
+ "orl $0x40000000,%eax\n\t" /* Set CD */
+ "movl %eax,%cr0\n\t"
"wbinvd\n\t"
- "CB1:\n\t"
- "popa\n\t");
+ "pop %eax\n\t");
}
static inline void cache_on(void)
{
- asm(
- "pusha\n\t"
+ asm(
+ "push %eax\n\t"
"movl %cr0,%eax\n\t"
- "andl $0x9fffffff,%eax\n\t" /* Clear CD and NW */
- "movl %eax,%cr0\n\t"
- "movl $0x01, %eax\n\t" /* Put 1 in eax */
- "cpuid\n\t" /* cpuid */
- "andl $0x01000, %edx\n\t" /* MTRR available ? */
- "jz CB2\n\t" /* No, go to end */
- "movl $0x02FF, %ecx\n\t" /* Yes, enable it */
- "rdmsr\n\t"
- "orl $0x0C00,%eax\n\t"
- "wrmsr\n\t"
- "CB2:\n\t"
- "popa\n\t");
+ "andl $0x9fffffff,%eax\n\t" /* Clear CD and NW */
+ "movl %eax,%cr0\n\t"
+ "pop %eax\n\t");
}
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"
@@ -276,8 +258,6 @@ struct vars {
int ecount;
int ecc_ecount;
int msegs;
- int cache_flag;
- int xtst_flag;
int testsel;
int scroll_start;
int rdtsc;
@@ -286,7 +266,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;
@@ -296,7 +276,7 @@ struct vars {
ulong startl;
ulong snaph;
ulong snapl;
- ulong extclock;
+ ulong extclock;
int printmode;
int numpatn;
struct pair patn [BADRAM_MAXPATNS];