In the seven years the
DELL Precision 690 microcode update thread has been up on the bios-mods.com site no one has figured out how to run Harpertowns or even to boot with quad-core Clovertowns on the wrong motherboard revision. User DeathBringer has however posted this
insightful piece of code from module 0B_9.ROM of the DELL Precision 690 firmware. The code checks the CPUID and if it does not like what it sees it jumps to a subroutine to display messages on the VGA screen with and error status of 0x16 meaning
"Alert! Incompatible processor detected." It then halts the processor, preventing it from booting. It
may be possible to bypass the compatibility check and boot once by clearing the CMOS memory.
Code:
9FD8 push eax
9FDA mov eax, 1
9FE0 cpuid
9FE2 and ax, 0FFF0h
9FE5 cmp ax, 0F60h ; Dempsey
9FE8 jz short 0A00Ah
9FEA cmp ax, 6F0h ; Woodcrest & Clovertown
9FED jnz short 0A00Ah
9FEF call sub_AE1D ; reading byte in 0F000h:4D73h
9FF2 cmp al, 3
9FF4 jb short 0A00Ah
9FF6 mov al, 50h ; 'P'
9FF8 call 0F000h:0F18Ch ; reading CMOS memory
9FFD cmp al, 30h ; '0' ;
9FFF jnb short 0A00Ah
A001 mov cx, 16h ; set error status to 16h
A004 call sub_B7A5
A007 jmp 732Bh ; jump to halt state
A00A pop eax ; continued normal
Many users still believe the issue is missing microcode. It is not, the firmware has microcodes for quad-core Clovertown Xeons in both B3 and G0 steppings. I believe the issue is in the FGPI strappings.
Wrong strappings mean Clovertowns are "unsupported" and system refuses to boot.
Actually the code above with the simple
cpuid instruction cannot distinguish between dual-core 5100 Woodcrests and quad-core 5300 Clovertowns, as thay share the same die and CPUID. It will however prevent the system from booting with 5400-series Harpertowns.
Dempsey with CPUID 0F60h (Family ID F, Model 6, Stepping ID 0-4) is a Pentium 4-derived hyperthreaded dual-core processor. Despite its larger transistor count and its 3.7 GHz top frequency it has half the performance of Core 2-derived dual-core Xeons.
These are relevant CPU IDs. The Mac Pro 2,1 firmware actually supports Dempseys, although no Mac OS version may be able to boot on them.
CPUID (Stepping)
Dempsey (5000)
0F64 (C1)
Woodcrest / Clovertown (5100 / 5300)
06F6 (B2)
06F7 (B3)
06FB (G0)
Wolfdale / Harpertown (5200 / 5400)
0676 (C0)
067A (E0)
I checked if there were similar CPUID checks in the Mac Pro 2,1 firmware. I opened the Mac Pro EFI Firmware Update package that I had downloaded from Apple. After peeling though about ten layers of encapsulation (.dmgs, packages, .zips) I found the file named LOCKED_MP21_007F_06B.fd. I saved it on disk and opened it with UEFITool.
The EFI image containes three main parts, each with the same GUID of "7A9354D9-0468-444A-81CE-0BF617D890DF". The first part is 1572864 bytes (180000h) long and contains a DXE core and DXE drivers. The next 16384 byte (4000h) section contains mainly a raw section. (
Update August 21, 2020: GUID 00000000-0000-0000-0000-000000000000 contains the microcode updates.)
The last section is 262144 bytes long (40000h) and contains PEI modules. PEI stands for Pre-EFI Initialization. Two modules stand out, a PEI core and a SEC core. SEC or SECurity phase is the first part of EFI firmware to be executed.
I extracted module SEC core.fbd from the EFI image and saved it to disk. I then opened it with a demo version of the Hopper disassembler.
The module has code for both Dempsey (CPUID 0F60h) and Woodcrest / Clovertown (CPUID 06F0h) processors. Every time it sees the CPUID 06F0h it does some processor initialization specific to Core 2 processors. It seems evident that if this initialization is not done the system will not post or boot. A Harpertown processor with CPUID 0670h would not be initialized.
The code
compares the masked
CPUID against the value 6F0h (0x6f0 on the Hopper listing). If it is a match, it sets a bit in a Model Specific Register by
reading and writing to the register.
A simple way to add support for Harpertowns would be to do the same initializations to all Family 6 processors. This can be done by narrowing the CPUID mask to only cover the Family ID part of the bit vector.
The code
Code:
mov eax, 1
cpuid
and ax, 0xff0
cmp ax, 0x6f0
jne loc_13ab
would become.
Code:
...
cpuid
and ax, 0xf00
cmp ax, 0x600
...
0xF and 0x7 share the last three bits. If we wanted to be more restrictive we could write
Code:
and ax, 0xf70
cmp ax, 0x670
This would imply changing the least amount of bits in the code.
I also extracted the whole PEI section. It contains some 10 others calls to
cpuid. Two of these make an explicit compare to 0x6f0. These too need to be changed.
Update August 3, 2020: Would it be possible to combine the PEI code from the Intel S5000-series firmware with the rest of the EFI firmware from Mac Pro 2,1? At a minimum we might want to take the SEC core module from the Intel S5000XVN server board. (Actually we may want to use the Mac Pro 3,1 EFI with the Intel Pre-EFI Initialization.)
I extracted the SEC core module from the Intel R0098 BIOS update package. It has code to support all there LGA771 Xeon generations, Dempsey, Clovertown, and Harpertown. The coding style is different from the one used in the Mac Pro firmware. Mac explicitly checks for CPUIDs 0x6f0 and 0xf60. Intel assumes that it will ever see only three different CPUIDs, namely 0x6f0, 0x670, and 0xf60. Or at the minimum it assumes that any future Clovertown-compatible CPU will have a CPUID with a numerical value that is less than 0x6f.
The above is a typical example of the Intel code. It first checks to see if the bitmasked CPUID is less or equal to 0x6f0, i.e. the CPU is a Clovertown or Harpertown. If so it jumps to a "subroutine" section that sets certain bits in Model Specific Registers 0xe2 and 0x1a0. It then next compares the CPUID to 0xf60 and if it is a match it performs a different set of initializations. (Note that the "subroutine" sub_1a7f+118 shown in the yellow box on the right is actually the same code as on the left starting at address 00001af5. The arrows on the left also show the same control flow.)
There is only one time the code explicitly checks for the CPUID 0x670 (Harpertown). It is seen on line 000001b37 in the code above.
P.S. - I think I have found the Halt and Catch Fire (
HCF) instruction. It is located at address 00001d91. A jump to sub_1ce0+177, as used above, goes to this address. Note the address notation, 1ce0 is in hexadecimal and 177 is in decimal. I still have not figured out which CPUID combination actually goes there.
As far as I can tell there is only one difference in the behavior of the Intel SEC core module between Clovertowns and Harpertowns. In both cases Model Specific Registers
0x198 is read and
masked against a bitmask. Clovertowns with CPUID 0x6f0 read bits 0x1f while Harpertowns with CPUID 0x670 read one extra bit using bitmask 0x5f. I do not think the missing bit would prevent Harpertowns from booting on a Mac Pro, if only the Clovertown specific code of the Mac Pro 2,1 firmware was executed.
More on the Intel firmware file...
Compilers produce object modules from source files. An object module typically contains three parts, a .text segment for code, a .data segment for static and global variables and a relocation table (.reloc) containing relocation entries. A linker then combines the object modules into one executable program merging each of the segments. (At least I
think they do, but I have not written a dynamic linker/loader in 30 years.) A program that is executable in an operating system retains the relocation table. The loader can then map the local offsets to global addresses depending on where in the address space it loads the program.
Static firmware like the Pre-EFI Initialization part of the boot ROM would not need relocation tables. It sits at a fixed address defined by the processor architecture. As expected, the .bin image of the flash rom Intel offers as an alternative does not contain any .text or data or .reloc segments.
I was however surprised to see .text and .data segment and relocation tables in both the Apple and Intel EFI images. The processor would not know how to link and load these if it ever saw them on the flash rom chip! The EFI flash utility must therefore contain its own linker to create the .bin image for the flash chip. But why then does the EFI image contain padding files? Shouldn't the linker decide where it wants to put each piece of code in the binary image? (This is relevant as we may need to change the size of the padding files if we change the size of an object module.)
I was not able to open the Intel EFI image with UEFITool. I therefore decided to look for the SEC core module with a hex editor. The object modules in the EFI image are easy to spot. In clear text you can read ".text", ".data", and ".reloc" near the beginning of the module. The SEC core module was easy to find, as it was at the end of both files. Also, it may have been compiled with a different compiler that the other modules. In both EFI images the SEC core module has five segments, labeled .text, _TEXT_RE4, _TEXT_PR, data and .reloc. The Intel module is somewhat longer than the Apple module. (I suspect the "Apple" module actually comes from Intel, as part of the Intel® Firmware Support Package.)
From the Apple EFI image I had earlier extracted the SEC core module both as "Extract as is..." and "Extract body". The resulting files differed in the "SEC core.ffs" file having some extra bytes of header around the content of the "SEC core.fdb" file. I the hex editor I tried to cut a segment from the Intel EFI image along the same lines as the SEC core.ffs file was cut. The beginning was easy, but I am not 100% sure of the the end, as there was some extra padding after the module in the Intel file. (One must check if the file size matches the data in the EFI header.) In theory it should be possible to implant this module to the Apple EFI image by replacing its original SEC core. I don't think this alone would make the system boot, as there are still other CPUID checks in other parts of the Pre-EFI Initialization.
I am including a copy of the Intel SEC core module for commentary and research. (2,745 byte .zip file)
Update: I was able to replace the Apple SEC core module with the Intel SEC core module in the LOCKED_MP21_007F_06B.fd file using UEFITool. The file size stays the same at 200000h (2097152).