
                           [1]logo[2]ASUS[3]eMail
                        Please [4]visit my sponsor.
   ______________________________________________________________________
                                      
                          microcode update feature
        1996-1997 by Christian Ludloff. Last [5]updated on Tuesday,
                          22-Jul-97 02:22:55 EDT.
    The entire sandpile.org website can be [6]searched for keywords, or
                                for phrases.
    Please, use your browsers [[7]BACK] button or shortcut key to go to
                             the previous page!
   ______________________________________________________________________
                                      
                                Introduction
                                      
   This page does shed light on the so-called microcode update feature,
   which is supported by many modern microprocessors. First, some reasons
   why this page does exist will be explained. Then a brief [8]overview
   on what microcode is, what it is used for, and why it is useful to be
   able to update it, will be given. Also, the page will look back at the
   [9]history, and the [10]roots of the feature, describe some
   [11]variations, and -- last but not least -- it will give an outlook
   from [12]today into the [13]future, discussing a few interesting
   [14]questions.
   This material has been collected over the past few months, whereas
   some of the sources can be traced back until as early as 1992. One
   reason, why this page does exist, was a short [15]article, which
   appeared in the [16]EE Times on June 30th 1997, written by Alexander
   Wolfe. In this article he claimed that "...Intel plans to make a
   high-profile public announcement [in July 1997] that it has developed
   a technology to quickly fix bugs that crop up in its microprocessors
   without having to recall the chips."
   To set the record straight from the beginning -- [17]Intel did neither
   invent, nor did they patent [as of writing this] such a technology.
   The truth is, that they are just another vendor, who is using it, and
   that [as of writing this] nobody has a patent on this technology. A
   quick research, using a powerful [18]patent database, did not show any
   issued patents, which would explicitly describe the microcode update
   feature, but rather it resulted in various microcode related patents.
   Another fact is, that Intel didn't just recently add such technology
   to their processors. It has been around since late 1995, when Intel
   had introduced their PentiumPro processor. Just by reading the
   PentiumPro processor BIOS writer's guide, v2.01 dated February 1996,
   one can confirm that the feature does exist, although it is named
   "BIOS update feature". (Click [19]here for a huge list of manuals.)
   The only problem is, that -- except for how updates are loaded -- no
   information, and no updates are available from Intel.
   To make something else clear from the beginning -- this page is not
   intended to put Intel under fire, or continue the [20]Appendix H saga
   (of Intel, [21]hiding useful information), as it might seem to some
   readers after the above two paragraphs. Instead -- since no other
   resource on the Internet has done this so far -- it is intended to
   give an informative background, so that a reader can draw his/her own
   conclusions. Now, that this is clear, a short explanation of what
   microcode is, should follow.
   
                                  Overview
                                      
   Although other devices may contain microcode too, only microprocessors
   will be looked at here. These microprocessors -- especially 80x86
   parts -- often use two main methods, of how they implement
   instructions. Simple instructions are hard-wired, which allows a very
   high performance. Complex instructions are described by some sort of a
   small program, which controls the microprocessor units. This program's
   code is refered to as microcode, which is stored inside the chip.
   Although writing microcode is similar to other programming, it is much
   more an art, and requires a very deep knowledge about the target
   microprocessor. Thus, only a few people practice this art, and usually
   they stick with their jobs for a long time. Often writing microcode
   resembles programming a parallel computer, as each of the microcode
   instructions is supposed to make use of the microprocessor's units as
   effectively, as possible. For details just talk to one of the
   microcoders.  :-)
   When a microprocessor design is finalized, the microcode is translated
   into a binary data block, which is then hard-wired into the chip. If
   such a chip does execute a complex instruction, it will look up the
   microcode, and execute it, to control its units. The difference to the
   hard-wired and simple instructions is, that a hard-wired microcode is
   generated based on some sort of a program. By contrast, eg. some
   simple adding functionality is based on standard [22]VHDL libraries.
   Following the above explanation it becomes clear, that microcode may
   contain bugs. While manufacturing bugs, which would cause that the
   wrong binary data seems to be stored in the microcode storage array,
   can be detected by checksums, other bugs which come into life because
   of an error during the final translation, and of course those bugs
   which come from mistakes, the microcoder made, are not only much more
   common, but also much harder to detect, and much more difficult to
   avoid.
   That makes it clear, why it would be nice to be able to correct such
   bugs with an easy-to-use, simple, and not too expensive method. The
   microcode update feature is, what gets used to fulfill these needs.
   Instead of having microcode in a read-only storage array (the
   historical microcode ROM), microprocessors allow to modify the
   microcode. Either the entire microcode gets loaded during the startup
   process, or it can be loaded later and override all, or parts of the
   built-in hard-wired microcode.
   A nice side effect of being able to update microcode is, that you may
   be able to enhance the existing functionality, optimize it, or even
   add completely new functionality, as permitted by the existing
   microprocessor hardware. Another short introduction to microcode and
   microcode updates, is given by [23]IBM. They provide this feature, and
   updates, for their RS/6000 platform. Hey, Intel & Co -- let IBM be a
   good example for how this business does work!
   
                                  History
                                      
   Although the microcode update feature is probably older than that,
   some of the earliest references to it, can be found in documents from
   [24]DEC, all dated 1992. The [25]first one is about the Alpha
   microprocessor ("A 200 MHz 64bit dual issue CMOS microprocessor", 217
   KB), the [26]second one is about the roots of [27]FX!32 ("Binary
   translation", 100 KB), and the [28]third one is about the Alpha
   development ("Using simulation to develop and port software", 76 KB).
   The first document describes on page 7, how the Alpha microprocessor
   loads some block of binary data from a read-only memory into its
   instruction cache, before it does begin to execute instructions.
   
   "When the chip is reset, the first action is to read from a serial
   read-only memory (SROM) into the I-cache via a private three-wire
   port. The CPU is then enabled and the program counter (PC) is forced
   to 0. [...] This initial set of instructions is used to write the bus
   control registers inside the CPU chip to set the cache timing and to
   test the chip and module from the CPU out."
   
   The second document claims on page 2, that RISC microprocessors do not
   have any microcode. As their name implies, they use some reduced
   instruction set, which is simple, and can be hard-wired for
   performance reasons.
   
   "[...] since RISC architectures do not have a microcoded hardware
   layer underlying the visible machine architecture."
   
   The third document describes on page 2, how the Alpha microprocessor
   was simulated on a VAX 8800 machine, and how additional VAX microcode
   was used to speed up this simulation. It mentions updateable VAX
   microcode.
   
   "The [...] microcode occupies 93 percent of the total 1,024 words of
   the user-writable control store."
   
   With that, DEC might be able to claim to be one of the first
   companies, to have used the microcode update feature technology. This
   may even put new oil into the flames of the fire, caused by the recent
   lawsuit, DEC has filed against Intel, claiming patent infringements.
   (An interesting [29]article (137 KB) about that lawsuit has been
   published by the [30]Microprocessor Report in June 1997.) But that is
   another story, which doesn't really belong here.
   
                                   Roots
                                      
   Another player has been NexGen, a small 80x86 company, which has
   [31]merged with [32]AMD in 1995. NexGen introduced their Nx586
   microprocessor in 1994 as a competitor to Intel's Pentium. Although
   the chip was neither pin, nor fully binary compatible, it offered
   about equal performance, for less money. Due to its proprietary pinout
   only two boards, one VLB and one PCI, both supplied by NexGen, were
   available -- which at that time helped to doom this part from the
   beginning.
   Since NexGen had started to design their CPU as an 80386 competitor,
   but faced delays, the final outcome was a chip, running as fast as a
   Pentium, but looking like an 80386 to software. In example the Nx586
   did not support the alignment checking feature, which allows to cause
   an exception (AC#) on unaligned data. This feature is enabled by
   setting the AC bit in the [33]EFLAGS register (after the AM bit in the
   Control Register [34]CR0 has been set). Now Intel comes in again...
   Because they provided a CPU detection algorithm, which checked for an
   80486 microprocessor by trying to toggle the EFLAGS.AC bit, most
   programs did follow the Intel algorithm, and thus identified the Nx586
   as an 80386 microprocessor. Not only does the algorithm violate
   Intel's own rule, not to rely on any undefined bits -- and for
   pre-80486 microprocessors EFLAGS.AC is not defined --, but also many
   programs did refuse to work with the Nx586 due to that stupid mistake.
   Always be paranoid, Intel!  :-)
   Another problem was, that the Pentium had introduced a new
   instruction, [35]CPUID, which assists software in a simple
   identification of the microprocessor. Programs started to use CPUID,
   and failed on the Nx586, again. But luckily NexGen had implemented the
   soon to be very useful microcode update feature into their Nx586! That
   way they were able to fix several problems which came from bad CPU
   detection algorithms. (Read [36]here for one of the better ones.)
   From AMD's website you can [37]download toolboxes for the NexGen Nx586
   VLB, or PCI board. These toolboxes contains four interesting little
   programs: IDON, IDOFF, EXTON, and EXTOFF. To see what these programs
   do, check these dis-assembly listings:
   
   IDON.COM   IDOFF.COM

0000:   BE0EB0          mov si,B00E
0003:   B003            mov al,03
0005:   B44C            mov ah,4C
0007:   0F55            ???

0000:   BE0EB0          mov si,B00E
0003:   B004            mov al,04
0005:   B44C            mov ah,4C
0007:   0F55            ???

   EXTON.EXE   EXTOFF.EXE

0212:   B80400          mov ax,0004
0215:   8ED8            mov ds,ax
0217:   8EC0            mov es,ax
0219:   BE00B0          mov si,B000
021C:   0F55            ???
021E:   66C1EA10        shr edx,10
0222:   80FA33          cmp dl,33
0225:   7515            jne wrong_BIOS
0227:   80FE77          cmp dh,77
022A:   7210            jb  wrong_BIOS
022C:   80FE7A          cmp dh,7A
022F:   770B            ja  wrong_BIOS
0231:   B005            mov al,05
0233:   B101            mov cl,01
0235:   BE0EB0          mov si,B00E
0238:   0F55            ???

0212:   B80400          mov ax,0004
0215:   8ED8            mov ds,ax
0217:   8EC0            mov es,ax
0219:   BE00B0          mov si,B000
021C:   0F55            ???
021E:   66C1EA10        shr edx,10
0222:   80FA33          cmp dl,33
0225:   7515            jne wrong_BIOS
0227:   80FE77          cmp dh,77
022A:   7210            jb  wrong_BIOS
022C:   80FE7A          cmp dh,7A
022F:   770B            ja  wrong_BIOS
0231:   B005            mov al,05
0233:   B100            mov cl,00
0235:   BE0EB0          mov si,B00E
0238:   0F55            ???

   notes: These are only fragments. Reserved opcodes are marked red. Any
   differences between the files are marked with bold text.
   
   The opcode 0Fh 55h is reserved. The 2-byte opcode [38]map shows, that
   even todays MMX instructions still make no use of this particular
   opcode. So NexGen's choice of a "special opcode" was a lucky choice.
   Since no further documentation about this opcode is available, one
   must guess, what this opcode could stand for. A very hot guess is of
   course, that it does affect the way, the Nx586 works, and behaves. In
   addition, rumors claim, that it could be part of some sort of a
   microcode update feature.
   These rumors, combined with the fact, that detecting the external
   cache size in a NexGen Nx586-based system never returns a 100%
   reliable result, lead to some very interesting conclusion: The Nx586
   is capable of microcode updates, and it does store the necessary data
   in a write protected portion of its external L2 cache. You may ask
   now, why the slow L2 cache would be used for that, rather than the
   much faster L1 cache. Well, there is an explanation.
   First of all the L1 cache is pretty small. Using a larger portion of
   it to hold the microcode update would dramatically decrease the
   overall performance. Second, the Nx586 did include a proprietary L2
   cache controller, which was one of the reasons for its incompatible
   pinout. This provided the Nx586 with a very fast interface to its
   external L2 cache. And third, only NexGen supplied the motherboards
   for the Nx586, as mentioned earlier. Both available models always
   contained 256 KB of L2 cache.
   With these facts, and the knowledge that most of the microcode update
   would not be used too often, NexGen probably made the good decision,
   to store some sort of a microcode update in a write protected portion
   of the external L2 cache. And the 0Fh 55h opcode was part of the
   control mechanism for it. Depending on register values, the processor
   executed certain functions. As it can be seen above, one function
   returns the BIOS version, while others control the microprocessor
   behavior (EFLAGS.AC, EFLAGS.ID, and CPUID).
   Since NexGen never provided an in-circuit emulation (ICE) tool for the
   Nx586, nor a logic analyzer for its proprietary bus, and since the
   Nx586 died out a while ago, further research remains to those, who
   still are interested in more details. Maybe some of all these former
   NexGen workers, which now build microprocessors for AMD, are in a
   position, to release the missing information. Or is anyone really
   concerned, that this is still vital information? Come on...
   
                                 Variations
                                      
   Another 80x86 microprocessor, known to support some microcode
   update-like feature, is the 6x86 processor, designed by [39]Cyrix, and
   manufactured by [40]IBM. Once this microprocessor faced a totally
   different problem than the Nx586, which may lead to trouble with any
   Intel clone -- it just was too fast. In particular, the LOOP
   instruction executes in only one clock cycle on the 6x86, while eg. a
   Pentium takes 5 or 6 clocks. This started to cause problems with badly
   designed programs.
   These programs used LOOP instruction for delay loops, and thus became
   useless when running on the 6x86 microprocessor. Since the 6x86 market
   share was not big enough to have the programs fixed -- the
   [41]well-known problem of older 6x86s with WinNT 4.0 and the writeback
   caching made that pretty clear, didn't it? -- Cyrix and IBM had to
   come up with some other solution. Luckily, the 6x86 did include quite
   some (undocumented) feature control through CCRs, and so a workaround
   was born: [42]PIPELOOP.EXE (4 KB).
   Instead of a long dis-assembly listing, pseudo-code is given below. It
   is assumed, that the reader is familiar with the CCRs, and their
   usage. If not, then all the required details can be found [43]here.
   
   PIPELOOP.EXE (slowed)   PIPELOOP.EXE (normal)

CCR3.MAPEN=0001b
DBR0.bit7=0
DBR1=B8h
DBR2=7Fh
DBR3=00h
DOR=E2h (opcode for LOOP)
CCR3.MAPEN=0000b

CCR3.MAPEN=0001b
DBR1=00h
DBR2=00h
DBR3=00h
DOR=00h (cleared opcode)
CCR3.MAPEN=0000b

   notes: Accessing CCR3.MAPEN enables and disables access to the full
   CCR range.
   
   While DOR gets loaded with the first byte of the LOOP instruction
   opcode ([44]E2h), DBR1..3 get loaded with some sort of control data.
   Whenever the LOOP instruction is executed, this control information
   ensures a slowdown, probably by partially, or fully serializing the
   6x86 microprocessor. Later versions of the 6x86 include a bit,
   CCR5.SLOP, which has the same effect as the above sequences: it does
   slow down the LOOP instruction (when set).
   Although the 6x86 microprocessor probably uses a hard-wired LOOP
   instruction, rather than a microcoded one, this example makes clear,
   why a microcode update feature is very useful, and where its
   limitations lie. If, in example, a basic adding functionality has been
   hard-wired, containing a bug, then nothing but a new mask revision
   would fix the problem. But for many other problems a microcode update
   feature, combined with other control accessibility to the core, can
   help to fix problems without chip exchanges.
   
                                   Today
                                      
   After the above explanations, it should be clear, that Intel hasn't
   invented the microcode update feature. But what about the claim, that
   the feature has been added to the Intel microprocessors just recently?
   To answer that question, one must remember the PentiumPro BIOS
   writer's guide, mentioned earlier. It contains technical information,
   describing Intel's implementation of the microcode update feature, and
   it is dated early 1996. Doesn't that time stamp alone cry out "not
   recently"?
   As described in chapter 8 of the PentiumPro BIOS writer's guide, the
   microcode update is stored in a 2,048 byte long block of data, whereas
   Intel claims that "No executable code resides within the update." -- a
   claim which is not entirely true. Although the data is encrypted --
   "The encryption scheme also guards against tampering of the update
   data and provides a means for determining the authenticity of any
   given [...] update." -- it does contain some code which later, inside
   the chip, is executed: microcode.
   Furthermore, Intel claims that "The data within the update is [...]
   designed such that it is rejected by any stepping of the processor
   other than its intended recipient. Thus, a given [...] Update is
   associated with a particular family, model, and stepping of the
   processor as returned by the CPUID instruction." In fact the data
   contains quite some revision information -- refer to the layout of the
   data block below --, which is checked by the loading mechanism,
   described later.
   
   bits and description offset
   31 24 23 16 15 8 7 0
   header revision #1 +000h
   update revision #2 +004h
   month day year #3 +008h
   reserved type family model step #4 +00Ch
   checksum #5 +010h
   loader revision #6 +014h
   reserved #7 +018h
   ...
   +02Ch
   update data #8 +030h
   ...
   +7FCh
   notes description
   #1 update block header version number (defines layout, currently
   00000001h)
   #2 unique update version number, basis for the MSR 8Bh (see below)
   #3 update creation date (BCD format, eg. 07181995h for July 18th 1995)
   #4 target processor's [45]CPUID type, family, model, and stepping
   (must match)
   #5 if the sum of all 512 doublewords is zero, then the update is
   (probably) okay
   #6 required update loader version (must match, currently 00000001h)
   #7 reserved for future expansions
   #8 update block data (microcode)
   
   To load a microcode update, the following procedure is
   required/recommended. First, the loader must store the 2,048 byte
   microcode update block in memory. It must ensure that this memory can
   be accessed in the current operating mode, eg. that neither
   segmentation, nor paging protection will cause any problems. No
   particular alignment is required. Then it must check the header
   revision. Only if it is equal to 00000001h, the format, given above,
   is valid.
   As a next step the loader must query the CPUID information of the used
   microprocessor, and compare it to the CPUID information, stored in the
   microcode update block header. In multi-processor environments this
   must be done for the target microprocessor, as different versions of
   the same microprocessor might be used in one system. This check must
   include a test of the [46]MSR 8Bh value (the update signature, see
   below), to ensure that the microcode update is newer than a possibly
   already loaded microcode update.
   Finally, the loader must check, whether the microcode update is
   authentic, by calculating the checksum, and comparing it to zero. Only
   after all these steps, the loader can load EAX with the linear base
   address of the update block data (not the header!), EDX with zero, and
   execute a [47]WRMSR instruction, using MSR 79h. Although the update is
   possible in any microprocessor mode, the WRMSR is a privileged
   instruction, and thus requires real mode, or protected mode CPL=0.
   After the microprocessor has executed the WRMSR instruction, the
   loader should check, whether the microcode update was loaded into the
   chip. This can be done by using the above mentioned MSR 8Bh. When
   [48]CPUID level #1 is queried, in addition to the regular output, MSR
   8Bh will be loaded with the update revision (see above, offset +004h),
   if any microcode update is currently active. If MSR 8Bh is not changed
   by such a CPUID, then no microcode update has been loaded (or loading
   one has failed).
   That way, MSR 8Bh and the update revision value can be used, to
   confirm a successful microcode update, or to check, whether a
   microcode update is required. (If MSR 8Bh returns a higher value, than
   stored in some microcode update block, then a newer block already has
   been loaded earlier, and no further update loading is required.) To
   remove microcode updates, a [49]RESET is required (but not just an
   INIT!). Also, it is guaranteed that the microprocessor executes
   without microcode updates, and rejects wrong updates.
   All the above information comes from chapter 8 of the PentiumPro BIOS
   writer's guide. In addition, this document contains the (long)
   description of an API, based on INT 15h, which is supposed to be used
   by BIOS vendors, to implement the above functionality. Details can be
   obtained by reading the BIOS writer's guide, using Intel's PentiumPro
   processor BIOS reference kit, or by browsing through the famous
   [50]DOS interrupt list, maintained by Ralf Brown.
   BTW, many people have been wondering about the very large transistor
   count of the P6 core, used in the PentiumPro and PentiumII
   microprocessors, as well as the Pentium with MMX technology processor
   core, when compared to a classic Pentium core. A microcode update must
   be stored somewhere in the chip, and one bit of RAM requires more
   transistors than a ROM bit. The mentioned processors support microcode
   updates, and thus include a storage array for them, in addition to
   their microcode ROM.
   
                                   Future
                                      
   One thing is for sure: most new microprocessors will implement a
   microcode update feature. But there might be more potential, hidden in
   this technology. In example, take a look at this [51]announcement from
   International Meta Systems ([52]IMS). If you look up the [53]patent,
   which is metioned there, then you will see, that the same
   microprocessor could be configured to execute several different
   instruction sets, just by loading a different microcode.
   A potential limitation is, that only one microcode can be active at a
   time. This prevents executing two instruction sets, as it is supposed
   to be possible with eg. [54]IA64 and Merced. On the other hand, there
   are quite some 80x86 emulations on the market by now -- click [55]here
   for links -- which would allow an interesting combination: For full
   performance a microprocessor could be used with a special microcode
   update, while for the occasional use of some different instruction set
   an emulation would be good enough.
   
                                 Questions
                                      
   It has been asked, whether the well-known [56]Pentium FDIV bug could
   have been fixed that way. Well, even if the Pentium would have had
   some microcode update feature (which it did not), the problem, caused
   by wrong entries in a hard-wired data table for the SRT division
   algorithm (more [57]details, 200 KB), could only have been fixed, if
   this table would have been updateable too. It could be very
   interesting to compare the extra costs for a microcode update feature
   to the costs of Intel's Pentium exchange program.
   Also, it has been asked, whether the well-known [58]PentiumPro and
   [59]PentiumII FIST bug could be fixed that way. According to Intel's
   [60]documentation (750 KB) the FIST instruction is not complex, but
   broken into four simple OPs. Thus it is unlikely, that microcode is
   used for FIST itself. But since the bug occurs when an exception is
   caused, and the Performance Monitoring [61]event list for both the
   PentiumPro and PentiumII contains an event named "microcode handled
   floating point exception cases", it might be possible.
   Finally, it has been asked, whether it would be possible to create
   your own version of microcode, which could in example be optimized, or
   even add more functionality, eg. new instructions. This question can
   be answered with a no. To create such a microcode some would need
   information about the interna of the target microprocessor, which
   exceed the level of all known documentation. The only possible way is,
   if those, who originally created the microprocessor, do create the
   microcode updates.
   [INLINE] Another issue which was brought up in a follow-up [62]article
   in the [63]EE Times, also written by Alexander Wolfe, dated July 10th
   1997, is the possibility of faked microcode updates. Someone could
   modify the data block, and adapt the checksums, so that an update
   looks authentic. Although encryption is supposed to avoid that, and
   probably other protection mechanisms are used by the vendor, but will
   never be publically documented, nor even ever mentioned, this scenario
   is possible.
   [INLINE] The most likely result when trying to load a faked update,
   which nevertheless looks authentic to the user, or the microcode
   loader, is that the microprocessor refuses to active such an update
   after loading it, due to the above mentioned security checks. In the
   rare occasion of a faked update, which would pass all these
   undocumented tests, the result would be a hang in most cases, but a
   slight chance of modified microprocessor operation remains.
   Conclusion:
   Not only would it be very foolish, if a vendor releases all the
   details about the used microcode, since such a vendor would give
   valuable information away to its competitors, but also disclosing such
   information may lead customers to their own experiments, which, as
   soon as they fail, would be blamed on the vendor. The microcode update
   feature is only powerful, and does help, if it is used appropriately,
   in example through vendor-provided updates. As mentioned above, IBM is
   a good [64]example here.
   I hope, that you did enjoy the above thoughts, as I enjoyed writing
   them down. If you should have any questions or comments, then please,
   let me know by dropping me an [65]eMail.
   
                            [INLINE] & [INLINE]
                                  07/20/97
                                   Update
                                      
   The sandpile.org website is proud to provide you with microcode
   updates for the Intel PentiumPro and PentiumII processors, even before
   Intel itself is doing so. Recently I came accross a [66]public FTP
   site, where I found the appropriate files. Both, a version 2.0, dated
   September 1996, as well as the brand new version 3.2, dated June 1997,
   are available for a free download from there. Since the help file
   doesn't claim anything like "confidential", you can download the
   packages directly from here too.
   
   version release date download size file (WWW) file (FTP)
   2.0 09/96 57.937 [67]UPDATE20.ZIP [68]UPDATE20.ZIP
   3.2 06/97 63.872 [69]UPDATE32.ZIP [70]UPDATE32.ZIP
   ______________________________________________________________________
                                      
                                 [71][LINK]
   This website has been accessed 306998 times since November 20th 1996.
    According to daily provided server logs 2377476 hits did occur until
                                 yesterday.

References

   1. http://www.sandpile.org/misc/addanad.shtml
   2. http://www.asus.com.tw/
   3. http://www.sandpile.org/misc/mail.shtml
   4. http://www.asus.com.tw/
   5. http://www.sandpile.org/misc/news.shtml
   6. http://www.sandpile.org/misc/search.shtml
   7. http://www.sandpile.org/80x86/overview.shtml
   8. http://www.sandpile.org/80x86/mcupdate.shtml#overview
   9. http://www.sandpile.org/80x86/mcupdate.shtml#history
  10. http://www.sandpile.org/80x86/mcupdate.shtml#roots
  11. http://www.sandpile.org/80x86/mcupdate.shtml#variations
  12. http://www.sandpile.org/80x86/mcupdate.shtml#today
  13. http://www.sandpile.org/80x86/mcupdate.shtml#future
  14. http://www.sandpile.org/80x86/mcupdate.shtml#questions
  15. http://www.techweb.com/se/directlink.cgi?EET19970630S0007
  16. http://www.techweb.com/eet/
  17. http://www.intel.com/
  18. http://patent.womplex.ibm.com/
  19. http://www.sandpile.org/80x86/manuals.shtml
  20. http://www.sandpile.org/80x86/appendix.shtml
  21. http://techweb.cmp.com/eet/column1/wintel12.html
  22. http://www.vhdl.org/
  23. http://www.austin.ibm.com/support/micro/help.html
  24. http://www.dec.com/
  25. http://www.dec.com/info/DTJ802/DTJ802PF.PDF
  26. http://www.dec.com/info/DTJ809/DTJ809PF.PDF
  27. http://www.service.digital.com/FX32/
  28. http://www.dec.com/info/DTJ812/DTJ812PF.PDF
  29. http://www.chipanalyst.com/mpr/patents/LAWSUIT.PDF
  30. http://www.chipanalyst.com/
  31. http://www.amd.com/news/corppr/9619.html
  32. http://www.amd.com/
  33. http://www.sandpile.org/80x86/ia32/eflags.shtml
  34. http://www.sandpile.org/80x86/ia32/crx.shtml
  35. http://www.sandpile.org/80x86/cpuid.shtml
  36. http://www.sandpile.org/80x86/nexgen.shtml
  37. http://www.amd.com/products/cpg/nx586/support/toolbox.html
  38. http://www.sandpile.org/80x86/opcodes2.shtml
  39. http://www.cyrix.com/
  40. http://www.chips.ibm.com/
  41. http://www.alternativecpu.com/
  42. ftp://ftp.cyrix.com/TECH/PIPELOOP.EXE
  43. http://www.sandpile.org/80x86/ccr.shtml
  44. http://www.sandpile.org/80x86/opcodes1.shtml
  45. http://www.sandpile.org/80x86/cpuid.shtml#level1
  46. http://www.sandpile.org/80x86/msr_p6.shtml
  47. http://www.sandpile.org/80x86/wrmsr.shtml
  48. http://www.sandpile.org/80x86/cpuid.shtml#level1
  49. http://www.sandpile.org/80x86/reset.shtml
  50. http://www.cs.cmu.edu/afs/cs.cmu.edu/user/ralf/pub/WWW/
  51. http://www.imes.com/page4.html
  52. http://www.imes.com/
  53. http://patent.womplex.ibm.com/details?patent_number=5574927
  54. http://www.sandpile.org/80x86/ia64/index.shtml
  55. http://www.sandpile.org/80x86/80x86.shtml
  56. http://www.sandpile.org/80x86/bugs_p5.shtml
  57. ftp://download.intel.com/enduser_reseller/overdrive_processors/FPUWP.PDF
  58. http://www.sandpile.org/80x86/bugs_p6.shtml
  59. http://www.sandpile.org/80x86/bugs_p2.shtml
  60. ftp://download.intel.com/design/pentiumii/manuals/24281603.pdf
  61. http://www.sandpile.org/80x86/ev_p6.shtml
  62. http://www.techweb.com/se/directlink.cgi?EET19970714S0016
  63. http://www.techweb.com/eet/
  64. http://www.austin.ibm.com/support/micro/
  65. http://www.sandpile.org/misc/mail.shtml
  66. ftp://ftp.einsteinscomputer.com/pub/intel/p6/
  67. http://www.sandpile.org/80x86/mcupdate/update20.zip
  68. ftp://ftp.sandpile.org/mcupdate/update20.zip
  69. http://www.sandpile.org/80x86/mcupdate/update32.zip
  70. ftp://ftp.sandpile.org/mcupdate/update32.zip
  71. http://www.sandpile.org/80x86/index.shtml
