I recently came across hints suggesting that in the 1987 timeframe, Microsoft contemplated the use of the 386 LOADALL instruction in OS/2. As far as I know, no released version of OS/2 (including the SDK betas) utilized the 386 LOADALL.
But it got me wondering. Did anyone use it in commercial software? And which 386 CPUs support LOADALL?
To be clear, the 386 LOADALL instruction is very similar to its infamous 286 sibling but it’s not compatible (even the opcode is different). On the 286, LOADALL could accomplish things that were not otherwise possible, but on the 386 there is little that LOADALL can do that can’t be done using documented interfaces (and that retail software would want to do).
Robert Collins has an excellent writeup on both LOADALL flavors with lots of details and test programs. The article contains the following rather interesting statement: “Very few people at Intel will acknowledge that LOADALL even exists in the 80386 mask. The official Intel line is that, due to U.S. Military pressure, LOADALL was removed from the 80386 mask over a year ago. However, running the program in Listing-2 demonstrates that LOADALL is alive, well, and still available on the latest stepping of the 80386.”
So LOADALL was supposedly removed from 386s… except it maybe wasn’t. And it was top secret? Further searching revealed a surprising fact: The existence of 386 LOADALL instruction became a matter of public record no later than September 1, 1992 when Compaq’s U.S patent 5,144,551 was published.
The patent contains the following text: “In 1988, Intel announced that it was discontinuing support for the 80386 LOADALL instruction and was going to remove it from the 80386 instruction set. This 80386 instruction was used to emulate the 80286 LOADALL instruction. Like the 80286 LOADALL instruction the 386 LOADALL was undocumented. However, it has not been widely used in application or operating system software.”
Presumably the 1988 Intel announcement wasn’t exactly public. The 1992 patent certainly was. But the obvious questions are: Why would anyone want to use 386 LOADALL, and what CPUs support it?
The answer to the first question can largely be found here. Some versions of OS/2 1.0 and 1.1 unconditionally executed the 286 LOADALL instruction in real mode on AT compatible system. To support OS/2, such systems had to emulate 286 LOADALL in the BIOS. Using 386 LOADALL for the purpose seems obvious, as noted in the quote from the patent. What’s more, a BIOS for a 386 system does not typically worry about non-386 CPUs.
As to the other question, there is no reason to doubt that any older 386s didn’t support LOADALL. But what about the newer ones? Robert Collins claims that “latest steppings” of the 386 (as of 1991?) still support LOADALL.
386 LOADALL Support
The OS/2 Museum tested a selection of Intel and AMD 386DX processors (using Mr. Collins’ utility) and found that indeed, every CPU tested supported LOADALL. That included old B1-step 386s from 1987, various AMD 386s (25/33/40 MHz parts), and it also covered Intel 386s manufactured in 1998 (that’s 98, not 88). 386SX parts were not tested but—lacking evidence to the contrary—are assumed to support LOADALL.
The C&T Super386 also implements LOADALL. It does not quite pass the tests devised by Mr. Collins, but it very likely does enough to support the emulation of 286 LOADALL via 386 LOADALL.
Intel 486 and newer CPUs do not support LOADALL (tested on a old B-step 486 SX308 as well as several newer chips). Perhaps Intel’s 1988 announcement about removing the LOADALL instruction referred to the i486 (1989) and not actual 386 processors. For system software writers it didn’t matter if LOADALL was removed from 386s or not supported in 486s, they just couldn’t use it.
Cyrix 386 upgrades (486DLC) likewise do not support LOADALL. Since these were sold as upgrades for 386 boards, it is more or less a given that the 386 LOADALL instruction was not used in any kind of volume software.
On the other hand, the IBM 486DLC aka Blue Lightning (and presumably 386/486SLC) does support LOADALL, and passes all of the torture tests with flying colors. That’s a proof as good as any that IBM’s clock-tripled DLC is indeed the world’s fastest 386. This was tested on a clock-tripled part.
So far the only 486-socket processor found to support LOADALL is the UMC U5S. Like the Super386, the U5S does not behave quite like a 386 but probably does enough to support typical usage scenarios. Why UMC thought it was worth implementing at all is a question that will probably never be answered.
Compaq Patent
Compaq’s patent deals with emulating the 286 LOADALL instruction on 386 compatible processors without utilizing 386 LOADALL. It works by switching to protected mode, loading appropriate descriptor values, and switching back to real mode. It is an improvement on the method reportedly suggested by Intel, probably in a confidential document. The LOADALL emulation is not perfect but it is sufficient for all practical purposes.
It should be noted that the original suggestion to use 386 LOADALL to emulate 286 LOADALL also came from Intel in an earlier confidential document (undated).
The whole mess is a consequence of a 286 design defect—the inability to switch from protected back to real mode. It’s something the 286 designers probably considered a feature, but reality disagreed.
Using the 386 LOADALL you could do real mode paging – normally if you try to set the PG bit of CR0 when in real mode you would get an exception but you could set this illegal mode via 386 LOADALL and it actually worked, CR3 would be used as the page directory address as expected. Now this really couldn’t be used in production software since there was no guarantee it would work on non-Intel 386s and of course it didn’t work on 486s or later. Also it was unclear as to how stable that configuration was but it did seem to work.
One problem would be processing page faults.
The utility Robert Collins wrote actually tests paged real mode, among other things.
Real mode paging was noticeably faster than standard protected mode paging. Besides better emulation of the 286 LOADALL, the 386 LOADALL wasn’t really useful at all. I’m guessing both LOADALL opcodes were originally intended for ICE usage.
Did you test the embedded versions of the 386 (80376/80386EX) for LOADALL? Those would be more likely candidates for Pentagon concern. The introduction of the 80376 also seems to match the timeline of announcements.
Robert Collins specifically said they were for ICE usage.
I don’t have any, or at least not in a form where I could run tests on them (either just chips or built into SCSI controllers and such). If anyone has the hardware, the LOADALL test from Mr. Collins is easily available.
I guess some BIOSes could use 386 LOADALL to simulate 286 LOADALL instruction when int 6 exception being hit.
I suppose some obscure DOS Extender could use it as well. But this is just a wild guess. Another possible usage is some obscure copy protection scheme. Debugging code with LOADALL instruction without proper knowledge of its internals wasn’t fun.
Secondly the “Undocumented PC” mentions some AMD and IBM 486 CPUs supporting 386 LOADALL. Maybe the book is wrong but it would be interesting to confirm it.
As for ICE support don’t forget ICEBP instruction.
AFAIK on the AMD and IBM cases I think they basically enabled ICE mode and called it “SMM”, disguising 386 LOADALL under a different name in the documentation.
The IBM 486 CPUs mentioned by Undocumented PC were the 486SLC/DLC processors (386 core). LOADALL is definitely there. The AMDs were some early power managed CPUs but LOADALL seems to have been only supported from within SMM, not user code. Basically it was RSM by another name.
I have never seen any 386 BIOS or any production software for that matter use the 386 LOADALL. I’m guessing it was one of those curiosities that was never actually used outside of Intel.
Why exactly would the military care so much about the presence of the LOADALL instruction that they even convinced Intel to remove it? Because of the added complexity?
Again this is just my guess but I can come up with 2 reasons:
1) it allowed you to break some of protected mode features – look above for dosfan explanation
2) in case of software/hardware error this could lead to unexpected results. Normally the system should hang but you have to remember about all the Murphy’s laws.
But I would love to hear the real explanation.
I bet Intel didn’t need much convincing. LOADALL exposes too many implementation details because it does not check the inputs at all. Comparing with VT-x is instructive since VMRUN/VMRESUME instructions perform a rather long list of checks on the guest state to enforce architectural rules. Basically if Intel says that (for example) paging does not work in real mode, it’s in their best interest to enforce that because if they don’t, they might be forced to support such things in perpetuity. Another possible concern could be that LOADALL makes it easier for cloners to reverse engineer how the CPU really works. Again not something Intel wants.
Regarding dosfan’s comment that the 386 LOADALL was not likely used outside of Intel, it was at least used by Compaq. I have a DeskPro 386 ROM dated Jan 28, 1988 that uses the 386 LOADALL here to emulate the 286 LOADALL, as their patent suggests.
Excellent. The available information strongly suggested that some 386 BIOSes used LOADALL, but none of my 386 boards (various AMI BIOS versions) do. Either they’re too new, starting circa 1989, or AMI never used it. Good to know that Compaq was one such user.
I don’t believe IBM emulated the 286 LOADALL it in their PS/2 386s (but will have to double check my Model 80 BIOS dumps).
So someone did actually use it. Do you know if the original Compaq Deskpro 386 BIOS from 1986 used it or is this the first use of it ?
I don’t know, because I’ve not yet found any earlier Compaq DeskPro 386 ROMs. But I would love to find some, because those would have been what we (I and my coworkers) were actually using in early 1987.
Pingback: 386 LOADALL usage | corexor
There is one possible candidate for a 486 with LOADALL: the AMD 486DXLV*. The Undocumented PC by Van Gilluwe points out that the AMD RES4 instruction is functionally identical to LOADALL and uses the same opcode. The book also devotes a bit of time showing the similarities between LOADALL and various other RESUME instructions. LOADALL never really left; it just became harder to call and with the Pentium finally got some validation checking. (In the second edition of the book, relevant pages are 86, 89, and 117-118.)
My apologies for the delay in finding this.
* Also referred to as 486DXLC which is nomenclature used by AMD in Patent US6202174.
I’m familiar with the text. The catch is that these systems supposedly only allowed LOADALL within SMM. That didn’t affect what it did, but it completely changed how it could (or rather couldn’t) be used.
Yes, I think Intel changed LOADALL to check for ICE mode in the 486, and then the aforementioned processors used ICE mode as “SMM” resulting in lawsuits from Intel.
AMD SVM actually allows paged real mode BTW. The manual claims that “The behavior of running a guest in paged real mode without intercepting page faults to the VMM is
undefined.”
“Examination of the virtual machine monitor code in Windows/386 2.1 shows it uses both the 286 and the even less known 386 variant [of LOADALL].”
The text above is a quote from the Wikipedia page on LOADALL. Is Wikipedia wrong on this one? AFAIK, Windows/386 2.1 runs quite well on 486, how would this be possible if it uses 386 LOADALL?
That is an excellent question. Since this is an unsourced claim on Wikipedia, the default assumption must be that it’s utter nonsense. Wikipedia is wrong on many things.
I couldn’t find any mention of this anywhere. I couldn’t find any mention of Windows/386 using 286 LOADALL either, and that sounds like outright BS because the VMM is designed to run on CPUs which do not implement 286 LOADALL.
It’s 286 LOADALL, but it’s still interesting: http://www.vcfed.org/forum/showthread.php?70386-I-found-the-SAVEALL-opcode
Basically, there’s an undocumented opcode that saves all the internal registers where LOADALL expects them; it seems both were for ICEs, but LOADALL was still useful without one. STOREALL seems to hang without without one, but using the F1 prefix (ICEBP on 386) lets it work in the normal address space.
Thread seems to cover it, but it might be interesting to read more about…