| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .. | ||
| README.md | ||
Early 80386 CPUs
Assembling a detailed and accurate history of the 80386, including a complete listing of all the "steppings" (revisions), when they were released, what "errata" (problems) each stepping suffered from, and which of those problems were fixed by a later stepping, seems virtually impossible at this late date.
I won't make the attempt here, either. I'm just going to throw together everything I know into one pile, as I begin adding 80386 support to PCjs.
Let's start with steppings (revision levels), then move on to errata, and finally undocumented and/or deprecated instructions.
Steppings
As the "INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986", section 10.1, explains:
The contents of EAX depend upon the results of the power-up self test. The self-test may be requested externally by assertion of BUSY# at the end of RESET. The EAX register holds zero if the 80386 passed the test. A nonzero value in EAX after self-test indicates that the particular 80386 unit is faulty. If the self-test is not requested, the contents of EAX after RESET is undefined.
DX holds a component identifier and revision number after RESET as Figure 10-1 illustrates. DH contains 3, which indicates an 80386 component. DL contains a unique identifier of the revision level.
But what "revision levels" did Intel actually use?
Based on information below (see the ill-fated XBTS instruction), it seems there were A0-B0 steppings. However, all we can really infer from that is the existence of A0 and B0 steppings. It doesn't tell us whether there were any intervening (eg, A1, A2) steppings, or what revision levels were used on reset.
I've read reports that A steppings had serious problems, like an inability to return to real mode (reminiscent of the 80286). By all accounts, no A-stepping 80386 CPUs were sold commercially, so we can more or less ignore them.
As for the B0 stepping, the October 15, 1991 issue of PC Magazine reported:
You can tell if you have a B0 or B1 Step level 386 by looking at the markings on the chip.
If it has the ID number S40336 or S40337 stamped on it, then it's a Step B0; if it's marked
with S40343, S40344, or S40362, it's a Step B1. Some B0 and B1 chips were marked B0 or B1
rather than with an ID number.
Unfortunately, this doesn't tell us what revision number an 80386-B0 reported.
Most of the information I have about the 80386 begins with the B1 stepping. From a December 17, 1986 document titled "80386-B1 STEPPING INFORMATION":
80386-B1 component identifier readable in DH after reset: 03H
80386-B1 revision identifier readable in DL after reset: 03H
At this time, B1 stepping parts are identified with one of the marks shown
below:
|
ii | ii
|
ii A80386-16 | ii A80386-20
ii S40344 | ii S40362
ii (FPO number) | ii (FPO number)
ii m c i '85 '86 | ii m c i '85 '86
|
----------------------------------- ----------------------------------
|
ii |
|
ii A80386 ES B1 |
ii |
ii |
ii m c i '85 '86 |
|
So, the B1 stepping set DL to 0x03 on reset. It also seems a safe bet that the revision number for a B0 stepping was 0x02. Does that mean the revision number for the A0 was 0x01? I can only guess.
The 80386 CPU on my Compaq DeskPro 386 "Version 2" System Board is labeled as:
A80386-16
S40344
L8260347
(m)(c)i '85 '86
The "S40344" indicates that it's a B1 stepping, although I'm not currently able to power it and run any tests.
According to OS/2 Museum proprietor Michal Necasek, the "L8260347" means:
[I]t was actually manufactured in mid-1988. It took me many years to realize how Intel marked the chips.
The initial 'L' (or whatever number/letter it is) can be ignored and the following 3 digits (826) are the
date code. The first is the last digit of the year.... The last two digits are the week of manufacture,
so week 26 of 1988. Many Intel CPUs actually have 2 or 3 date codes on them, probably related to when the
die was made, when the package was assembled, and when it was tested/binned and stamped. On your 386,
there might be another date code on the bottom side, but if there is, it's not going to be too far apart
from the one on the top and it's going to be slightly older.
Fortunately, my 80386-B1 CPU is also marked with a "ΣΣ" (double sigma), which is how Intel marked parts that tested safe for 32-bit multiplication. Some 80386 CPUs suffered from a manufacturing defect that could occasionally result in multiplication errors; defective parts that Intel caught were marked with "16 BIT S/W ONLY" instead of the double sigma.
The only other information I have about revision levels comes from a March 30, 1987 document titled "80386-C0 STEPPING INFORMATION":
80386-C0 component identifier readable in DH after reset: 03H
80386-C0 revision identifier readable in DL after reset: 04H
However, that document does not indicate how a 80386-C0 part was marked, and I've found very little other information on the C0 stepping; it may have been quickly superseded by the D0 stepping, which used revision identifier 0x05.
Errata
It's fair to say that the 80386 B1 stepping had a lot of problems. Although, for a CPU of significantly greater complexity than its predecessors, that doesn't seem terribly surprising.
From the aforementioned December 17, 1986 document, here's what the world knew about 80386-B1 problems at that time:
- Opcode Field Incorrect for FSAVE and FSTENV
- FSAVE, FRESTOR, FSTENV and FLDENV Anomolies [sic] with Paging
- Wraparound Coprocessor Operands
- IRET to TSS with Limit too Small
- Single-Stepping First Iteration of REP MOVS
- Task Switch to Virtual 8086 Mode Doesn't Update Prefetch Limit
- Wrong Register Size for String Instructions in Mixed 16/32-bit Addressing Systems
- FAR Jump Located Near Page Boundary in Virtual 8086 Mode Paged Systems
- Page Fault Error Code on Stack Not Reliable
- Certain I/O Addresses Incorrect when Paging is Enabled
- Wrong ECX Update by REP INS
- NMI Doesn't Always Bring Chip Out of Shutdown in Obscure Condition with Paging Enabled
- HOLD Input During Protected Mode Interlevel IRET when Paging is Enabled
- Protected Mode LSL Instruction Should not be Followed by PUSH/POP
- LSL/LAR/VERR/VERW. Instructions Malfunction with Null Selector
- "Not Present" LDT in VM86 Task Raises Wrong Exception
- Coprocessor Instructions Crossing Page/Segment Boundaries
- Double Page Faults Do Not Raise Double Fault Exception
An errata update dated March 26, 1987, produced internally by IBM rather than Intel, noted two additional issues:
- Maximum Sized Segments Need Alignment
- CR3/TRx Move Corrupts LIP (Linear Instruction Pointer)
As an aside, an 80386-C0 document dated March 30, 1987 lists none of the above errata, suggesting that the C0 stepping fixed all the above problems -- with the exception of #18, which was apparently reclassified from errata to "feature":
Double Page Faults Do Not Raise Double Fault Exception
Problem: If a second page fault occurs, while the processor is attempting to enter the service routine for the first, then the processor will invoke the page fault (exception 14) handler a second time, rather than the double fault (exception 8) handler. A subsequent fault, though, will lead to shutdown.
Workaround: No workaround is necessary in a working system.
On April 30, 1987, another errata update omitted #18, as well as the two new issues documented by IBM (which, like #18, Intel must have decided were not significant problems "in a working system"), and added the following:
- Breakpoints Malfunction after Reading CR3, TR6, or TR7
- Return Address Incorrect for Segment Limit Fault during FNINIT
On September 1, 1987, the final 80386-B1 errata update that I'm aware of continued to list previous errata (#1-#17), plus the two errata from April 30 (#18 and #19), along with the following new errata:
- VERR/VERW/LAR/LSL Instructions Malfunction with Bad Selector
- Coprocessor Malfunctions with Paging Enabled
This brought the total number of 80386-B1 errata to 21.
There was also a manufacturing problem that caused 32-bit multiplications to fail on some parts, which Intel publicly acknowledged in April 1987.
From the San Jose Mercury News, April 11, 1987:
INTEL DISCOVERS A BUG IN ITS NEW 80386 CHIP
Author(s): CHRISTOPHER H. SCHMITT AND JIM BARTIMO, Mercury News
Business Writers Date: April 11, 1987 Section: Business
Intel acknowledged Friday that a bug has cropped up in its new flagship microprocessor chip.
Microprocessors serve as the electronic brains of devices ranging from personal computers to
home appliances.
Intel said the bug in its 80386 microprocessor produces incorrect answers when the chip
performs certain mathematical operations. "When you multiply one 32-bit number by another
32-bit number, you get the error," said Intel spokesman Jim Jarrett. A 32-bit number is one
that utilizes the full data path of the chip.
However, operating system software that would let the chip fully use its 32-bit characteristics
is still being developed, so the problem shouldn't immediately affect personal computer users.
Microsoft Corp. of Redmond, Wash., has announced its intention to deliver in early 1988 a 32-bit
operating system known as OS/2.
Even when using the 32-bit capabilities of the chip, the possibility of an error is "rare,"
Jarrett said.
Spokesman Bruce LeBoss said not all of the 100,000 80386 chips Intel has produced so far are
affected, but he declined to elaborate. Intel is sticking with a previously announced estimate
that it will sell from 500,000 to 1 million 80386s this year.
To address the problem, Intel said it is notifying computer companies and other customers and
extending the chip's warranty from one to two years. Anticipating that it will replace some
80386s already in the field, the company charged off an undisclosed amount to cover the
expense. One analyst estimated the charge at about $7 million.
Intel will test the chips it has already sold to determine which ones have the bug. But it will
not replace the chips for free. Instead, Intel will work with customers on an upgrade program.
Intel said it will be up to individual computer makers to work with consumers who have
purchased machines using the 80386 chip.
The problem may be most acutely felt by Houston-based Compaq Computer, which so far has
been the biggest producer of 80386-based computers. Compaq said it will disclose by early
next week plans for coping with the possibility that versions of its Deskpro 386 computer model
contain flawed chips.
The bug may cause some shortages of the 80386. The problem won't be fixed until July, so the
only guaranteed chips are those that have already been produced and have passed Intel's test.
"Everybody wants perfect chips and we'll have fewer of those to go around for a while," Jarrett
said. Analysts indicated that in the long run, the bug is more likely to be embarrassing than
anything else. "You have a complex chip here," said Daniel Klesken, an analyst for Montgomery
Securities in San Francisco. "One should not be surprised that (problems) happen occasionally."
The problem affected the B1 stepping; it's unknown whether other steppings were affected as well.
What follows is some additional information about early 80386 processors from various online sources.
Excerpt from "CPU Identification by the Windows Kernel", by Geoff Chappell:
80386
Finer identification of 80386 processors is largely academic. Whatever the model or stepping, the 80386 processor is unsupported since [Windows NT] version 4.0, and soon causes the bug check UNSUPPORTED_PROCESSOR (0x5D), though not without the kernel having worked its way through more tests for defects to identify models and steppings. For any 80386 processor that passes all tests, the model and stepping leap ahead to 3 and 1. Version 3.51, which was the last to support the 80386 (and only then in a single-processor configuration), rejects any 80386 that does not pass all these tests.
Family Model Stepping Test
------ ----- -------- ----
3 0 0 32-bit MUL not reliably correct
3 1 0 supports XBTS instruction
3 1 1 set TF bit (0x0100) in EFLAGS causes Debug exception (interrupt 0x01) only at completion of REP MOVSB
3 3 1
The particular multiplication that distinguishes model 0 is of 0x81 by 0x0417A000. This same test was used by Microsoft at least as far back as Windows 3.10 Enhanced Mode, to advise:
The Intel 80386 processor in this computer does not reliably execute 32-bit
multiply operations. Windows usually works correctly on computers with this
problem but may occasionally fail. You may want to replace your 80386 processor.
Press any key to continue...
The instruction whose support is tested for model 1 stepping 0 has opcode bytes 0x0F 0xA6 followed by a Mod R/M byte and by whatever more this byte indicates is needed for the operand. This opcode is disassembled as XBTS by Microsoft’s DUMPBIN utility from Visual C++, and has been since at least the mid-90s. However, the same opcode was apparently reused for the CMPXCHG instruction on some 80486 processors. The confusion seems to have left a lasting mark: Intel’s opcode charts leave 0x0F 0xA6 unassigned even now. The specific test performed by the Windows kernel is to load EAX and EDX with zero and ECX with 0xFF00. If executing XBTS ECX,EDX does not cause an Invalid Opcode exception and clears ecx to zero (which CMPXCHG ECX,EDX would not), then XBTS is deemed to be supported and the processor is model 1 stepping 0. This case of 80386 processor also was known to Windows 3.10 Enhanced Mode, and was rejected as fatal:
Windows may not run correctly with the 80386 processor in this computer.
Upgrade your 80386 processor or start Windows in standard mode by typing
WIN /s at the MS-DOS prompt.
When string instructions such as MOVSB are repeated because of a REP prefix, each operation is ordinarily interruptible. As Intel says (for REP in the Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 2B: Instruction Set Reference N-Z), this “allows long string operations to proceed without affecting the interrupt response time of the system.” It ordinarily applies also to the Debug exception, such as raised by the processor at the end of executing an instruction for which the TF bit is set in the EFLAGS when the instruction started. Programmers may have noticed this in the real world of assembly-language debugging. If the debugger actually does implement its trace command as a trace, as opposed to setting an INT 3 breakpoint where the instruction is calculated to end, then a two-byte REP MOVSB may take many keystrokes to trace through! That model 1 stepping 1 traces through a REP MOVSB without interruption may be helpful when debugging, but it is surely a defect.
More examples of problems with early 80386 CPUs are posted in "The Old New Thing" blog. Here are some highlights from "My, what strange NOPs you have!", by Raymond Chen:
[I]f the instruction following a string operation (such as movs) uses opposite-sized addresses from that in the string instruction (for example, if you performed a movs es:[edi], ds:[esi] followed by a mov ax, [bx]) or if the following instruction accessed an opposite-sized stack (for example, if you performed a movs es:[edi], ds:[esi] on a 16-bit stack, and the next instruction was a push), then the movs instruction would not operate correctly.
...
[T]here was one bug that manifested itself in incorrect instruction decoding if a conditional branch instruction had just the right sequence of taken/not-taken history, and the branch instruction was followed immediately by a selector load, and one of the first two instructions at the destination of the branch was itself a jump, call, or return. The easy workaround: Insert a NOP between the branch and the selector load.
...
[T]he B1 stepping did not support virtual memory in the first 64KB of memory. Fine, don't use virtual memory there.
...
If virtual memory was enabled, if a certain race condition was encountered inside the hardware prefetch, and if you executed a floating point coprocessor instruction that accessed memory at an address in the range 0x800000F8 through 0x800000FF, then the CPU would end up reading from addresses 0x000000F8 through 0x0000000FF instead. This one was easy to work around: Never allocate valid memory at 0x80000xxx.
Instructions
Regarding Opcode XBTS:
Opcode XBTS
CPU: 80386 step A0-B0 only
Type of Instruction: User
Instruction: XBTS dest,base,bitoffset,len
Description:
Write bit string length bits from bitfield, defined by
and bitsoffset from this base to start of
the field to read. String read from this start field bit to
higher memory addresses or register bits.
And after it string placed to operand, lowest bit of
register or memory to bit 0 of .
Note: Use SHLD/SHRD instructions for extract bits strings.
On 80386 steps B1+ this opcode generation INT 6,
and on some of 486 other instruction replace this
instruction opcode.
Flags Affected: None
CPU mode: RM,PM,VM
+++++++++++++++++++++++
Physical Form: XBTS r16,r/m16,AX,CL
XBTS r32,r/m32,EAX,CL
COP (Code of Operation) : 0FH A6H Postbyte
Clocks: XBTS
80386: 6/13
@jeffpar
February 23, 2015